@Override
  public Object @NotNull [] getFileReferenceCompletionVariants(final FileReference reference) {
    final String s = reference.getText();
    if (s != null && s.equals("/")) {
      return ArrayUtilRt.EMPTY_OBJECT_ARRAY;
    }

    Condition<PsiFileSystemItem> filter = reference.getFileReferenceSet().getReferenceCompletionFilter();
    final CommonProcessors.CollectProcessor<PsiFileSystemItem> collector =
      new CommonProcessors.CollectProcessor<>(CollectionFactory.createCustomHashingStrategySet(VARIANTS_HASHING_STRATEGY));
    final PsiElementProcessor<PsiFileSystemItem> processor = new PsiElementProcessor<>() {
      @Override
      public boolean execute(@NotNull PsiFileSystemItem fileSystemItem) {
        return new FilteringProcessor<>(filter, collector).process(FileReference.getOriginalFile(fileSystemItem));
      }
    };

    List<Object> additionalItems = new ArrayList<>();
    for (PsiFileSystemItem context : reference.getContexts()) {
      for (final PsiElement child : context.getChildren()) {
        if (child instanceof PsiFileSystemItem) {
          processor.execute((PsiFileSystemItem)child);
        }
      }
      if (context instanceof FileReferenceResolver) {
        additionalItems.addAll(((FileReferenceResolver)context).getVariants(reference));
      }
    }

    final FileType[] types = reference.getFileReferenceSet().getSuitableFileTypes();
    final PsiElement[] candidates = PsiUtilCore.toPsiElementArray(collector.getResults());

    final Object[] variants = new Object[candidates.length + additionalItems.size()];
    for (int i = 0; i < candidates.length; i++) {
      PsiElement candidate = candidates[i];
      Object item = reference.createLookupItem(candidate);
      if (item == null) {
        item = FileInfoManager.getFileLookupItem(candidate);
      }
      if (candidate instanceof PsiFile && item instanceof LookupElement &&
          types.length > 0 && ArrayUtil.contains(((PsiFile)candidate).getFileType(), types)) {
        item = PrioritizedLookupElement.withPriority((LookupElement)item, Double.MAX_VALUE);
      }
      variants[i] = item;
    }

    for (int i = 0; i < additionalItems.size(); i++) {
      variants[i + candidates.length] = additionalItems.get(i);
    }
    if (!reference.getFileReferenceSet().isUrlEncoded()) {
      return variants;
    }
    List<Object> encodedVariants = new ArrayList<>(variants.length + additionalItems.size());
    for (int i = 0; i < candidates.length; i++) {
      final PsiElement element = candidates[i];
      if (element instanceof PsiNamedElement psiElement) {
        String name = psiElement.getName();
        final String encoded = reference.encode(name, psiElement);
        if (encoded == null) continue;
        if (!encoded.equals(name)) {
          final Icon icon = psiElement.getIcon(Iconable.ICON_FLAG_READ_STATUS | Iconable.ICON_FLAG_VISIBILITY);
          LookupElementBuilder item = FileInfoManager.getFileLookupItem(candidates[i], encoded, icon);
          encodedVariants.add(item.withTailText(" (" + name + ")"));
        }
        else {
          encodedVariants.add(variants[i]);
        }
      }
    }
    encodedVariants.addAll(additionalItems);
    return ArrayUtil.toObjectArray(encodedVariants);
  }
@Override
  public Object @NotNull [] getFileReferenceCompletionVariants(final FileReference reference)