diff --git a/dev/bots/analyze-sample-code.dart b/dev/bots/analyze-sample-code.dart
index 9e04582..5c9f056 100644
--- a/dev/bots/analyze-sample-code.dart
+++ b/dev/bots/analyze-sample-code.dart
@@ -11,6 +11,11 @@
 // Only code in "## Sample code" or "### Sample code" sections is examined.
 // Subheadings can also be specified, as in "## Sample code: foo".
 //
+// Additionally, code inside of dartdoc snippet and sample blocks
+// ({@tool snippet ...}{@end-tool}, and {@tool sample ...}{@end-tool})
+// is recognized as sample code. Snippets are processed as separate programs,
+// and samples are processed in the same way as "## Sample code" blocks are.
+//
 // There are several kinds of sample code you can specify:
 //
 // * Constructor calls, typically showing what might exist in a build method.
@@ -38,8 +43,6 @@
 // top level. Instead, wrap it in a function or even a whole class, or make it a
 // valid variable declaration.
 
-import 'dart:async';
-import 'dart:convert';
 import 'dart:io';
 
 import 'package:path/path.dart' as path;
@@ -47,165 +50,385 @@
 // To run this: bin/cache/dart-sdk/bin/dart dev/bots/analyze-sample-code.dart
 
 final String _flutterRoot = path.dirname(path.dirname(path.dirname(path.fromUri(Platform.script))));
+final String _defaultFlutterPackage = path.join(_flutterRoot, 'packages', 'flutter', 'lib');
 final String _flutter = path.join(_flutterRoot, 'bin', Platform.isWindows ? 'flutter.bat' : 'flutter');
 
-class Line {
-  const Line(this.filename, this.line, this.indent);
-  final String filename;
-  final int line;
-  final int indent;
-  Line get next => this + 1;
-  Line operator +(int count) {
-    if (count == 0)
-      return this;
-    return Line(filename, line + count, indent);
+void main(List<String> arguments) {
+  Directory flutterPackage;
+  if (arguments.length == 1) {
+    // Used for testing.
+    flutterPackage = Directory(arguments.single);
+  } else {
+    flutterPackage = Directory(_defaultFlutterPackage);
   }
-  @override
-  String toString([int column]) {
-    if (column != null)
-      return '$filename:$line:${column + indent}';
-    return '$filename:$line';
-  }
+  exitCode = SampleChecker(flutterPackage).checkSamples();
 }
 
-class Section {
-  const Section(this.start, this.preamble, this.code, this.postamble);
-  final Line start;
-  final String preamble;
-  final List<String> code;
-  final String postamble;
-  Iterable<String> get strings sync* {
-    if (preamble != null) {
-      assert(!preamble.contains('\n'));
-      yield preamble;
-    }
-    assert(!code.any((String line) => line.contains('\n')));
-    yield* code;
-    if (postamble != null) {
-      assert(!postamble.contains('\n'));
-      yield postamble;
-    }
+/// Checks samples and code snippets for analysis errors.
+///
+/// Extracts dartdoc content from flutter package source code, identifies code
+/// sections, and writes them to a temporary directory, where 'flutter analyze'
+/// is used to analyze the sources for problems. If problems are found, the
+/// error output from the analyzer is parsed for details, and the problem
+/// locations are translated back to the source location.
+///
+/// For snippets, the snippets are generated using the snippets tool, and they
+/// are analyzed with the samples. If errors are found in snippets, then the
+/// line number of the start of the snippet is given instead of the actual error
+/// line, since snippets get reformatted when written, and the line numbers
+/// don't necessarily match. It does, however, print the source of the
+/// problematic line.
+class SampleChecker {
+  SampleChecker(this._flutterPackage) {
+    _tempDir = Directory.systemTemp.createTempSync('flutter_analyze_sample_code.');
   }
-  List<Line> get lines {
-    final List<Line> result = List<Line>.generate(code.length, (int index) => start + index);
-    if (preamble != null)
-      result.insert(0, null);
-    if (postamble != null)
-      result.add(null);
-    return result;
+
+  /// The prefix of each comment line
+  static const String _dartDocPrefix = '///';
+
+  /// The prefix of each comment line with a space appended.
+  static const String _dartDocPrefixWithSpace = '$_dartDocPrefix ';
+
+  /// A RegExp that matches the beginning of a dartdoc snippet or sample.
+  static final RegExp _dartDocSampleBeginRegex = RegExp(r'{@tool (sample|snippet)(?:| ([^}]*))}');
+
+  /// A RegExp that matches the end of a dartdoc snippet or sample.
+  static final RegExp _dartDocSampleEndRegex = RegExp(r'{@end-tool}');
+
+  /// A RegExp that matches the start of a code block within dartdoc.
+  static final RegExp _codeBlockStartRegex = RegExp(r'/// ```dart.*$');
+
+  /// A RegExp that matches the end of a code block within dartdoc.
+  static final RegExp _codeBlockEndRegex = RegExp(r'/// ```\s*$');
+
+  /// A RegExp that matches a Dart constructor.
+  static final RegExp _constructorRegExp = RegExp(r'[A-Z][a-zA-Z0-9<>.]*\(');
+
+  /// The temporary directory where all output is written. This will be deleted
+  /// automatically if there are no errors.
+  Directory _tempDir;
+
+  /// The package directory for the flutter package within the flutter root dir.
+  final Directory _flutterPackage;
+
+  /// A serial number so that we can create unique expression names when we
+  /// generate them.
+  int _expressionId = 0;
+
+  /// The exit code from the analysis process.
+  int _exitCode = 0;
+
+  // Once the snippets tool has been precompiled by Dart, this contains the AOT
+  // snapshot.
+  String _snippetsSnapshotPath;
+
+  /// Finds the location of the snippets script.
+  String get _snippetsExecutable {
+    final String platformScriptPath = path.dirname(Platform.script.toFilePath());
+    return path.canonicalize(path.join(platformScriptPath, '..', 'snippets', 'lib', 'main.dart'));
   }
-}
 
-const String kDartDocPrefix = '///';
-const String kDartDocPrefixWithSpace = '$kDartDocPrefix ';
+  static List<File> _listDartFiles(Directory directory, {bool recursive = false}) {
+    return directory.listSync(recursive: recursive, followLinks: false)
+      .whereType<File>()
+      .where((File file) => path.extension(file.path) == '.dart').toList();
+  }
 
-Future<void> main(List<String> arguments) async {
-  final Directory tempDir = Directory.systemTemp.createTempSync('flutter_analyze_sample_code.');
-  int exitCode = 1;
-  bool keepMain = false;
-  final List<String> buffer = <String>[];
-  try {
-    final File mainDart = File(path.join(tempDir.path, 'main.dart'));
-    final File pubSpec = File(path.join(tempDir.path, 'pubspec.yaml'));
-    final File analysisOptions = File(path.join(tempDir.path, 'analysis_options.yaml'));
-    Directory flutterPackage;
-    if (arguments.length == 1) {
-      // Used for testing.
-      flutterPackage = Directory(arguments.single);
-    } else {
-      flutterPackage = Directory(path.join(_flutterRoot, 'packages', 'flutter', 'lib'));
-    }
-    final List<Section> sections = <Section>[];
-    int sampleCodeSections = 0;
-    for (FileSystemEntity file in flutterPackage.listSync(recursive: true, followLinks: false)) {
-      if (file is File && path.extension(file.path) == '.dart') {
-        final List<String> lines = file.readAsLinesSync();
-        bool inPreamble = false;
-        bool inSampleSection = false;
-        bool inDart = false;
-        bool foundDart = false;
-        int lineNumber = 0;
-        final List<String> block = <String>[];
-        Line startLine;
-        for (String line in lines) {
-          lineNumber += 1;
-          final String trimmedLine = line.trim();
-          if (inPreamble) {
-            if (line.isEmpty) {
-              inPreamble = false;
-              processBlock(startLine, block, sections);
-            } else if (!line.startsWith('// ')) {
-              throw '${file.path}:$lineNumber: Unexpected content in sample code preamble.';
-            } else {
-              block.add(line.substring(3));
-            }
-          } else if (inSampleSection) {
-            if (!trimmedLine.startsWith(kDartDocPrefix) || trimmedLine.startsWith('/// ## ')) {
-              if (inDart)
-                throw '${file.path}:$lineNumber: Dart section inexplicably unterminated.';
-              if (!foundDart)
-                throw '${file.path}:$lineNumber: No dart block found in sample code section';
-              inSampleSection = false;
-            } else {
-              if (inDart) {
-                if (trimmedLine == '/// ```') {
-                  inDart = false;
-                  processBlock(startLine, block, sections);
-                } else if (trimmedLine == kDartDocPrefix) {
-                  block.add('');
-                } else {
-                  final int index = line.indexOf(kDartDocPrefixWithSpace);
-                  if (index < 0)
-                    throw '${file.path}:$lineNumber: Dart section inexplicably did not contain "$kDartDocPrefixWithSpace" prefix.';
-                  block.add(line.substring(index + 4));
-                }
-              } else if (trimmedLine == '/// ```dart') {
-                assert(block.isEmpty);
-                startLine = Line(file.path, lineNumber + 1, line.indexOf(kDartDocPrefixWithSpace) + kDartDocPrefixWithSpace.length);
-                inDart = true;
-                foundDart = true;
-              }
-            }
-          }
-          if (!inSampleSection) {
-            if (line == '// Examples can assume:') {
-              assert(block.isEmpty);
-              startLine = Line(file.path, lineNumber + 1, 3);
-              inPreamble = true;
-            } else if (trimmedLine == '/// ## Sample code' ||
-                       trimmedLine.startsWith('/// ## Sample code:') ||
-                       trimmedLine == '/// ### Sample code' ||
-                       trimmedLine.startsWith('/// ### Sample code:')) {
-              inSampleSection = true;
-              foundDart = false;
-              sampleCodeSections += 1;
-            }
-          }
-        }
-      }
-    }
-    buffer.add('// generated code');
-    buffer.add('import \'dart:async\';');
-    buffer.add('import \'dart:convert\';');
-    buffer.add('import \'dart:math\' as math;');
-    buffer.add('import \'dart:typed_data\';');
-    buffer.add('import \'dart:ui\' as ui;');
-    buffer.add('import \'package:flutter_test/flutter_test.dart\';');
-    for (FileSystemEntity file in flutterPackage.listSync(recursive: false, followLinks: false)) {
-      if (file is File && path.extension(file.path) == '.dart') {
+  /// Computes the headers needed for each sample file.
+  List<Line> get headers {
+    if (_headers == null) {
+      final List<String> buffer = <String>[];
+      buffer.add('// generated code');
+      buffer.add('import \'dart:async\';');
+      buffer.add('import \'dart:convert\';');
+      buffer.add('import \'dart:math\' as math;');
+      buffer.add('import \'dart:typed_data\';');
+      buffer.add('import \'dart:ui\' as ui;');
+      buffer.add('import \'package:flutter_test/flutter_test.dart\';');
+      for (File file in _listDartFiles(Directory(_defaultFlutterPackage))) {
         buffer.add('');
         buffer.add('// ${file.path}');
         buffer.add('import \'package:flutter/${path.basename(file.path)}\';');
       }
+      _headers = buffer.map<Line>((String code) => Line(code)).toList();
     }
-    buffer.add('');
-    final List<Line> lines = List<Line>.filled(buffer.length, null, growable: true);
+    return _headers;
+  }
+
+  List<Line> _headers;
+
+  /// Checks all the samples in the Dart files in [_flutterPackage] for errors.
+  int checkSamples() {
+    _exitCode = 0;
+    Map<String, List<AnalysisError>> errors = <String, List<AnalysisError>>{};
+    try {
+      final Map<String, Section> sections = <String, Section>{};
+      final Map<String, Snippet> snippets = <String, Snippet>{};
+      _extractSamples(sections, snippets);
+      errors = _analyze(_tempDir, sections, snippets);
+    } finally {
+      if (errors.isNotEmpty) {
+        for (String filePath in errors.keys) {
+          errors[filePath].forEach(stderr.writeln);
+        }
+        stderr.writeln('\nFound ${errors.length} sample code errors.');
+      }
+      try {
+        _tempDir.deleteSync(recursive: true);
+      } on FileSystemException catch (e) {
+        stderr.writeln('Failed to delete ${_tempDir.path}: $e');
+      }
+      // If we made a snapshot, remove it (so as not to clutter up the tree).
+      if (_snippetsSnapshotPath != null) {
+        final File snapshot = File(_snippetsSnapshotPath);
+        if (snapshot.existsSync()) {
+          snapshot.deleteSync();
+        }
+      }
+    }
+    return _exitCode;
+  }
+
+  /// Creates a name for the snippets tool to use for the snippet ID from a
+  /// filename and starting line number.
+  String _createNameFromSource(String prefix, String filename, int start) {
+    String snippetId = path.relative(filename, from: _flutterPackage.path);
+    snippetId = path.split(snippetId).join('.');
+    snippetId = path.basenameWithoutExtension(snippetId);
+    snippetId = '$prefix.$snippetId.$start';
+    return snippetId;
+  }
+
+  // Precompiles the snippets tool if _snippetsSnapshotPath isn't set yet, and
+  // runs the precompiled version if it is set.
+  ProcessResult _runSnippetsScript(List<String> args) {
+    if (_snippetsSnapshotPath == null) {
+      _snippetsSnapshotPath = '$_snippetsExecutable.snapshot';
+      return Process.runSync(
+        Platform.executable,
+        <String>[
+          '--snapshot=$_snippetsSnapshotPath',
+          '--snapshot-kind=app-jit',
+          _snippetsExecutable,
+        ]..addAll(args),
+        workingDirectory: _flutterRoot,
+      );
+    } else {
+      return Process.runSync(
+        Platform.executable,
+        <String>[_snippetsSnapshotPath]..addAll(args),
+        workingDirectory: _flutterRoot,
+      );
+    }
+  }
+
+  /// Writes out the given [snippet] to an output file in the [_tempDir] and
+  /// returns the output file.
+  File _writeSnippet(Snippet snippet) {
+    // Generate the snippet.
+    final String snippetId = _createNameFromSource('snippet', snippet.start.filename, snippet.start.line);
+    final String inputName = '$snippetId.input';
+    // Now we have a filename like 'lib.src.material.foo_widget.123.dart' for each snippet.
+    final File inputFile = File(path.join(_tempDir.path, inputName))..createSync(recursive: true);
+    inputFile.writeAsStringSync(snippet.input.join('\n'));
+    final File outputFile = File(path.join(_tempDir.path, '$snippetId.dart'));
+    final List<String> args = <String>[
+      '--output=${outputFile.absolute.path}',
+      '--input=${inputFile.absolute.path}',
+    ]..addAll(snippet.args);
+    print('Generating snippet for ${snippet.start?.filename}:${snippet.start?.line}');
+    final ProcessResult process = _runSnippetsScript(args);
+    if (process.exitCode != 0) {
+      throw 'Unable to create snippet for ${snippet.start.filename}:${snippet.start.line} '
+          '(using input from ${inputFile.path}):\n${process.stdout}\n${process.stderr}';
+    }
+    return outputFile;
+  }
+
+  /// Extracts the samples from the Dart files in [_flutterPackage], writes them
+  /// to disk, and adds them to the appropriate [sectionMap] or [snippetMap].
+  void _extractSamples(Map<String, Section> sectionMap, Map<String, Snippet> snippetMap) {
+    final List<Section> sections = <Section>[];
+    final List<Snippet> snippets = <Snippet>[];
+
+    for (File file in _listDartFiles(_flutterPackage, recursive: true)) {
+      final String relativeFilePath = path.relative(file.path, from: _flutterPackage.path);
+      final List<String> sampleLines = file.readAsLinesSync();
+      final List<Section> preambleSections = <Section>[];
+      bool inPreamble = false;
+      bool inSampleSection = false;
+      bool inSnippet = false;
+      bool inDart = false;
+      bool foundDart = false;
+      int lineNumber = 0;
+      final List<String> block = <String>[];
+      List<String> snippetArgs = <String>[];
+      Line startLine;
+      for (String line in sampleLines) {
+        lineNumber += 1;
+        final String trimmedLine = line.trim();
+        if (inSnippet) {
+          if (!trimmedLine.startsWith(_dartDocPrefix)) {
+            throw '$relativeFilePath:$lineNumber: Snippet section unterminated.';
+          }
+          if (_dartDocSampleEndRegex.hasMatch(trimmedLine)) {
+            snippets.add(
+              Snippet(
+                start: startLine,
+                input: block,
+                args: snippetArgs,
+                serial: snippets.length,
+              ),
+            );
+            snippetArgs = <String>[];
+            block.clear();
+            inSnippet = false;
+            inSampleSection = false;
+          } else {
+            block.add(line.replaceFirst(RegExp(r'\s*/// ?'), ''));
+          }
+        } else if (inPreamble) {
+          if (line.isEmpty) {
+            inPreamble = false;
+            preambleSections.add(_processBlock(startLine, block));
+            block.clear();
+          } else if (!line.startsWith('// ')) {
+            throw '$relativeFilePath:$lineNumber: Unexpected content in sample code preamble.';
+          } else {
+            block.add(line.substring(3));
+          }
+        } else if (inSampleSection) {
+          if (!trimmedLine.startsWith(_dartDocPrefix) || trimmedLine.startsWith('$_dartDocPrefix ## ')) {
+            if (inDart) {
+              throw '$relativeFilePath:$lineNumber: Dart section inexplicably unterminated.';
+            }
+            if (!foundDart) {
+              throw '$relativeFilePath:$lineNumber: No dart block found in sample code section';
+            }
+            inSampleSection = false;
+          } else {
+            if (inDart) {
+              if (_codeBlockEndRegex.hasMatch(trimmedLine)) {
+                inDart = false;
+                final Section processed = _processBlock(startLine, block);
+                if (preambleSections.isEmpty) {
+                  sections.add(processed);
+                } else {
+                  sections.add(Section.combine(preambleSections
+                    ..toList()
+                    ..add(processed)));
+                }
+                block.clear();
+              } else if (trimmedLine == _dartDocPrefix) {
+                block.add('');
+              } else {
+                final int index = line.indexOf(_dartDocPrefixWithSpace);
+                if (index < 0) {
+                  throw '$relativeFilePath:$lineNumber: Dart section inexplicably did not '
+                      'contain "$_dartDocPrefixWithSpace" prefix.';
+                }
+                block.add(line.substring(index + 4));
+              }
+            } else if (_codeBlockStartRegex.hasMatch(trimmedLine)) {
+              assert(block.isEmpty);
+              startLine = Line(
+                '',
+                filename: relativeFilePath,
+                line: lineNumber + 1,
+                indent: line.indexOf(_dartDocPrefixWithSpace) + _dartDocPrefixWithSpace.length,
+              );
+              inDart = true;
+              foundDart = true;
+            }
+          }
+        }
+        if (!inSampleSection) {
+          final Match sampleMatch = _dartDocSampleBeginRegex.firstMatch(trimmedLine);
+          if (line == '// Examples can assume:') {
+            assert(block.isEmpty);
+            startLine = Line('', filename: relativeFilePath, line: lineNumber + 1, indent: 3);
+            inPreamble = true;
+          } else if (trimmedLine == '/// ## Sample code' ||
+              trimmedLine.startsWith('/// ## Sample code:') ||
+              trimmedLine == '/// ### Sample code' ||
+              trimmedLine.startsWith('/// ### Sample code:') ||
+              sampleMatch != null) {
+            inSnippet = sampleMatch != null ? sampleMatch[1] == 'snippet' : false;
+            if (inSnippet) {
+              startLine = Line(
+                '',
+                filename: relativeFilePath,
+                line: lineNumber + 1,
+                indent: line.indexOf(_dartDocPrefixWithSpace) + _dartDocPrefixWithSpace.length,
+              );
+              if (sampleMatch[2] != null) {
+                // There are arguments to the snippet tool to keep track of.
+                snippetArgs = _splitUpQuotedArgs(sampleMatch[2]).toList();
+              } else {
+                snippetArgs = <String>[];
+              }
+            }
+            inSampleSection = !inSnippet;
+            foundDart = false;
+          }
+        }
+      }
+    }
+    print('Found ${sections.length} sample code sections.');
     for (Section section in sections) {
-      buffer.addAll(section.strings);
-      lines.addAll(section.lines);
+      sectionMap[_writeSection(section).path] = section;
     }
-    assert(buffer.length == lines.length);
-    mainDart.writeAsStringSync(buffer.join('\n'));
+    for (Snippet snippet in snippets) {
+      final File snippetFile = _writeSnippet(snippet);
+      snippet.contents = snippetFile.readAsLinesSync();
+      snippetMap[snippetFile.absolute.path] = snippet;
+    }
+  }
+
+  /// Helper to process arguments given as a (possibly quoted) string.
+  ///
+  /// First, this will split the given [argsAsString] into separate arguments,
+  /// taking any quoting (either ' or " are accepted) into account, including
+  /// handling backslash-escaped quotes.
+  ///
+  /// Then, it will prepend "--" to any args that start with an identifier
+  /// followed by an equals sign, allowing the argument parser to treat any
+  /// "foo=bar" argument as "--foo=bar" (which is a dartdoc-ism).
+  Iterable<String> _splitUpQuotedArgs(String argsAsString) {
+    // Regexp to take care of splitting arguments, and handling the quotes
+    // around arguments, if any.
+    //
+    // Match group 1 is the "foo=" (or "--foo=") part of the option, if any.
+    // Match group 2 contains the quote character used (which is discarded).
+    // Match group 3 is a quoted arg, if any, without the quotes.
+    // Match group 4 is the unquoted arg, if any.
+    final RegExp argMatcher = RegExp(r'([a-zA-Z\-_0-9]+=)?' // option name
+        r'(?:' // Start a new non-capture group for the two possibilities.
+        r'''(["'])((?:\\{2})*|(?:.*?[^\\](?:\\{2})*))\2|''' // with quotes.
+        r'([^ ]+))'); // without quotes.
+    final Iterable<Match> matches = argMatcher.allMatches(argsAsString);
+
+    // Remove quotes around args, and if convertToArgs is true, then for any
+    // args that look like assignments (start with valid option names followed
+    // by an equals sign), add a "--" in front so that they parse as options.
+    return matches.map<String>((Match match) {
+      String option = '';
+      if (match[1] != null && !match[1].startsWith('-')) {
+        option = '--';
+      }
+      if (match[2] != null) {
+        // This arg has quotes, so strip them.
+        return '$option${match[1] ?? ''}${match[3] ?? ''}${match[4] ?? ''}';
+      }
+      return '$option${match[0]}';
+    });
+  }
+
+  /// Creates the configuration files necessary for the analyzer to consider
+  /// the temporary director a package, and sets which lint rules to enforce.
+  void _createConfigurationFiles(Directory directory) {
+    final File pubSpec = File(path.join(directory.path, 'pubspec.yaml'))..createSync(recursive: true);
+    final File analysisOptions = File(path.join(directory.path, 'analysis_options.yaml'))..createSync(recursive: true);
     pubSpec.writeAsStringSync('''
 name: analyze_sample_code
 dependencies:
@@ -220,145 +443,391 @@
     - unnecessary_const
     - unnecessary_new
 ''');
-    print('Found $sampleCodeSections sample code sections.');
-    final Process process = await Process.start(
+  }
+
+  /// Writes out a sample section to the disk and returns the file.
+  File _writeSection(Section section) {
+    final String sectionId = _createNameFromSource('sample', section.start.filename, section.start.line);
+    final File outputFile = File(path.join(_tempDir.path, '$sectionId.dart'))..createSync(recursive: true);
+    final List<Line> mainContents = headers.toList();
+    mainContents.add(const Line(''));
+    mainContents.add(Line('// From: ${section.start.filename}:${section.start.line}'));
+    mainContents.addAll(section.code);
+    outputFile.writeAsStringSync(mainContents.map<String>((Line line) => line.code).join('\n'));
+    return outputFile;
+  }
+
+  /// Invokes the analyzer on the given [directory] and returns the stdout.
+  List<String> _runAnalyzer(Directory directory) {
+    print('Starting analysis of samples.');
+    _createConfigurationFiles(directory);
+    final ProcessResult result = Process.runSync(
       _flutter,
-      <String>['--no-wrap', 'analyze', '--no-preamble', '--no-congratulate', mainDart.parent.path],
-      workingDirectory: tempDir.path,
+      <String>['--no-wrap', 'analyze', '--no-preamble', '--no-congratulate', '.'],
+      workingDirectory: directory.absolute.path,
     );
-    final List<String> errors = <String>[];
-    errors.addAll(await process.stderr.transform<String>(utf8.decoder).transform<String>(const LineSplitter()).toList());
-    errors.add(null);
-    errors.addAll(await process.stdout.transform<String>(utf8.decoder).transform<String>(const LineSplitter()).toList());
-    // top is stderr
-    if (errors.isNotEmpty && (errors.first.contains(' issues found. (ran in ') || errors.first.contains(' issue found. (ran in '))) {
-      errors.removeAt(0); // the "23 issues found" message goes onto stderr, which is concatenated first
-      if (errors.isNotEmpty && errors.last.isEmpty)
-        errors.removeLast(); // if there's an "issues found" message, we put a blank line on stdout before it
+    final List<String> stderr = result.stderr.toString().trim().split('\n');
+    final List<String> stdout = result.stdout.toString().trim().split('\n');
+    // Check out the stderr to see if the analyzer had it's own issues.
+    if (stderr.isNotEmpty && (stderr.first.contains(' issues found. (ran in ') || stderr.first.contains(' issue found. (ran in '))) {
+      // The "23 issues found" message goes onto stderr, which is concatenated first.
+      stderr.removeAt(0);
+      // If there's an "issues found" message, we put a blank line on stdout before it.
+      if (stderr.isNotEmpty && stderr.last.isEmpty) {
+        stderr.removeLast();
+      }
     }
-    // null separates stderr from stdout
-    if (errors.first != null)
-      throw 'cannot analyze dartdocs; unexpected error output: $errors';
-    errors.removeAt(0);
-    // rest is stdout
-    if (errors.isNotEmpty && errors.first == 'Building flutter tool...')
-      errors.removeAt(0);
-    if (errors.isNotEmpty && errors.first.startsWith('Running "flutter packages get" in '))
-      errors.removeAt(0);
-    int errorCount = 0;
+    if (stderr.isNotEmpty) {
+      throw 'Cannot analyze dartdocs; unexpected error output:\n$stderr';
+    }
+    if (stdout.isNotEmpty && stdout.first == 'Building flutter tool...') {
+      stdout.removeAt(0);
+    }
+    if (stdout.isNotEmpty && stdout.first.startsWith('Running "flutter packages get" in ')) {
+      stdout.removeAt(0);
+    }
+    _exitCode = result.exitCode;
+    return stdout;
+  }
+
+  /// Starts the analysis phase of checking the samples by invoking the analyzer
+  /// and parsing its output to create a map of filename to [AnalysisError]s.
+  Map<String, List<AnalysisError>> _analyze(
+    Directory directory,
+    Map<String, Section> sections,
+    Map<String, Snippet> snippets,
+  ) {
+    final List<String> errors = _runAnalyzer(directory);
+    final Map<String, List<AnalysisError>> analysisErrors = <String, List<AnalysisError>>{};
+    void addAnalysisError(File file, AnalysisError error) {
+      if (analysisErrors.containsKey(file.path)) {
+        analysisErrors[file.path].add(error);
+      } else {
+        analysisErrors[file.path] = <AnalysisError>[error];
+      }
+    }
+
     final String kBullet = Platform.isWindows ? ' - ' : ' • ';
-    final RegExp errorPattern = RegExp('^ +([a-z]+)$kBullet(.+)$kBullet(.+):([0-9]+):([0-9]+)$kBullet([-a-z_]+)\$', caseSensitive: false);
+    // RegExp to match an error output line of the analyzer.
+    final RegExp errorPattern = RegExp(
+      '^ +([a-z]+)$kBullet(.+)$kBullet(.+):([0-9]+):([0-9]+)$kBullet([-a-z_]+)\$',
+      caseSensitive: false,
+    );
+    bool unknownAnalyzerErrors = false;
+    final int headerLength = headers.length + 2;
     for (String error in errors) {
       final Match parts = errorPattern.matchAsPrefix(error);
       if (parts != null) {
         final String message = parts[2];
-        final String file = parts[3];
+        final File file = File(path.join(_tempDir.path, parts[3]));
+        final List<String> fileContents = file.readAsLinesSync();
+        final bool isSnippet = path.basename(file.path).startsWith('snippet.');
+        final bool isSample = path.basename(file.path).startsWith('sample.');
         final String line = parts[4];
         final String column = parts[5];
         final String errorCode = parts[6];
-        final int lineNumber = int.parse(line, radix: 10);
+        final int lineNumber = int.parse(line, radix: 10) - (isSample ? headerLength : 0);
         final int columnNumber = int.parse(column, radix: 10);
-        if (file != 'main.dart') {
-          keepMain = true;
-          throw 'cannot analyze dartdocs; analysis errors exist in $file: $error';
+        if (lineNumber < 0 && errorCode == 'unused_import') {
+          // We don't care about unused imports.
+          continue;
         }
-        if (lineNumber < 1 || lineNumber > lines.length) {
-          keepMain = true;
-          throw 'failed to parse error message (read line number as $lineNumber; total number of lines is ${lines.length}): $error';
+
+        // For when errors occur outside of the things we're trying to analyze.
+        if (!isSnippet && !isSample) {
+          addAnalysisError(
+            file,
+            AnalysisError(
+              lineNumber,
+              columnNumber,
+              message,
+              errorCode,
+              Line(
+                '',
+                filename: file.path,
+                line: lineNumber,
+              ),
+            ),
+          );
+          throw 'Cannot analyze dartdocs; analysis errors exist in ${file.path}: $error';
         }
-        final Line actualLine = lines[lineNumber - 1];
+
         if (errorCode == 'unused_element' || errorCode == 'unused_local_variable') {
           // We don't really care if sample code isn't used!
-        } else if (actualLine == null) {
-          if (errorCode == 'missing_identifier' && lineNumber > 1 && buffer[lineNumber - 2].endsWith(',')) {
-            final Line actualLine = lines[lineNumber - 2];
-            print('${actualLine.toString(buffer[lineNumber - 2].length - 1)}: unexpected comma at end of sample code');
-            errorCount += 1;
-          } else {
-            print('${mainDart.path}:${lineNumber - 1}:$columnNumber: $message');
-            keepMain = true;
-            errorCount += 1;
-          }
+          continue;
+        }
+
+        if (isSnippet) {
+          addAnalysisError(
+            file,
+            AnalysisError(
+              lineNumber,
+              columnNumber,
+              message,
+              errorCode,
+              null,
+              snippet: snippets[file.path],
+            ),
+          );
         } else {
-          print('${actualLine.toString(columnNumber)}: $message ($errorCode)');
-          errorCount += 1;
+          if (lineNumber < 1 || lineNumber > fileContents.length) {
+            addAnalysisError(
+              file,
+              AnalysisError(
+                lineNumber,
+                columnNumber,
+                message,
+                errorCode,
+                Line('', filename: file.path, line: lineNumber),
+              ),
+            );
+            throw 'Failed to parse error message (read line number as $lineNumber; '
+                'total number of lines is ${fileContents.length}): $error';
+          }
+
+          final Section actualSection = sections[file.path];
+          final Line actualLine = actualSection.code[lineNumber - 1];
+
+          if (actualLine.filename == null) {
+            if (errorCode == 'missing_identifier' && lineNumber > 1) {
+              if (fileContents[lineNumber - 2].endsWith(',')) {
+                final Line actualLine = sections[file.path].code[lineNumber - 2];
+                addAnalysisError(
+                  file,
+                  AnalysisError(
+                    actualLine.line,
+                    actualLine.indent + fileContents[lineNumber - 2].length - 1,
+                    'Unexpected comma at end of sample code.',
+                    errorCode,
+                    actualLine,
+                  ),
+                );
+              }
+            } else {
+              addAnalysisError(
+                file,
+                AnalysisError(
+                  lineNumber - 1,
+                  columnNumber,
+                  message,
+                  errorCode,
+                  actualLine,
+                ),
+              );
+            }
+          } else {
+            addAnalysisError(
+              file,
+              AnalysisError(
+                actualLine.line,
+                actualLine.indent + columnNumber,
+                message,
+                errorCode,
+                actualLine,
+              ),
+            );
+          }
         }
       } else {
-        print('?? $error');
-        keepMain = true;
-        errorCount += 1;
+        stderr.writeln('Analyzer output: $error');
+        unknownAnalyzerErrors = true;
       }
     }
-    exitCode = await process.exitCode;
-    if (exitCode == 1 && errorCount == 0)
-      exitCode = 0;
-    if (exitCode == 0)
-      print('No errors!');
-  } finally {
-    if (keepMain) {
-      print('Kept ${tempDir.path} because it had errors (see above).');
-      print('-------8<-------');
-      int number = 1;
-      for (String line in buffer) {
-        print('${number.toString().padLeft(6, " ")}: $line');
-        number += 1;
-      }
-      print('-------8<-------');
+    if (_exitCode == 1 && analysisErrors.isEmpty && !unknownAnalyzerErrors) {
+      _exitCode = 0;
+    }
+    if (_exitCode == 0) {
+      print('No analysis errors in samples!');
+      assert(analysisErrors.isEmpty);
+    }
+    return analysisErrors;
+  }
+
+  /// Process one block of sample code (the part inside of "```" markers).
+  /// Splits any sections denoted by "// ..." into separate blocks to be
+  /// processed separately. Uses a primitive heuristic to make sample blocks
+  /// into valid Dart code.
+  Section _processBlock(Line line, List<String> block) {
+    if (block.isEmpty) {
+      throw '$line: Empty ```dart block in sample code.';
+    }
+    if (block.first.startsWith('new ') || block.first.startsWith('const ') || block.first.startsWith(_constructorRegExp)) {
+      _expressionId += 1;
+      return Section.surround(line, 'dynamic expression$_expressionId = ', block.toList(), ';');
+    } else if (block.first.startsWith('await ')) {
+      _expressionId += 1;
+      return Section.surround(line, 'Future<void> expression$_expressionId() async { ', block.toList(), ' }');
+    } else if (block.first.startsWith('class ') || block.first.startsWith('enum ')) {
+      return Section.fromStrings(line, block.toList());
+    } else if ((block.first.startsWith('_') || block.first.startsWith('final ')) && block.first.contains(' = ')) {
+      _expressionId += 1;
+      return Section.surround(line, 'void expression$_expressionId() { ', block.toList(), ' }');
     } else {
-      try {
-        tempDir.deleteSync(recursive: true);
-      } on FileSystemException catch (e) {
-        print('Failed to delete ${tempDir.path}: $e');
+      final List<String> buffer = <String>[];
+      int subblocks = 0;
+      Line subline;
+      final List<Section> subsections = <Section>[];
+      for (int index = 0; index < block.length; index += 1) {
+        // Each section of the dart code that is either split by a blank line, or with '// ...' is
+        // treated as a separate code block.
+        if (block[index] == '' || block[index] == '// ...') {
+          if (subline == null)
+            throw '${Line('', filename: line.filename, line: line.line + index, indent: line.indent)}: '
+                'Unexpected blank line or "// ..." line near start of subblock in sample code.';
+          subblocks += 1;
+          subsections.add(_processBlock(subline, buffer));
+          buffer.clear();
+          assert(buffer.isEmpty);
+          subline = null;
+        } else if (block[index].startsWith('// ')) {
+          if (buffer.length > 1) // don't include leading comments
+            buffer.add('/${block[index]}'); // so that it doesn't start with "// " and get caught in this again
+        } else {
+          subline ??= Line(
+            block[index],
+            filename: line.filename,
+            line: line.line + index,
+            indent: line.indent,
+          );
+          buffer.add(block[index]);
+        }
+      }
+      if (subblocks > 0) {
+        if (subline != null) {
+          subsections.add(_processBlock(subline, buffer));
+        }
+        // Combine all of the subsections into one section, now that they've been processed.
+        return Section.combine(subsections);
+      } else {
+        return Section.fromStrings(line, block.toList());
       }
     }
   }
-  exit(exitCode);
 }
 
-final RegExp _constructorRegExp = RegExp(r'[A-Z][a-zA-Z0-9<>.]*\(');
+/// A class to represent a line of input code.
+class Line {
+  const Line(this.code, {this.filename, this.line, this.indent});
+  final String filename;
+  final int line;
+  final int indent;
+  final String code;
 
-int _expressionId = 0;
-
-void processBlock(Line line, List<String> block, List<Section> sections) {
-  if (block.isEmpty)
-    throw '$line: Empty ```dart block in sample code.';
-  if (block.first.startsWith('new ') || block.first.startsWith('const ') || block.first.startsWith(_constructorRegExp)) {
-    _expressionId += 1;
-    sections.add(Section(line, 'dynamic expression$_expressionId = ', block.toList(), ';'));
-  } else if (block.first.startsWith('await ')) {
-    _expressionId += 1;
-    sections.add(Section(line, 'Future<void> expression$_expressionId() async { ', block.toList(), ' }'));
-  } else if (block.first.startsWith('class ') || block.first.startsWith('enum ')) {
-    sections.add(Section(line, null, block.toList(), null));
-  } else if ((block.first.startsWith('_') || block.first.startsWith('final ')) && block.first.contains(' = ')) {
-    _expressionId += 1;
-    sections.add(Section(line, 'void expression$_expressionId() { ', block.toList(), ' }'));
-  } else {
-    final List<String> buffer = <String>[];
-    int subblocks = 0;
-    Line subline;
-    for (int index = 0; index < block.length; index += 1) {
-      if (block[index] == '' || block[index] == '// ...') {
-        if (subline == null)
-          throw '${line + index}: Unexpected blank line or "// ..." line near start of subblock in sample code.';
-        subblocks += 1;
-        processBlock(subline, buffer, sections);
-        assert(buffer.isEmpty);
-        subline = null;
-      } else if (block[index].startsWith('// ')) {
-        if (buffer.length > 1) // don't include leading comments
-          buffer.add('/${block[index]}'); // so that it doesn't start with "// " and get caught in this again
-      } else {
-        subline ??= line + index;
-        buffer.add(block[index]);
-      }
+  String toStringWithColumn(int column) {
+    if (column != null) {
+      return '$filename:$line:${column + indent}: $code';
     }
-    if (subblocks > 0) {
-      if (subline != null)
-        processBlock(subline, buffer, sections);
+    return toString();
+  }
+
+  @override
+  String toString() => '$filename:$line: $code';
+}
+
+/// A class to represent a section of sample code, either marked by
+/// "/// ## Sample code" in the comment, or by "{@tool sample}...{@end-tool}".
+class Section {
+  const Section(this.code);
+  factory Section.combine(List<Section> sections) {
+    final List<Line> code = <Line>[];
+    for (Section section in sections) {
+      code.addAll(section.code);
+    }
+    return Section(code);
+  }
+  factory Section.fromStrings(Line firstLine, List<String> code) {
+    final List<Line> codeLines = <Line>[];
+    for (int i = 0; i < code.length; ++i) {
+      codeLines.add(
+        Line(
+          code[i],
+          filename: firstLine.filename,
+          line: firstLine.line + i,
+          indent: firstLine.indent,
+        ),
+      );
+    }
+    return Section(codeLines);
+  }
+  factory Section.surround(Line firstLine, String prefix, List<String> code, String postfix) {
+    assert(prefix != null);
+    assert(postfix != null);
+    final List<Line> codeLines = <Line>[];
+    for (int i = 0; i < code.length; ++i) {
+      codeLines.add(
+        Line(
+          code[i],
+          filename: firstLine.filename,
+          line: firstLine.line + i,
+          indent: firstLine.indent,
+        ),
+      );
+    }
+    return Section(<Line>[Line(prefix)]
+      ..addAll(codeLines)
+      ..add(Line(postfix)));
+  }
+  Line get start => code.firstWhere((Line line) => line.filename != null);
+  final List<Line> code;
+}
+
+/// A class to represent a snippet in the dartdoc comments, marked by
+/// "{@tool snippet ...}...{@end-tool}". Snippets are processed separately from
+/// regular samples, because they must be injected into templates in order to be
+/// analyzed.
+class Snippet {
+  Snippet({this.start, List<String> input, List<String> args, this.serial}) {
+    this.input = <String>[]..addAll(input);
+    this.args = <String>[]..addAll(args);
+  }
+  final Line start;
+  final int serial;
+  List<String> input;
+  List<String> args;
+  List<String> contents;
+
+  @override
+  String toString() {
+    final StringBuffer buf = StringBuffer('snippet ${args.join(' ')}\n');
+    int count = start.line;
+    for (String line in input) {
+      buf.writeln(' ${count.toString().padLeft(4, ' ')}: $line');
+      count++;
+    }
+    return buf.toString();
+  }
+}
+
+/// A class representing an analysis error along with the context of the error.
+///
+/// Changes how it converts to a string based on the source of the error.
+class AnalysisError {
+  const AnalysisError(
+    this.line,
+    this.column,
+    this.message,
+    this.errorCode,
+    this.source, {
+    this.snippet,
+  });
+
+  final int line;
+  final int column;
+  final String message;
+  final String errorCode;
+  final Line source;
+  final Snippet snippet;
+
+  @override
+  String toString() {
+    if (source != null) {
+      return '${source.toStringWithColumn(column)}\n>>> $message ($errorCode)';
+    } else if (snippet != null) {
+      return 'In snippet starting at '
+          '${snippet.start.filename}:${snippet.start.line}:${snippet.contents[line - 1]}\n'
+          '>>> $message ($errorCode)';
     } else {
-      sections.add(Section(line, null, block.toList(), null));
+      return '<source unknown>:$line:$column\n>>> $message ($errorCode)';
     }
   }
-  block.clear();
 }
