class FeatureManagerActor {

    public void addFeatures(final AddFeatureWrapper wrapper)
            throws FeatureManagementException {
        try {
            Set<IFeature> features = new HashSet<>(wrapper.getFeatures());
            Set<IFeature> featuresForInfo = new HashSet<>(wrapper.getFeatures());
            IMessageProcessor mp = wrapper.getMessageProcessor();

            IQueue<ITask> queue = IOC.resolve(Keys.getOrAdd("task_queue"));
            String scatterChainName = wrapper.getScatterChainName();
            Object chainId = IOC.resolve(Keys.getOrAdd("chain_id_from_map_name"), scatterChainName);
            IChainStorage chainStorage = IOC.resolve(Keys.getOrAdd(IChainStorage.class.getCanonicalName()));
            int stackDepth = DEFAULT_STACK_DEPTH;
            IReceiverChain scatterChain = chainStorage.resolve(chainId);


            IQueue afterFeaturesCallbackQueue = IOC.resolve(Keys.getOrAdd(IQueue.class.getCanonicalName()));


            int count = 0;
            for (IFeature feature : features) {
                Object featureName = feature.getName();
                if (
                        null == this.processingFeatures.get(featureName) &&
                        null == this.loadedFeatures.get(featureName)
                ) {
                    this.processingFeatures.put(feature.getName(), feature);
                    IMessageProcessingSequence processingSequence =
                            IOC.resolve(Keys.getOrAdd("info.smart_tools.smartactors.message_processing_interfaces.message_processing.IMessageProcessingSequence"), stackDepth, scatterChain);
                    IMessageProcessor messageProcessor =
                            IOC.resolve(Keys.getOrAdd("info.smart_tools.smartactors.message_processing_interfaces.message_processing.IMessageProcessor"), queue, processingSequence);
                    IObject message = IOC.resolve(Keys.getOrAdd("info.smart_tools.smartactors.iobject.iobject.IObject"));
                    message.setValue(this.loadedFeatureFN, this.loadedFeatures);
                    message.setValue(this.failedFeatureFN, this.failedFeatures);
                    message.setValue(this.processingFeatureFN, this.processingFeatures);
                    message.setValue(this.featureProcessFN, this.featureProcess);
                    message.setValue(this.featureFN, feature);
                    message.setValue(this.afterFeaturesCallbackQueueFN, afterFeaturesCallbackQueue);
                    IObject context = IOC.resolve(Keys.getOrAdd("info.smart_tools.smartactors.iobject.iobject.IObject"));
                    messageProcessor.process(message, context);
                    ++count;
                }
            }
            if (count > 0) {
                mp.pauseProcess();
                this.mainProcesses.put(mp, features);
                this.mainProcessesForInfo.put(mp, featuresForInfo);
            }
        } catch (
                ReadValueException |
                ChangeValueException |
                InvalidArgumentException |
                ResolutionException |
                ChainNotFoundException |
                MessageProcessorProcessException |
                AsynchronousOperationException e
        ) {
            throw new FeatureManagementException(e);
        }
    }

    public  FeatureManagerActor();

}