private static String getName(
      final PsiClass psiClass, final LookupItem<?> item, boolean diamond) {
    if (item instanceof JavaPsiClassReferenceElement) {
      String forced = ((JavaPsiClassReferenceElement) item).getForcedPresentableName();
      if (forced != null) {
        return forced;
      }
    }

    String name = PsiUtilCore.getName(psiClass);

    if (item.getAttribute(LookupItem.FORCE_QUALIFY) != null) {
      if (psiClass.getContainingClass() != null) {
        name = psiClass.getContainingClass().getName() + "." + name;
      }
    }

    if (diamond) {
      return name + "<>";
    }

    PsiSubstitutor substitutor = (PsiSubstitutor) item.getAttribute(LookupItem.SUBSTITUTOR);
    if (substitutor != null) {
      final PsiTypeParameter[] params = psiClass.getTypeParameters();
      if (params.length > 0) {
        return name + formatTypeParameters(substitutor, params);
      }
    }

    return StringUtil.notNullize(name);
  }
  public static void renderClassItem(
      LookupElementPresentation presentation, LookupItem item, PsiClass psiClass, boolean diamond) {
    if (!(psiClass instanceof PsiTypeParameter)) {
      presentation.setIcon(DefaultLookupItemRenderer.getRawIcon(item, presentation.isReal()));
    }

    final boolean bold = item.getAttribute(LookupItem.HIGHLIGHTED_ATTR) != null;
    boolean strikeout = JavaElementLookupRenderer.isToStrikeout(item);
    presentation.setItemText(getName(psiClass, item, diamond));
    presentation.setStrikeout(strikeout);
    presentation.setItemTextBold(bold);

    String tailText = StringUtil.notNullize((String) item.getAttribute(LookupItem.TAIL_TEXT_ATTR));
    PsiSubstitutor substitutor = (PsiSubstitutor) item.getAttribute(LookupItem.SUBSTITUTOR);

    if (item instanceof PsiTypeLookupItem
        && ((PsiTypeLookupItem) item).isIndicateAnonymous()
        && (psiClass.isInterface() || psiClass.hasModifierProperty(PsiModifier.ABSTRACT))) {
      tailText = "{...}" + tailText;
    }
    if (substitutor == null && !diamond && psiClass.getTypeParameters().length > 0) {
      tailText =
          "<"
              + StringUtil.join(
                  psiClass.getTypeParameters(),
                  new Function<PsiTypeParameter, String>() {
                    @Override
                    public String fun(PsiTypeParameter psiTypeParameter) {
                      return psiTypeParameter.getName();
                    }
                  },
                  "," + (showSpaceAfterComma(psiClass) ? " " : ""))
              + ">"
              + tailText;
    }
    presentation.setTailText(tailText, true);
  }
  public static boolean insertTail(
      InsertionContext context, LookupElement item, TailType tailType, boolean hasTail) {
    TailType toInsert = tailType;
    LookupItem<?> lookupItem = item.as(LookupItem.CLASS_CONDITION_KEY);
    if (lookupItem == null
        || lookupItem.getAttribute(LookupItem.TAIL_TYPE_ATTR) != TailType.UNKNOWN) {
      if (!hasTail
          && item.getObject() instanceof PsiMethod
          && ((PsiMethod) item.getObject()).getReturnType() == PsiType.VOID) {
        PsiDocumentManager.getInstance(context.getProject()).commitAllDocuments();
        if (psiElement()
            .beforeLeaf(psiElement().withText("."))
            .accepts(context.getFile().findElementAt(context.getTailOffset() - 1))) {
          return false;
        }

        boolean insertAdditionalSemicolon = true;
        final PsiReferenceExpression referenceExpression =
            PsiTreeUtil.getTopmostParentOfType(
                context.getFile().findElementAt(context.getStartOffset()),
                PsiReferenceExpression.class);
        if (referenceExpression instanceof PsiMethodReferenceExpression
            && LambdaHighlightingUtil.insertSemicolon(referenceExpression.getParent())) {
          insertAdditionalSemicolon = false;
        } else if (referenceExpression != null) {
          PsiElement parent = referenceExpression.getParent();
          if (parent instanceof PsiMethodCallExpression) {
            parent = parent.getParent();
          }
          if (parent instanceof PsiLambdaExpression
              && !LambdaHighlightingUtil.insertSemicolonAfter((PsiLambdaExpression) parent)) {
            insertAdditionalSemicolon = false;
          }
        }
        if (insertAdditionalSemicolon) {
          toInsert = TailType.SEMICOLON;
        }
      }
    }
    toInsert.processTail(context.getEditor(), context.getTailOffset());
    return true;
  }