def bubble(self, packet, state):
    ''''''
    if 'bubble_lp' not in packet.stats:
        packet.stats = {
            f'bubble_{reason}': 0
            for reason in ['direct', 'lp', 'gp']
        }


    stats = packet.stats
    dest = packet.destination
    community = self.network.community

    def send(to, reason):
        stats[f'bubble_{reason}'] += 1
        self.send(to, packet, reason=reason)

    if dest in self.links:
        send(dest, 'direct')
        return True

    lp = lambda n: community.get_lp(n)
    gp = lambda n: community.get_gp(n)

    local_community = [
        met for met in self.links if met in self.community
    ]

    not_local_community = [
        met for met in self.links if met not in self.community
    ]

    if local_community:
        max_lp = max(local_community, key=lp)
        if lp(max_lp) > lp(self):
            send(max_lp, 'lp')
            return True

    elif not_local_community:
        max_gp = max(not_local_community, key=gp)
        if gp(max_gp) > gp(self):
            send(max_gp, 'gp')
            return True

    return False