Scans a module, collecting all used origins, assuming that modules
        are obtained only by dotted paths and no other kinds of expressions.

def scan_module(self, modpath, node):
        """Scans a module, collecting all used origins, assuming that modules
        are obtained only by dotted paths and no other kinds of expressions."""

        used_origins = self.map.setdefault(modpath, set())

        def get_origins(modpath, name):
            """Returns the chain of all origins for a given name in a module."""
            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):
            """Returns the set of all possible origins to which the given
            dotted-path expression might dereference."""
            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):
            """Returns the set of all possible origins that could be used
            during dereferencing of the given dotted-path expression."""
            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)