protected void lookupItemSelected(
      final CompletionProgressIndicator indicator,
      @NotNull final LookupElement item,
      final char completionChar,
      final List<LookupElement> items) {
    if (indicator.isAutopopupCompletion()) {
      FeatureUsageTracker.getInstance()
          .triggerFeatureUsed(CodeCompletionFeatures.EDITING_COMPLETION_BASIC);
    }

    CompletionAssertions.WatchingInsertionContext context = null;
    try {
      Lookup lookup = indicator.getLookup();
      CompletionLookupArranger.StatisticsUpdate update =
          CompletionLookupArranger.collectStatisticChanges(item, lookup);
      context = insertItemHonorBlockSelection(indicator, item, completionChar, items, update);
      CompletionLookupArranger.trackStatistics(context, update);
    } finally {
      afterItemInsertion(indicator, context == null ? null : context.getLaterRunnable());
    }
  }
 @TestOnly
 public static void cleanupForNextTest() {
   CompletionProgressIndicator currentCompletion =
       CompletionServiceImpl.getCompletionService().getCurrentCompletion();
   if (currentCompletion != null) {
     currentCompletion.finishCompletionProcess(true);
     CompletionServiceImpl.assertPhase(CompletionPhase.NoCompletion.getClass());
   } else {
     CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
   }
   CompletionLookupArranger.cancelLastCompletionStatisticsUpdate();
 }
  public final void invokeCompletion(
      @NotNull final Project project,
      @NotNull final Editor editor,
      int time,
      boolean hasModifiers,
      boolean restarted,
      @NotNull final Caret caret) {
    markCaretAsProcessed(caret);

    if (invokedExplicitly) {
      CompletionLookupArranger.applyLastCompletionStatisticsUpdate();
    }

    checkNoWriteAccess();

    CompletionAssertions.checkEditorValid(editor);

    int offset = editor.getCaretModel().getOffset();
    if (editor.isViewer() || editor.getDocument().getRangeGuard(offset, offset) != null) {
      editor.getDocument().fireReadOnlyModificationAttempt();
      CodeInsightUtilBase.showReadOnlyViewWarning(editor);
      return;
    }

    if (!FileDocumentManager.getInstance().requestWriting(editor.getDocument(), project)) {
      return;
    }

    CompletionPhase phase = CompletionServiceImpl.getCompletionPhase();
    boolean repeated =
        phase.indicator != null && phase.indicator.isRepeatedInvocation(myCompletionType, editor);
    /*
    if (repeated && isAutocompleteCommonPrefixOnInvocation() && phase.fillInCommonPrefix()) {
      return;
    }
    */

    final int newTime = phase.newCompletionStarted(time, repeated);
    if (invokedExplicitly) {
      time = newTime;
    }
    final int invocationCount = time;
    if (CompletionServiceImpl.isPhase(CompletionPhase.InsertedSingleItem.class)) {
      CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
    }
    CompletionServiceImpl.assertPhase(
        CompletionPhase.NoCompletion.getClass(), CompletionPhase.CommittingDocuments.class);

    if (invocationCount > 1 && myCompletionType == CompletionType.BASIC) {
      FeatureUsageTracker.getInstance()
          .triggerFeatureUsed(CodeCompletionFeatures.SECOND_BASIC_COMPLETION);
    }

    final CompletionInitializationContext[] initializationContext = {null};

    Runnable initCmd =
        new Runnable() {
          @Override
          public void run() {
            Runnable runnable =
                new Runnable() {
                  @Override
                  public void run() {
                    EditorUtil.fillVirtualSpaceUntilCaret(editor);
                    PsiDocumentManager.getInstance(project).commitAllDocuments();
                    CompletionAssertions.checkEditorValid(editor);

                    final PsiFile psiFile = PsiUtilBase.getPsiFileInEditor(caret, project);
                    assert psiFile != null
                        : "no PSI file: "
                            + FileDocumentManager.getInstance().getFile(editor.getDocument());
                    psiFile.putUserData(PsiFileEx.BATCH_REFERENCE_PROCESSING, Boolean.TRUE);
                    CompletionAssertions.assertCommitSuccessful(editor, psiFile);

                    initializationContext[0] =
                        runContributorsBeforeCompletion(editor, psiFile, invocationCount, caret);
                  }
                };
            ApplicationManager.getApplication().runWriteAction(runnable);
          }
        };
    if (autopopup) {
      CommandProcessor.getInstance().runUndoTransparentAction(initCmd);
      if (!restarted && shouldSkipAutoPopup(editor, initializationContext[0].getFile())) {
        CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
        return;
      }
    } else {
      CommandProcessor.getInstance().executeCommand(project, initCmd, null, null);
    }

    insertDummyIdentifier(initializationContext[0], hasModifiers, invocationCount);
  }