@NotNull
 @Override
 public Comparable weigh(@NotNull LookupElement element) {
   final PsiTypeLookupItem lookupItem = element.as(PsiTypeLookupItem.CLASS_CONDITION_KEY);
   if (lookupItem != null) {
     return lookupItem.getBracketsCount() * 10 + (lookupItem.isAddArrayInitializer() ? 1 : 0);
   }
   if (element.as(CastingLookupElementDecorator.CLASS_CONDITION_KEY) != null) {
     return 239;
   }
   return 0;
 }
    @NotNull
    @Override
    public Comparable weigh(@NotNull LookupElement element) {
      final Object object = element.getObject();
      if (object instanceof PsiMethod) {
        PsiType type = ((PsiMethod) object).getReturnType();
        final JavaMethodCallElement callItem =
            element.as(JavaMethodCallElement.CLASS_CONDITION_KEY);
        if (callItem != null) {
          type = callItem.getSubstitutor().substitute(type);
        }

        if (type instanceof PsiClassType
            && ((PsiClassType) type).resolve() instanceof PsiTypeParameter) return 1;
      }

      return 0;
    }
  @Override
  public void renderElement(LookupElementPresentation presentation) {
    super.renderElement(presentation);
    final LookupElementPresentation qualifierPresentation = new LookupElementPresentation();
    myQualifier.renderElement(qualifierPresentation);
    String name = maybeAddParentheses(qualifierPresentation.getItemText());
    final String qualifierText =
        myQualifier.as(CastingLookupElementDecorator.CLASS_CONDITION_KEY) != null
            ? "(" + name + ")"
            : name;
    presentation.setItemText(qualifierText + "." + presentation.getItemText());

    if (myQualifier instanceof LookupItem && getQualifierObject() instanceof PsiClass) {
      String locationString =
          JavaPsiClassReferenceElement.getLocationString((LookupItem) myQualifier);
      presentation.setTailText(StringUtil.notNullize(presentation.getTailText()) + locationString);
    }
  }
  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;
  }
 @Nullable
 public static PsiType getLookupElementType(final LookupElement element) {
   TypedLookupItem typed = element.as(TypedLookupItem.CLASS_CONDITION_KEY);
   return typed != null ? typed.getType() : null;
 }
 @NotNull
 private LookupElement getComparableQualifier() {
   final CastingLookupElementDecorator casting =
       myQualifier.as(CastingLookupElementDecorator.CLASS_CONDITION_KEY);
   return casting == null ? myQualifier : casting.getDelegate();
 }