code: def findAndHandleDeadJobs(cls, nodeInfo, batchSystemShutdown=False):
          
          # A list of tuples of (job name, pid or process running job, registered defer functions)
          for jobState in cls._getAllJobStates(nodeInfo):
              if not cls._pidExists(jobState['jobPID']):
                  # using same logic to prevent races as CachingFileStore._setupCache
                  myPID = str(os.getpid())
                  cleanupFile = os.path.join(jobState['jobDir'], '.cleanup')
                  with open(os.path.join(jobState['jobDir'], '.' + myPID), 'w') as f:
                      f.write(myPID)
                  while True:
                      try:
                          os.rename(f.name, cleanupFile)
                      except OSError as err:
                          if err.errno == errno.ENOTEMPTY:
                              with open(cleanupFile, 'r') as f:
                                  cleanupPID = f.read()
                              if cls._pidExists(int(cleanupPID)):
                                  # Cleanup your own mess.  It's only polite.
                                  os.remove(f.name)
                                  break
                              else:
                                  os.remove(cleanupFile)
                                  continue
                          else:
                              raise
                      else:
                          logger.warning('Detected that job (%s) prematurely terminated.  Fixing the '
                                         'state of the job on disk.', jobState['jobName'])
                          if not batchSystemShutdown:
                              logger.debug("Deleting the stale working directory.")
                              # Delete the old work directory if it still exists.  Do this only during
                              # the life of the program and dont' do it during the batch system
                              # cleanup.  Leave that to the batch system cleanup code.
                              shutil.rmtree(jobState['jobDir'])
                          # Run any deferred functions associated with the job
                          logger.debug('Running user-defined deferred functions.')
                          cls._runDeferredFunctions(jobState['deferredFunctions'])
                          break
docs: Look at the state of all jobs registered in the individual job state files, and handle them
          (clean up the disk, and run any registered defer functions)
  
          :param str nodeInfo: The location of the workflow directory on the node.
          :param bool batchSystemShutdown: Is the batch system in the process of shutting down?
          :return: