anchor.diff:  /// Parse the full body of [source] and return it's compilation unit.
   CompilationUnit parseFull(Source source) {
     var token = tokenize(source);
  +  parseTimer.start();
     var parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER);
  -  return parser.parseCompilationUnit(token);
  +  var unit = parser.parseCompilationUnit(token);
  +  parseTimer.stop();
  +  return unit;
   }
   
   UnlinkedUnitBuilder unlinkedSummarize(Source source) {
     var unit = parseFull(source);
  -  return serializeAstUnlinked(unit);
  +  unlinkedSummarizeTimer.start();
  +  var unlinkedUnit = serializeAstUnlinked(unit);
  +  unlinkedSummarizeTimer.stop();
  +  return unlinkedUnit;
   }
   
   /// Scan [source] and return the first token produced by the scanner.
  
positive.code:   scanTimer = new Stopwatch();
    var old = scanTotalChars;
    scanTotalChars = 0;
    var summarizeTimer = new Stopwatch()..start();
    for (var source in files) {
      unlinkedSummarize(source);
    }
    summarizeTimer.stop();
  
    if (old != scanTotalChars) print('input size changed? ${old} chars');
  
    // TODO(paulberry): subtract out scan/parse time?
    var summarizeTime = summarizeTimer.elapsedMicroseconds;
    report('unlinked summarize', summarizeTime);
  }
  
  /// Add to [files] all sources reachable from [start].
  
negative.code: 
  /// Cumulative time spent scanning.
  Stopwatch scanTimer = new Stopwatch();
  
  /// Cumulative time spent parsing.
  Stopwatch parseTimer = new Stopwatch();
  
  /// Cumulative time spent building unlinked summaries.
  Stopwatch unlinkedSummarizeTimer = new Stopwatch();
  
  /// Factory to load and resolve app, packages, and sdk sources.
  SourceFactory sources;
  