def filepaths(path, exclude=(), hidden=True, empty=True):
    if not os.path.exists(path):
        raise error.PathNotFoundError(path)
    elif not os.access(path, os.R_OK,
                       effective_ids=os.access in os.supports_effective_ids):
        raise error.ReadError(errno.EACCES, path)
    if os.path.isfile(path):
        return [path]
    else:
        filepaths = []
        for dirpath, dirnames, filenames in os.walk(path):
            if not hidden and is_hidden(dirpath):
                continue
            for filename in filenames:
                if not hidden and is_hidden(filename):
                    continue
                filepath = os.path.join(dirpath, filename)
                if any(is_match(filepath, pattern) for pattern in exclude):
                    continue
                else:
                    if empty or os.path.getsize(os.path.realpath(filepath)) > 0:
                        filepaths.append(filepath)
        return sorted(filepaths, key=lambda fp: fp.casefold())