def compress_for_rename(paths):
    # type: (Iterable[str]) -> Set[str]
    """Returns a set containing the paths that need to be renamed.

    This set may include directories when the original sequence of paths
    included every file on disk.
    """
    case_map = dict((os.path.normcase(p), p) for p in paths)
    remaining = set(case_map)
    unchecked = sorted(set(os.path.split(p)[0]
                           for p in case_map.values()), key=len)
    wildcards = set()  # type: Set[str]

    def norm_join(*a):
        # type: (str) -> str
        return os.path.normcase(os.path.join(*a))

    for root in unchecked:
        if any(os.path.normcase(root).startswith(w)
               for w in wildcards):
            # This directory has already been handled.
            continue

        all_files = set()  # type: Set[str]
        all_subdirs = set()  # type: Set[str]
        for dirname, subdirs, files in os.walk(root):
            all_subdirs.update(norm_join(root, dirname, d)
                               for d in subdirs)
            all_files.update(norm_join(root, dirname, f)
                             for f in files)
        # If all the files we found are in our remaining set of files to
        # remove, then remove them from the latter set and add a wildcard
        # for the directory.
        if not (all_files - remaining):
            remaining.difference_update(all_files)
            wildcards.add(root + os.sep)

    return set(map(case_map.__getitem__, remaining)) | wildcards
Returns a set containing the paths that need to be renamed.

    This set may include directories when the original sequence of paths
    included every file on disk.
    
product/gradle-plugin/src/main/python/pip/_internal/req/req_uninstall.py