private CompletionInitializationContext runContributorsBeforeCompletion(
      Editor editor, PsiFile psiFile, int invocationCount, Caret caret) {
    final Ref<CompletionContributor> current = Ref.create(null);
    CompletionInitializationContext context =
        new CompletionInitializationContext(
            editor, caret, psiFile, myCompletionType, invocationCount) {
          CompletionContributor dummyIdentifierChanger;

          @Override
          public void setDummyIdentifier(@NotNull String dummyIdentifier) {
            super.setDummyIdentifier(dummyIdentifier);

            if (dummyIdentifierChanger != null) {
              LOG.error(
                  "Changing the dummy identifier twice, already changed by "
                      + dummyIdentifierChanger);
            }
            dummyIdentifierChanger = current.get();
          }
        };
    List<CompletionContributor> contributors =
        CompletionContributor.forLanguage(context.getPositionLanguage());
    Project project = psiFile.getProject();
    List<CompletionContributor> filteredContributors =
        DumbService.getInstance(project).filterByDumbAwareness(contributors);
    for (final CompletionContributor contributor : filteredContributors) {
      current.set(contributor);
      contributor.beforeCompletion(context);
      CompletionAssertions.checkEditorValid(editor);
      assert !PsiDocumentManager.getInstance(project).isUncommited(editor.getDocument())
          : "Contributor " + contributor + " left the document uncommitted";
    }
    return context;
  }
  private AutoCompletionDecision shouldAutoComplete(
      final CompletionProgressIndicator indicator, final LookupElement[] items) {
    if (!invokedExplicitly) {
      return AutoCompletionDecision.SHOW_LOOKUP;
    }
    final CompletionParameters parameters = indicator.getParameters();
    final LookupElement item = items[0];
    if (items.length == 1) {
      final AutoCompletionPolicy policy = getAutocompletionPolicy(item);
      if (policy == AutoCompletionPolicy.NEVER_AUTOCOMPLETE)
        return AutoCompletionDecision.SHOW_LOOKUP;
      if (policy == AutoCompletionPolicy.ALWAYS_AUTOCOMPLETE)
        return AutoCompletionDecision.insertItem(item);
      if (!indicator.getLookup().itemMatcher(item).isStartMatch(item))
        return AutoCompletionDecision.SHOW_LOOKUP;
    }
    if (!isAutocompleteOnInvocation(parameters.getCompletionType())) {
      return AutoCompletionDecision.SHOW_LOOKUP;
    }
    if (isInsideIdentifier(indicator.getOffsetMap())) {
      return AutoCompletionDecision.SHOW_LOOKUP;
    }
    if (items.length == 1
        && getAutocompletionPolicy(item) == AutoCompletionPolicy.GIVE_CHANCE_TO_OVERWRITE) {
      return AutoCompletionDecision.insertItem(item);
    }

    AutoCompletionContext context =
        new AutoCompletionContext(
            parameters, items, indicator.getOffsetMap(), indicator.getLookup());
    for (final CompletionContributor contributor :
        CompletionContributor.forParameters(parameters)) {
      final AutoCompletionDecision decision = contributor.handleAutoCompletionPossibility(context);
      if (decision != null) {
        return decision;
      }
    }

    return AutoCompletionDecision.SHOW_LOOKUP;
  }