public String calcGenerics(@NotNull PsiElement context, InsertionContext insertionContext) {
    if (insertionContext.getCompletionChar() == '<') {
      return "";
    }

    assert context.isValid();
    if (myDiamond) {
      return "<>";
    }

    if (getObject() instanceof PsiClass) {
      PsiClass psiClass = (PsiClass) getObject();
      PsiResolveHelper resolveHelper =
          JavaPsiFacade.getInstance(psiClass.getProject()).getResolveHelper();
      PsiSubstitutor substitutor = getSubstitutor();
      StringBuilder builder = new StringBuilder();
      for (PsiTypeParameter parameter : psiClass.getTypeParameters()) {
        PsiType substitute = substitutor.substitute(parameter);
        if (substitute == null
            || (PsiUtil.resolveClassInType(substitute) == parameter
                && resolveHelper.resolveReferencedClass(parameter.getName(), context)
                    != CompletionUtil.getOriginalOrSelf(parameter))) {
          return "";
        }
        if (builder.length() > 0) {
          builder.append(", ");
        }
        builder.append(substitute.getCanonicalText());
      }
      if (builder.length() > 0) {
        return "<" + builder + ">";
      }
    }
    return "";
  }
  private static PsiTypeLookupItem doCreateItem(
      final PsiType type,
      PsiElement context,
      int bracketsCount,
      boolean diamond,
      InsertHandler<PsiTypeLookupItem> importFixer) {
    if (type instanceof PsiClassType) {
      PsiClassType.ClassResolveResult classResolveResult = ((PsiClassType) type).resolveGenerics();
      final PsiClass psiClass = classResolveResult.getElement();

      if (psiClass != null) {
        String name = psiClass.getName();
        if (name != null) {
          final PsiSubstitutor substitutor = classResolveResult.getSubstitutor();

          PsiClass resolved =
              JavaPsiFacade.getInstance(psiClass.getProject())
                  .getResolveHelper()
                  .resolveReferencedClass(name, context);

          Set<String> allStrings = new HashSet<String>();
          allStrings.add(name);
          if (!psiClass.getManager().areElementsEquivalent(resolved, psiClass)
              && !PsiUtil.isInnerClass(psiClass)) {
            // inner class name should be shown qualified if its not accessible by single name
            PsiClass aClass = psiClass.getContainingClass();
            while (aClass != null && !PsiUtil.isInnerClass(aClass) && aClass.getName() != null) {
              name = aClass.getName() + '.' + name;
              allStrings.add(name);
              aClass = aClass.getContainingClass();
            }
          }

          PsiTypeLookupItem item =
              new PsiTypeLookupItem(
                  psiClass, name, diamond, bracketsCount, importFixer, substitutor);
          item.addLookupStrings(ArrayUtil.toStringArray(allStrings));
          return item;
        }
      }
    }
    return new PsiTypeLookupItem(
        type, type.getPresentableText(), false, bracketsCount, importFixer, PsiSubstitutor.EMPTY);
  }