anchor.diff:        });
       }
   
  -    return collectValues(_n).then((description) {
  -      if (description != null) return description;
  +    return collectValues(_n).then((failure) {
  +      if (failure != null) return failure;
         var matchState = {};
         if (_matcher.matches(collectedValues, matchState)) return null;
         return _matcher.describeMismatch(collectedValues, new StringDescription(),
  
positive.code: 
    Future<Description> tryMatch(ScheduledStream stream) {
      var fork = stream.fork();
      return _matcher.tryMatch(fork).whenComplete(fork.close).then((description) {
        if (description != null) return null;
        return _matcher.tryMatch(stream);
      });
    }
  
negative.code:     return Future.wait([
        _matcher1.tryMatch(stream1).whenComplete(stream1.close),
        _matcher2.tryMatch(stream2).whenComplete(stream2.close)
      ]).then((failures) {
        var failure1 = failures.first;
        var failure2 = failures.last;
  
        // If both matchers matched, use the one that consumed more of the stream.
        if (failure1 == null && failure2 == null) {
          if (stream1.emittedValues.length >= stream2.emittedValues.length) {
            return _matcher1.tryMatch(stream);
          } else {
            return _matcher2.tryMatch(stream);
          }
        } else if (failure1 == null) {
          return _matcher1.tryMatch(stream);
        } else if (failure2 == null) {
          return _matcher2.tryMatch(stream);
        } else {
          return new StringDescription('both\n')
              .add(prefixLines(failure1.toString(), prefix: '  '))
              .add('\nand\n')
              .add(prefixLines(failure2.toString(), prefix: '  '))
              .toString();
        }
      });
  