@Override
	public final T rollback() throws InvalidProcessStateException, ProcessRollbackException {
		if (state != ProcessState.EXECUTION_FAILED && state != ProcessState.EXECUTION_SUCCEEDED
				&& state != ProcessState.PAUSED) {
			throw new InvalidProcessStateException(this, state);
		}
		// only rollback if component was marked
		if (!requiresRollback) {
			return null;
		}

		logger.debug("Rollbacking '{}'.", this);
		setState(ProcessState.ROLLBACKING);
		notifyListeners(ProcessState.ROLLBACKING);
		isRollbacking = true;

		T result;
		try {
			result = doRollback();
			setState(ProcessState.ROLLBACK_SUCCEEDED);
			notifyListeners(ProcessState.ROLLBACK_SUCCEEDED);
		} catch (Exception ex) {
			setState(ProcessState.ROLLBACK_FAILED);
			notifyListeners(ProcessState.ROLLBACK_FAILED);

			// log exception, wrap it to PRE, throw
			String msg = "An exception has been catched during rollback. See cause for more information.";
			logger.error(msg, ex);
			if (ex instanceof ProcessRollbackException) {
				throw ex;
			} else {
				throw new ProcessRollbackException(this, ex, msg);
			}
		}
		return result;
	}