@Override
  public AutoCompletionDecision handleAutoCompletionPossibility(
      @NotNull AutoCompletionContext context) {
    final CompletionParameters parameters = context.getParameters();

    if (parameters.getCompletionType() != CompletionType.SMART
        && parameters.getCompletionType() != CompletionType.BASIC) {
      return null;
    }

    boolean needInsertBrace = false;
    boolean needInsertParenth = false;

    final LookupElement[] items = context.getItems();
    if (items.length > 1) {
      String commonName = null;
      final ArrayList<PsiMethod> allMethods = new ArrayList<PsiMethod>();
      for (LookupElement item : items) {
        Object o = item.getPsiElement();
        if (item.getUserData(LookupItem.FORCE_SHOW_SIGNATURE_ATTR) != null
            || !(o instanceof PsiMethod)) {
          return AutoCompletionDecision.SHOW_LOOKUP;
        }

        final PsiMethod method = (PsiMethod) o;
        final JavaChainLookupElement chain = item.as(JavaChainLookupElement.CLASS_CONDITION_KEY);
        final String name =
            method.getName() + "#" + (chain == null ? "" : chain.getQualifier().getLookupString());

        if (commonName != null && !commonName.equals(name)) {
          return AutoCompletionDecision.SHOW_LOOKUP;
        }

        if (hasOnlyClosureParams(method)) {
          needInsertBrace = true;
        } else {
          needInsertParenth = true;
        }

        if (needInsertBrace && needInsertParenth) {
          return AutoCompletionDecision.SHOW_LOOKUP;
        }

        commonName = name;
        allMethods.add(method);
        item.putUserData(JavaCompletionUtil.ALL_METHODS_ATTRIBUTE, allMethods);
      }
      return AutoCompletionDecision.insertItem(
          JavaMethodMergingContributor.findBestOverload(items));
    }

    return super.handleAutoCompletionPossibility(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;
  }