class HttpEndpointPlugin implements IPlugin {

    @Override
    public void load() throws PluginException {
        try {
            IBootstrapItem<String> item = new BootstrapItem("CreateHttpEndpoint");
            item
                    .after("EndpointPlugin")
                    .after("response")
                    .after("response_content_strategy")
                    .before("configure")
                    .process(
                            () -> {
                                try {
                                    initializeFieldNames();
                                    IKey httpEndpointKey = Keys.getOrAdd("http_endpoint");
                                    registerCookiesSetter();
                                    registerHeadersExtractor();
                                    registerResponseStatusExtractor();
                                    registerExceptionalResponse();
                                    IOC.register(
                                            Keys.getOrAdd(IEnvironmentHandler.class.getCanonicalName()),
                                            new CreateNewInstanceStrategy(
                                                    (args) -> {
                                                        IObject configuration = (IObject) args[0];
                                                        IQueue queue = null;
                                                        Integer stackDepth = null;
                                                        try {
                                                            queue = (IQueue) configuration.getValue(queueFieldName);
                                                            stackDepth =
                                                                    (Integer) configuration.getValue(stackDepthFieldName);
                                                            return new EnvironmentHandler(queue, stackDepth);
                                                        } catch (ReadValueException | InvalidArgumentException | ResolutionException e) {
                                                            throw new RuntimeException(e);
                                                        }
                                                    }
                                            )
                                    );

                                    IOC.register(httpEndpointKey,
                                            new CreateNewInstanceStrategy(
                                                    (args) -> {
                                                        IObject configuration = (IObject) args[0];
                                                        try {

                                                            IOC.resolve(
                                                                    Keys.getOrAdd("info.smart_tools.smartactors.endpoint.interfaces.ideserialize_strategy.IDeserializeStrategy"),
                                                                    "HTTP_GET",
                                                                    configuration.getValue(endpointNameFieldName),
                                                                    configuration.getValue(templatesFieldName));
                                                            IOC.resolve(
                                                                    Keys.getOrAdd("info.smart_tools.smartactors.endpoint.interfaces.ideserialize_strategy.IDeserializeStrategy"),
                                                                    "HTTP_application/json",
                                                                    configuration.getValue(endpointNameFieldName));
                                                            IOC.resolve(
                                                                    Keys.getOrAdd("info.smart_tools.smartactors.endpoint.interfaces.ideserialize_strategy.IDeserializeStrategy"),
                                                                    "HTTP_application/x-www-form-urlencoded",
                                                                    configuration.getValue(endpointNameFieldName));

                                                            IUpCounter upCounter = IOC.resolve(Keys.getOrAdd("root upcounter"));

                                                            IEnvironmentHandler environmentHandler = IOC.resolve(
                                                                    Keys.getOrAdd(IEnvironmentHandler.class.getCanonicalName()),
                                                                    configuration);
                                                            HttpEndpoint endpoint = new HttpEndpoint(
                                                                    (Integer) configuration.getValue(portFieldName),
                                                                    (Integer) configuration.getValue(maxContentLengthFieldName),
                                                                    ScopeProvider.getCurrentScope(), environmentHandler,
                                                                    (IReceiverChain) configuration.getValue(startChainNameFieldName),
                                                                    (String) configuration.getValue(endpointNameFieldName),
                                                                    upCounter);

                                                            upCounter.onShutdownComplete(endpoint::stop);

                                                            return endpoint;
                                                        } catch (ReadValueException | InvalidArgumentException
                                                                | ScopeProviderException | ResolutionException
                                                                | UpCounterCallbackExecutionException e) {
                                                            throw new RuntimeException(e);
                                                        }
                                                    }
                                            )
                                    );
                                    registerDeserializationStrategies();
                                    registerResponseSenders();
                                    IKey emptyIObjectKey = Keys.getOrAdd("EmptyIObject");
                                    IOC.register(emptyIObjectKey, new CreateNewInstanceStrategy(
                                                    (args) -> new DSObject()
                                            )
                                    );

                                    IKey channelHandlerNettyKey = Keys.getOrAdd("info.smart_tools.smartactors.http_endpoint.channel_handler_netty.ChannelHandlerNetty");
                                    IOC.register(channelHandlerNettyKey,
                                            new CreateNewInstanceStrategy(
                                                    (args) -> {
                                                        ChannelHandlerNetty channelHandlerNetty = new ChannelHandlerNetty();
                                                        channelHandlerNetty.init((ChannelHandlerContext) args[0]);
                                                        return channelHandlerNetty;
                                                    }
                                            ));

                                } catch (ResolutionException e) {
                                    throw new ActionExecuteException("EndpointCollection plugin can't load: can't get key", e);
                                } catch (InvalidArgumentException e) {
                                    throw new ActionExecuteException("EndpointCollection plugin can't load: can't create strategy", e);
                                } catch (RegistrationException | AdditionDependencyStrategyException e) {
                                    throw new ActionExecuteException("EndpointCollection plugin can't load: can't register new strategy", e);
                                }
                            }
                    );
            bootstrap.add(item);
        } catch (Exception e) {
            throw new PluginException("Can't load \"CreateHttpEndpoint\" plugin", e);
        }
    }

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

}