anchor.diff:  check_result({error, ?EPERM}) -> ignored;
   check_result({error, ?EACCES}) -> ignored;
   check_result({error, _} = Error) -> Error.
  +
  +
  +%% @private
  +-spec create_symlink_path(file_meta:path() | undefined, file_meta_symlinks:symlink(), file_meta:path()) -> 
  +    file_meta_symlinks:symlink().
  +create_symlink_path(undefined, LinkPath, _FileRelativePath) ->
  +    LinkPath;
  +create_symlink_path(RootDirPath, LinkPath, FileRelativePath) ->
  +    [_Sep, _SpaceName | RootDirPathTokens] = filename:split(RootDirPath),
  +    [_SpacePrefix, RootDirName | LinkPathTokens] = filename:split(LinkPath),
  +    case lists:prefix(RootDirPathTokens, [RootDirName, LinkPathTokens]) of
  +        true ->
  +            Depth = length(filename:split(FileRelativePath)),
  +            filename:join(lists:duplicate(Depth - 2, <<"..">>) ++ LinkPathTokens);
  +        false -> 
  +            LinkPath
  +    end.
  +    
positive.code:     [#file_attr{guid = Guid, type = ?DIRECTORY_TYPE, name = Name} = FileAttrs | Tail],
      BulkDownloadId, UserCtx, State
  ) ->
      % add starting dir to the tarball here as traverse does not execute slave job on it
      {Bytes, UpdatedState} = new_tar_file_entry(State, FileAttrs, Name),
      UpdatedState1 = send_data(Bytes, UpdatedState),
      bulk_download_traverse:start(BulkDownloadId, UserCtx, Guid, State#state.follow_symlinks_policy, Name),
      FinalState = wait_for_traverse(UpdatedState1, user_ctx:get_session_id(UserCtx)),
      handle_multiple_files(Tail, BulkDownloadId, UserCtx, FinalState);
  handle_multiple_files(
      [#file_attr{type = ?REGULAR_FILE_TYPE, name = Name} = FileAttrs | Tail], 
      BulkDownloadId, UserCtx, State
  
negative.code:     connection_pid :: pid(),
      tar_stream :: tar_utils:stream(),
      send_retry_delay = 100 :: time:millis(),
      follow_symlinks_policy = external :: tree_traverse:symlink_resolution_policy(),
      root_dir_path :: file_meta:path() | undefined
  }).
  
  -type state() :: #state{}.
  