Identify all functional groups (or all within a certain subset) in the
        molecule, combining the methods described above.

        :param elements: List of elements that will qualify a carbon as special
            (if only certain functional groups are of interest).
            Default None.
        :param func_groups: List of strs representing the functional groups of
            interest. Default to None, meaning that all of the functional groups
            defined in this function will be sought.
        :param catch_basic: bool. If True, use get_basic_functional_groups and
            other methods
        :return: list of sets of ints, representing groups of connected atoms

def get_all_functional_groups(self, elements=None, func_groups=None,
                                  catch_basic=True):
        """
        Identify all functional groups (or all within a certain subset) in the
        molecule, combining the methods described above.

        :param elements: List of elements that will qualify a carbon as special
            (if only certain functional groups are of interest).
            Default None.
        :param func_groups: List of strs representing the functional groups of
            interest. Default to None, meaning that all of the functional groups
            defined in this function will be sought.
        :param catch_basic: bool. If True, use get_basic_functional_groups and
            other methods
        :return: list of sets of ints, representing groups of connected atoms
        """

        heteroatoms = self.get_heteroatoms(elements=elements)
        special_cs = self.get_special_carbon(elements=elements)
        groups = self.link_marked_atoms(heteroatoms.union(special_cs))

        if catch_basic:
            groups += self.get_basic_functional_groups(func_groups=func_groups)

        return groups