@Override
  protected void complete(final int time) {
    new CodeCompletionHandlerBase(type, false, false, true)
        .invokeCompletion(getProject(), getEditor(), time, false);

    Lookup lookup = LookupManager.getActiveLookup(myEditor);
    myItems = lookup == null ? null : lookup.getItems().toArray(LookupElement.EMPTY_ARRAY);
    myPrefix = lookup == null ? null : lookup.itemPattern(lookup.getItems().get(0));
  }
 public void update(final AnActionEvent e) {
   final EditorEx editor = myLanguageConsole.getConsoleEditor();
   final Lookup lookup = LookupManager.getActiveLookup(editor);
   e.getPresentation()
       .setEnabled(
           !editor.isRendererMode()
               && !myProcessHandler.isProcessTerminated()
               && (lookup == null || !(lookup.isCompletion() && lookup.isFocused())));
 }
 private static void addCurrentlySelectedItemToTop(
     Lookup lookup, List<LookupElement> items, LinkedHashSet<LookupElement> model) {
   if (!lookup.isSelectionTouched()) {
     LookupElement lastSelection = lookup.getCurrentItem();
     if (ContainerUtil.indexOfIdentity(items, lastSelection) >= 0) {
       model.add(lastSelection);
     }
   }
 }
  private void adjustPositionForLookup(@NotNull Lookup lookup) {
    if (!myHint.isVisible() || myEditor.isDisposed()) {
      Disposer.dispose(this);
      return;
    }

    IdeTooltip tooltip = myHint.getCurrentIdeTooltip();
    if (tooltip != null) {
      JRootPane root = myEditor.getComponent().getRootPane();
      if (root != null) {
        Point p = tooltip.getShowingPoint().getPoint(root.getLayeredPane());
        if (lookup.isPositionedAboveCaret()) {
          if (Position.above == tooltip.getPreferredPosition()) {
            myHint.pack();
            myHint.updatePosition(Position.below);
            myHint.updateLocation(p.x, p.y + tooltip.getPositionChangeY());
          }
        } else {
          if (Position.below == tooltip.getPreferredPosition()) {
            myHint.pack();
            myHint.updatePosition(Position.above);
            myHint.updateLocation(p.x, p.y - tooltip.getPositionChangeY());
          }
        }
      }
    }
  }
  private void invokeCompletion(final ExpressionContext context) {
    final Project project = context.getProject();
    final Editor editor = context.getEditor();

    final PsiFile psiFile = editor != null ? PsiUtilBase.getPsiFileInEditor(editor, project) : null;
    Runnable runnable =
        () -> {
          if (project.isDisposed()
              || editor == null
              || editor.isDisposed()
              || psiFile == null
              || !psiFile.isValid()) return;

          // it's invokeLater, so another completion could have started
          if (CompletionServiceImpl.getCompletionService().getCurrentCompletion() != null) return;

          CommandProcessor.getInstance()
              .executeCommand(
                  project,
                  () -> {
                    // if we're in some completion's insert handler, make sure our new completion
                    // isn't treated as the second invocation
                    CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);

                    invokeCompletionHandler(project, editor);
                    Lookup lookup = LookupManager.getInstance(project).getActiveLookup();

                    if (lookup != null) {
                      lookup.addLookupListener(
                          new MyLookupListener(context, myCheckCompletionChar));
                    }
                  },
                  "",
                  null);
        };
    ApplicationManager.getApplication().invokeLater(runnable);
  }
  public static StatisticsUpdate collectStatisticChanges(LookupElement item, final Lookup lookup) {
    applyLastCompletionStatisticsUpdate();

    final StatisticsInfo base = StatisticsWeigher.getBaseStatisticsInfo(item, null);
    if (base == StatisticsInfo.EMPTY) {
      return new StatisticsUpdate(StatisticsInfo.EMPTY);
    }

    StatisticsUpdate update =
        new StatisticsUpdate(
            StatisticsWeigher.composeStatsWithPrefix(base, lookup.itemPattern(item), true));
    ourPendingUpdate = update;
    Disposer.register(
        update,
        new Disposable() {
          @Override
          public void dispose() {
            //noinspection AssignmentToStaticFieldFromInstanceMethod
            ourPendingUpdate = null;
          }
        });

    return update;
  }
  @Override
  public Result acceptChar(char c, final int prefixLength, final Lookup lookup) {
    if (!lookup.getPsiFile().getLanguage().isKindOf(JavaLanguage.INSTANCE)) {
      return null;
    }

    LookupElement item = lookup.getCurrentItem();
    if (item == null) return null;

    final Object o = item.getObject();
    if (c == '!') {
      if (o instanceof PsiVariable) {
        if (PsiType.BOOLEAN.isAssignableFrom(((PsiVariable) o).getType()))
          return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
      }
      if (o instanceof PsiMethod) {
        final PsiType type = ((PsiMethod) o).getReturnType();
        if (type != null && PsiType.BOOLEAN.isAssignableFrom(type))
          return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
      }
      if (o instanceof PsiKeyword && ((PsiKeyword) o).textMatches(PsiKeyword.INSTANCEOF)) {
        return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
      }

      return null;
    }
    if (c == '.' && isWithinLiteral(lookup)) return Result.ADD_TO_PREFIX;

    if (c == ':') {
      PsiFile file = lookup.getPsiFile();
      PsiDocumentManager.getInstance(file.getProject())
          .commitDocument(lookup.getEditor().getDocument());
      PsiElement leaf = file.findElementAt(lookup.getEditor().getCaretModel().getOffset() - 1);
      if (PsiUtil.getLanguageLevel(file).isAtLeast(LanguageLevel.JDK_1_8)) {
        PsiStatement statement = PsiTreeUtil.getParentOfType(leaf, PsiStatement.class);
        if (statement == null
            || statement.getTextRange().getStartOffset()
                != leaf.getTextRange().getStartOffset()) { // not typing a statement label
          return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
        }
      }
      if (PsiTreeUtil.getParentOfType(leaf, PsiSwitchLabelStatement.class) != null
          || PsiTreeUtil.getParentOfType(leaf, PsiConditionalExpression.class) != null) {
        return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
      }
      return Result.HIDE_LOOKUP;
    }

    if (c == '[' || c == ']' || c == ')' || c == '>')
      return CharFilter.Result.SELECT_ITEM_AND_FINISH_LOOKUP;
    if (c == '<' && o instanceof PsiClass) return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
    if (c == '(') {
      if (o instanceof PsiClass) {
        if (PsiJavaPatterns.psiElement()
            .afterLeaf(PsiKeyword.NEW)
            .accepts(lookup.getPsiElement())) {
          return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
        }
        return Result.HIDE_LOOKUP;
      }
      if (o instanceof PsiType) {
        return Result.HIDE_LOOKUP;
      }
    }
    if ((c == ',' || c == '=') && o instanceof PsiVariable) {
      int lookupStart = lookup.getLookupStart();
      String name = ((PsiVariable) o).getName();
      if (lookupStart >= 0 && name != null && name.equals(lookup.itemPattern(item))) {
        return Result.HIDE_LOOKUP;
      }
    }

    if (c == '#'
        && PsiTreeUtil.getParentOfType(lookup.getPsiElement(), PsiDocComment.class) != null) {
      if (o instanceof PsiClass) {
        return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
      }
    }
    if (c == '(' && PsiKeyword.RETURN.equals(item.getLookupString())) {
      return Result.HIDE_LOOKUP;
    }
    return null;
  }
 private static boolean isWithinLiteral(final Lookup lookup) {
   PsiElement psiElement = lookup.getPsiElement();
   return psiElement != null && psiElement.getParent() instanceof PsiLiteralExpression;
 }