private static @NotNull Map<Class<?>, Collection<Class<?>>> getTargetPsiClasses(@NotNull List<? extends PsiElement> elements) {
    if (!useOptimizedVisitors) return Collections.emptyMap();

    Map<Class<?>, Collection<Class<?>>> targetPsiClasses = new IdentityHashMap<>(100);
    Set<Class<?>> uniqueElementClasses = CollectionFactory.createSmallMemoryFootprintSet(100);
    for (int i = 0; i < elements.size(); i++) {
      PsiElement element = elements.get(i);
      Class<? extends PsiElement> elementClass = element.getClass();

      // this check guarantees that items are unique in value collections, so we can use simple lists inside
      if (uniqueElementClasses.add(elementClass)) {
        for (Class<?> aSuper : SELF_AND_SUPERS.get(elementClass)) {
          Collection<Class<?>> classes = targetPsiClasses.computeIfAbsent(aSuper, aClass -> {
            List<Class<?>> c = new ArrayList<>(10);
            if (!aSuper.isInterface() && !Modifier.isAbstract(aSuper.getModifiers())) { // PSI elements in the tree cannot be abstract
              c.add(aSuper);
            }
            return c;
          });
          classes.add(elementClass);
        }
      }
    }

    return targetPsiClasses;
  }
private static @NotNull Map<Class<?>, Collection<Class<?>>> getTargetPsiClasses(@NotNull List<? extends PsiElement> elements)