docs: def resolve_job_references(io_hash, job_outputs, should_resolve=True):
      '''
      :param io_hash: an input or output hash in which to resolve any job-based object references possible
      :type io_hash: dict
      :param job_outputs: a mapping of finished local jobs to their output hashes
      :type job_outputs: dict
      :param should_resolve: whether it is an error if a job-based object reference in *io_hash* cannot be resolved yet
      :type should_resolve: boolean
  
      Modifies *io_hash* in-place.
      '''
      q = []
  
      for field in io_hash:
          if is_job_ref(io_hash[field]):
              io_hash[field] = resolve_job_ref(io_hash[field], job_outputs, should_resolve)
          elif isinstance(io_hash[field], list) or isinstance(io_hash[field], dict):
              q.append(io_hash[field])
  
      while len(q) > 0:
          thing = q.pop()
          if isinstance(thing, list):
              for i in range(len(thing)):
                  if is_job_ref(thing[i]):
                      thing[i] = resolve_job_ref(thing[i], job_outputs, should_resolve)
                  elif isinstance(thing[i], list) or isinstance(thing[i], dict):
                      q.append(thing[i])
          else:
              for field in thing:
                  if is_job_ref(thing[field]):
                      thing[field] = resolve_job_ref(thing[field], job_outputs, should_resolve)
                  elif isinstance(thing[field], list) or isinstance(thing[field], dict):
                      q.append(thing[field])