class ResolveIObjectByTypeStrategiesPlugin implements IPlugin {

    @Override
    public void load() throws PluginException {
        try {
            IBootstrapItem<String> item = new BootstrapItem("ResolveIObjectByTypeStrategiesPlugin");
            item
                .after("IOC")
                .process(() -> {
                    try {
                        IFunction argToKey = arg -> arg.getClass();
                        IBiFunction findValueByArgument = (map, arg) -> {
                            IResolveDependencyStrategy strategy = null;
                            for (Map.Entry<Class, IResolveDependencyStrategy> entry : ((Map<Class, IResolveDependencyStrategy>) map).entrySet()) {
                                if (entry.getKey().isInstance(arg)) {
                                    strategy = entry.getValue();

                                    break;
                                }
                            }
                            return strategy;
                        };

                        IKey typeStrategy = Keys.getOrAdd("info.smart_tools.smartactors.iobject.iobject.IObject" + "convert");
                        IKey expandableTypeStrategy = Keys.getOrAdd("expandable_strategy#" + "info.smart_tools.smartactors.iobject.iobject.IObject");
                        IResolveDependencyStrategy resolveStrategy = new StrategyStorageWithCacheStrategy(argToKey, findValueByArgument);
                        ((IAdditionDependencyStrategy) resolveStrategy).register(Map.class, new MapToIObjectResolveDependencyStrategy());
                        ((IAdditionDependencyStrategy) resolveStrategy).register(String.class, new StringToIObjectResolveDependencyStrategy());
                        IOC.register(typeStrategy, resolveStrategy);
                        IOC.register(expandableTypeStrategy, new SingletonStrategy(resolveStrategy));
                    } catch (ResolutionException e) {
                        throw new ActionExecuteException("ResolveIObjectByTypeStrategies plugin can't load: can't get ResolveIObjectByTypeStrategies key", e);
                    } catch (RegistrationException | AdditionDependencyStrategyException | InvalidArgumentException e) {
                        throw new ActionExecuteException("ResolveIObjectByTypeStrategies plugin can't load: can't register new strategy", e);
                    }
                });
            bootstrap.add(item);
        } catch (InvalidArgumentException e) {
            throw new PluginException("Can't load resolve iobject by type strategies plugin", e);
        }
    }

    public  ResolveIObjectByTypeStrategiesPlugin(final IBootstrap<IBootstrapItem<String>> bootstrap);

}