function evaluateJSONataExpression(expr,msg,callback) {
    var context = msg;
    if (expr._legacyMode) {
        context = {msg:msg};
    }
    var bindings = {};

    if (callback) {
        // If callback provided, need to override the pre-assigned sync
        // context functions to be their async variants
        bindings.flowContext = function(val, store) {
            return new Promise((resolve,reject) => {
                expr._node.context().flow.get(val, store, function(err,value) {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(value);
                    }
                })
            });
        }
        bindings.globalContext = function(val, store) {
            return new Promise((resolve,reject) => {
                expr._node.context().global.get(val, store, function(err,value) {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(value);
                    }
                })
            });
        }
    } else {
        const error = new Error('Calls to RED.util.evaluateJSONataExpression must include a callback.')
        throw error
    }

    expr.evaluate(context, bindings).then(result => {
        callback(null, result)
    }).catch(err => {
        callback(err)
    })
}
Evaluates a JSONata expression.
The expression must have been prepared with {@link @node-red/util-util.prepareJSONataExpression}
before passing to this function.

@param  {Object}   expr     - the prepared JSONata expression
@param  {Object}   msg      - the message object to evaluate against
@param  {Function} callback - (optional) called when the expression is evaluated
@return {any} If no callback was provided, the result of the expression
@memberof @node-red/util_util