private static boolean checkDependants(
      final IdeaPluginDescriptor pluginDescriptor,
      final Function<PluginId, IdeaPluginDescriptor> pluginId2Descriptor,
      final Condition<PluginId> check,
      final Set<PluginId> processed) {
    processed.add(pluginDescriptor.getPluginId());
    final PluginId[] dependentPluginIds = pluginDescriptor.getDependentPluginIds();
    final Set<PluginId> optionalDependencies =
        new HashSet<PluginId>(Arrays.asList(pluginDescriptor.getOptionalDependentPluginIds()));
    for (final PluginId dependentPluginId : dependentPluginIds) {
      if (processed.contains(dependentPluginId)) continue;

      // TODO[yole] should this condition be a parameter?
      if (isModuleDependency(dependentPluginId)
          && (ourAvailableModules.isEmpty()
              || ourAvailableModules.contains(dependentPluginId.getIdString()))) {
        continue;
      }
      if (!optionalDependencies.contains(dependentPluginId)) {
        if (!check.value(dependentPluginId)) {
          return false;
        }
        final IdeaPluginDescriptor dependantPluginDescriptor =
            pluginId2Descriptor.fun(dependentPluginId);
        if (dependantPluginDescriptor != null
            && !checkDependants(dependantPluginDescriptor, pluginId2Descriptor, check, processed)) {
          return false;
        }
      }
    }
    return true;
  }
  static Collection<URL> getClassLoaderUrls() {
    final ClassLoader classLoader = PluginManagerCore.class.getClassLoader();
    final Class<? extends ClassLoader> aClass = classLoader.getClass();
    try {
      @SuppressWarnings("unchecked")
      List<URL> urls = (List<URL>) aClass.getMethod("getUrls").invoke(classLoader);
      return urls;
    } catch (IllegalAccessException ignored) {
    } catch (InvocationTargetException ignored) {
    } catch (NoSuchMethodException ignored) {
    }

    if (classLoader instanceof URLClassLoader) {
      return Arrays.asList(((URLClassLoader) classLoader).getURLs());
    }

    return Collections.emptyList();
  }