function processVersioningState(mst, vstat, nullVersionCompatMode) {
    const versioningSuspended = (vstat === 'Suspended');
    const masterIsNull = mst.exists && (mst.isNull || !mst.versionId);

    if (versioningSuspended) {
        // versioning is suspended: overwrite the existing null version
        const options = { versionId: '', isNull: true };
        if (masterIsNull) {
            // if the null version exists, clean it up prior to put
            if (mst.objLocation) {
                options.dataToDelete = mst.objLocation;
            }
            // backward-compat: a null version key may exist even with
            // a null master (due to S3C-7526), if so, delete it (its
            // data will be deleted as part of the master cleanup, so
            // no "deleteData" param is needed)
            //
            // "isNull2" attribute is set in master metadata when
            // null keys are used, which is used as an optimization to
            // avoid having to check the versioned key since there can
            // be no more versioned key to clean up
            if (mst.isNull && mst.versionId && !mst.isNull2) {
                const delOptions = { versionId: mst.versionId };
                return { options, delOptions };
            }
            return { options };
        }
        if (mst.nullVersionId) {
            // backward-compat: delete the null versioned key and data
            const delOptions = { versionId: mst.nullVersionId, deleteData: true };
            if (mst.nullUploadId) {
                delOptions.replayId = mst.nullUploadId;
            }
            return { options, delOptions };
        }
        // clean up the eventual null key's location data prior to put

        // NOTE: due to metadata v1 internal format, we cannot guess
        // from the master key whether there is an associated null
        // key, because the master key may be removed whenever the
        // latest version becomes a delete marker. Hence we need to
        // pessimistically try to get the null key metadata and delete
        // it if it exists.
        const delOptions = { versionId: 'null', deleteData: true };
        return { options, delOptions };
    }

    // versioning is enabled: create a new version
    const options = { versioning: true };
    if (masterIsNull) {
        // if master is a null version or a non-versioned key,
        // copy it to a new null key
        const nullVersionId = (mst.isNull && mst.versionId) ? mst.versionId : nonVersionedObjId;
        if (nullVersionCompatMode) {
            options.extraMD = {
                nullVersionId,
            };
            if (mst.uploadId) {
                options.extraMD.nullUploadId = mst.uploadId;
            }
            return { options, nullVersionId };
        }
        if (mst.isNull && !mst.isNull2) {
            // if master null version was put with an older
            // Cloudserver (or in compat mode), there is a
            // possibility that it also has a null versioned key
            // associated, so we need to delete it as we write the
            // null key
            const delOptions = {
                versionId: nullVersionId,
            };
            return { options, nullVersionId, delOptions };
        }
        return { options, nullVersionId };
    }
    // backward-compat: keep a reference to the existing null
    // versioned key
    if (mst.nullVersionId) {
        options.extraMD = {
            nullVersionId: mst.nullVersionId,
        };
        if (mst.nullUploadId) {
            options.extraMD.nullUploadId = mst.nullUploadId;
        }
    }
    return { options };
}
Process state from the master version of an object and the bucket
versioning configuration, return a set of options objects

@param {object} mst - state of master version, as returned by
getMasterState()
@param {string} vstat - bucket versioning status: 'Enabled' or 'Suspended'
@param {boolean} nullVersionCompatMode - if true, behaves in null
version compatibility mode and return appropriate values: this mode
does not attempt to create null keys but create null versioned keys
instead

@return {object} result object with the following attributes:
- {object} options: versioning-related options to pass to the
     services.metadataStoreObject() call
- {object} [options.extraMD]: extra attributes to set in object metadata
- {string} [nullVersionId]: null version key to create, if needed
- {object} [delOptions]: options for metadata to delete the null
     version key, if needed