@NotNull
  static Runnable completeReference(final CompletionParameters parameters,
                                    final GrReferenceElement<?> reference,
                                    final JavaCompletionSession inheritorsHolder,
                                    final PrefixMatcher matcher,
                                    final @Nullable CompletionResultSet resultSet,
                                    final Consumer<? super LookupElement> _consumer) {
    final HashSet<LookupElement> addedElements = new HashSet<>();
    final Consumer<LookupElement> consumer = new Consumer<>() {
      final Set<LookupElement> added = addedElements;

      @Override
      public void consume(LookupElement element) {
        if (added.add(element)) {
          _consumer.consume(element);
        }
      }
    };

    final Map<PsiModifierListOwner, LookupElement> staticMembers = new HashMap<>();
    final PsiElement qualifier = reference.getQualifier();
    final PsiType qualifierType = GroovyCompletionUtil.getQualifierType(qualifier);

    if (reference instanceof GrReferenceExpression && (qualifier instanceof GrExpression || qualifier == null)) {
      for (String string : CompleteReferencesWithSameQualifier.getVariantsWithSameQualifier((GrReferenceExpression)reference, matcher, (GrExpression)qualifier)) {
        consumer.consume(LookupElementBuilder.create(string).withItemTextUnderlined(true));
      }
      if (parameters.getInvocationCount() < 2 && qualifier != null && qualifierType == null && !canResolveToPackage(qualifier)) {
        if (resultSet != null && parameters.getInvocationCount() == 1) {
          resultSet.addLookupAdvertisement(GroovyBundle.message("invoke.completion.second.time.to.show.skipped.methods"));
        }
        return EmptyRunnable.INSTANCE;
      }
    }

    final List<LookupElement> zeroPriority = new ArrayList<>();

    PsiClass qualifierClass = com.intellij.psi.util.PsiUtil.resolveClassInClassTypeOnly(qualifierType);
    final boolean honorExcludes = qualifierClass == null || !JavaCompletionUtil.isInExcludedPackage(qualifierClass, false);

    Consumer<LookupElement> elementConsumer = lookupElement -> {
      Object object = lookupElement.getObject();
      if (object instanceof GroovyResolveResult) {
        object = ((GroovyResolveResult)object).getElement();
      }

      if (isLightElementDeclaredDuringCompletion(object)) {
        return;
      }

      if (!(lookupElement instanceof LookupElementBuilder) && inheritorsHolder.alreadyProcessed(lookupElement)) {
        return;
      }

      if (honorExcludes && object instanceof PsiMember && JavaCompletionUtil.isInExcludedPackage((PsiMember)object, true)) {
        return;
      }

      if (!(object instanceof PsiClass)) {
        int priority = assignPriority(lookupElement, qualifierType);
        lookupElement = PrioritizedLookupElement.withPriority(lookupElement, priority);
        if (object != null) {
          lookupElement = JavaCompletionUtil.highlightIfNeeded(qualifierType, parameters.getOriginalFile().getVirtualFile(), lookupElement, object, reference);
        }
      }

      if ((object instanceof PsiMethod || object instanceof PsiField) &&
          ((PsiModifierListOwner)object).hasModifierProperty(PsiModifier.STATIC)) {
        if (lookupElement.getLookupString().equals(((PsiMember)object).getName())) {
          staticMembers.put(CompletionUtil.getOriginalOrSelf((PsiModifierListOwner)object), lookupElement);
        }
      }

      PrioritizedLookupElement<?> prioritized = lookupElement.as(PrioritizedLookupElement.CLASS_CONDITION_KEY);
      if (prioritized == null || prioritized.getPriority() == 0) {
        zeroPriority.add(lookupElement);
      }
      else {
        consumer.consume(lookupElement);
      }
    };

    GroovyCompletionUtil.processVariants(reference, matcher, parameters, elementConsumer);

    for (LookupElement element : zeroPriority) {
      consumer.consume(element);
    }
    zeroPriority.clear();

    if (qualifierType != null) {
      processImplicitSpread(qualifierType, consumer, matcher, addedElements);
    }

    if (qualifier == null) {
      return () -> {
        PsiFile file = reference.getContainingFile();
        if (!(file instanceof GroovyFileBaseImpl) || !(reference instanceof GrReferenceExpressionImpl)) {
          return;
        }
        CompleteReferenceExpression.processSpecificPlace(matcher, (GrReferenceExpressionImpl)reference, parameters, (processor) -> ((GroovyFileBaseImpl)file).processComplexImports(processor, ResolveUtilKt.initialState(true), reference), elementConsumer);
        for (LookupElement element : zeroPriority) {
          consumer.consume(element);
        }
        addStaticMembers(parameters, matcher, staticMembers, consumer).run();
      };
    }
    return EmptyRunnable.INSTANCE;
  }
@NotNull
  static Runnable completeReference(final CompletionParameters parameters,
                                    final GrReferenceElement<?> reference,
                                    final JavaCompletionSession inheritorsHolder,
                                    final PrefixMatcher matcher,
                                    final @Nullable CompletionResultSet resultSet,
                                    final Consumer<? super LookupElement> _consumer)