protected void completionFinished(
      final int offset1,
      final int offset2,
      final CompletionProgressIndicator indicator,
      final LookupElement[] items,
      boolean hasModifiers) {
    if (items.length == 0) {
      LookupManager.getInstance(indicator.getProject()).hideActiveLookup();
      indicator.handleEmptyLookup(true);
      checkNotSync(indicator, items);
      return;
    }

    LOG.assertTrue(!indicator.isRunning(), "running");
    LOG.assertTrue(!indicator.isCanceled(), "canceled");

    indicator.getLookup().refreshUi(true, false);
    final AutoCompletionDecision decision = shouldAutoComplete(indicator, items);
    if (decision == AutoCompletionDecision.SHOW_LOOKUP) {
      CompletionServiceImpl.setCompletionPhase(new CompletionPhase.ItemsCalculated(indicator));
      indicator.getLookup().setCalculating(false);
      indicator.showLookup();
    } else if (decision instanceof AutoCompletionDecision.InsertItem) {
      final Runnable restorePrefix = rememberDocumentState(indicator.getEditor());

      final LookupElement item = ((AutoCompletionDecision.InsertItem) decision).getElement();
      CommandProcessor.getInstance()
          .executeCommand(
              indicator.getProject(),
              new Runnable() {
                @Override
                public void run() {
                  indicator.setMergeCommand();
                  indicator.getLookup().finishLookup(Lookup.AUTO_INSERT_SELECT_CHAR, item);
                }
              },
              "Autocompletion",
              null);

      // the insert handler may have started a live template with completion
      if (CompletionService.getCompletionService().getCurrentCompletion() == null
          && !ApplicationManager.getApplication().isUnitTestMode()) {
        CompletionServiceImpl.setCompletionPhase(
            hasModifiers
                ? new CompletionPhase.InsertedSingleItem(indicator, restorePrefix)
                : CompletionPhase.NoCompletion);
      }
      checkNotSync(indicator, items);
    } else if (decision == AutoCompletionDecision.CLOSE_LOOKUP) {
      LookupManager.getInstance(indicator.getProject()).hideActiveLookup();
      checkNotSync(indicator, items);
    }
  }
  private LookupElement[] calculateItems(
      CompletionInitializationContext initContext, WeighingDelegate weigher) {
    duringCompletion(initContext);
    ProgressManager.checkCanceled();

    LookupElement[] result =
        CompletionService.getCompletionService().performCompletion(myParameters, weigher);
    ProgressManager.checkCanceled();

    weigher.waitFor();
    ProgressManager.checkCanceled();

    return result;
  }