Add one or more ClassFile sources to the class loader.

        If a given source is a directory path, it is traversed up to the
        maximum set depth and all files under it are added to the class loader
        lookup table.

        If a given source is a .jar or .zip file it will be opened and the
        file index added to the class loader lookup table.

        If a given source is a ClassFile or a subclass, it's immediately
        added to the class loader lookup table and the class cache.

        :param sources: One or more ClassFile sources to be added.
        :param follow_symlinks: True if symlinks should be followed when
                                traversing filesystem directories.
                                [default: False]
        :param maximum_depth: The maximum sub-directory depth when traversing
                              filesystem directories. If set to `None` no limit
                              will be enforced. [default: 20]

def update(self, *sources, follow_symlinks: bool=False,
               maximum_depth: int=20):
        """Add one or more ClassFile sources to the class loader.

        If a given source is a directory path, it is traversed up to the
        maximum set depth and all files under it are added to the class loader
        lookup table.

        If a given source is a .jar or .zip file it will be opened and the
        file index added to the class loader lookup table.

        If a given source is a ClassFile or a subclass, it's immediately
        added to the class loader lookup table and the class cache.

        :param sources: One or more ClassFile sources to be added.
        :param follow_symlinks: True if symlinks should be followed when
                                traversing filesystem directories.
                                [default: False]
        :param maximum_depth: The maximum sub-directory depth when traversing
                              filesystem directories. If set to `None` no limit
                              will be enforced. [default: 20]
        """
        for source in sources:
            if isinstance(source, self.klass):
                self.path_map[source.this.name.value] = source
                self.class_cache[source.this.name.value] = source
                continue

            # Explicit cast to str to support Path objects.
            source = str(source)
            if source.lower().endswith(('.zip', '.jar')):
                zf = ZipFile(source, 'r')
                self.path_map.update(zip(zf.namelist(), repeat(zf)))
            elif os.path.isdir(source):
                walker = _walk(
                    source,
                    follow_links=follow_symlinks,
                    maximum_depth=maximum_depth
                )
                for root, dirs, files in walker:
                    for file_ in files:
                        path_full = os.path.join(root, file_)
                        path_suffix = os.path.relpath(path_full, source)
                        self.path_map[path_suffix] = path_full