@Override
    public <T> List<ExtensionWrapper<T>> find(Class<T> type) {
        log.debug("Finding extensions of extension point '{}'", type.getName());
        Map<String, Set<String>> entries = getEntries();
        List<ExtensionWrapper<T>> result = new ArrayList<>();

        // add extensions found in classpath and plugins
        for (String pluginId : entries.keySet()) {
            // classpath's extensions <=> pluginId = null
            List<ExtensionWrapper<T>> pluginExtensions = find(type, pluginId);
            result.addAll(pluginExtensions);
        }

        if (result.isEmpty()) {
            log.debug("No extensions found for extension point '{}'", type.getName());
        } else {
            log.debug("Found {} extensions for extension point '{}'", result.size(), type.getName());
        }

        // sort by "ordinal" property
        Collections.sort(result);

        return result;
    }
@Test
    public void testFindExtensionWrappersFromPluginId() {
        // complicate the test to show hot to deal with dynamic Java classes (generated at runtime from sources)
        PluginWrapper plugin3 = mock(PluginWrapper.class);
        JavaFileObject object = JavaSources.compile(DefaultExtensionFactoryTest.FailTestExtension);
        JavaFileObjectClassLoader classLoader = new JavaFileObjectClassLoader();
        classLoader.load(object);
        when(plugin3.getPluginClassLoader()).thenReturn(classLoader);
        when(plugin3.getPluginState()).thenReturn(PluginState.STARTED);
        when(pluginManager.getPluginClassLoader("plugin3")).thenReturn(classLoader);
        when(pluginManager.getPlugin("plugin3")).thenReturn(plugin3);

        ExtensionFinder instance = new AbstractExtensionFinder(pluginManager) {

            @Override
            public Map<String, Set<String>> readPluginsStorages() {
                Map<String, Set<String>> entries = new LinkedHashMap<>();

                Set<String> bucket = new HashSet<>();
                bucket.add("org.pf4j.test.TestExtension");
                entries.put("plugin1", bucket);
                bucket = new HashSet<>();
                bucket.add("org.pf4j.test.TestExtension");
                entries.put("plugin2", bucket);
                bucket = new HashSet<>();
                bucket.add(JavaFileObjectUtils.getClassName(object));
                entries.put("plugin3", bucket);

                return entries;
            }

            @Override
            public Map<String, Set<String>> readClasspathStorages() {
                return Collections.emptyMap();
            }

        };

        List<ExtensionWrapper> plugin1Result = instance.find("plugin1");
        assertEquals(1, plugin1Result.size());

        List<ExtensionWrapper> plugin2Result = instance.find("plugin2");
        assertEquals(0, plugin2Result.size());

        List<ExtensionWrapper> plugin3Result = instance.find("plugin3");
        assertEquals(1, plugin3Result.size());

        List<ExtensionWrapper> plugin4Result = instance.find(UUID.randomUUID().toString());
        assertEquals(0, plugin4Result.size());
    }