docs: def add_sequence(self, sequence_id, sequence, ignore_bad_chains = False):
          '''If ignore_bad_chains is True then any chains containing all Xs as the sequence will be silently skipped.
             The default behavior is to raise a MalformedSequenceException in this case.'''
  
          # This is a sanity check. ClustalO allows ':' in the chain ID but ClustalW replaces ':' with '_' which breaks our parsing
          # All callers to add_sequence now need to replace ':' with '_' so that we can use ClustalW
          assert(sequence_id.find(':') == -1)
  
          if sequence_id in self.sequence_ids.values():
              raise Exception("Sequence IDs must be unique")
          if list(set(sequence)) == ['X']:
              if ignore_bad_chains:
                  return
              else:
                  raise MalformedSequenceException('The sequence contains only X characters. This will crash Clustal Omega.')
          self.records.append(">%s\n%s" % (sequence_id, "\n".join([sequence[i:i+80] for i in range(0, len(sequence), 80)])))
          self.sequence_ids[len(self.sequence_ids) + 1] = sequence_id