def reversibility_heuristics(model, no_reverse_atp=True, no_proton_pumps=
    True, override_trusted=False):
    """ Apply heuristic rules to constrain reaction reversibilities.

    Args:
        model (CBModel): model
        no_reverse_atp (bool): no reversible ATP production from ATP consumers, except for trusted reactions (default: True)
        no_proton_pumps (bool): no pumping of electrons from cytosol to periplasm or extracellular space
    """
    if no_reverse_atp:
        for r_id, rxn in model.reactions.items():
            if rxn.trusted and not override_trusted:
                continue
            if 'M_atp_c' in rxn.get_substrates():
                model.set_flux_bounds(r_id, 0, 1000)
                rxn.reversible = False
    if no_proton_pumps:
        protons = {'M_h_c', 'M_h_p', 'M_h_e'}
        for r_id, rxn in model.reactions.items():
            if rxn.trusted and not override_trusted:
                continue
            substrates = set(rxn.get_substrates())
            products = set(rxn.get_products())
            if len(substrates) == len(products) == 2:
                if ('M_h_p' in substrates or 'M_h_e' in substrates
                    ) and 'M_h_c' in products:
                    substrate = (substrates - protons).pop()
                    product = (products - protons).pop()
                    if substrate[:-2] == product[:-2]:
                        model.set_flux_bounds(r_id, 0, 1000)
                        rxn.reversible = False
                if ('M_h_p' in products or 'M_h_e' in products
                    ) and 'M_h_c' in substrates:
                    substrate = (substrates - protons).pop()
                    product = (products - protons).pop()
                    if substrate[:-2] == product[:-2]:
                        model.set_flux_bounds(r_id, -1000, 0)
