@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);
  }
  @Nullable
  public static PsiElement getTargetElement(LookupElement lookupElement) {
    PsiElement psiElement = lookupElement.getPsiElement();
    if (psiElement != null) {
      return getOriginalElement(psiElement);
    }

    Object object = lookupElement.getObject();
    if (object instanceof LookupValueWithPsiElement) {
      final PsiElement element = ((LookupValueWithPsiElement) object).getElement();
      if (element != null) return getOriginalElement(element);
    }

    return null;
  }