test_class.file: core/src/test/java/org/carrot2/language/LanguageComponentsLoaderTest.java
test_class.identifier: LanguageComponentsLoaderTest
test_class.superclass: extends TestBase
test_case.body: @Test
    public void testMultipleSpiDeduplicatesProviders() {
      Map<String, List<LanguageComponentsProvider>> langs =
          LanguageComponentsLoader.loadProvidersFromSpi(
              getClass().getClassLoader(), getClass().getClassLoader());
  
      for (List<LanguageComponentsProvider> perLangProviders : langs.values()) {
        perLangProviders.stream()
            .collect(Collectors.groupingBy(LanguageComponentsProvider::getClass))
            .values()
            .forEach(
                providersByClass -> {
                  Assertions.assertThat(providersByClass).hasSize(1);
                });
      }
    }
test_case.class_method_signature: LanguageComponentsLoaderTest.testMultipleSpiDeduplicatesProviders()
test_case.full_signature: @Test public void testMultipleSpiDeduplicatesProviders()
test_case.identifier: testMultipleSpiDeduplicatesProviders
test_case.invocations: loadProvidersFromSpi getClassLoader getClass getClassLoader getClass values forEach values collect stream groupingBy hasSize assertThat
test_case.modifiers: @Test public
test_case.parameters: ()
test_case.return: void
test_case.signature: void testMultipleSpiDeduplicatesProviders()
focal_class.declarator: languageRestrictions
focal_class.modifier: private
focal_class.original_string: private Set<String> languageRestrictions;
focal_class.type: Set<String>
focal_class.var_name: languageRestrictions
focal_class.declarator: resourceLookupModifier
focal_class.modifier: private
focal_class.original_string: private Function<LanguageComponentsProvider, ResourceLookup> resourceLookupModifier;
focal_class.type: Function<LanguageComponentsProvider, ResourceLookup>
focal_class.var_name: resourceLookupModifier
focal_class.declarator: algorithmRestriction
focal_class.modifier: private
focal_class.original_string: private ClusteringAlgorithm[] algorithmRestriction;
focal_class.type: ClusteringAlgorithm[]
focal_class.var_name: algorithmRestriction
focal_class.file: core/src/main/java/org/carrot2/language/LanguageComponentsLoader.java
focal_class.identifier: LanguageComponentsLoader
focal_class.class_method_signature: LanguageComponentsLoader.load()
focal_class.full_signature: public LoadedLanguages load()
focal_class.identifier: load
focal_class.modifiers: public
focal_class.parameters: ()
focal_class.return: LoadedLanguages
focal_class.signature: LoadedLanguages load()
focal_class.class_method_signature: LanguageComponentsLoader.load(Map<String, List<LanguageComponentsProvider>> languageProviders)
focal_class.full_signature: public LoadedLanguages load(Map<String, List<LanguageComponentsProvider>> languageProviders)
focal_class.identifier: load
focal_class.modifiers: public
focal_class.parameters: (Map<String, List<LanguageComponentsProvider>> languageProviders)
focal_class.return: LoadedLanguages
focal_class.signature: LoadedLanguages load(Map<String, List<LanguageComponentsProvider>> languageProviders)
focal_class.class_method_signature: LanguageComponentsLoader.limitToLanguages(String... languages)
focal_class.full_signature: public LanguageComponentsLoader limitToLanguages(String... languages)
focal_class.identifier: limitToLanguages
focal_class.modifiers: public
focal_class.parameters: (String... languages)
focal_class.return: LanguageComponentsLoader
focal_class.signature: LanguageComponentsLoader limitToLanguages(String... languages)
focal_class.class_method_signature: LanguageComponentsLoader.limitToAlgorithms(ClusteringAlgorithm... algorithms)
focal_class.full_signature: public LanguageComponentsLoader limitToAlgorithms(ClusteringAlgorithm... algorithms)
focal_class.identifier: limitToAlgorithms
focal_class.modifiers: public
focal_class.parameters: (ClusteringAlgorithm... algorithms)
focal_class.return: LanguageComponentsLoader
focal_class.signature: LanguageComponentsLoader limitToAlgorithms(ClusteringAlgorithm... algorithms)
focal_class.class_method_signature: LanguageComponentsLoader.withResourceLookup(
        Function<LanguageComponentsProvider, ResourceLookup> resourceLookupModifier)
focal_class.full_signature: public LanguageComponentsLoader withResourceLookup(
        Function<LanguageComponentsProvider, ResourceLookup> resourceLookupModifier)
focal_class.identifier: withResourceLookup
focal_class.modifiers: public
focal_class.parameters: (
        Function<LanguageComponentsProvider, ResourceLookup> resourceLookupModifier)
focal_class.return: LanguageComponentsLoader
focal_class.signature: LanguageComponentsLoader withResourceLookup(
        Function<LanguageComponentsProvider, ResourceLookup> resourceLookupModifier)
focal_class.class_method_signature: LanguageComponentsLoader.sanityCheck(Map<String, List<LanguageComponentsProvider>> languageProviders)
focal_class.full_signature: private void sanityCheck(Map<String, List<LanguageComponentsProvider>> languageProviders)
focal_class.identifier: sanityCheck
focal_class.modifiers: private
focal_class.parameters: (Map<String, List<LanguageComponentsProvider>> languageProviders)
focal_class.return: void
focal_class.signature: void sanityCheck(Map<String, List<LanguageComponentsProvider>> languageProviders)
focal_class.class_method_signature: LanguageComponentsLoader.defaultSpiClassloader()
focal_class.full_signature: private ClassLoader defaultSpiClassloader()
focal_class.identifier: defaultSpiClassloader
focal_class.modifiers: private
focal_class.parameters: ()
focal_class.return: ClassLoader
focal_class.signature: ClassLoader defaultSpiClassloader()
focal_class.class_method_signature: LanguageComponentsLoader.loadProvidersFromSpi(
        ClassLoader... classloaders)
focal_class.full_signature: public static Map<String, List<LanguageComponentsProvider>> loadProvidersFromSpi(
        ClassLoader... classloaders)
focal_class.identifier: loadProvidersFromSpi
focal_class.modifiers: public static
focal_class.parameters: (
        ClassLoader... classloaders)
focal_class.return: Map<String, List<LanguageComponentsProvider>>
focal_class.signature: Map<String, List<LanguageComponentsProvider>> loadProvidersFromSpi(
        ClassLoader... classloaders)
focal_method.body: public static Map<String, List<LanguageComponentsProvider>> loadProvidersFromSpi(
        ClassLoader... classloaders) {
      Map<String, List<LanguageComponentsProvider>> providers = new TreeMap<>();
  
      BiPredicate<LanguageComponentsProvider, LanguageComponentsProvider> sameProvider =
          (p1, p2) -> {
            return Objects.equals(p1.name(), p2.name())
                && Objects.equals(p1.getClass(), p2.getClass())
                && Objects.equals(p1.componentTypes(), p2.componentTypes())
                && Objects.equals(p1.languages(), p2.languages());
          };
  
      for (ClassLoader classLoader : classloaders) {
        for (LanguageComponentsProvider candidate :
            ServiceLoader.load(LanguageComponentsProvider.class, classLoader)) {
          for (String language : candidate.languages()) {
            List<LanguageComponentsProvider> existingProviders =
                providers.computeIfAbsent(language, key -> new ArrayList<>());
  
            if (existingProviders.stream()
                .noneMatch(existing -> sameProvider.test(existing, candidate))) {
              existingProviders.add(candidate);
            }
          }
        }
      }
  
      return providers;
    }
focal_method.class_method_signature: LanguageComponentsLoader.loadProvidersFromSpi(
        ClassLoader... classloaders)
focal_method.full_signature: public static Map<String, List<LanguageComponentsProvider>> loadProvidersFromSpi(
        ClassLoader... classloaders)
focal_method.identifier: loadProvidersFromSpi
focal_method.invocations: equals name name equals getClass getClass equals componentTypes componentTypes equals languages languages load languages computeIfAbsent noneMatch stream test add
focal_method.modifiers: public static
focal_method.parameters: (
        ClassLoader... classloaders)
focal_method.return: Map<String, List<LanguageComponentsProvider>>
focal_method.signature: Map<String, List<LanguageComponentsProvider>> loadProvidersFromSpi(
        ClassLoader... classloaders)