boolean matches(@NotNull RuntimeModuleDescriptor moduleDescriptor) {
    String stringId = moduleDescriptor.getModuleId().getStringId();
    Boolean cached = myCache.get(stringId);
    if (cached != null) return cached;
    
    boolean matches;
    if (myIncompatibleRootModule.equals(stringId)) {
      matches = false;
    }
    else {
      myCache.put(stringId, true); //this is needed to prevent StackOverflowError in case of circular dependencies
      //noinspection SSBasedInspection
      matches = moduleDescriptor.getDependencies().stream().allMatch(this::matches);
    }
    myCache.put(stringId, matches);
    return matches;
  }
boolean matches(@NotNull RuntimeModuleDescriptor moduleDescriptor)