anchor.diff:            return a.url.compareTo(b.url);
           });
       });
  +
  +    _statsSubscription = pinManager.hostsStream.listen(_updateStats);
  +  }
  +
  +  @override
  +  void dispose() {
  +    super.dispose();
  +    _statsSubscription.cancel();
  +  }
  +
  +  void _updateStats(Set<pin.Host> hosts) {
  +    int newNumDirectories = 0;
  +    int newNumSongs = 0;
  +    for (pin.Host host in hosts) {
  +      for (dto.CollectionFile file in host.content) {
  +        if (file.isDirectory()) {
  +          newNumDirectories += 1;
  +        } else {
  +          newNumSongs += 1;
  +        }
  +      }
  +    }
  +    setState(() {
  +      numDirectories = newNumDirectories;
  +      numSongs = newNumSongs;
  +    });
     }
   
     @override
  
positive.code: 
  class _OfflineMusicPageState extends State<OfflineMusicPage> {
    late Stream<List<pin.Host>> _hosts;
  
    @override
    initState() {
  
negative.code:         children: [
            Row(
              children: const [
                // TODO directory stats
                Caption('14 songs'),
                Caption('2.58 MB'),
              ],
  