anchor.diff:   * report the offending difference in a nice way. For other [Pattern]s, just
    * reports whether the output contained the pattern.
    */
  -void _validateOutput(Pattern expected, List<String> actual) {
  +void _validateOutput(List<String> failures, String pipe, Pattern expected,
  +                     List<String> actual) {
     if (expected == null) return;
   
  -  if (expected is String) return _validateOutputString(expected, actual);
  -  var actualText = Strings.join(actual, "\n");
  +  if (expected is RegExp) {
  +    _validateOutputRegex(failures, pipe, expected, actual);
  +  } else {
  +    _validateOutputString(failures, pipe, expected, actual);
  +  }
  +}
  +
  +void _validateOutputRegex(List<String> failures, String pipe,
  +                          RegExp expected, List<String> actual) {
  +  var actualText = Strings.join(actual, '\n');
     if (actualText.contains(expected)) return;
  -  Expect.fail('Expected output to match "$expected", was:\n$actualText');
  -}
  -
  -void _validateOutputString(String expectedText, List<String> actual) {
  +
  +  if (actual.length == 0) {
  +    failures.add('Expected $pipe to match "${expected.pattern}" but got none.');
  +  } else {
  +    failures.add('Expected $pipe to match "${expected.pattern}" but got:');
  +    failures.addAll(actual.map((line) => '| $line'));
  +  }
  +}
  +
  +void _validateOutputString(List<String> failures, String pipe,
  +                           String expectedText, List<String> actual) {
     final expected = expectedText.split('\n');
   
     // Strip off the last line. This lets us have expected multiline strings
  
positive.code:       environment['DART_SDK'] = pathInSandbox(sdkPath);
  
        return runProcess(dartBin, dartArgs, workingDir: pathInSandbox(appPath),
            environment: environment, pipeStdout: output == null,
            pipeStderr: error == null);
      }).transform((result) {
        _validateOutput(output, result.stdout);
        _validateOutput(error, result.stderr);
  
        Expect.equals(result.exitCode, exitCode,
            'Pub returned exit code ${result.exitCode}, expected $exitCode.');
  
        return null;
      });
  
negative.code:   var dir = new Path.fromNative(new Options().script);
    while (dir.filename != 'pub') dir = dir.directoryPath;
  
    return new File(dir.toNativePath()).fullPathSync();
  }
  
  /**
  