@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 handleInsert(InsertionContext context) {
   myClassItem.handleInsert(context);
   super.handleInsert(context);
 }
  static Set<LookupElement> completeFinalReference(
      final PsiElement element,
      PsiJavaCodeReferenceElement reference,
      ElementFilter filter,
      final JavaSmartCompletionParameters parameters) {
    final Set<PsiField> used =
        parameters.getParameters().getInvocationCount() < 2
            ? findConstantsUsedInSwitch(element)
            : Collections.<PsiField>emptySet();

    final Set<LookupElement> elements =
        JavaSmartCompletionContributor.completeReference(
            element,
            reference,
            new AndFilter(
                filter,
                new ElementFilter() {
                  @Override
                  public boolean isAcceptable(Object o, PsiElement context) {
                    if (o instanceof CandidateInfo) {
                      final CandidateInfo info = (CandidateInfo) o;
                      final PsiElement member = info.getElement();

                      final PsiType expectedType = parameters.getExpectedType();
                      if (expectedType.equals(PsiType.VOID)) {
                        return member instanceof PsiMethod;
                      }

                      //noinspection SuspiciousMethodCalls
                      if (member instanceof PsiEnumConstant
                          && used.contains(CompletionUtil.getOriginalOrSelf(member))) {
                        return false;
                      }

                      return AssignableFromFilter.isAcceptable(
                          member, element, expectedType, info.getSubstitutor());
                    }
                    return false;
                  }

                  @Override
                  public boolean isClassAcceptable(Class hintClass) {
                    return true;
                  }
                }),
            false,
            true,
            parameters.getParameters(),
            PrefixMatcher.ALWAYS_TRUE);
    for (LookupElement lookupElement : elements) {
      if (lookupElement.getObject() instanceof PsiMethod) {
        final JavaMethodCallElement item =
            lookupElement.as(JavaMethodCallElement.CLASS_CONDITION_KEY);
        if (item != null) {
          final PsiMethod method = (PsiMethod) lookupElement.getObject();
          if (SmartCompletionDecorator.hasUnboundTypeParams(method, parameters.getExpectedType())) {
            item.setInferenceSubstitutor(
                SmartCompletionDecorator.calculateMethodReturnTypeSubstitutor(
                    method, parameters.getExpectedType()),
                element);
          }
        }
      }
    }

    return elements;
  }