This function checks the status of the task by inspecting the output and the
        error files produced by the application and by the queue manager.

def check_status(self):
        """
        This function checks the status of the task by inspecting the output and the
        error files produced by the application and by the queue manager.
        """
        # 1) see it the job is blocked
        # 2) see if an error occured at submitting the job the job was submitted, TODO these problems can be solved
        # 3) see if there is output
        # 4) see if abinit reports problems
        # 5) see if both err files exist and are empty
        # 6) no output and no err files, the job must still be running
        # 7) try to find out what caused the problems
        # 8) there is a problem but we did not figure out what ...
        # 9) the only way of landing here is if there is a output file but no err files...

        # 1) A locked task can only be unlocked by calling set_status explicitly.
        # an errored task, should not end up here but just to be sure
        black_list = (self.S_LOCKED, self.S_ERROR)
        #if self.status in black_list: return self.status

        # 2) Check the returncode of the job script
        if self.returncode != 0:
            msg = "job.sh return code: %s\nPerhaps the job was not submitted properly?" % self.returncode
            return self.set_status(self.S_QCRITICAL, msg=msg)

        # If we have an abort file produced by Abinit
        if self.mpiabort_file.exists:
            return self.set_status(self.S_ABICRITICAL, msg="Found ABINIT abort file")

        # Analyze the stderr file for Fortran runtime errors.
        # getsize is 0 if the file is empty or it does not exist.
        err_msg = None
        if self.stderr_file.getsize() != 0:
            err_msg = self.stderr_file.read()

        # Analyze the stderr file of the resource manager runtime errors.
        # TODO: Why are we looking for errors in queue.qerr?
        qerr_info = None
        if self.qerr_file.getsize() != 0:
            qerr_info = self.qerr_file.read()

        # Analyze the stdout file of the resource manager (needed for PBS !)
        qout_info = None
        if self.qout_file.getsize():
            qout_info = self.qout_file.read()

        # Start to check ABINIT status if the output file has been created.
        #if self.output_file.getsize() != 0:
        if self.output_file.exists:
            try:
                report = self.get_event_report()
            except Exception as exc:
                msg = "%s exception while parsing event_report:\n%s" % (self, exc)
                return self.set_status(self.S_ABICRITICAL, msg=msg)

            if report is None:
                return self.set_status(self.S_ERROR, msg="got None report!")

            if report.run_completed:
                # Here we  set the correct timing data reported by Abinit
                self.datetimes.start = report.start_datetime
                self.datetimes.end = report.end_datetime

                # Check if the calculation converged.
                not_ok = report.filter_types(self.CRITICAL_EVENTS)
                if not_ok:
                    return self.set_status(self.S_UNCONVERGED, msg='status set to unconverged based on abiout')
                else:
                    return self.set_status(self.S_OK, msg="status set to ok based on abiout")

            # Calculation still running or errors?
            if report.errors:
                # Abinit reported problems
                logger.debug('Found errors in report')
                for error in report.errors:
                    logger.debug(str(error))
                    try:
                        self.abi_errors.append(error)
                    except AttributeError:
                        self.abi_errors = [error]

                # The job is unfixable due to ABINIT errors
                logger.debug("%s: Found Errors or Bugs in ABINIT main output!" % self)
                msg = "\n".join(map(repr, report.errors))
                return self.set_status(self.S_ABICRITICAL, msg=msg)

            # 5)
            if self.stderr_file.exists and not err_msg:
                if self.qerr_file.exists and not qerr_info:
                    # there is output and no errors
                    # The job still seems to be running
                    return self.set_status(self.S_RUN, msg='there is output and no errors: job still seems to be running')

        # 6)
        if not self.output_file.exists:
            logger.debug("output_file does not exists")
            if not self.stderr_file.exists and not self.qerr_file.exists:
                # No output at allThe job is still in the queue.
                return self.status

        # 7) Analyze the files of the resource manager and abinit and execution err (mvs)
        # MG: This section has been disabled: several portability issues
        # Need more robust logic in error_parser, perhaps logic provided by users via callbacks.
        if False and (qerr_info or qout_info):
            from pymatgen.io.abinit.scheduler_error_parsers import get_parser
            scheduler_parser = get_parser(self.manager.qadapter.QTYPE, err_file=self.qerr_file.path,
                                          out_file=self.qout_file.path, run_err_file=self.stderr_file.path)

            if scheduler_parser is None:
                return self.set_status(self.S_QCRITICAL,
                                       msg="Cannot find scheduler_parser for qtype %s" % self.manager.qadapter.QTYPE)

            scheduler_parser.parse()

            if scheduler_parser.errors:
                # Store the queue errors in the task
                self.queue_errors = scheduler_parser.errors
                # The job is killed or crashed and we know what happened
                msg = "scheduler errors found:\n%s" % str(scheduler_parser.errors)
                return self.set_status(self.S_QCRITICAL, msg=msg)

            elif lennone(qerr_info) > 0:
                # if only qout_info, we are not necessarily in QCRITICAL state,
                # since there will always be info in the qout file
                self.history.info('Found unknown message in the queue qerr file: %s' % str(qerr_info))
                #try:
                #    rt = self.datetimes.get_runtime().seconds
                #except:
                #    rt = -1.0
                #tl = self.manager.qadapter.timelimit
                #if rt > tl:
                #    msg += 'set to error : runtime (%s) exceded walltime (%s)' % (rt, tl)
                #    print(msg)
                #    return self.set_status(self.S_ERROR, msg=msg)
                # The job may be killed or crashed but we don't know what happened
                # It may also be that an innocent message was written to qerr, so we wait for a while
                # it is set to QCritical, we will attempt to fix it by running on more resources

        # 8) analyzing the err files and abinit output did not identify a problem
        # but if the files are not empty we do have a problem but no way of solving it:
        # The job is killed or crashed but we don't know what happend
        # it is set to QCritical, we will attempt to fix it by running on more resources
        if err_msg:
            msg = 'Found error message:\n %s' % str(err_msg)
            self.history.warning(msg)
            #return self.set_status(self.S_QCRITICAL, msg=msg)

        # 9) if we still haven't returned there is no indication of any error and the job can only still be running
        # but we should actually never land here, or we have delays in the file system ....
        # print('the job still seems to be running maybe it is hanging without producing output... ')

        # Check time of last modification.
        if self.output_file.exists and \
           (time.time() - self.output_file.get_stat().st_mtime > self.manager.policy.frozen_timeout):
            msg = "Task seems to be frozen, last change more than %s [s] ago" % self.manager.policy.frozen_timeout
            return self.set_status(self.S_ERROR, msg=msg)

        # Handle weird case in which either run.abo, or run.log have not been produced
        #if self.status not in (self.S_INIT, self.S_READY) and (not self.output.file.exists or not self.log_file.exits):
        #    msg = "Task have been submitted but cannot find the log file or the output file"
        #    return self.set_status(self.S_ERROR, msg)

        return self.set_status(self.S_RUN, msg='final option: nothing seems to be wrong, the job must still be running')