def scan_module(self, modpath, node):
        used_origins = self.map.setdefault(modpath, set())
        def get_origins(modpath, name):
            origins = set()
            def walk_origins(modpath, name):
                for origin in self.import_map.get_origins(modpath, name):
                    if origin not in origins:
                        origins.add(origin)
                        if '.' in origin:
                            walk_origins(*origin.rsplit('.', 1))
            walk_origins(modpath, name)
            return origins
        def get_origins_for_node(node):
            if node_type(node) == 'Name' and node_type(node.ctx) == 'Load':
                return {modpath + '.' + node.id} | get_origins(modpath, node.id)
            if node_type(node) == 'Attribute' and node_type(node.ctx) == 'Load':
                return set.union(set(), *[
                    {parent + '.' + node.attr} | get_origins(parent, node.attr)
                    for parent in get_origins_for_node(node.value)])
            return set()
        def get_origins_used_by_node(node):
            if node_type(node) == 'Name':
                return get_origins_for_node(node)
            if node_type(node) == 'Attribute':
                return set.union(get_origins_used_by_node(node.value),
                                 get_origins_for_node(node))
            return set()
        def scan_loads(node):
            if node_type(node) in ['Name', 'Attribute']:
                used_origins.update(get_origins_used_by_node(node))
            for_each_child(node, scan_loads)
        for_each_child(node, scan_loads)
        intermediate_origins = set()
        for origin in used_origins:
            parts = origin.split('.')
            for i in range(1, len(parts)):
                intermediate_origins.add('.'.join(parts[:i]))
        used_origins.update(intermediate_origins)