Defer to engine for option-aware context config.

* Leans on new `configureContext` function to pick up latest options support from engine.
* Adds options integration tests.
* Cleans up `Driver` test output.

BUG=
R=brianwilkerson@google.com

Review URL: https://codereview.chromium.org//1412293005 .
diff --git a/lib/src/driver.dart b/lib/src/driver.dart
index 0b6c526..23bc826 100644
--- a/lib/src/driver.dart
+++ b/lib/src/driver.dart
@@ -26,6 +26,7 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/services/lint.dart';
+import 'package:analyzer/src/task/options.dart';
 import 'package:analyzer_cli/src/analyzer_impl.dart';
 import 'package:analyzer_cli/src/options.dart';
 import 'package:linter/src/plugin/linter_plugin.dart';
@@ -135,14 +136,14 @@
       sourcePath = sourcePath.trim();
       // Check that file exists.
       if (!new File(sourcePath).existsSync()) {
-        stderr.writeln('File not found: $sourcePath');
+        errorSink.writeln('File not found: $sourcePath');
         exitCode = ErrorSeverity.ERROR.ordinal;
         //Fail fast; don't analyze more files
         return ErrorSeverity.ERROR;
       }
       // Check that file is Dart file.
       if (!AnalysisEngine.isDartFileName(sourcePath)) {
-        stderr.writeln('$sourcePath is not a Dart file');
+        errorSink.writeln('$sourcePath is not a Dart file');
         exitCode = ErrorSeverity.ERROR.ordinal;
         // Fail fast; don't analyze more files.
         return ErrorSeverity.ERROR;
@@ -492,6 +493,11 @@
       if (options.lints && !containsLintRuleEntry(optionMap)) {
         setLints(context, linterPlugin.contributedRules);
       }
+
+      // Ask engine to further process options.
+      if (optionMap != null) {
+        configureContextOptions(context, optionMap);
+      }
     } on Exception catch (e) {
       optionsProcessors.forEach((OptionsProcessor p) => p.onError(e));
     }
diff --git a/lib/src/options.dart b/lib/src/options.dart
index ac1463b..966090e 100644
--- a/lib/src/options.dart
+++ b/lib/src/options.dart
@@ -6,6 +6,7 @@
 
 import 'dart:io';
 
+import 'package:analyzer_cli/src/driver.dart';
 import 'package:args/args.dart';
 import 'package:cli_util/cli_util.dart' show getSdkDir;
 
@@ -18,7 +19,7 @@
 
 /// Print the given message to stderr and exit with the given [exitCode]
 void printAndFail(String message, {int exitCode: 15}) {
-  stderr.writeln(message);
+  errorSink.writeln(message);
   exitHandler(exitCode);
 }
 
diff --git a/pubspec.yaml b/pubspec.yaml
index 8656d0e..ec4dc06 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -6,7 +6,7 @@
 environment:
   sdk: '>=1.12.0 <2.0.0'
 dependencies:
-  analyzer: ^0.26.1+13
+  analyzer: ^0.26.1+17
   args: ^0.13.0
   cli_util: ^0.0.1
   linter: ^0.1.3+4
diff --git a/test/data/empty_options.yaml b/test/data/empty_options.yaml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/data/empty_options.yaml
diff --git a/test/data/no_lints_project/.analysis_options b/test/data/no_lints_project/.analysis_options
new file mode 100644
index 0000000..1bb8bf6
--- /dev/null
+++ b/test/data/no_lints_project/.analysis_options
@@ -0,0 +1 @@
+# empty
diff --git a/test/data/no_lints_project/test_file.dart b/test/data/no_lints_project/test_file.dart
new file mode 100644
index 0000000..93088d6
--- /dev/null
+++ b/test/data/no_lints_project/test_file.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer_cli.test.data.no_lints_project.test_file;
+
+class a {}
diff --git a/test/data/options_tests_project/.analysis_options b/test/data/options_tests_project/.analysis_options
new file mode 100644
index 0000000..ebd4e64
--- /dev/null
+++ b/test/data/options_tests_project/.analysis_options
@@ -0,0 +1,5 @@
+analyzer:
+  errors:
+    unused_local_variable: ignore
+  language:
+    enableSuperMixins: true
diff --git a/test/data/options_tests_project/test_file.dart b/test/data/options_tests_project/test_file.dart
new file mode 100644
index 0000000..e8f168b
--- /dev/null
+++ b/test/data/options_tests_project/test_file.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer_cli.test.data.options_test_project.test_file;
+
+class a {}
diff --git a/test/driver_test.dart b/test/driver_test.dart
index 88791dc..3151c51 100644
--- a/test/driver_test.dart
+++ b/test/driver_test.dart
@@ -10,6 +10,8 @@
 import 'package:analyzer/plugin/options.dart';
 import 'package:analyzer/source/analysis_options_provider.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/plugin/plugin_configuration.dart';
 import 'package:analyzer/src/services/lint.dart';
 import 'package:analyzer_cli/src/bootloader.dart';
@@ -22,6 +24,21 @@
 
 main() {
   group('Driver', () {
+    StringSink savedOutSink, savedErrorSink;
+    int savedExitCode;
+    setUp(() {
+      savedOutSink = outSink;
+      savedErrorSink = errorSink;
+      savedExitCode = exitCode;
+      outSink = new StringBuffer();
+      errorSink = new StringBuffer();
+    });
+    tearDown(() {
+      outSink = savedOutSink;
+      errorSink = savedErrorSink;
+      exitCode = savedExitCode;
+    });
+
     group('options', () {
       test('custom processor', () {
         Driver driver = new Driver();
@@ -38,67 +55,62 @@
     });
 
     group('exit codes', () {
+      StringSink savedOutSink, savedErrorSink;
       int savedExitCode;
       ExitHandler savedExitHandler;
       setUp(() {
+        savedOutSink = outSink;
+        savedErrorSink = errorSink;
         savedExitCode = exitCode;
         savedExitHandler = exitHandler;
         exitHandler = (code) => exitCode = code;
+        outSink = new StringBuffer();
+        errorSink = new StringBuffer();
       });
       tearDown(() {
+        outSink = savedOutSink;
+        errorSink = savedErrorSink;
         exitCode = savedExitCode;
         exitHandler = savedExitHandler;
       });
 
       test('fatal hints', () {
-        Driver driver = new Driver();
-        driver.start(['--fatal-hints', 'test/data/file_with_hint.dart']);
+        drive('test/data/file_with_hint.dart', args: ['--fatal-hints']);
         expect(exitCode, 3);
       });
 
       test('not fatal hints', () {
-        Driver driver = new Driver();
-        driver.start(['test/data/file_with_hint.dart']);
+        drive('test/data/file_with_hint.dart');
         expect(exitCode, 0);
       });
 
       test('fatal errors', () {
-        Driver driver = new Driver();
-        driver.start(['test/data/file_with_error.dart']);
+        drive('test/data/file_with_error.dart');
         expect(exitCode, 3);
       });
 
       test('not fatal warnings', () {
-        Driver driver = new Driver();
-        driver.start(['test/data/file_with_warning.dart']);
+        drive('test/data/file_with_warning.dart');
         expect(exitCode, 0);
       });
 
       test('fatal warnings', () {
-        Driver driver = new Driver();
-        driver.start(['--fatal-warnings', 'test/data/file_with_warning.dart']);
+        drive('test/data/file_with_warning.dart', args: ['--fatal-warnings']);
         expect(exitCode, 3);
       });
 
       test('missing options file', () {
-        Driver driver = new Driver();
-        driver.start([
-          '--options',
-          'test/data/NO_OPTIONS_HERE',
-          'test/data/test_file.dart'
-        ]);
+        drive('test/data/test_file.dart', options: 'test/data/NO_OPTIONS_HERE');
         expect(exitCode, 3);
       });
 
       test('missing dart file', () {
-        Driver driver = new Driver();
-        driver.start(['test/data/NO_DART_FILE_HERE.dart']);
+        drive('test/data/NO_DART_FILE_HERE.dart');
         expect(exitCode, 3);
       });
 
       test('part file', () {
-        Driver driver = new Driver();
-        driver.start(['test/data/library_and_parts/part2.dart']);
+        drive('test/data/library_and_parts/part2.dart');
         expect(exitCode, 3);
       });
 
@@ -167,7 +179,12 @@
           outSink = new StringBuffer();
 
           driver = new Driver();
-          driver.start(['--lints', 'test/data/linter_project/test_file.dart']);
+          driver.start([
+            '--lints',
+            'test/data/linter_project/test_file.dart',
+            '--options',
+            'test/data/linter_project/.analysis_options'
+          ]);
         });
         tearDown(() {
           outSink = savedOutSink;
@@ -188,7 +205,7 @@
         });
       });
 
-      group('no `--lints` flag', () {
+      group('no `--lints` flag (none in options)', () {
         StringSink savedOutSink;
         Driver driver;
 
@@ -197,7 +214,11 @@
           outSink = new StringBuffer();
 
           driver = new Driver();
-          driver.start(['test/data/linter_project/test_file.dart']);
+          driver.start([
+            'test/data/no_lints_project/test_file.dart',
+            '--options',
+            'test/data/no_lints_project/.analysis_options'
+          ]);
         });
         tearDown(() {
           outSink = savedOutSink;
@@ -242,6 +263,44 @@
       expect(containsLintRuleEntry(options), false);
     });
 
+    group('options processing', () {
+      group('error filters', () {
+        StringSink savedOutSink;
+        Driver driver;
+
+        setUp(() {
+          savedOutSink = outSink;
+          outSink = new StringBuffer();
+
+          driver = new Driver();
+          driver.start([
+            'test/data/options_tests_project/test_file.dart',
+            '--options',
+            'test/data/options_tests_project/.analysis_options'
+          ]);
+        });
+        tearDown(() {
+          outSink = savedOutSink;
+        });
+
+        test('filters', () {
+          var filters =
+              driver.context.getConfigurationData(CONFIGURED_ERROR_FILTERS);
+          expect(filters, hasLength(1));
+
+          var unused_error = new AnalysisError(
+              new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
+            ['x']
+          ]);
+          expect(filters.any((filter) => filter(unused_error)), isTrue);
+        });
+
+        test('language config', () {
+          expect(driver.context.analysisOptions.enableSuperMixins, isTrue);
+        });
+      });
+    });
+
     group('in temp directory', () {
       StringSink savedOutSink, savedErrorSink;
       int savedExitCode;
@@ -369,6 +428,17 @@
   });
 }
 
+const emptyOptionsFile = 'test/data/empty_options.yaml';
+
+/// Start a driver for the given [source], optionally providing additional
+/// [args] and an [options] file path.  The value of [options] defaults to
+/// an empty options file to avoid unwanted configuration from an otherwise
+/// discovered options file.
+void drive(String source,
+        {String options: emptyOptionsFile,
+        List<String> args: const <String>[]}) =>
+    new Driver().start(['--options', options, source]..addAll(args));
+
 Map<String, YamlNode> parseOptions(String src) =>
     new AnalysisOptionsProvider().getOptionsFromString(src);
 
@@ -405,3 +475,10 @@
     this.options = options;
   }
 }
+
+class TestSource implements Source {
+  TestSource();
+
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
diff --git a/test/strong_mode_test.dart b/test/strong_mode_test.dart
index b915318..926452c 100644
--- a/test/strong_mode_test.dart
+++ b/test/strong_mode_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 @TestOn("vm")
-
 library analyzer_cli.test.strong_mode;
 
 import 'dart:io';
@@ -12,6 +11,7 @@
 import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 
+import 'driver_test.dart';
 import 'utils.dart';
 
 /// End-to-end test for --strong checking.
@@ -40,7 +40,7 @@
 
     test('produces stricter errors', () async {
       var testPath = path.join(testDirectory, 'data/strong_example.dart');
-      new Driver().start(['--strong', testPath]);
+      new Driver().start(['--options', emptyOptionsFile, '--strong', testPath]);
 
       expect(exitCode, 3);
       var stdout = outSink.toString();