class FeatureManagerActor {

    public void onFeatureLoaded(final OnFeatureLoadedWrapper wrapper)
            throws FeatureManagementException {
        IFeature feature;
        try {
            feature = wrapper.getFeature();

            this.processingFeatures.remove(feature.getName());
            if (feature.isFailed()) {
                this.failedFeatures.put(feature.getName(), feature);

            } else {
                this.loadedFeatures.put(feature.getName(), feature);
                this.failedFeatures.remove(feature.getName());
                removeLoadedFeatureFromDependencies(feature);
                checkAndRunConnectedFeatures();
            }

            this.mainProcesses.forEach((k, v) -> {
                v.remove(feature);
            });
            Collection<IMessageProcessor> needContinueProcesses = new HashSet<>();
            this.mainProcesses.forEach((k, v) -> {
                if (v.isEmpty()) {
                    needContinueProcesses.add(k);
                    this.mainProcesses.remove(k);
                }
            });
            needContinueProcesses.forEach((mp) -> {
                try {

                    IQueue<ITask> afterFeatureCallbackQueue = wrapper.getAfterFeaturesCallbackQueue();
                    ITask task;
                    while (null != (task = afterFeatureCallbackQueue.tryTake())) {
                        try {
                            task.execute();
                        } catch (TaskExecutionException e) {
                            throw new ActionExecuteException(e);
                        }
                    }

                    mp.continueProcess(null);
                    System.out.println(
                            "\n\n[INFO] Feature group has been loaded: " +
                                    this.mainProcessesForInfo.get(mp).stream().map(
                                            a -> "\n" + a.getName() + " - " + (!a.isFailed() ? "(OK)" : "(Failed)")
                                    ).collect(Collectors.toList())
                            + "\n\n"
                    );
                    this.mainProcessesForInfo.remove(mp);
                } catch (AsynchronousOperationException | ReadValueException | ActionExecuteException e) {
                    throw new RuntimeException(e);
                }
            });
            checkUnresolved();

        } catch (ReadValueException e) {
            throw new FeatureManagementException("Feature should not be null.");
        }
    }

    public  FeatureManagerActor();

}