function taskArgs(args) {

    if (!args || typeof args.length !== 'number') {
        throw new TypeError('Parameter \'args\' must be an array-like object of arguments.');
    }

    let options = args[0], cb;
    if (typeof options === 'function') {
        cb = options;
        options = {};
        if (cb.name) {
            options.tag = cb.name;
        }
    } else {
        if (typeof args[1] === 'function') {
            cb = args[1];
        }
        if (typeof options === 'string' || typeof options === 'number') {
            options = {tag: options};
        } else {
            options = (typeof options === 'object' && options) || {};
            if (!('tag' in options) && cb && cb.name) {
                options.tag = cb.name;
            }
        }
    }

    const res = [options, cb];

    Object.defineProperty(res, 'options', {
        get: function () {
            return this[0];
        },
        set: function (newValue) {
            this[0] = newValue;
        },
        enumerable: true
    });

    Object.defineProperty(res, 'cb', {
        get: function () {
            return this[1];
        },
        set: function (newValue) {
            this[1] = newValue;
        },
        enumerable: true
    });

    return res;
}
@method utils.taskArgs
@description
Normalizes/prepares arguments for tasks and transactions.

Its main purpose is to simplify adding custom methods {@link Database#task task}, {@link Database#taskIf taskIf},
{@link Database#tx tx} and {@link Database#txIf txIf} within event {@link event:extend extend}, as the those methods use fairly
complex logic for parsing inputs.

@param args {Object}
Array-like object of `arguments` that was passed into the method. It is expected that the `arguments`
are always made of two parameters - `(options, cb)`, same as all the default task/transaction methods.

And if your custom method needs additional parameters, they should be passed in as extra properties within `options`.

@returns {Array}
Array of arguments that can be passed into a task or transaction.

It is extended with properties `options` and `cb` to access the corresponding array elements `[0]` and `[1]` by name.

@example

// Registering a custom transaction method that assigns a default Transaction Mode:

const initOptions = {
    extend: obj => {
        obj.myTx = function(options, cb) {
            const args = pgp.utils.taskArgs(arguments); // prepare arguments

            if (!('mode' in args.options)) {
                // if no 'mode' was specified, set default for transaction mode:
                args.options.mode = myTxModeObject; // of type pgp.txMode.TransactionMode
            }

            return obj.tx.apply(this, args);
            // or explicitly, if needed:
            // return obj.tx.call(this, args.options, args.cb);
        }
    }
};