public static void addAllClasses(
      CompletionParameters parameters,
      final CompletionResultSet result,
      final InheritorsHolder inheritors) {
    if (!isClassNamePossible(parameters) || !mayStartClassName(result)) {
      return;
    }

    if (parameters.getInvocationCount() >= 2) {
      JavaClassNameCompletionContributor.addAllClasses(
          parameters,
          parameters.getInvocationCount() <= 2,
          result.getPrefixMatcher(),
          new Consumer<LookupElement>() {
            @Override
            public void consume(LookupElement element) {
              if (!inheritors.alreadyProcessed(element)) {
                result.addElement(element);
              }
            }
          });
    } else {
      advertiseSecondCompletion(parameters.getPosition().getProject(), result);
    }
  }
  public static void fillCompletionVariants(
      CompletionParameters parameters, CompletionResultSet result) {
    if (parameters.getCompletionType() != CompletionType.BASIC
        && parameters.getCompletionType() != CompletionType.SMART) {
      return;
    }

    PsiElement position = parameters.getPosition();
    if (psiElement(PsiIdentifier.class)
        .withParents(PsiJavaCodeReferenceElement.class, PsiTypeElement.class, PsiClass.class)
        .andNot(JavaCompletionData.AFTER_DOT)
        .andNot(psiElement().afterLeaf(psiElement().inside(PsiModifierList.class)))
        .accepts(position)) {
      suggestGeneratedMethods(result, position);
    } else if (psiElement(PsiIdentifier.class)
        .withParents(
            PsiJavaCodeReferenceElement.class,
            PsiAnnotation.class,
            PsiModifierList.class,
            PsiClass.class)
        .accepts(position)) {
      PsiAnnotation annotation =
          ObjectUtils.assertNotNull(PsiTreeUtil.getParentOfType(position, PsiAnnotation.class));
      int annoStart = annotation.getTextRange().getStartOffset();
      suggestGeneratedMethods(
          result.withPrefixMatcher(
              annotation.getText().substring(0, parameters.getOffset() - annoStart)),
          position);
    }
  }
  private static void addKeywords(CompletionParameters parameters, CompletionResultSet result) {
    PsiElement position = parameters.getPosition();
    final Set<LookupElement> lookupSet = new LinkedHashSet<LookupElement>();
    final Set<CompletionVariant> keywordVariants = new HashSet<CompletionVariant>();
    final JavaCompletionData completionData = getCompletionData(PsiUtil.getLanguageLevel(position));
    completionData.addKeywordVariants(keywordVariants, position, parameters.getOriginalFile());
    completionData.completeKeywordsBySet(
        lookupSet,
        keywordVariants,
        position,
        result.getPrefixMatcher(),
        parameters.getOriginalFile());
    completionData.fillCompletions(parameters, result);

    for (final LookupElement item : lookupSet) {
      result.addElement(item);
    }
  }
 public static void advertiseSecondCompletion(Project project, CompletionResultSet result) {
   if (FeatureUsageTracker.getInstance()
       .isToBeAdvertisedInLookup(CodeCompletionFeatures.SECOND_BASIC_COMPLETION, project)) {
     result.addLookupAdvertisement(
         "Press "
             + getActionShortcut(IdeActions.ACTION_CODE_COMPLETION)
             + " to see non-imported classes");
   }
 }
    @Override
    public boolean process(
        @NotNull String name,
        @NotNull GoNamedElement element,
        @NotNull ExistingImportData importData,
        @NotNull CompletionResultSet result) {
      GoTypeSpec spec = ((GoTypeSpec) element);
      boolean forTypes = myParent instanceof GoTypeReferenceExpression;
      double priority;
      if (importData.exists) {
        priority = forTypes ? GoCompletionUtil.TYPE_PRIORITY : GoCompletionUtil.TYPE_CONVERSION;
      } else {
        priority =
            forTypes
                ? GoCompletionUtil.NOT_IMPORTED_TYPE_PRIORITY
                : GoCompletionUtil.NOT_IMPORTED_TYPE_CONVERSION;
      }

      String lookupString = replacePackageWithAlias(name, importData.alias);
      if (forTypes) {
        result.addElement(
            GoCompletionUtil.createTypeLookupElement(
                spec,
                lookupString,
                GoAutoImportInsertHandler.SIMPLE_INSERT_HANDLER,
                importData.importPath,
                priority));
      } else {
        result.addElement(
            GoCompletionUtil.createTypeConversionLookupElement(
                spec,
                lookupString,
                GoAutoImportInsertHandler.TYPE_CONVERSION_INSERT_HANDLER,
                importData.importPath,
                priority));
      }
      return true;
    }
 private static void addSuperSignatureElements(
     final PsiClass parent,
     boolean implemented,
     CompletionResultSet result,
     Set<MethodSignature> addedSignatures) {
   for (CandidateInfo candidate :
       OverrideImplementExploreUtil.getMethodsToOverrideImplement(parent, implemented)) {
     PsiMethod baseMethod = (PsiMethod) candidate.getElement();
     PsiClass baseClass = baseMethod.getContainingClass();
     PsiSubstitutor substitutor = candidate.getSubstitutor();
     if (!baseMethod.isConstructor()
         && baseClass != null
         && addedSignatures.add(baseMethod.getSignature(substitutor))) {
       result.addElement(
           createOverridingLookupElement(implemented, baseMethod, baseClass, substitutor));
     }
   }
 }
 @Override
 public boolean process(
     @NotNull String name,
     @NotNull GoNamedElement element,
     @NotNull ExistingImportData importData,
     @NotNull CompletionResultSet result) {
   double priority =
       importData.exists
           ? GoCompletionUtil.VAR_PRIORITY
           : GoCompletionUtil.NOT_IMPORTED_VAR_PRIORITY;
   result.addElement(
       GoCompletionUtil.createVariableLikeLookupElement(
           element,
           replacePackageWithAlias(name, importData.alias),
           GoAutoImportInsertHandler.SIMPLE_INSERT_HANDLER,
           priority));
   return true;
 }
 @Override
 public boolean process(
     @NotNull String name,
     @NotNull GoNamedElement element,
     @NotNull ExistingImportData importData,
     @NotNull CompletionResultSet result) {
   GoFunctionDeclaration function = ((GoFunctionDeclaration) element);
   double priority =
       importData.exists
           ? GoCompletionUtil.FUNCTION_PRIORITY
           : GoCompletionUtil.NOT_IMPORTED_FUNCTION_PRIORITY;
   result.addElement(
       GoCompletionUtil.createFunctionOrMethodLookupElement(
           function,
           replacePackageWithAlias(name, importData.alias),
           GoAutoImportInsertHandler.FUNCTION_INSERT_HANDLER,
           priority));
   return true;
 }
  private static void addGetterSetterElements(
      CompletionResultSet result, PsiClass parent, Set<MethodSignature> addedSignatures) {
    int count = 0;
    for (PsiField field : parent.getFields()) {
      if (field instanceof PsiEnumConstant) continue;

      List<PsiMethod> prototypes = ContainerUtil.newSmartList();
      Collections.addAll(
          prototypes, GetterSetterPrototypeProvider.generateGetterSetters(field, true));
      Collections.addAll(
          prototypes, GetterSetterPrototypeProvider.generateGetterSetters(field, false));
      for (final PsiMethod prototype : prototypes) {
        if (parent.findMethodBySignature(prototype, false) == null
            && addedSignatures.add(prototype.getSignature(PsiSubstitutor.EMPTY))) {
          Icon icon = prototype.getIcon(Iconable.ICON_FLAG_VISIBILITY);
          result.addElement(
              createGenerateMethodElement(
                  prototype,
                  PsiSubstitutor.EMPTY,
                  icon,
                  "",
                  new InsertHandler<LookupElement>() {
                    @Override
                    public void handleInsert(InsertionContext context, LookupElement item) {
                      removeLookupString(context);

                      insertGenerationInfos(
                          context,
                          Collections.singletonList(new PsiGenerationInfo<PsiMethod>(prototype)));
                    }
                  }));

          if (count++ > 100) return;
        }
      }
    }
  }
 static void processLabelReference(CompletionResultSet result, PsiLabelReference ref) {
   for (String s : ref.getVariants()) {
     result.addElement(
         TailTypeDecorator.withTail(LookupElementBuilder.create(s), TailType.SEMICOLON));
   }
 }
  private static void completeAnnotationAttributeName(
      CompletionResultSet result, PsiElement insertedElement, CompletionParameters parameters) {
    PsiNameValuePair pair = PsiTreeUtil.getParentOfType(insertedElement, PsiNameValuePair.class);
    PsiAnnotationParameterList parameterList = (PsiAnnotationParameterList) pair.getParent();
    PsiAnnotation anno = (PsiAnnotation) parameterList.getParent();
    boolean showClasses = psiElement().afterLeaf("(").accepts(insertedElement);
    PsiClass annoClass = null;
    final PsiJavaCodeReferenceElement referenceElement = anno.getNameReferenceElement();
    if (referenceElement != null) {
      final PsiElement element = referenceElement.resolve();
      if (element instanceof PsiClass) {
        annoClass = (PsiClass) element;
        if (annoClass.findMethodsByName("value", false).length == 0) {
          showClasses = false;
        }
      }
    }

    if (showClasses && insertedElement.getParent() instanceof PsiReferenceExpression) {
      final Set<LookupElement> set =
          JavaCompletionUtil.processJavaReference(
              insertedElement,
              (PsiJavaReference) insertedElement.getParent(),
              new ElementExtractorFilter(createAnnotationFilter(insertedElement)),
              JavaCompletionProcessor.Options.DEFAULT_OPTIONS,
              result.getPrefixMatcher(),
              parameters);
      for (final LookupElement element : set) {
        result.addElement(element);
      }
      addAllClasses(parameters, result, new InheritorsHolder(insertedElement, result));
    }

    if (annoClass != null) {
      final PsiNameValuePair[] existingPairs = parameterList.getAttributes();

      methods:
      for (PsiMethod method : annoClass.getMethods()) {
        if (!(method instanceof PsiAnnotationMethod)) continue;

        final String attrName = method.getName();
        for (PsiNameValuePair existingAttr : existingPairs) {
          if (PsiTreeUtil.isAncestor(existingAttr, insertedElement, false)) break;
          if (Comparing.equal(existingAttr.getName(), attrName)
              || PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(attrName)
                  && existingAttr.getName() == null) continue methods;
        }
        LookupElementBuilder element =
            LookupElementBuilder.createWithIcon(method)
                .withInsertHandler(
                    new InsertHandler<LookupElement>() {
                      @Override
                      public void handleInsert(InsertionContext context, LookupElement item) {
                        final Editor editor = context.getEditor();
                        TailType.EQ.processTail(editor, editor.getCaretModel().getOffset());
                        context.setAddCompletionChar(false);

                        context.commitDocument();
                        PsiAnnotationParameterList paramList =
                            PsiTreeUtil.findElementOfClassAtOffset(
                                context.getFile(),
                                context.getStartOffset(),
                                PsiAnnotationParameterList.class,
                                false);
                        if (paramList != null
                            && paramList.getAttributes().length > 0
                            && paramList.getAttributes()[0].getName() == null) {
                          int valueOffset =
                              paramList.getAttributes()[0].getTextRange().getStartOffset();
                          context
                              .getDocument()
                              .insertString(
                                  valueOffset, PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME);
                          TailType.EQ.processTail(
                              editor,
                              valueOffset + PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.length());
                        }
                      }
                    });

        PsiAnnotationMemberValue defaultValue = ((PsiAnnotationMethod) method).getDefaultValue();
        if (defaultValue != null) {
          Object constant =
              JavaPsiFacade.getInstance(method.getProject())
                  .getConstantEvaluationHelper()
                  .computeConstantExpression(defaultValue);
          if (constant != null) {
            element =
                element.withTailText(
                    " default " + (constant instanceof String ? "\"" + constant + "\"" : constant),
                    true);
          }
        }

        result.addElement(element);
      }
    }
  }
 public static boolean mayStartClassName(CompletionResultSet result) {
   return StringUtil.isNotEmpty(result.getPrefixMatcher().getPrefix());
 }
  @Override
  public void fillCompletionVariants(
      final CompletionParameters parameters, final CompletionResultSet _result) {
    if (parameters.getCompletionType() != CompletionType.BASIC) {
      return;
    }

    final PsiElement position = parameters.getPosition();
    if (!isInJavaContext(position)) {
      return;
    }

    if (AFTER_NUMBER_LITERAL.accepts(position)
        || UNEXPECTED_REFERENCE_AFTER_DOT.accepts(position)) {
      _result.stopHere();
      return;
    }

    final CompletionResultSet result = JavaCompletionSorting.addJavaSorting(parameters, _result);

    if (ANNOTATION_ATTRIBUTE_NAME.accepts(position)
        && !JavaCompletionData.isAfterPrimitiveOrArrayType(position)) {
      JavaCompletionData.addExpectedTypeMembers(parameters, result);
      completeAnnotationAttributeName(result, position, parameters);
      result.stopHere();
      return;
    }

    final InheritorsHolder inheritors = new InheritorsHolder(position, result);
    if (JavaSmartCompletionContributor.IN_TYPE_ARGS.accepts(position)) {
      new TypeArgumentCompletionProvider(false, inheritors)
          .addCompletions(parameters, new ProcessingContext(), result);
    }

    PrefixMatcher matcher = result.getPrefixMatcher();
    if (JavaSmartCompletionContributor.AFTER_NEW.accepts(position)) {
      new JavaInheritorsGetter(ConstructorInsertHandler.BASIC_INSTANCE)
          .generateVariants(parameters, matcher, inheritors);
    }

    if (IMPORT_REFERENCE.accepts(position)) {
      result.addElement(LookupElementBuilder.create("*"));
    }

    addKeywords(parameters, result);

    Set<String> usedWords = addReferenceVariants(parameters, result, inheritors);

    if (psiElement().inside(PsiLiteralExpression.class).accepts(position)) {
      PsiReference reference = position.getContainingFile().findReferenceAt(parameters.getOffset());
      if (reference == null || reference.isSoft()) {
        WordCompletionContributor.addWordCompletionVariants(result, parameters, usedWords);
      }
    }

    JavaGenerateMemberCompletionContributor.fillCompletionVariants(parameters, result);

    addAllClasses(parameters, result, inheritors);

    final PsiElement parent = position.getParent();
    if (parent instanceof PsiReferenceExpression
        && !((PsiReferenceExpression) parent).isQualified()
        && parameters.isExtendedCompletion()
        && StringUtil.isNotEmpty(matcher.getPrefix())) {
      new JavaStaticMemberProcessor(parameters).processStaticMethodsGlobally(matcher, result);
    }
    result.stopHere();
  }