private static <T> Iterator<T> getFactories(Class<T> type, ClassLoader classLoader, boolean includeGlobal) {
        Set<T> factories = new LinkedHashSet<>();
        final ServiceLoader<T> loader = ServiceLoader.load(type, classLoader);
        for (T factory : loader) {
            factories.add(factory);
        }
        if (includeGlobal) {
            Set<String> loadedClasses = new HashSet<>();
            final String filter = type.getSimpleName() + ".";

            Provider[] providers = Security.getProviders();
            for (Provider currentProvider : providers) {
                final ClassLoader cl = currentProvider.getClass().getClassLoader();
                currentProvider.keySet().stream().filter(currentKey -> currentKey instanceof String && ((String)currentKey).startsWith(filter)
                  && ((String)currentKey).indexOf(' ') < 0).forEach(currentKey -> {
                    String className=currentProvider.getProperty((String)currentKey);
                    if(className != null && loadedClasses.add(className)) {
                        try {
                            factories.add(Class.forName(className, true, cl).asSubclass(type).newInstance());
                        } catch(ClassNotFoundException | ClassCastException | InstantiationException | IllegalAccessException e) {
                        }
                    }
                });
            }
        }
        return factories.iterator();
    }