class CheckpointActor {

    public void enter(final EnteringMessage message)
            throws ReadValueException, InvalidArgumentException, ResolutionException, ChangeValueException,
            SendingMessageException, SerializeException {
        IObject originalCheckpointStatus = message.getCheckpointStatus();

        if (null != originalCheckpointStatus) {
            ISchedulerEntry presentEntry = storageObserver
                    .getPresentEntry(originalCheckpointStatus.getValue(checkpointEntryIdFieldName).toString());

            if (null != presentEntry) {
                // If this checkpoint already received the message and has entry for it ...
                // Notify (again) previous checkpoint
                sendFeedback(originalCheckpointStatus, message.getCheckpointId(),
                        presentEntry.getId());

                // And stop processing of the message
                message.getProcessor().getSequence().end();
                return;
            }
        }

        IObject entryArguments = IOC.resolve(Keys.getOrAdd("info.smart_tools.smartactors.iobject.iobject.IObject"));

        entryArguments.setValue(schedulingFieldName, message.getSchedulingConfiguration());
        entryArguments.setValue(messageFieldName, cloneMessage(message.getMessage()));

        if (null != originalCheckpointStatus) {
            entryArguments.setValue(prevCheckpointEntryIdFieldName,
                    originalCheckpointStatus.getValue(responsibleCheckpointIdFieldName));
            entryArguments.setValue(prevCheckpointIdFieldName,
                    originalCheckpointStatus.getValue(checkpointEntryIdFieldName));
        }

        // Checkpoint action will initialize recover strategy
        entryArguments.setValue(recoverFieldName, message.getRecoverConfiguration());
        entryArguments.setValue(actionFieldName, CHECKPOINT_ACTION);
        entryArguments.setValue(processorFieldName, message.getProcessor());

        ISchedulerEntry entry = IOC.resolve(Keys.getOrAdd("new scheduler entry"), entryArguments, service.getEntryStorage());

        // Update checkpoint status in message.
        // Checkpoint status of re-sent messages will be set by checkpoint scheduler action.
        IObject newCheckpointStatus = IOC.resolve(Keys.getOrAdd("info.smart_tools.smartactors.iobject.iobject.IObject"));

        newCheckpointStatus.setValue(responsibleCheckpointIdFieldName, message.getCheckpointId());
        newCheckpointStatus.setValue(checkpointEntryIdFieldName, entry.getId());

        message.setCheckpointStatus(newCheckpointStatus);

        // Send feedback message to previous checkpoint
        if (null != originalCheckpointStatus) {
            sendFeedback(originalCheckpointStatus, message.getCheckpointId(), entry.getId());
        }
    }

    public  CheckpointActor(final IObject args);

}