Returns the content of two PDB files and (optionally) a PyMOL session and associated script.
           The first returned PDB file ("bonsai") is missing the ATOM (and any related ANISOU) and HETATM records identified by atom_serial_numbers.
           The second returned PDB file ("cutting") only contains ATOM, ANISOU, and HETATM records which are identified by atom_serial_numbers.
           Both PDB objects contain all records from the original PDB which are not ATOM, ANISOU, or HETATM records.

           If keep_CA_in_cutting is set, the cutting will also contain the associated Calpha atoms. This is useful purely
           to visualize the cutting in the PyMOL session. If a PyMOL session is not to be generated, this option should
           be set to False.

def prune(self, arbitrary_atom_serial_numbers, sidechain_atom_serial_numbers = set(), atoms_serial_numbers_to_keep_in_cutting = set(), keep_CA_in_cutting = True, generate_pymol_session = True, bonsai_label = 'Bonsai', cutting_label = 'Cutting', pymol_executable = 'pymol'):
        '''Returns the content of two PDB files and (optionally) a PyMOL session and associated script.
           The first returned PDB file ("bonsai") is missing the ATOM (and any related ANISOU) and HETATM records identified by atom_serial_numbers.
           The second returned PDB file ("cutting") only contains ATOM, ANISOU, and HETATM records which are identified by atom_serial_numbers.
           Both PDB objects contain all records from the original PDB which are not ATOM, ANISOU, or HETATM records.

           If keep_CA_in_cutting is set, the cutting will also contain the associated Calpha atoms. This is useful purely
           to visualize the cutting in the PyMOL session. If a PyMOL session is not to be generated, this option should
           be set to False.
           '''
        bonsai = []
        cutting = []

        # Determine the set of sidechain residues in case keep_CA_in_cutting is True and we wish to keep those atoms in the cutting
        sidechain_residues = set()
        if keep_CA_in_cutting and sidechain_atom_serial_numbers:
            for line in self.indexed_lines:
                if line[0] == 'ATOM' and line[1] in sidechain_atom_serial_numbers:
                    residue_id = line[3].residue.id()
                    sidechain_residues.add(residue_id[0] + residue_id[1])

        atom_serial_numbers_to_remove = arbitrary_atom_serial_numbers.union(sidechain_atom_serial_numbers)
        for line in self.indexed_lines:
            if line[0]: # record type
                PDB_line = line[2]
                if line[1] in atom_serial_numbers_to_remove:
                    cutting.append(PDB_line)
                else:
                    if atoms_serial_numbers_to_keep_in_cutting and int(PDB_line[6:11]) in atoms_serial_numbers_to_keep_in_cutting:
                        cutting.append(PDB_line)
                    elif keep_CA_in_cutting and PDB_line[21:27] in sidechain_residues and PDB_line[12:16] == ' CA ':
                        cutting.append(PDB_line)
                    bonsai.append(PDB_line)
            else:
                bonsai.append(line[1])
                cutting.append(line[1])
        bonsai_pdb_content = '\n'.join(bonsai)
        cutting_pdb_content = '\n'.join(cutting)
        PSE_file, PSE_script = None, None
        try:
            PSE_file, PSE_script = self.generate_pymol_session(bonsai_pdb_content, cutting_pdb_content, bonsai_label = bonsai_label, cutting_label = cutting_label, pymol_executable = pymol_executable, settings = {})
        except Exception, e:
            colortext.error('Failed to generate the PyMOL session: "{0}"'.format(e))
        return bonsai_pdb_content, cutting_pdb_content, PSE_file, PSE_script