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 "";
  }
  public static void addImportForItem(InsertionContext context, PsiClass aClass) {
    if (aClass.getQualifiedName() == null) return;
    PsiFile file = context.getFile();

    int startOffset = context.getStartOffset();
    int tail = context.getTailOffset();
    int newTail = JavaCompletionUtil.insertClassReference(aClass, file, startOffset, tail);
    if (newTail > context.getDocument().getTextLength() || newTail < 0) {
      LOG.error(
          LogMessageEx.createEvent(
              "Invalid offset after insertion ",
              "offset="
                  + newTail
                  + "\n"
                  + "start="
                  + startOffset
                  + "\n"
                  + "tail="
                  + tail
                  + "\n"
                  + "file.length="
                  + file.getTextLength()
                  + "\n"
                  + "document="
                  + context.getDocument()
                  + "\n"
                  + DebugUtil.currentStackTrace(),
              AttachmentFactory.createAttachment(context.getDocument())));
      return;
    }
    context.setTailOffset(newTail);
    JavaCompletionUtil.shortenReference(file, context.getStartOffset());
    PostprocessReformattingAspect.getInstance(context.getProject()).doPostponedFormatting();
  }
  private static void qualifyFieldReference(InsertionContext context, PsiField field) {
    context.commitDocument();
    PsiFile file = context.getFile();
    final PsiReference reference = file.findReferenceAt(context.getStartOffset());
    if (reference instanceof PsiJavaCodeReferenceElement
        && ((PsiJavaCodeReferenceElement) reference).isQualified()) {
      return;
    }

    PsiClass containingClass = field.getContainingClass();
    if (containingClass != null && containingClass.getName() != null) {
      OffsetKey oldStart = context.trackOffset(context.getStartOffset(), true);
      JavaCompletionUtil.insertClassReference(containingClass, file, context.getStartOffset());
      context.getDocument().insertString(context.getOffsetMap().getOffset(oldStart), ".");
      PsiDocumentManager.getInstance(context.getProject()).commitDocument(context.getDocument());
    }
  }
  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);
  }