class IntentData {

    public static boolean isUpdateAcceptable(IntentData currentData, IntentData newData) {

        if (currentData == null) {
            return true;
        } else if (currentData.version().isOlderThan(newData.version())) {
            return true;
        } else if (currentData.version().isNewerThan(newData.version())) {
            return false;
        }

        // current and new data versions are the same
        IntentState currentState = currentData.state();
        IntentState newState = newData.state();

        switch (newState) {
        case INSTALLING:
            if (currentState == INSTALLING) {
                return false;
            }
            // FALLTHROUGH
        case INSTALLED:
            if (currentState == INSTALLED) {
                return false;
            } else if (currentState == WITHDRAWING || currentState == WITHDRAWN
                    || currentState == PURGE_REQ) {
                log.warn("Invalid state transition from {} to {} for intent {}",
                         currentState, newState, newData.key());
                return false;
            }
            return true;

        case WITHDRAWING:
            if (currentState == WITHDRAWING) {
                return false;
            }
            // FALLTHROUGH
        case WITHDRAWN:
            if (currentState == WITHDRAWN) {
                return false;
            } else if (currentState == INSTALLING || currentState == INSTALLED
                    || currentState == PURGE_REQ) {
                log.warn("Invalid state transition from {} to {} for intent {}",
                         currentState, newState, newData.key());
                return false;
            }
            return true;

        case FAILED:
            if (currentState == FAILED) {
                return false;
            }
            return true;

        case CORRUPT:
            if (currentState == CORRUPT) {
                return false;
            }
            return true;

        case PURGE_REQ:
            // TODO we should enforce that only WITHDRAWN intents can be purged
            return true;

        case COMPILING:
        case RECOMPILING:
        case INSTALL_REQ:
        case WITHDRAW_REQ:
        default:
            log.warn("Invalid state {} for intent {}", newState, newData.key());
            return false;
        }
    }

    public  IntentData(Intent intent, IntentState state, Timestamp version);
    public  IntentData(Intent intent, IntentState state, Timestamp version, NodeId origin);
    public  IntentData(IntentData intentData);
    public  IntentData(IntentData original, List<Intent> installables);
    protected  IntentData();

}