class BlockingMessageSchedulerAction implements ISchedulerAction {

    @Override
    public void init(final ISchedulerEntry entry, final IObject args) throws SchedulerActionInitializationException {
        try {
            Object message = args.getValue(messageFN);
            Object chainId = args.getValue(chainFN);

            if (message == null || !(message instanceof IObject)) {
                throw new SchedulerActionInitializationException("\"message\" field of arguments should contain a message object", null);
            }

            if (null == chainId) {
                throw new SchedulerActionInitializationException("\"chain\" field of arguments should contain name of the chain", null);
            }

            String entryIdFieldFN = (String) args.getValue(setEntryIdFN);

            if (entryIdFieldFN != null && !entryIdFieldFN.isEmpty()) {
                ((IObject) message).setValue(IOC.resolve(Keys.getOrAdd(IFieldName.class.getCanonicalName()), entryIdFieldFN), entry.getId());
            }

            entry.getState().setValue(messageFN, message);
            entry.getState().setValue(chainFN, chainId);

            Object preShutdownExecConfig = args.getValue(preShutdownExecFN);
            entry.getState().setValue(preShutdownExecFN,
                    (preShutdownExecConfig == null || preShutdownExecConfig == Boolean.FALSE) ? Boolean.FALSE : Boolean.TRUE);

            Number stackDepth = (Number) args.getValue(stackDepthFN);

            if (null == stackDepth) {
                stackDepth = IOC.resolve(Keys.getOrAdd("default_stack_depth"));
            }

            entry.getState().setValue(stackDepthFN, stackDepth);
        } catch (ReadValueException | ChangeValueException | InvalidArgumentException | ResolutionException e) {
            throw new SchedulerActionInitializationException("Error occurred copying message from arguments to entry state.", e);
        }
    }

    public  BlockingMessageSchedulerAction();

}