code: def _follow_link(self, link_path_components, link):
          
          link_path = link.contents
          sep = self._path_separator(link_path)
          # For links to absolute paths, we want to throw out everything
          # in the path built so far and replace with the link. For relative
          # links, we have to append the link to what we have so far,
          if not self._starts_with_root_path(link_path):
              # Relative path. Append remainder of path to what we have
              # processed so far, excluding the name of the link itself.
              # /a/b => ../c  should yield /a/../c
              # (which will normalize to /c)
              # /a/b => d should yield a/d
              components = link_path_components[:-1]
              components.append(link_path)
              link_path = sep.join(components)
          # Don't call self.NormalizePath(), as we don't want to prepend
          # self.cwd.
          return self.normpath(link_path)
docs: Follow a link w.r.t. a path resolved so far.
  
          The component is either a real file, which is a no-op, or a
          symlink. In the case of a symlink, we have to modify the path
          as built up so far
            /a/b => ../c  should yield /a/../c (which will normalize to /a/c)
            /a/b => x     should yield /a/x
            /a/b => /x/y/z should yield /x/y/z
          The modified path may land us in a new spot which is itself a
          link, so we may repeat the process.
  
          Args:
              link_path_components: The resolved path built up to the link
                  so far.
              link: The link object itself.
  
          Returns:
              (string) The updated path resolved after following the link.
  
          Raises:
              IOError: if there are too many levels of symbolic link