function createSubscriberWrapper({ shim, fn, spec, name }) {
  return function wrappedSubscribe(...args) {
    if (shim.isFunction(spec)) {
      spec = spec.call(this, shim, fn, name, args)
    }

    // Make sure our spec has what we need.
    if (!shim.isFunction(spec.messageHandler)) {
      shim.logger.debug('spec.messageHandler should be a function')
      return fn.apply(this, args)
    } else if (!shim.isNumber(spec.consumer)) {
      shim.logger.debug('spec.consumer is required for recordSubscribedConsume')
      return fn.apply(this, args)
    }

    const destNameIsArg = shim.isNumber(spec.destinationName)

    const queueIdx = shim.normalizeIndex(args.length, spec.queue)
    const consumerIdx = shim.normalizeIndex(args.length, spec.consumer)
    const queue = queueIdx === null ? null : args[queueIdx]
    let destinationName = null

    if (destNameIsArg) {
      const destNameIdx = shim.normalizeIndex(args.length, spec.destinationName)
      if (destNameIdx !== null) {
        destinationName = args[destNameIdx]
      }
    }

    if (consumerIdx !== null && !spec.functions) {
      args[consumerIdx] = shim.wrap(
        args[consumerIdx],
        makeWrapConsumer.call(this, { spec, queue, destinationName, destNameIsArg })
      )
    }

    if (consumerIdx !== null && spec.functions) {
      spec.functions.forEach((name) => {
        // only wrap the function if it exists on consumer
        if (args[consumerIdx][name]) {
          args[consumerIdx][name] = shim.wrap(
            args[consumerIdx][name],
            // bind the proper this scope into the consumers
            makeWrapConsumer.call(this, { spec, queue, destinationName, destNameIsArg })
          )
        }
      })
    }

    return fn.apply(this, args)
  }
}
Wrapper for subscribing to a queue.

@private
@param {object} params to function
@param {MessageShim} params.shim instance of shim
@param {Function} params.fn subscriber function
@param {specs.MessageSubscribeSpec} params.spec spec for subscriber
@param params.name
@param {boolean} params.destNameIsArg flag to state if destination is an argument
@returns {Function} wrapped subscribe function