anchor.diff:      return cachedContent;
     }
   
  +  Future<List<dto.Song>> flatten(String host, String path) async {
  +    final cachedContent = collectionCache.flattenDirectory(host, path);
  +    // TODO filter out songs that don't have cached audio
  +    if (cachedContent == null) {
  +      throw throw APIError.unexpectedCacheMiss;
  +    }
  +    return cachedContent;
  +  }
  +
     Future<Uint8List?> getImage(String path) async {
  +    final String host = _getHost();
  +    final cacheFile = await mediaCache.getImage(host, path);
  +    if (cacheFile != null) {
  +      return cacheFile.readAsBytes();
  +    }
  +    return null;
  +  }
  +
  +  String _getHost() {
       final String? host = connectionManager.url;
       if (host == null) {
         throw APIError.unspecifiedHost;
       }
  -    final cacheFile = await mediaCache.getImage(host, path);
  -    if (cacheFile != null) {
  -      return cacheFile.readAsBytes();
  -    }
  -    return null;
  +    return host;
     }
   }
   
  
positive.code:       return offlineClient.browse(path);
      }
  
      final String? host = connectionManager.url;
      if (host == null) {
        throw APIError.unspecifiedHost;
      }
  
      if (useCache && collectionCache.hasPopulatedDirectory(host, path)) {
        final cachedContent = collectionCache.getDirectory(host, path);
  
negative.code:   OfflineClient({required this.connectionManager, required this.mediaCache, required this.collectionCache});
  
    List<dto.CollectionFile> browse(String path) {
      final String host = _getHost();
      final cachedContent = collectionCache.getDirectory(host, path);
      if (cachedContent == null) {
        throw throw APIError.unexpectedCacheMiss;
  