protected <T> T create(Class<T> type, Map<String, String> config) {
        // Use #doInstantiate so inheriting classes can override it, as #instantiate is static final.
        T instance = doInstantiate(type, config);

        if (instance instanceof AsyncInitialize) {
            asyncInitializeAwaiting.incrementAndGet();
            ((AsyncInitialize) instance).initialize(initResult -> {
                asyncInitializeAwaiting.decrementAndGet();
                if (initResult.isError()) {
                    if (!failed) { // Not already failed before
                        failed = true;
                        if (handler != null)
                            handler.handle(initResult);
                    } else {
                        LOGGER.error("Failure occurred, but error handler was already invoked", initResult.getError().getCause()); //$NON-NLS-1$
                    }
                } else {
                    checkLoadingStatus();
                }
            });
        }

        checkLoadingStatus();
        return instance;
    }
Creates a new instance of the given type, passing the given config
map if possible (if the class has a Map constructor).
@param type the type to create
@param config config to pass
@return a new instance of 'type'
gateway/engine/core/src/main/java/io/apiman/gateway/engine/impl/ConfigDrivenEngineFactory.java