allow any android sdk version
diff --git a/packages/flutter_tools/test/android_device_test.dart b/packages/flutter_tools/test/android_device_test.dart
index 1d34f1e..d71878d 100644
--- a/packages/flutter_tools/test/android_device_test.dart
+++ b/packages/flutter_tools/test/android_device_test.dart
@@ -5,7 +5,7 @@
 import 'package:flutter_tools/src/android/device_android.dart';
 import 'package:test/test.dart';
 
-import 'src/test_context.dart';
+import 'src/context.dart';
 
 main() => defineTests();
 
diff --git a/packages/flutter_tools/test/create_test.dart b/packages/flutter_tools/test/create_test.dart
index 4e736d9..00306f3 100644
--- a/packages/flutter_tools/test/create_test.dart
+++ b/packages/flutter_tools/test/create_test.dart
@@ -11,7 +11,7 @@
 import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 
-import 'src/test_context.dart';
+import 'src/context.dart';
 
 main() => defineTests();
 
diff --git a/packages/flutter_tools/test/daemon_test.dart b/packages/flutter_tools/test/daemon_test.dart
index 7ad73a1..e735bd3 100644
--- a/packages/flutter_tools/test/daemon_test.dart
+++ b/packages/flutter_tools/test/daemon_test.dart
@@ -16,11 +16,17 @@
 main() => defineTests();
 
 defineTests() {
-  group('daemon', () {
-    Daemon daemon;
-    AppContext appContext;
-    NotifyingLogger notifyingLogger;
+  Daemon daemon;
+  AppContext appContext;
+  NotifyingLogger notifyingLogger;
 
+  void _testUsingContext(String description, dynamic testMethod()) {
+    test(description, () {
+      return appContext.runInZone(testMethod);
+    });
+  }
+
+  group('daemon', () {
     setUp(() {
       appContext = new AppContext();
       notifyingLogger = new NotifyingLogger();
@@ -32,7 +38,7 @@
         return daemon.shutdown();
     });
 
-    test('daemon.version', () async {
+    _testUsingContext('daemon.version', () async {
       StreamController<Map<String, dynamic>> commands = new StreamController();
       StreamController<Map<String, dynamic>> responses = new StreamController();
       daemon = new Daemon(
@@ -47,7 +53,7 @@
       expect(response['result'] is String, true);
     });
 
-    test('daemon.logMessage', () {
+    _testUsingContext('daemon.logMessage', () {
       return appContext.runInZone(() async {
         StreamController<Map<String, dynamic>> commands = new StreamController();
         StreamController<Map<String, dynamic>> responses = new StreamController();
@@ -68,7 +74,7 @@
       });
     });
 
-    test('daemon.shutdown', () async {
+    _testUsingContext('daemon.shutdown', () async {
       StreamController<Map<String, dynamic>> commands = new StreamController();
       StreamController<Map<String, dynamic>> responses = new StreamController();
       daemon = new Daemon(
@@ -82,7 +88,7 @@
       });
     });
 
-    test('daemon.stopAll', () async {
+    _testUsingContext('daemon.stopAll', () async {
       DaemonCommand command = new DaemonCommand();
       applyMocksToCommand(command);
 
@@ -112,7 +118,7 @@
       expect(response['result'], true);
     });
 
-    test('device.getDevices', () async {
+    _testUsingContext('device.getDevices', () async {
       StreamController<Map<String, dynamic>> commands = new StreamController();
       StreamController<Map<String, dynamic>> responses = new StreamController();
       daemon = new Daemon(
diff --git a/packages/flutter_tools/test/device_test.dart b/packages/flutter_tools/test/device_test.dart
index dd9b5c6..3ea8f09 100644
--- a/packages/flutter_tools/test/device_test.dart
+++ b/packages/flutter_tools/test/device_test.dart
@@ -5,7 +5,7 @@
 import 'package:flutter_tools/src/device.dart';
 import 'package:test/test.dart';
 
-import 'src/test_context.dart';
+import 'src/context.dart';
 
 main() => defineTests();
 
diff --git a/packages/flutter_tools/test/install_test.dart b/packages/flutter_tools/test/install_test.dart
index f876456..e6302bc 100644
--- a/packages/flutter_tools/test/install_test.dart
+++ b/packages/flutter_tools/test/install_test.dart
@@ -2,18 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'package:args/command_runner.dart';
 import 'package:flutter_tools/src/commands/install.dart';
 import 'package:mockito/mockito.dart';
 import 'package:test/test.dart';
 
+import 'src/common.dart';
+import 'src/context.dart';
 import 'src/mocks.dart';
 
 main() => defineTests();
 
 defineTests() {
   group('install', () {
-    test('returns 0 when Android is connected and ready for an install', () {
+    testUsingContext('returns 0 when Android is connected and ready for an install', () {
       InstallCommand command = new InstallCommand();
       applyMocksToCommand(command);
       MockDeviceStore mockDevices = command.devices;
@@ -30,13 +31,12 @@
       when(mockDevices.iOSSimulator.isAppInstalled(any)).thenReturn(false);
       when(mockDevices.iOSSimulator.installApp(any)).thenReturn(false);
 
-
-      CommandRunner runner = new CommandRunner('test_flutter', '')
-        ..addCommand(command);
-      return runner.run(['install']).then((int code) => expect(code, equals(0)));
+      return createTestCommandRunner(command).run(['install']).then((int code) {
+        expect(code, equals(0));
+      });
     });
 
-    test('returns 0 when iOS is connected and ready for an install', () {
+    testUsingContext('returns 0 when iOS is connected and ready for an install', () {
       InstallCommand command = new InstallCommand();
       applyMocksToCommand(command);
       MockDeviceStore mockDevices = command.devices;
@@ -53,9 +53,9 @@
       when(mockDevices.iOSSimulator.isAppInstalled(any)).thenReturn(false);
       when(mockDevices.iOSSimulator.installApp(any)).thenReturn(false);
 
-      CommandRunner runner = new CommandRunner('test_flutter', '')
-        ..addCommand(command);
-      return runner.run(['install']).then((int code) => expect(code, equals(0)));
+      return createTestCommandRunner(command).run(['install']).then((int code) {
+        expect(code, equals(0));
+      });
     });
   });
 }
diff --git a/packages/flutter_tools/test/list_test.dart b/packages/flutter_tools/test/list_test.dart
index f01949c..bff9e94 100644
--- a/packages/flutter_tools/test/list_test.dart
+++ b/packages/flutter_tools/test/list_test.dart
@@ -2,43 +2,34 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'dart:io';
-
-import 'package:args/command_runner.dart';
+import 'package:flutter_tools/src/android/android_sdk.dart';
 import 'package:flutter_tools/src/commands/list.dart';
-import 'package:mockito/mockito.dart';
+import 'package:flutter_tools/src/device.dart';
 import 'package:test/test.dart';
 
-import 'src/mocks.dart';
-import 'src/test_context.dart';
+import 'src/common.dart';
+import 'src/context.dart';
 
 main() => defineTests();
 
 defineTests() {
   group('list', () {
     testUsingContext('returns 0 when called', () {
-      final String mockCommand = Platform.isWindows ? 'cmd /c echo' : 'echo';
-
       ListCommand command = new ListCommand();
-      applyMocksToCommand(command);
-      MockDeviceStore mockDevices = command.devices;
+      return createTestCommandRunner(command).run(['list']).then((int code) {
+        expect(code, equals(0));
+      });
+    });
 
-      // Avoid relying on adb being installed on the test system.
-      // Instead, cause the test to run the echo command.
-      when(mockDevices.android.adbPath).thenReturn(mockCommand);
-
-      // Avoid relying on idevice* being installed on the test system.
-      // Instead, cause the test to run the echo command.
-      when(mockDevices.iOS.informerPath).thenReturn(mockCommand);
-      when(mockDevices.iOS.installerPath).thenReturn(mockCommand);
-      when(mockDevices.iOS.listerPath).thenReturn(mockCommand);
-
-      // Avoid relying on xcrun being installed on the test system.
-      // Instead, cause the test to run the echo command.
-      when(mockDevices.iOSSimulator.xcrunPath).thenReturn(mockCommand);
-
-      CommandRunner runner = new CommandRunner('test_flutter', '')..addCommand(command);
-      return runner.run(['list']).then((int code) => expect(code, equals(0)));
+    testUsingContext('no error when no connected devices', () {
+      ListCommand command = new ListCommand();
+      return createTestCommandRunner(command).run(['list']).then((int code) {
+        expect(code, equals(0));
+        expect(testLogger.statusText, contains('No connected devices'));
+      });
+    }, overrides: <Type, dynamic>{
+      AndroidSdk: null,
+      DeviceManager: new DeviceManager()
     });
   });
 }
diff --git a/packages/flutter_tools/test/listen_test.dart b/packages/flutter_tools/test/listen_test.dart
index dcbf122..ddc0bd5 100644
--- a/packages/flutter_tools/test/listen_test.dart
+++ b/packages/flutter_tools/test/listen_test.dart
@@ -2,14 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'package:args/command_runner.dart';
 import 'package:flutter_tools/src/commands/listen.dart';
-import 'package:flutter_tools/src/runner/flutter_command_runner.dart';
 import 'package:mockito/mockito.dart';
 import 'package:test/test.dart';
 
+import 'src/common.dart';
+import 'src/context.dart';
 import 'src/mocks.dart';
-import 'src/test_context.dart';
 
 main() => defineTests();
 
@@ -24,8 +23,9 @@
       when(mockDevices.iOS.isConnected()).thenReturn(false);
       when(mockDevices.iOSSimulator.isConnected()).thenReturn(false);
 
-      CommandRunner runner = new FlutterCommandRunner()..addCommand(command);
-      return runner.run(['listen']).then((int code) => expect(code, equals(0)));
+      return createTestCommandRunner(command).run(['listen']).then((int code) {
+        expect(code, equals(0));
+      });
     });
   });
 }
diff --git a/packages/flutter_tools/test/logs_test.dart b/packages/flutter_tools/test/logs_test.dart
index 2dd67d5..ba5bdc9 100644
--- a/packages/flutter_tools/test/logs_test.dart
+++ b/packages/flutter_tools/test/logs_test.dart
@@ -2,13 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'package:args/command_runner.dart';
 import 'package:flutter_tools/src/commands/logs.dart';
-import 'package:flutter_tools/src/runner/flutter_command_runner.dart';
 import 'package:test/test.dart';
 
+import 'src/common.dart';
+import 'src/context.dart';
 import 'src/mocks.dart';
-import 'src/test_context.dart';
 
 main() => defineTests();
 
@@ -17,8 +16,7 @@
     testUsingContext('fail with a bad device id', () {
       LogsCommand command = new LogsCommand();
       applyMocksToCommand(command);
-      CommandRunner runner = new FlutterCommandRunner()..addCommand(command);
-      return runner.run(<String>['-d', 'abc123', 'logs']).then((int code) {
+      return createTestCommandRunner(command).run(<String>['-d', 'abc123', 'logs']).then((int code) {
         expect(code, equals(1));
       });
     });
diff --git a/packages/flutter_tools/test/src/common.dart b/packages/flutter_tools/test/src/common.dart
new file mode 100644
index 0000000..5183515
--- /dev/null
+++ b/packages/flutter_tools/test/src/common.dart
@@ -0,0 +1,11 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:args/command_runner.dart';
+import 'package:flutter_tools/src/runner/flutter_command.dart';
+import 'package:flutter_tools/src/runner/flutter_command_runner.dart';
+
+CommandRunner createTestCommandRunner(FlutterCommand command) {
+  return new FlutterCommandRunner()..addCommand(command);
+}
diff --git a/packages/flutter_tools/test/src/test_context.dart b/packages/flutter_tools/test/src/context.dart
similarity index 65%
rename from packages/flutter_tools/test/src/test_context.dart
rename to packages/flutter_tools/test/src/context.dart
index c5a5d9d..b1c518c 100644
--- a/packages/flutter_tools/test/src/test_context.dart
+++ b/packages/flutter_tools/test/src/context.dart
@@ -9,12 +9,25 @@
 import 'package:flutter_tools/src/device.dart';
 import 'package:test/test.dart';
 
-void testUsingContext(String description, dynamic testMethod(), { Timeout timeout }) {
+/// Return the test logger. This assumes that the current Logger is a BufferLogger.
+BufferLogger get testLogger => context[Logger];
+
+void testUsingContext(String description, dynamic testMethod(), {
+  Timeout timeout,
+  Map<Type, dynamic> overrides: const <Type, dynamic>{}
+}) {
   test(description, () {
     AppContext testContext = new AppContext();
 
-    testContext[Logger] = new BufferLogger();
-    testContext[DeviceManager] = new MockDeviceManager();
+    overrides.forEach((Type type, dynamic value) {
+      testContext[type] = value;
+    });
+
+    if (!overrides.containsKey(Logger))
+      testContext[Logger] = new BufferLogger();
+
+    if (!overrides.containsKey(DeviceManager))
+      testContext[DeviceManager] = new MockDeviceManager();
 
     return testContext.runInZone(testMethod);
   }, timeout: timeout);
diff --git a/packages/flutter_tools/test/stop_test.dart b/packages/flutter_tools/test/stop_test.dart
index f700e3b..0c0c08e 100644
--- a/packages/flutter_tools/test/stop_test.dart
+++ b/packages/flutter_tools/test/stop_test.dart
@@ -2,18 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'package:args/command_runner.dart';
 import 'package:flutter_tools/src/commands/stop.dart';
 import 'package:mockito/mockito.dart';
 import 'package:test/test.dart';
 
+import 'src/common.dart';
+import 'src/context.dart';
 import 'src/mocks.dart';
 
 main() => defineTests();
 
 defineTests() {
   group('stop', () {
-    test('returns 0 when Android is connected and ready to be stopped', () {
+    testUsingContext('returns 0 when Android is connected and ready to be stopped', () {
       StopCommand command = new StopCommand();
       applyMocksToCommand(command);
       MockDeviceStore mockDevices = command.devices;
@@ -27,12 +28,12 @@
       when(mockDevices.iOSSimulator.isConnected()).thenReturn(false);
       when(mockDevices.iOSSimulator.stopApp(any)).thenReturn(false);
 
-      CommandRunner runner = new CommandRunner('test_flutter', '')
-        ..addCommand(command);
-      return runner.run(['stop']).then((int code) => expect(code, equals(0)));
+      return createTestCommandRunner(command).run(['stop']).then((int code) {
+        expect(code, equals(0));
+      });
     });
 
-    test('returns 0 when iOS is connected and ready to be stopped', () {
+    testUsingContext('returns 0 when iOS is connected and ready to be stopped', () {
       StopCommand command = new StopCommand();
       applyMocksToCommand(command);
       MockDeviceStore mockDevices = command.devices;
@@ -46,9 +47,9 @@
       when(mockDevices.iOSSimulator.isConnected()).thenReturn(false);
       when(mockDevices.iOSSimulator.stopApp(any)).thenReturn(false);
 
-      CommandRunner runner = new CommandRunner('test_flutter', '')
-        ..addCommand(command);
-      return runner.run(['stop']).then((int code) => expect(code, equals(0)));
+      return createTestCommandRunner(command).run(['stop']).then((int code) {
+        expect(code, equals(0));
+      });
     });
   });
 }
diff --git a/packages/flutter_tools/test/trace_test.dart b/packages/flutter_tools/test/trace_test.dart
index 279e7a8..444da3e 100644
--- a/packages/flutter_tools/test/trace_test.dart
+++ b/packages/flutter_tools/test/trace_test.dart
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'package:args/command_runner.dart';
 import 'package:flutter_tools/src/commands/trace.dart';
 import 'package:mockito/mockito.dart';
 import 'package:test/test.dart';
 
+import 'src/common.dart';
+import 'src/context.dart';
 import 'src/mocks.dart';
-import 'src/test_context.dart';
 
 main() => defineTests();
 
@@ -21,9 +21,9 @@
 
       when(mockDevices.android.isConnected()).thenReturn(false);
 
-      CommandRunner runner = new CommandRunner('test_flutter', '')
-        ..addCommand(command);
-      return runner.run(['trace']).then((int code) => expect(code, equals(1)));
+      return createTestCommandRunner(command).run(['trace']).then((int code) {
+        expect(code, equals(1));
+      });
     });
   });
 }