def fix_pdbline(self, pdbline, lastnum):
        """Fix a PDB line if information is missing."""
        pdbqt_conversion = {
            "HD": "H", "HS": "H", "NA": "N",
            "NS": "N", "OA": "O", "OS": "O", "SA": "S"}
        fixed = False
        newnum = 0
        forbidden_characters = "[^a-zA-Z0-9_]"
        pdbline = pdbline.strip('\n')
        # Some MD / Docking tools produce empty lines, leading to segfaults
        if len(pdbline.strip()) == 0:
            self.num_fixed_lines += 1
            return None, lastnum
        if len(pdbline) > 100:  # Should be 80 long
            self.num_fixed_lines += 1
            return None, lastnum
        # TER Entries also have continuing numbering, consider them as well
        if pdbline.startswith('TER'):
            newnum = lastnum + 1
        if pdbline.startswith('ATOM'):
            newnum = lastnum + 1
            currentnum = int(pdbline[6:11])
            resnum = pdbline[22:27].strip()
            resname = pdbline[17:21].strip()
            # Invalid residue number
            try:
                int(resnum)
            except ValueError:
                pdbline = pdbline[:22] + '   0 ' + pdbline[27:]
                fixed = True
            # Invalid characters in residue name
            if re.match(forbidden_characters, resname.strip()):
                pdbline = pdbline[:17] + 'UNK ' + pdbline[21:]
                fixed = True
            if lastnum + 1 != currentnum:
                pdbline = pdbline[:6] + (5 - len(str(newnum))) * ' ' + str(newnum) + ' ' + pdbline[12:]
                fixed = True
            # No chain assigned
            if pdbline[21] == ' ':
                pdbline = pdbline[:21] + 'A' + pdbline[22:]
                fixed = True
            if pdbline.endswith('H'):
                self.num_fixed_lines += 1
                return None, lastnum
            # Sometimes, converted PDB structures contain PDBQT atom types. Fix that.
            for pdbqttype in pdbqt_conversion:
                if pdbline.strip().endswith(pdbqttype):
                    pdbline = pdbline.strip()[:-2] + ' ' + pdbqt_conversion[pdbqttype] + '\n'
                    self.num_fixed_lines += 1
        if pdbline.startswith('HETATM'):
            newnum = lastnum + 1
            try:
                currentnum = int(pdbline[6:11])
            except ValueError:
                currentnum = None
                write_message("Invalid HETATM entry: %s\n" % pdbline, mtype='debug')
            if lastnum + 1 != currentnum:
                pdbline = pdbline[:6] + (5 - len(str(newnum))) * ' ' + str(newnum) + ' ' + pdbline[12:]
                fixed = True
            # No chain assigned or number assigned as chain
            if pdbline[21] == ' ':
                pdbline = pdbline[:21] + 'Z' + pdbline[22:]
                fixed = True
            # No residue number assigned
            if pdbline[23:26] == '   ':
                pdbline = pdbline[:23] + '999' + pdbline[26:]
                fixed = True
            # Non-standard Ligand Names
            ligname = pdbline[17:21].strip()
            if len(ligname) > 3:
                pdbline = pdbline[:17] + ligname[:3] + ' ' + pdbline[21:]
                fixed = True
            if re.match(forbidden_characters, ligname.strip()):
                pdbline = pdbline[:17] + 'LIG ' + pdbline[21:]
                fixed = True
            if len(ligname.strip()) == 0:
                pdbline = pdbline[:17] + 'LIG ' + pdbline[21:]
                fixed = True
            if pdbline.endswith('H'):
                self.num_fixed_lines += 1
                return None, lastnum
            # Sometimes, converted PDB structures contain PDBQT atom types. Fix that.
            for pdbqttype in pdbqt_conversion:
                if pdbline.strip().endswith(pdbqttype):
                    pdbline = pdbline.strip()[:-2] + ' ' + pdbqt_conversion[pdbqttype] + ' '
                    self.num_fixed_lines += 1
        self.num_fixed_lines += 1 if fixed else 0
        return pdbline + '\n', max(newnum, lastnum)
Fix a PDB line if information is missing.