@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);
  }
  public static List<PsiMethod> getAllMethods(LookupElement item) {
    List<SmartPsiElementPointer<PsiMethod>> pointers = item.getUserData(ALL_METHODS_ATTRIBUTE);
    if (pointers == null) return null;

    return ContainerUtil.mapNotNull(
        pointers,
        new Function<SmartPsiElementPointer<PsiMethod>, PsiMethod>() {
          @Override
          public PsiMethod fun(SmartPsiElementPointer<PsiMethod> pointer) {
            return pointer.getElement();
          }
        });
  }
 static boolean isWrapped(LookupElement element) {
   return element.getUserData(WRAPPING_CONSTRUCTOR_CALL) != null;
 }
 public static PsiType getQualifierType(LookupElement item) {
   return item.getUserData(QUALIFIER_TYPE_ATTR);
 }