public static void addAllClasses(
      CompletionParameters parameters,
      final CompletionResultSet result,
      final InheritorsHolder inheritors) {
    if (!isClassNamePossible(parameters) || !mayStartClassName(result)) {
      return;
    }

    if (parameters.getInvocationCount() >= 2) {
      JavaClassNameCompletionContributor.addAllClasses(
          parameters,
          parameters.getInvocationCount() <= 2,
          result.getPrefixMatcher(),
          new Consumer<LookupElement>() {
            @Override
            public void consume(LookupElement element) {
              if (!inheritors.alreadyProcessed(element)) {
                result.addElement(element);
              }
            }
          });
    } else {
      advertiseSecondCompletion(parameters.getPosition().getProject(), result);
    }
  }
  private static void addKeywords(CompletionParameters parameters, CompletionResultSet result) {
    PsiElement position = parameters.getPosition();
    final Set<LookupElement> lookupSet = new LinkedHashSet<LookupElement>();
    final Set<CompletionVariant> keywordVariants = new HashSet<CompletionVariant>();
    final JavaCompletionData completionData = getCompletionData(PsiUtil.getLanguageLevel(position));
    completionData.addKeywordVariants(keywordVariants, position, parameters.getOriginalFile());
    completionData.completeKeywordsBySet(
        lookupSet,
        keywordVariants,
        position,
        result.getPrefixMatcher(),
        parameters.getOriginalFile());
    completionData.fillCompletions(parameters, result);

    for (final LookupElement item : lookupSet) {
      result.addElement(item);
    }
  }
 public static void advertiseSecondCompletion(Project project, CompletionResultSet result) {
   if (FeatureUsageTracker.getInstance()
       .isToBeAdvertisedInLookup(CodeCompletionFeatures.SECOND_BASIC_COMPLETION, project)) {
     result.addLookupAdvertisement(
         "Press "
             + getActionShortcut(IdeActions.ACTION_CODE_COMPLETION)
             + " to see non-imported classes");
   }
 }
 static void processLabelReference(CompletionResultSet result, PsiLabelReference ref) {
   for (String s : ref.getVariants()) {
     result.addElement(
         TailTypeDecorator.withTail(LookupElementBuilder.create(s), TailType.SEMICOLON));
   }
 }
  private static void completeAnnotationAttributeName(
      CompletionResultSet result, PsiElement insertedElement, CompletionParameters parameters) {
    PsiNameValuePair pair = PsiTreeUtil.getParentOfType(insertedElement, PsiNameValuePair.class);
    PsiAnnotationParameterList parameterList = (PsiAnnotationParameterList) pair.getParent();
    PsiAnnotation anno = (PsiAnnotation) parameterList.getParent();
    boolean showClasses = psiElement().afterLeaf("(").accepts(insertedElement);
    PsiClass annoClass = null;
    final PsiJavaCodeReferenceElement referenceElement = anno.getNameReferenceElement();
    if (referenceElement != null) {
      final PsiElement element = referenceElement.resolve();
      if (element instanceof PsiClass) {
        annoClass = (PsiClass) element;
        if (annoClass.findMethodsByName("value", false).length == 0) {
          showClasses = false;
        }
      }
    }

    if (showClasses && insertedElement.getParent() instanceof PsiReferenceExpression) {
      final Set<LookupElement> set =
          JavaCompletionUtil.processJavaReference(
              insertedElement,
              (PsiJavaReference) insertedElement.getParent(),
              new ElementExtractorFilter(createAnnotationFilter(insertedElement)),
              JavaCompletionProcessor.Options.DEFAULT_OPTIONS,
              result.getPrefixMatcher(),
              parameters);
      for (final LookupElement element : set) {
        result.addElement(element);
      }
      addAllClasses(parameters, result, new InheritorsHolder(insertedElement, result));
    }

    if (annoClass != null) {
      final PsiNameValuePair[] existingPairs = parameterList.getAttributes();

      methods:
      for (PsiMethod method : annoClass.getMethods()) {
        if (!(method instanceof PsiAnnotationMethod)) continue;

        final String attrName = method.getName();
        for (PsiNameValuePair existingAttr : existingPairs) {
          if (PsiTreeUtil.isAncestor(existingAttr, insertedElement, false)) break;
          if (Comparing.equal(existingAttr.getName(), attrName)
              || PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(attrName)
                  && existingAttr.getName() == null) continue methods;
        }
        LookupElementBuilder element =
            LookupElementBuilder.createWithIcon(method)
                .withInsertHandler(
                    new InsertHandler<LookupElement>() {
                      @Override
                      public void handleInsert(InsertionContext context, LookupElement item) {
                        final Editor editor = context.getEditor();
                        TailType.EQ.processTail(editor, editor.getCaretModel().getOffset());
                        context.setAddCompletionChar(false);

                        context.commitDocument();
                        PsiAnnotationParameterList paramList =
                            PsiTreeUtil.findElementOfClassAtOffset(
                                context.getFile(),
                                context.getStartOffset(),
                                PsiAnnotationParameterList.class,
                                false);
                        if (paramList != null
                            && paramList.getAttributes().length > 0
                            && paramList.getAttributes()[0].getName() == null) {
                          int valueOffset =
                              paramList.getAttributes()[0].getTextRange().getStartOffset();
                          context
                              .getDocument()
                              .insertString(
                                  valueOffset, PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME);
                          TailType.EQ.processTail(
                              editor,
                              valueOffset + PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.length());
                        }
                      }
                    });

        PsiAnnotationMemberValue defaultValue = ((PsiAnnotationMethod) method).getDefaultValue();
        if (defaultValue != null) {
          Object constant =
              JavaPsiFacade.getInstance(method.getProject())
                  .getConstantEvaluationHelper()
                  .computeConstantExpression(defaultValue);
          if (constant != null) {
            element =
                element.withTailText(
                    " default " + (constant instanceof String ? "\"" + constant + "\"" : constant),
                    true);
          }
        }

        result.addElement(element);
      }
    }
  }
 public static boolean mayStartClassName(CompletionResultSet result) {
   return StringUtil.isNotEmpty(result.getPrefixMatcher().getPrefix());
 }
  @Override
  public void fillCompletionVariants(
      final CompletionParameters parameters, final CompletionResultSet _result) {
    if (parameters.getCompletionType() != CompletionType.BASIC) {
      return;
    }

    final PsiElement position = parameters.getPosition();
    if (!isInJavaContext(position)) {
      return;
    }

    if (AFTER_NUMBER_LITERAL.accepts(position)
        || UNEXPECTED_REFERENCE_AFTER_DOT.accepts(position)) {
      _result.stopHere();
      return;
    }

    final CompletionResultSet result = JavaCompletionSorting.addJavaSorting(parameters, _result);

    if (ANNOTATION_ATTRIBUTE_NAME.accepts(position)
        && !JavaCompletionData.isAfterPrimitiveOrArrayType(position)) {
      JavaCompletionData.addExpectedTypeMembers(parameters, result);
      completeAnnotationAttributeName(result, position, parameters);
      result.stopHere();
      return;
    }

    final InheritorsHolder inheritors = new InheritorsHolder(position, result);
    if (JavaSmartCompletionContributor.IN_TYPE_ARGS.accepts(position)) {
      new TypeArgumentCompletionProvider(false, inheritors)
          .addCompletions(parameters, new ProcessingContext(), result);
    }

    PrefixMatcher matcher = result.getPrefixMatcher();
    if (JavaSmartCompletionContributor.AFTER_NEW.accepts(position)) {
      new JavaInheritorsGetter(ConstructorInsertHandler.BASIC_INSTANCE)
          .generateVariants(parameters, matcher, inheritors);
    }

    if (IMPORT_REFERENCE.accepts(position)) {
      result.addElement(LookupElementBuilder.create("*"));
    }

    addKeywords(parameters, result);

    Set<String> usedWords = addReferenceVariants(parameters, result, inheritors);

    if (psiElement().inside(PsiLiteralExpression.class).accepts(position)) {
      PsiReference reference = position.getContainingFile().findReferenceAt(parameters.getOffset());
      if (reference == null || reference.isSoft()) {
        WordCompletionContributor.addWordCompletionVariants(result, parameters, usedWords);
      }
    }

    JavaGenerateMemberCompletionContributor.fillCompletionVariants(parameters, result);

    addAllClasses(parameters, result, inheritors);

    final PsiElement parent = position.getParent();
    if (parent instanceof PsiReferenceExpression
        && !((PsiReferenceExpression) parent).isQualified()
        && parameters.isExtendedCompletion()
        && StringUtil.isNotEmpty(matcher.getPrefix())) {
      new JavaStaticMemberProcessor(parameters).processStaticMethodsGlobally(matcher, result);
    }
    result.stopHere();
  }