public void navigateByLink(@NotNull DocumentationComponent component, @Nullable PsiElement context, @NotNull String url) {
    myPrecalculatedDocumentation = null;
    component.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
    PsiElement psiElement = context != null ? context : component.getElement();
    if (psiElement == null) {
      return;
    }
    PsiManager manager = PsiManager.getInstance(getProject(psiElement));
    if (url.equals("external_doc")) {
      component.showExternalDoc();
      return;
    }
    if (url.startsWith("open")) {
      OrderEntry libraryEntry = libraryEntry(myProject, psiElement);
      if (libraryEntry != null) {
        ProjectSettingsService.getInstance(myProject).openLibraryOrSdkSettings(libraryEntry);
      }
    }
    else if (url.startsWith(DocumentationManagerProtocol.PSI_ELEMENT_PROTOCOL)) {
      ActionCallback callback = createActionCallback();
      callback.doWhenProcessed(() -> component.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)));
      ReadAction.nonBlocking(
        () -> getTarget(psiElement, url)
      ).finishOnUiThread(ModalityState.defaultModalityState(), target -> {
        if (target == null) {
          callback.setDone();
          return;
        }
        cancelAndFetchDocInfoByLink(component, new MyCollector(myProject, target.first, null, target.second, callback, false, false));
      }).submit(AppExecutorUtil.getAppExecutorService());
      return;
    }
    else {
      DocumentationProvider provider = getProviderFromElement(psiElement);
      boolean processed = false;
      if (provider instanceof CompositeDocumentationProvider) {
        for (DocumentationProvider p : ((CompositeDocumentationProvider)provider).getAllProviders()) {
          if (!(p instanceof ExternalDocumentationHandler externalHandler)) continue;

          if (externalHandler.canFetchDocumentationLink(url)) {
            String ref = externalHandler.extractRefFromLink(url);
            cancelAndFetchDocInfoByLink(component, new DocumentationCollector(psiElement, url, ref, p, false) {
              @Override
              public @Nls String getDocumentation() {
                return externalHandler.fetchExternalDocumentation(url, psiElement);
              }
            });
            processed = true;
          }
          else if (externalHandler.handleExternalLink(manager, url, psiElement)) {
            processed = true;
            break;
          }
        }
      }

      if (!processed) {
        cancelAndFetchDocInfoByLink(component, new DocumentationCollector(psiElement, url, null, provider, false) {
          @Override
          public @Nls String getDocumentation() {
            if (BrowserUtil.isAbsoluteURL(url)) {
              BrowserUtil.browse(url);
              return "";
            }
            else {
              return CodeInsightBundle.message("javadoc.error.resolving.url", url);
            }
          }
        });
      }
    }

    component.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
  }
public void navigateByLink(@NotNull DocumentationComponent component, @Nullable PsiElement context, @NotNull String url)