protected @NotNull StringBuilder formatJDTagDescription(@Nullable String str,
                                                 @NotNull CharSequence firstLinePrefix,
                                                 @NotNull CharSequence continuationPrefix) {
    final int rightMargin = myCommonSettings.getRootSettings().getRightMargin(JavaLanguage.INSTANCE);
    final int maxCommentLength = rightMargin - continuationPrefix.length();
    final int firstLinePrefixLength = firstLinePrefix.length();
    final boolean firstLineShorter = firstLinePrefixLength > continuationPrefix.length();

    StringBuilder sb = new StringBuilder(firstLinePrefix);
    List<String> list;

    boolean canWrap = !mySettings.JD_PRESERVE_LINE_FEEDS || hasLineLongerThan(str, maxCommentLength);

    //If wrap comments selected, comments should be wrapped by the right margin
    if (myCommonSettings.WRAP_COMMENTS && canWrap) {
      list = toArrayWrapping(str, maxCommentLength);

      if (firstLineShorter
          && list != null && !list.isEmpty()
          && list.get(0).length() > rightMargin - firstLinePrefixLength)
      {
        list = new ArrayList<>();
        //want the first line to be shorter, according to it's prefix
        String firstLine = toArrayWrapping(str, rightMargin - firstLinePrefixLength).get(0);
        //so now first line is exactly same width we need
        list.add(firstLine);
        str = str.substring(firstLine.length());
        //actually there is one more problem - when first line has unclosed <pre> tag, substring should be processed if it's inside <pre>
        boolean unclosedPreTag = lineHasUnclosedPreTag(firstLine);
        if (unclosedPreTag) {
          str = PRE_TAG_START + str.replaceAll("^\\s+", "");
        }

        //getting all another lines according to their prefix
        List<String> subList = toArrayWrapping(str, maxCommentLength);

        //removing pre tag
        if (unclosedPreTag && subList != null && !subList.isEmpty()) {
          String firstLineTagRemoved = subList.get(0).substring(PRE_TAG_START.length());
          subList.set(0, firstLineTagRemoved);
        }
        if (subList != null) list.addAll(subList);
      }
    }
    else {
      list = toArray(str, new ArrayList<>());
    }

    if (list == null) {
      sb.append('\n');
    }
    else {
      int snippetBraceBalance = 0;
      boolean insidePreTag = false;
      for (int i = 0; i < list.size(); i++) {
        String line = list.get(i);
        if (line.isEmpty() && !mySettings.JD_KEEP_EMPTY_LINES) continue;
        if (i != 0) sb.append(continuationPrefix);
        if (line.isEmpty() && mySettings.JD_P_AT_EMPTY_LINES && !insidePreTag && !isFollowedByTagLine(list, i) && snippetBraceBalance == 0) {
          sb.append(P_START_TAG);
        }
        else {
          sb.append(line);

          // We want to track if we're inside <pre>...</pre> in order to not generate <p/> there.
          if (lineHasUnclosedPreTag(line)) {
            insidePreTag = true;
          }
          else if (lineHasClosingPreTag(line)) {
            insidePreTag = false;
          }

          if (snippetBraceBalance == 0) {
            if (lineHasUnclosedSnippetTag(line)) snippetBraceBalance = 1;
          } else {
            snippetBraceBalance += getLineSnippetTagBraceBalance(line);
          }
        }
        sb.append('\n');
      }
    }

    return sb;
  }
protected @NotNull StringBuilder formatJDTagDescription(@Nullable String str,
                                                 @NotNull CharSequence firstLinePrefix,
                                                 @NotNull CharSequence continuationPrefix)