'Find contacts/addresses of the right type(s) by doing a depth-first-search
through descendants within company boundaries (stop at entities flagged ``is_company``)
then continuing the search at the ancestors that are within the same company boundaries.
Defaults to partners of type ``\'default\'`` when the exact type is not found, or to the
provided partner itself if no type ``\'default\'`` is found either.'

@api.multi
def address_get(self, adr_pref=None):

    adr_pref = set((adr_pref or []))
    if ('contact' not in adr_pref):
        adr_pref.add('contact')
    result = {}
    visited = set()
    for partner in self:
        current_partner = partner
        while current_partner:
            to_scan = [current_partner]
            while to_scan:
                record = to_scan.pop(0)
                visited.add(record)
                if ((record.type in adr_pref) and (not result.get(record.type))):
                    result[record.type] = record.id
                if (len(result) == len(adr_pref)):
                    return result
                to_scan = ([c for c in record.child_ids if (c not in visited) if (not c.is_company)] + to_scan)
            if (current_partner.is_company or (not current_partner.parent_id)):
                break
            current_partner = current_partner.parent_id
    default = result.get('contact', (self.id or False))
    for adr_type in adr_pref:
        result[adr_type] = (result.get(adr_type) or default)
    return result
