private static boolean mayExpectBoolean(CompletionParameters parameters) {
   for (ExpectedTypeInfo info : JavaSmartCompletionContributor.getExpectedTypes(parameters)) {
     PsiType type = info.getType();
     if (type instanceof PsiClassType || type == PsiType.BOOLEAN) return true;
   }
   return false;
 }
  public static CompletionResultSet addJavaSorting(
      final CompletionParameters parameters, CompletionResultSet result) {
    final PsiElement position = parameters.getPosition();
    final ExpectedTypeInfo[] expectedTypes =
        PsiJavaPatterns.psiElement()
                .beforeLeaf(PsiJavaPatterns.psiElement().withText("."))
                .accepts(position)
            ? ExpectedTypeInfo.EMPTY_ARRAY
            : JavaSmartCompletionContributor.getExpectedTypes(parameters);
    final CompletionType type = parameters.getCompletionType();
    final boolean smart = type == CompletionType.SMART;
    final boolean afterNew = JavaSmartCompletionContributor.AFTER_NEW.accepts(position);

    List<LookupElementWeigher> afterProximity = new ArrayList<LookupElementWeigher>();
    afterProximity.add(new PreferContainingSameWords(expectedTypes));
    if (smart) {
      afterProximity.add(new PreferFieldsAndGetters());
    }
    afterProximity.add(new PreferShorter(expectedTypes));

    CompletionSorter sorter = CompletionSorter.defaultSorter(parameters, result.getPrefixMatcher());
    if (!smart && afterNew) {
      sorter = sorter.weighBefore("liftShorter", new PreferExpected(true, expectedTypes));
    } else if (PsiTreeUtil.getParentOfType(position, PsiReferenceList.class) == null) {
      sorter =
          ((CompletionSorterImpl) sorter)
              .withClassifier("liftShorterClasses", true, new LiftShorterClasses(position));
    }
    if (smart) {
      sorter =
          sorter.weighAfter("priority", new PreferDefaultTypeWeigher(expectedTypes, parameters));
    }

    List<LookupElementWeigher> afterPrefix = ContainerUtil.newArrayList();
    if (!smart) {
      ContainerUtil.addIfNotNull(afterPrefix, preferStatics(position, expectedTypes));
    }
    ContainerUtil.addIfNotNull(afterPrefix, recursion(parameters, expectedTypes));
    if (!smart && !afterNew) {
      afterPrefix.add(new PreferExpected(false, expectedTypes));
    }
    Collections.addAll(
        afterPrefix,
        new PreferByKindWeigher(type, position),
        new PreferSimilarlyEnding(expectedTypes),
        new PreferNonGeneric(),
        new PreferAccessible(position),
        new PreferSimple(),
        new PreferEnumConstants(parameters));

    sorter =
        sorter.weighAfter(
            "prefix", afterPrefix.toArray(new LookupElementWeigher[afterPrefix.size()]));
    sorter =
        sorter.weighAfter(
            "proximity", afterProximity.toArray(new LookupElementWeigher[afterProximity.size()]));
    return result.withRelevanceSorter(sorter);
  }
 static void addExpectedTypeMembers(
     CompletionParameters parameters, final CompletionResultSet result) {
   if (parameters.getInvocationCount()
       <= 1) { // on second completion, StaticMemberProcessor will suggest those
     for (final ExpectedTypeInfo info :
         JavaSmartCompletionContributor.getExpectedTypes(parameters)) {
       new JavaMembersGetter(info.getDefaultType(), parameters).addMembers(false, result);
     }
   }
 }
            @Override
            @Nullable
            public ExpectedTypeInfo[] fun(final CompletionLocation location) {
              if (PsiJavaPatterns.psiElement()
                  .beforeLeaf(PsiJavaPatterns.psiElement().withText("."))
                  .accepts(location.getCompletionParameters().getPosition())) {
                return ExpectedTypeInfo.EMPTY_ARRAY;
              }

              return JavaSmartCompletionContributor.getExpectedTypes(
                  location.getCompletionParameters());
            }
 @Nullable
 public static Set<PsiType> getExpectedTypes(final CompletionParameters parameters) {
   final PsiExpression expr =
       PsiTreeUtil.getContextOfType(parameters.getPosition(), PsiExpression.class, true);
   if (expr != null) {
     final Set<PsiType> set = new THashSet<PsiType>();
     for (final ExpectedTypeInfo expectedInfo :
         JavaSmartCompletionContributor.getExpectedTypes(parameters)) {
       set.add(expectedInfo.getType());
     }
     return set;
   }
   return null;
 }
  public static CompletionResultSet addJavaSorting(
      final CompletionParameters parameters, CompletionResultSet result) {
    String prefix = result.getPrefixMatcher().getPrefix();
    final PsiElement position = parameters.getPosition();
    final ExpectedTypeInfo[] expectedTypes =
        PsiJavaPatterns.psiElement()
                .beforeLeaf(PsiJavaPatterns.psiElement().withText("."))
                .accepts(position)
            ? ExpectedTypeInfo.EMPTY_ARRAY
            : JavaSmartCompletionContributor.getExpectedTypes(parameters);
    final CompletionType type = parameters.getCompletionType();
    final boolean smart = type == CompletionType.SMART;
    final boolean afterNew = JavaSmartCompletionContributor.AFTER_NEW.accepts(position);

    List<LookupElementWeigher> afterNegativeStats = new ArrayList<LookupElementWeigher>();
    if (!smart) {
      ContainerUtil.addIfNotNull(afterNegativeStats, preferStatics(position));
    }
    afterNegativeStats.add(new PreferLocalVariablesLiteralsAndAnnoMethodsWeigher(type, position));
    ContainerUtil.addIfNotNull(afterNegativeStats, recursion(parameters, expectedTypes));
    if (!smart && !afterNew) {
      afterNegativeStats.add(new PreferExpected(false, expectedTypes));
    }
    afterNegativeStats.add(new PreferSimilarlyEnding(expectedTypes, prefix));

    List<LookupElementWeigher> afterProximity = new ArrayList<LookupElementWeigher>();
    afterProximity.add(new PreferContainingSameWords(expectedTypes));
    if (smart) {
      afterProximity.add(new PreferFieldsAndGetters());
    }
    afterProximity.add(new PreferShorter(expectedTypes, prefix));

    CompletionSorter sorter = CompletionSorter.defaultSorter(parameters, result.getPrefixMatcher());
    if (!smart && afterNew) {
      sorter = sorter.weighBefore("liftShorter", new PreferExpected(true, expectedTypes));
    } else {
      final ProjectFileIndex fileIndex =
          ProjectRootManager.getInstance(position.getProject()).getFileIndex();
      sorter =
          ((CompletionSorterImpl) sorter)
              .withClassifier(
                  "liftShorter",
                  true,
                  new ClassifierFactory<LookupElement>("liftShorterClasses") {
                    @Override
                    public Classifier<LookupElement> createClassifier(
                        Classifier<LookupElement> next) {
                      return new LiftShorterItemsClassifier(
                          next,
                          new LiftShorterItemsClassifier.LiftingCondition() {
                            @Override
                            public boolean shouldLift(
                                LookupElement shorterElement,
                                LookupElement longerElement,
                                ProcessingContext context) {
                              if (super.shouldLift(shorterElement, longerElement, context)) {
                                return true;
                              }
                              Object object = shorterElement.getObject();
                              if (object instanceof PsiClass) {
                                PsiFile file = ((PsiClass) object).getContainingFile();
                                if (file != null) {
                                  VirtualFile vFile = file.getOriginalFile().getVirtualFile();
                                  if (vFile != null && fileIndex.isInSource(vFile)) {
                                    return true;
                                  }
                                }
                              }
                              return false;
                            }
                          });
                    }
                  });
    }
    if (smart) {
      sorter =
          sorter.weighBefore(
              "negativeStats", new PreferDefaultTypeWeigher(expectedTypes, parameters));
    }
    sorter =
        sorter.weighAfter(
            "negativeStats",
            afterNegativeStats.toArray(new LookupElementWeigher[afterNegativeStats.size()]));
    sorter =
        sorter.weighAfter(
            "prefix",
            new PreferNonGeneric(),
            new PreferAccessible(position),
            new PreferSimple(),
            new PreferEnumConstants(parameters));
    sorter =
        sorter.weighAfter(
            "proximity", afterProximity.toArray(new LookupElementWeigher[afterProximity.size()]));
    return result.withRelevanceSorter(sorter);
  }