# Source: control/CommandResult.js

    // Must be the ordinals of Java enum CommandResult.Status

    /**
     * Command execution has succeeded.
     * @type {number}
     * @see CommandResult
     */
    export const COMMAND_RESULT_DONE = 0;

    /**
     * Command execution has been stopped because
     * this <em>remote command</em> is interactive.
     * @type {number}
     * @see CommandResult
     */
    export const COMMAND_RESULT_STOPPED = 1;

    /**
     * Command execution was canceled by user.
     * @type {number}
     * @see CommandResult
     */
    export const COMMAND_RESULT_CANCELED = 2;

    /**
     * Command execution has failed.
     * @type {number}
     * @see CommandResult
     */
    export const COMMAND_RESULT_FAILED = 3;

    /**
     * Result object returned by {@link Command#execute}.
     */
    export class CommandResult {
        /**
         * Constructor.
         *
         * @param status - status of the command execution
         * @param [value=null] - result of the command execution
         */
        constructor(status, value=null) {
            this._status = status;
            this._value = value;
        }

        /**
         * Get the <code>status</code> property of this command result:
         * the status of the command execution.
         *
         * @type {number}
         * @see COMMAND_RESULT_DONE
         * @see COMMAND_RESULT_STOPPED
         * @see COMMAND_RESULT_CANCELED
         * @see COMMAND_RESULT_FAILED
         */
        get status() {
            return this._status;
        }

        /**
         * Get the <code>value</code> property of this command result:
         * the result of the command execution.
         * May be <code>null</code>, which means: nothing useful.
         *
         * <p>How to interpret <code>value</code> depends on <code>status</code>:
         * <dl>
         * <dt><code>COMMAND_RESULT_DONE</code>
         * <dd>The result value, a string, or <code>null</code>.
         * <dt><code>COMMAND_RESULT_STOPPED</code> (<em>Remote command only.</em>)
         * <dd><code>null</code> or a string which normally, after parsing it,
         * should be displayed in a dialog box (e.g. a list of choices
         * letting the user specify what she/he wants).</dd>
         * <dt><code>COMMAND_RESULT_CANCELED</code>
         * <dd>Should be <code>null</code>.
         * <dt><code>COMMAND_RESULT_FAILED</code>
         * <dd>An error message or <code>null</code>.
         * </dl>
         *
         * @type {string}
         */
        get value() {
            return this._value;
        }

        /**
         * Returns a a string representing this result.
         */
        toString() {
            let s = "CommandResult.";
            switch (this._status) {
            case COMMAND_RESULT_DONE:
                s += "DONE";
                break;
            case COMMAND_RESULT_STOPPED:
                s += "STOPPED";
                break;
            case COMMAND_RESULT_CANCELED:
                s += "CANCELED";
                break;
            case COMMAND_RESULT_FAILED:
                s += "FAILED";
                break;
            default:
                s += "???";
                break;
            }
            if (this._value !== null) {
                s += '(' + this._value.toString() + ')';
            }

            return s;
        }

        /**
         * Convenience method: tests whether specified result is successful.
         *
         * @param {CommandResult} result - result to be tested;
         * may be <code>null</code> which is considered to be
         * a non-successful result.
         */
        static isDone(result) {
            return (result !== null && result._status === COMMAND_RESULT_DONE);
        }

        /**
         * Convenience method equivalent to returning
         * <code>new CommandResult(COMMAND_RESULT_FAILED,value)</code>.
         */
        static failed(value) {
            return new CommandResult(COMMAND_RESULT_FAILED, value);
        }

        static deserialize(data) {
            if (Array.isArray(data) && // null data OK.
                data.length === 2 &&
                Number.isInteger(data[0])) {
                switch (data[0]) {
                case COMMAND_RESULT_DONE:
                case COMMAND_RESULT_STOPPED:
                case COMMAND_RESULT_CANCELED:
                case COMMAND_RESULT_FAILED:
                    data = new CommandResult(data[0], data[1]);
                    break;
                }
            }

            return data;
        }

        static formatCommandResult(cmd, result) {
            return (result === null)?
                `command\n"${cmd}"\ncould not be executed` :
                `command\n"${cmd}"\nreturned\n${result}`;
        }
    }
    CommandResult.DONE = new CommandResult(COMMAND_RESULT_DONE);
    CommandResult.STOPPED = new CommandResult(COMMAND_RESULT_STOPPED);
    CommandResult.CANCELED = new CommandResult(COMMAND_RESULT_CANCELED);
    CommandResult.FAILED = new CommandResult(COMMAND_RESULT_FAILED);