@Override
  protected void process(@NotNull PsiElement identifier,
                         @NotNull PsiClass psiClass,
                         @NotNull Collection<? super RelatedItemLineMarkerInfo<?>> result) {
    if (psiClass.getQualifiedName() == null) {
      return;
    }

    if (!PsiUtil.isInstantiable(psiClass)) {

      // non-instantiable, abstract/interface can be registered as
      // - component interface-class
      // - listener topic
      if (psiClass.hasModifierProperty(PsiModifier.ABSTRACT)) {
        Project project = psiClass.getProject();
        GlobalSearchScope scope = PluginRelatedLocatorsUtils.getCandidatesScope(project);
        if (IdeaPluginRegistrationIndex.isRegisteredComponentInterface(psiClass, scope)) {
          processComponent(identifier, psiClass, result, project, scope);
        }
        else if (IdeaPluginRegistrationIndex.isRegisteredListenerTopic(psiClass, scope)) {
          List<ListenerCandidate> listenerTargets = new SmartList<>();
          IdeaPluginRegistrationIndex.processListenerTopic(project, psiClass, scope, listener -> {
            listenerTargets.add(new ListenerCandidate(listener));
            return true;
          });
          result.add(LineMarkerInfoHelper.createListenerTopicLineMarkerInfo(listenerTargets, identifier));
        }
      }
      return;
    }

    Project project = psiClass.getProject();
    GlobalSearchScope candidatesScope = PluginRelatedLocatorsUtils.getCandidatesScope(project);

    // only extensions are not indexed via IdeaPluginRegistrationIndex
    if (!IdeaPluginRegistrationIndex.isRegisteredClass(psiClass, candidatesScope)) {
      List<ExtensionCandidate> epTargets = ExtensionLocatorKt.locateExtensionsByPsiClass(psiClass);
      if (!epTargets.isEmpty()) {
        result.add(LineMarkerInfoHelper.createExtensionLineMarkerInfo(epTargets, identifier));
      }
      return;
    }

    // Action/ActionGroup (most likely)
    // search all candidates, e.g. EmptyAction/NonTrivialActionGroup is registered multiple times
    if (IdeaPluginRegistrationIndex.isRegisteredActionOrGroup(psiClass, candidatesScope)) {
      List<ActionCandidate> targets = new SmartList<>();
      IdeaPluginRegistrationIndex.processActionOrGroupClass(project, psiClass, candidatesScope, actionOrGroup -> {
        targets.add(new ActionCandidate(actionOrGroup));
        return true;
      });
      if (InheritanceUtil.isInheritor(psiClass, ActionGroup.class.getName())) {
        result.add(LineMarkerInfoHelper.createActionGroupLineMarkerInfo(targets, identifier));
      }
      else {
        result.add(LineMarkerInfoHelper.createActionLineMarkerInfo(targets, identifier));
      }
      return;
    }

    // Listeners: search for _all_ candidates as
    // - some listeners are registered on both application- and project-level, e.g. com.intellij.notification.Notifications
    // - some classes implement multiple listeners, e.g. com.intellij.notification.impl.widget.NotificationWidgetListener
    List<ListenerCandidate> listenerTargets = new SmartList<>();
    IdeaPluginRegistrationIndex.processListener(project, psiClass, candidatesScope, listener -> {
      listenerTargets.add(new ListenerCandidate(listener));
      return true;
    });
    if (!listenerTargets.isEmpty()) {
      result.add(LineMarkerInfoHelper.createListenerLineMarkerInfo(listenerTargets, identifier));
      return;
    }

    processComponent(identifier, psiClass, result, project, candidatesScope);
  }
@Override
  protected void process(@NotNull PsiElement identifier,
                         @NotNull PsiClass psiClass,
                         @NotNull Collection<? super RelatedItemLineMarkerInfo<?>> result)