@Override
  public @Nls String generateDoc(PsiElement element, PsiElement originalElement) {
    // for new Class(<caret>) or methodCall(<caret>) proceed from method call or new expression
    // same for new Cl<caret>ass() or method<caret>Call()
    if (element instanceof PsiExpressionList ||
        element instanceof PsiReferenceExpression && element.getParent() instanceof PsiMethodCallExpression) {
      element = element.getParent();
      originalElement = null;
    }
    if (element instanceof PsiCallExpression && CodeInsightSettings.getInstance().SHOW_PARAMETER_NAME_HINTS_ON_COMPLETION) {
      PsiMethod method = CompletionMemory.getChosenMethod((PsiCallExpression)element);
      if (method != null) element = method;
    }
    if (element instanceof PsiMethodCallExpression) {
      return getMethodCandidateInfo((PsiMethodCallExpression)element);
    }

    if (element instanceof FakePsiElement) {
      PsiDocCommentBase docCommentBase = PsiTreeUtil.getParentOfType(originalElement, PsiDocCommentBase.class);
      if (docCommentBase != null) {
        element = docCommentBase.getOwner();
      }
    }

    // Try hard for documentation of incomplete new Class instantiation
    PsiElement elt = element;
    if (originalElement != null && !(originalElement instanceof PsiPackage || originalElement instanceof PsiFileSystemItem)) {
      elt = PsiTreeUtil.prevLeaf(originalElement);
    }
    if (elt instanceof PsiErrorElement) {
      elt = elt.getPrevSibling();
    }
    else if (elt != null && !(elt instanceof PsiNewExpression)) {
      elt = elt.getParent();
    }
    if (elt instanceof PsiNewExpression) {
      PsiClass targetClass = null;

      if (element instanceof PsiJavaCodeReferenceElement) {     // new Class<caret>
        PsiElement resolve = ((PsiJavaCodeReferenceElement)element).resolve();
        if (resolve instanceof PsiClass) targetClass = (PsiClass)resolve;
      }
      else if (element instanceof PsiClass) { //Class in completion
        targetClass = (PsiClass)element;
      }
      else if (element instanceof PsiNewExpression) { // new Class(<caret>)
        PsiJavaCodeReferenceElement reference = ((PsiNewExpression)element).getClassReference();
        if (reference != null) {
          PsiElement resolve = reference.resolve();
          if (resolve instanceof PsiClass) targetClass = (PsiClass)resolve;
        }
      }

      if (targetClass != null) {
        PsiMethod[] constructors = targetClass.getConstructors();
        if (constructors.length > 0) {
          if (constructors.length == 1) return generateDoc(constructors[0], originalElement);
          final StringBuilder sb = new StringBuilder();

          for (PsiMethod constructor : constructors) {
            final String str = PsiFormatUtil.formatMethod(constructor, PsiSubstitutor.EMPTY,
                                                          PsiFormatUtilBase.SHOW_NAME |
                                                          PsiFormatUtilBase.SHOW_TYPE |
                                                          PsiFormatUtilBase.SHOW_PARAMETERS,
                                                          PsiFormatUtilBase.SHOW_TYPE | PsiFormatUtilBase.SHOW_NAME);
            createElementLink(sb, constructor, StringUtil.escapeXmlEntities(str));
          }

          return JavaBundle.message("javadoc.constructor.candidates", targetClass.getName(), sb);
        }
      }
    }

    //external documentation finder
    return generateExternalJavadoc(element);
  }
@Override
  public @Nls String generateDoc(PsiElement element, PsiElement originalElement)