public static void fillCompletionVariants(
      CompletionParameters parameters, CompletionResultSet result) {
    if (parameters.getCompletionType() != CompletionType.BASIC
        && parameters.getCompletionType() != CompletionType.SMART) {
      return;
    }

    PsiElement position = parameters.getPosition();
    if (psiElement(PsiIdentifier.class)
        .withParents(PsiJavaCodeReferenceElement.class, PsiTypeElement.class, PsiClass.class)
        .andNot(JavaCompletionData.AFTER_DOT)
        .andNot(psiElement().afterLeaf(psiElement().inside(PsiModifierList.class)))
        .accepts(position)) {
      suggestGeneratedMethods(result, position);
    } else if (psiElement(PsiIdentifier.class)
        .withParents(
            PsiJavaCodeReferenceElement.class,
            PsiAnnotation.class,
            PsiModifierList.class,
            PsiClass.class)
        .accepts(position)) {
      PsiAnnotation annotation =
          ObjectUtils.assertNotNull(PsiTreeUtil.getParentOfType(position, PsiAnnotation.class));
      int annoStart = annotation.getTextRange().getStartOffset();
      suggestGeneratedMethods(
          result.withPrefixMatcher(
              annotation.getText().substring(0, parameters.getOffset() - annoStart)),
          position);
    }
  }
  private static void suggestChainedCalls(
      CompletionParameters parameters, CompletionResultSet result, PsiElement position) {
    PsiElement parent = position.getParent();
    if (!(parent instanceof PsiJavaCodeReferenceElement)) {
      return;
    }
    PsiElement qualifier = ((PsiJavaCodeReferenceElement) parent).getQualifier();
    if (!(qualifier instanceof PsiJavaCodeReferenceElement)
        || ((PsiJavaCodeReferenceElement) qualifier).isQualified()
        || ((PsiJavaCodeReferenceElement) qualifier).resolve() != null) {
      return;
    }

    String fullPrefix =
        position
            .getContainingFile()
            .getText()
            .substring(parent.getTextRange().getStartOffset(), parameters.getOffset());
    CompletionResultSet qualifiedCollector = result.withPrefixMatcher(fullPrefix);
    ElementFilter filter = JavaCompletionContributor.getReferenceFilter(position);
    for (LookupElement base :
        suggestQualifierItems(parameters, (PsiJavaCodeReferenceElement) qualifier, filter)) {
      PsiType type = JavaCompletionUtil.getLookupElementType(base);
      if (type != null && !PsiType.VOID.equals(type)) {
        PsiReferenceExpression ref =
            ReferenceExpressionCompletionContributor.createMockReference(position, type, base);
        for (final LookupElement item :
            JavaSmartCompletionContributor.completeReference(
                position, ref, filter, true, true, parameters, result.getPrefixMatcher())) {
          qualifiedCollector.addElement(new JavaChainLookupElement(base, item));
        }
      }
    }
  }
  @Override
  public void fillCompletionVariants(
      @NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) {
    final JavaCompletionSession session = new JavaCompletionSession(result);
    ResultTracker tracker =
        new ResultTracker(result) {
          @Override
          public void consume(CompletionResult plainResult) {
            super.consume(plainResult);

            LookupElement element = plainResult.getLookupElement();
            Object o = element.getObject();
            if (o instanceof PsiClass) {
              session.registerClass((PsiClass) o);
            }
            if (element instanceof TypeArgumentCompletionProvider.TypeArgsLookupElement) {
              ((TypeArgumentCompletionProvider.TypeArgsLookupElement) element)
                  .registerSingleClass(session);
            }
          }
        };
    result.runRemainingContributors(parameters, tracker);
    final boolean empty = tracker.containsOnlyPackages || suggestAllAnnotations(parameters);

    if (!empty && parameters.getInvocationCount() == 0) {
      result.restartCompletionWhenNothingMatches();
    }

    if (empty) {
      delegate(parameters, JavaCompletionSorting.addJavaSorting(parameters, result), session);
    } else if (Registry.is("ide.completion.show.better.matching.classes")) {
      if (parameters.getCompletionType() == CompletionType.BASIC
          && parameters.getInvocationCount() <= 1
          && JavaCompletionContributor.mayStartClassName(result)
          && JavaCompletionContributor.isClassNamePossible(parameters)
          && !JavaSmartCompletionContributor.AFTER_NEW.accepts(parameters.getPosition())) {
        suggestNonImportedClasses(
            parameters,
            JavaCompletionSorting.addJavaSorting(
                parameters, result.withPrefixMatcher(tracker.betterMatcher)),
            session);
      }
    }
  }