implicit-casts:false on flutter_tools/lib (#44447)

* implicit-casts:false on flutter_tools/lib

* address review comments

* use castStringKeyedMap

* introduce {bool,string,strings}Arg

* fix ci
diff --git a/packages/flutter_tools/bin/fuchsia_asset_builder.dart b/packages/flutter_tools/bin/fuchsia_asset_builder.dart
index f6974c7..bf98aad 100644
--- a/packages/flutter_tools/bin/fuchsia_asset_builder.dart
+++ b/packages/flutter_tools/bin/fuchsia_asset_builder.dart
@@ -57,11 +57,11 @@
   }
   Cache.flutterRoot = platform.environment['FLUTTER_ROOT'];
 
-  final String assetDir = argResults[_kOptionAsset];
+  final String assetDir = argResults[_kOptionAsset] as String;
   final AssetBundle assets = await buildAssets(
-    manifestPath: argResults[_kOptionManifest] ?? defaultManifestPath,
+    manifestPath: argResults[_kOptionManifest] as String ?? defaultManifestPath,
     assetDirPath: assetDir,
-    packagesPath: argResults[_kOptionPackages],
+    packagesPath: argResults[_kOptionPackages] as String,
     includeDefaultFonts: false,
   );
 
@@ -77,8 +77,8 @@
   });
   await Future.wait<void>(calls);
 
-  final String outputMan = argResults[_kOptionAssetManifestOut];
-  await writeFuchsiaManifest(assets, argResults[_kOptionAsset], outputMan, argResults[_kOptionComponentName]);
+  final String outputMan = argResults[_kOptionAssetManifestOut] as String;
+  await writeFuchsiaManifest(assets, argResults[_kOptionAsset] as String, outputMan, argResults[_kOptionComponentName] as String);
 }
 
 Future<void> writeFuchsiaManifest(AssetBundle assets, String outputBase, String fileDest, String componentName) async {
diff --git a/packages/flutter_tools/bin/fuchsia_attach.dart b/packages/flutter_tools/bin/fuchsia_attach.dart
index df16901..bfbf0f6 100644
--- a/packages/flutter_tools/bin/fuchsia_attach.dart
+++ b/packages/flutter_tools/bin/fuchsia_attach.dart
@@ -35,13 +35,13 @@
 
 Future<void> main(List<String> args) async {
   final ArgResults argResults = parser.parse(args);
-  final bool verbose = argResults['verbose'];
-  final String target = argResults['target'];
+  final bool verbose = argResults['verbose'] as bool;
+  final String target = argResults['target'] as String;
   final List<String> targetParts = _extractPathAndName(target);
   final String path = targetParts[0];
   final String name = targetParts[1];
   final File dartSdk = fs.file(argResults['dart-sdk']);
-  final String buildDirectory = argResults['build-dir'];
+  final String buildDirectory = argResults['build-dir'] as String;
   final File frontendServer = fs.file('$buildDirectory/host_x64/gen/third_party/flutter/frontend_server/frontend_server_tool.snapshot');
   final File sshConfig = fs.file('$buildDirectory/ssh-keys/ssh_config');
   final File devFinder = fs.file(argResults['dev-finder']);
@@ -69,13 +69,13 @@
   }
 
   // Check for a package with a lib directory.
-  final String entrypoint = argResults['entrypoint'];
+  final String entrypoint = argResults['entrypoint'] as String;
   String targetFile = 'lib/$entrypoint';
   if (!fs.file(targetFile).existsSync()) {
     // Otherwise assume the package is flat.
     targetFile = entrypoint;
   }
-  final String deviceName = argResults['device'];
+  final String deviceName = argResults['device'] as String;
   final List<String> command = <String>[
     'attach',
     '--module',
diff --git a/packages/flutter_tools/bin/fuchsia_tester.dart b/packages/flutter_tools/bin/fuchsia_tester.dart
index 5abd8a4..c6d32ff 100644
--- a/packages/flutter_tools/bin/fuchsia_tester.dart
+++ b/packages/flutter_tools/bin/fuchsia_tester.dart
@@ -86,7 +86,7 @@
       throwToolExit('Cannot find SDK files at ${sdkRootSrc.path}');
     }
     Directory coverageDirectory;
-    final String coverageDirectoryPath = argResults[_kOptionCoverageDirectory];
+    final String coverageDirectoryPath = argResults[_kOptionCoverageDirectory] as String;
     if (coverageDirectoryPath != null) {
       if (!fs.isDirectorySync(coverageDirectoryPath)) {
         throwToolExit('Cannot find coverage directory at $coverageDirectoryPath');
@@ -111,11 +111,11 @@
     fs.link(sdkRootDest.childFile('platform.dill').path).createSync('platform_strong.dill');
 
     PackageMap.globalPackagesPath =
-        fs.path.normalize(fs.path.absolute(argResults[_kOptionPackages]));
+        fs.path.normalize(fs.path.absolute(argResults[_kOptionPackages] as String));
 
     Directory testDirectory;
     CoverageCollector collector;
-    if (argResults['coverage']) {
+    if (argResults['coverage'] as bool) {
       collector = CoverageCollector(
         libraryPredicate: (String libraryName) {
           // If we have a specified coverage directory then accept all libraries.
@@ -134,7 +134,7 @@
 
     final Map<String, String> tests = <String, String>{};
     final List<Map<String, dynamic>> jsonList = List<Map<String, dynamic>>.from(
-      json.decode(fs.file(argResults[_kOptionTests]).readAsStringSync()));
+      json.decode(fs.file(argResults[_kOptionTests]).readAsStringSync()) as List<Map<String, dynamic>>);
     for (Map<String, dynamic> map in jsonList) {
       final String source = fs.file(map['source']).resolveSymbolicLinksSync();
       final String dill = fs.file(map['dill']).resolveSymbolicLinksSync();
@@ -150,7 +150,7 @@
       buildMode: BuildMode.debug,
       precompiledDillFiles: tests,
       concurrency: math.max(1, platform.numberOfProcessors - 2),
-      icudtlPath: fs.path.absolute(argResults[_kOptionIcudtl]),
+      icudtlPath: fs.path.absolute(argResults[_kOptionIcudtl] as String),
       coverageDirectory: coverageDirectory,
     );
 
@@ -163,7 +163,7 @@
       } else {
         fs.currentDirectory = testDirectory;
       }
-      if (!await collector.collectCoverageData(argResults[_kOptionCoveragePath], coverageDirectory: coverageDirectory)) {
+      if (!await collector.collectCoverageData(argResults[_kOptionCoveragePath] as String, coverageDirectory: coverageDirectory)) {
         throwToolExit('Failed to collect coverage data');
       }
     }
diff --git a/packages/flutter_tools/lib/src/android/android_device.dart b/packages/flutter_tools/lib/src/android/android_device.dart
index 5aea8b3..f0e493e 100644
--- a/packages/flutter_tools/lib/src/android/android_device.dart
+++ b/packages/flutter_tools/lib/src/android/android_device.dart
@@ -105,10 +105,10 @@
           stderrEncoding: latin1,
         );
         if (result.exitCode == 0 || allowHeapCorruptionOnWindows(result.exitCode)) {
-          _properties = parseAdbDeviceProperties(result.stdout);
+          _properties = parseAdbDeviceProperties(result.stdout as String);
         } else {
           printError('Error ${result.exitCode} retrieving device properties for $name:');
-          printError(result.stderr);
+          printError(result.stderr as String);
         }
       } on ProcessException catch (error) {
         printError('Error retrieving device properties for $name: $error');
@@ -334,18 +334,17 @@
     }
   }
 
-  String _getDeviceSha1Path(ApplicationPackage app) {
-    return '/data/local/tmp/sky.${app.id}.sha1';
+  String _getDeviceSha1Path(AndroidApk apk) {
+    return '/data/local/tmp/sky.${apk.id}.sha1';
   }
 
-  Future<String> _getDeviceApkSha1(ApplicationPackage app) async {
+  Future<String> _getDeviceApkSha1(AndroidApk apk) async {
     final RunResult result = await processUtils.run(
-      adbCommandForDevice(<String>['shell', 'cat', _getDeviceSha1Path(app)]));
+      adbCommandForDevice(<String>['shell', 'cat', _getDeviceSha1Path(apk)]));
     return result.stdout;
   }
 
-  String _getSourceSha1(ApplicationPackage app) {
-    final AndroidApk apk = app;
+  String _getSourceSha1(AndroidApk apk) {
     final File shaFile = fs.file('${apk.file.path}.sha1');
     return shaFile.existsSync() ? shaFile.readAsStringSync() : '';
   }
@@ -354,7 +353,7 @@
   String get name => modelID;
 
   @override
-  Future<bool> isAppInstalled(ApplicationPackage app) async {
+  Future<bool> isAppInstalled(AndroidApk app) async {
     // This call takes 400ms - 600ms.
     try {
       final RunResult listOut = await runAdbCheckedAsync(<String>['shell', 'pm', 'list', 'packages', app.id]);
@@ -366,16 +365,15 @@
   }
 
   @override
-  Future<bool> isLatestBuildInstalled(ApplicationPackage app) async {
+  Future<bool> isLatestBuildInstalled(AndroidApk app) async {
     final String installedSha1 = await _getDeviceApkSha1(app);
     return installedSha1.isNotEmpty && installedSha1 == _getSourceSha1(app);
   }
 
   @override
-  Future<bool> installApp(ApplicationPackage app) async {
-    final AndroidApk apk = app;
-    if (!apk.file.existsSync()) {
-      printError('"${fs.path.relative(apk.file.path)}" does not exist.');
+  Future<bool> installApp(AndroidApk app) async {
+    if (!app.file.existsSync()) {
+      printError('"${fs.path.relative(app.file.path)}" does not exist.');
       return false;
     }
 
@@ -384,9 +382,9 @@
       return false;
     }
 
-    final Status status = logger.startProgress('Installing ${fs.path.relative(apk.file.path)}...', timeout: timeoutConfiguration.slowOperation);
+    final Status status = logger.startProgress('Installing ${fs.path.relative(app.file.path)}...', timeout: timeoutConfiguration.slowOperation);
     final RunResult installResult = await processUtils.run(
-      adbCommandForDevice(<String>['install', '-t', '-r', apk.file.path]));
+      adbCommandForDevice(<String>['install', '-t', '-r', app.file.path]));
     status.stop();
     // Some versions of adb exit with exit code 0 even on failure :(
     // Parsing the output to check for failures.
@@ -413,7 +411,7 @@
   }
 
   @override
-  Future<bool> uninstallApp(ApplicationPackage app) async {
+  Future<bool> uninstallApp(AndroidApk app) async {
     if (!await _checkForSupportedAdbVersion() ||
         !await _checkForSupportedAndroidVersion()) {
       return false;
@@ -440,7 +438,7 @@
     return true;
   }
 
-  Future<bool> _installLatestApp(ApplicationPackage package) async {
+  Future<bool> _installLatestApp(AndroidApk package) async {
     final bool wasInstalled = await isAppInstalled(package);
     if (wasInstalled) {
       if (await isLatestBuildInstalled(package)) {
@@ -470,7 +468,7 @@
 
   @override
   Future<LaunchResult> startApp(
-    ApplicationPackage package, {
+    AndroidApk package, {
     String mainPath,
     String route,
     DebuggingOptions debuggingOptions,
@@ -537,8 +535,7 @@
       return LaunchResult.failed();
     }
 
-    final bool traceStartup = platformArgs['trace-startup'] ?? false;
-    final AndroidApk apk = package;
+    final bool traceStartup = platformArgs['trace-startup'] as bool ?? false;
     printTrace('$this startApp');
 
     ProtocolDiscovery observatoryDiscovery;
@@ -595,7 +592,7 @@
         if (debuggingOptions.verboseSystemLogs)
           ...<String>['--ez', 'verbose-logging', 'true'],
       ],
-      apk.launchActivity,
+      package.launchActivity,
     ];
     final String result = (await runAdbCheckedAsync(cmd)).stdout;
     // This invocation returns 0 even when it fails.
@@ -636,7 +633,7 @@
   bool get supportsHotRestart => true;
 
   @override
-  Future<bool> stopApp(ApplicationPackage app) {
+  Future<bool> stopApp(AndroidApk app) {
     final List<String> command = adbCommandForDevice(<String>['shell', 'am', 'force-stop', app.id]);
     return processUtils.stream(command).then<bool>(
         (int exitCode) => exitCode == 0 || allowHeapCorruptionOnWindows(exitCode));
@@ -648,7 +645,7 @@
   }
 
   @override
-  DeviceLogReader getLogReader({ ApplicationPackage app }) {
+  DeviceLogReader getLogReader({ AndroidApk app }) {
     // The Android log reader isn't app-specific.
     _logReader ??= _AdbLogReader(this);
     return _logReader;
diff --git a/packages/flutter_tools/lib/src/android/android_sdk.dart b/packages/flutter_tools/lib/src/android/android_sdk.dart
index b84c89d..6fbe3d3 100644
--- a/packages/flutter_tools/lib/src/android/android_sdk.dart
+++ b/packages/flutter_tools/lib/src/android/android_sdk.dart
@@ -304,7 +304,7 @@
     String findAndroidHomeDir() {
       String androidHomeDir;
       if (config.containsKey('android-sdk')) {
-        androidHomeDir = config.getValue('android-sdk');
+        androidHomeDir = config.getValue('android-sdk') as String;
       } else if (platform.environment.containsKey(kAndroidHome)) {
         androidHomeDir = platform.environment[kAndroidHome];
       } else if (platform.environment.containsKey(kAndroidSdkRoot)) {
diff --git a/packages/flutter_tools/lib/src/android/android_studio.dart b/packages/flutter_tools/lib/src/android/android_studio.dart
index 9ded536..fb43cd1 100644
--- a/packages/flutter_tools/lib/src/android/android_studio.dart
+++ b/packages/flutter_tools/lib/src/android/android_studio.dart
@@ -8,6 +8,7 @@
 import '../base/platform.dart';
 import '../base/process.dart';
 import '../base/process_manager.dart';
+import '../base/utils.dart';
 import '../base/version.dart';
 import '../globals.dart';
 import '../ios/plist_parser.dart';
@@ -45,14 +46,14 @@
     Map<String, dynamic> plistValues = PlistParser.instance.parseFile(plistFile);
     // As AndroidStudio managed by JetBrainsToolbox could have a wrapper pointing to the real Android Studio.
     // Check if we've found a JetBrainsToolbox wrapper and deal with it properly.
-    final String jetBrainsToolboxAppBundlePath = plistValues['JetBrainsToolboxApp'];
+    final String jetBrainsToolboxAppBundlePath = plistValues['JetBrainsToolboxApp'] as String;
     if (jetBrainsToolboxAppBundlePath != null) {
       studioPath = fs.path.join(jetBrainsToolboxAppBundlePath, 'Contents');
       plistFile = fs.path.join(studioPath, 'Info.plist');
       plistValues = PlistParser.instance.parseFile(plistFile);
     }
 
-    final String versionString = plistValues[PlistParser.kCFBundleShortVersionStringKey];
+    final String versionString = plistValues[PlistParser.kCFBundleShortVersionStringKey] as String;
 
     Version version;
     if (versionString != null) {
@@ -60,11 +61,11 @@
     }
 
     String pathsSelectorValue;
-    final Map<String, dynamic> jvmOptions = plistValues['JVMOptions'];
+    final Map<String, dynamic> jvmOptions = castStringKeyedMap(plistValues['JVMOptions']);
     if (jvmOptions != null) {
-      final Map<String, dynamic> jvmProperties = jvmOptions['Properties'];
+      final Map<String, dynamic> jvmProperties = castStringKeyedMap(jvmOptions['Properties']);
       if (jvmProperties != null) {
-        pathsSelectorValue = jvmProperties['idea.paths.selector'];
+        pathsSelectorValue = jvmProperties['idea.paths.selector'] as String;
       }
     }
     final String presetPluginsPath = pathsSelectorValue == null
@@ -149,7 +150,7 @@
 
   /// Locates the newest, valid version of Android Studio.
   static AndroidStudio latestValid() {
-    final String configuredStudio = config.getValue('android-studio-dir');
+    final String configuredStudio = config.getValue('android-studio-dir') as String;
     if (configuredStudio != null) {
       String configuredStudioPath = configuredStudio;
       if (platform.isMacOS && !configuredStudioPath.endsWith('Contents')) {
@@ -201,7 +202,7 @@
     _checkForStudio('/Applications');
     _checkForStudio(fs.path.join(homeDirPath, 'Applications'));
 
-    final String configuredStudioDir = config.getValue('android-studio-dir');
+    final String configuredStudioDir = config.getValue('android-studio-dir') as String;
     if (configuredStudioDir != null) {
       FileSystemEntity configuredStudio = fs.file(configuredStudioDir);
       if (configuredStudio.basename == 'Contents') {
@@ -248,7 +249,7 @@
       }
     }
 
-    final String configuredStudioDir = config.getValue('android-studio-dir');
+    final String configuredStudioDir = config.getValue('android-studio-dir') as String;
     if (configuredStudioDir != null && !_hasStudioAt(configuredStudioDir)) {
       studios.add(AndroidStudio(configuredStudioDir,
           configured: configuredStudioDir));
diff --git a/packages/flutter_tools/lib/src/android/android_studio_validator.dart b/packages/flutter_tools/lib/src/android/android_studio_validator.dart
index d31cf6d..5b35762 100644
--- a/packages/flutter_tools/lib/src/android/android_studio_validator.dart
+++ b/packages/flutter_tools/lib/src/android/android_studio_validator.dart
@@ -71,7 +71,7 @@
   Future<ValidationResult> validate() async {
     final List<ValidationMessage> messages = <ValidationMessage>[];
 
-    final String cfgAndroidStudio = config.getValue('android-studio-dir');
+    final String cfgAndroidStudio = config.getValue('android-studio-dir') as String;
     if (cfgAndroidStudio != null) {
       messages.add(ValidationMessage.error(userMessages.androidStudioMissing(cfgAndroidStudio)));
     }
diff --git a/packages/flutter_tools/lib/src/android/android_workflow.dart b/packages/flutter_tools/lib/src/android/android_workflow.dart
index 1bd62c5..543067b 100644
--- a/packages/flutter_tools/lib/src/android/android_workflow.dart
+++ b/packages/flutter_tools/lib/src/android/android_workflow.dart
@@ -83,7 +83,7 @@
         printTrace('java -version');
         final ProcessResult result = await processManager.run(<String>[javaBinary, '-version']);
         if (result.exitCode == 0) {
-          final List<String> versionLines = result.stderr.split('\n');
+          final List<String> versionLines = (result.stderr as String).split('\n');
           javaVersionText = versionLines.length >= 2 ? versionLines[1] : versionLines[0];
         }
       } catch (error) {
@@ -236,7 +236,7 @@
     try {
       final ProcessResult result = await processManager.run(<String>[javaBinary, '-version']);
       if (result.exitCode == 0) {
-        final List<String> versionLines = result.stderr.split('\n');
+        final List<String> versionLines = (result.stderr as String).split('\n');
         javaVersion = versionLines.length >= 2 ? versionLines[1] : versionLines[0];
       }
     } catch (error) {
diff --git a/packages/flutter_tools/lib/src/android/gradle.dart b/packages/flutter_tools/lib/src/android/gradle.dart
index aab8c9c..23e41c2 100644
--- a/packages/flutter_tools/lib/src/android/gradle.dart
+++ b/packages/flutter_tools/lib/src/android/gradle.dart
@@ -281,7 +281,7 @@
     command.add('-q');
   }
   if (artifacts is LocalEngineArtifacts) {
-    final LocalEngineArtifacts localEngineArtifacts = artifacts;
+    final LocalEngineArtifacts localEngineArtifacts = artifacts as LocalEngineArtifacts;
     final Directory localEngineRepo = _getLocalEngineRepo(
       engineOutPath: localEngineArtifacts.engineOutPath,
       androidBuildInfo: androidBuildInfo,
@@ -526,7 +526,7 @@
     command.add('-Ptarget-platform=$targetPlatforms');
   }
   if (artifacts is LocalEngineArtifacts) {
-    final LocalEngineArtifacts localEngineArtifacts = artifacts;
+    final LocalEngineArtifacts localEngineArtifacts = artifacts as LocalEngineArtifacts;
     final Directory localEngineRepo = _getLocalEngineRepo(
       engineOutPath: localEngineArtifacts.engineOutPath,
       androidBuildInfo: androidBuildInfo,
diff --git a/packages/flutter_tools/lib/src/application_package.dart b/packages/flutter_tools/lib/src/application_package.dart
index 76c1d9b..2953003 100644
--- a/packages/flutter_tools/lib/src/application_package.dart
+++ b/packages/flutter_tools/lib/src/application_package.dart
@@ -48,7 +48,7 @@
             : AndroidApk.fromApk(applicationBinary);
       case TargetPlatform.ios:
         return applicationBinary == null
-            ? IOSApp.fromIosProject(FlutterProject.current().ios)
+            ? await IOSApp.fromIosProject(FlutterProject.current().ios)
             : IOSApp.fromPrebuiltApp(applicationBinary);
       case TargetPlatform.tester:
         return FlutterTesterApp.fromCurrentDirectory();
@@ -225,7 +225,7 @@
           if (!(node is xml.XmlElement)) {
             continue;
           }
-          final xml.XmlElement xmlElement = node;
+          final xml.XmlElement xmlElement = node as xml.XmlElement;
           final String name = xmlElement.getAttribute('android:name');
           if (name == 'android.intent.action.MAIN') {
             actionName = name;
@@ -262,9 +262,8 @@
   String get name => file.basename;
 }
 
-/// Tests whether a [FileSystemEntity] is an iOS bundle directory
-bool _isBundleDirectory(FileSystemEntity entity) =>
-    entity is Directory && entity.path.endsWith('.app');
+/// Tests whether a [Directory] is an iOS bundle directory
+bool _isBundleDirectory(Directory dir) => dir.path.endsWith('.app');
 
 abstract class IOSApp extends ApplicationPackage {
   IOSApp({@required String projectBundleId}) : super(id: projectBundleId);
@@ -301,7 +300,7 @@
         return null;
       }
       try {
-        bundleDir = payloadDir.listSync().singleWhere(_isBundleDirectory);
+        bundleDir = payloadDir.listSync().whereType<Directory>().singleWhere(_isBundleDirectory);
       } on StateError {
         printError(
             'Invalid prebuilt iOS ipa. Does not contain a single app bundle.');
@@ -469,22 +468,21 @@
   }
 
   _Attribute firstAttribute(String name) {
-    return children.firstWhere(
-        (_Entry e) => e is _Attribute && e.key.startsWith(name),
+    return children.whereType<_Attribute>().firstWhere(
+        (_Attribute e) => e.key.startsWith(name),
         orElse: () => null,
     );
   }
 
   _Element firstElement(String name) {
-    return children.firstWhere(
-        (_Entry e) => e is _Element && e.name.startsWith(name),
+    return children.whereType<_Element>().firstWhere(
+        (_Element e) => e.name.startsWith(name),
         orElse: () => null,
     );
   }
 
-  Iterable<_Entry> allElements(String name) {
-    return children.where(
-            (_Entry e) => e is _Element && e.name.startsWith(name));
+  Iterable<_Element> allElements(String name) {
+    return children.whereType<_Element>().where((_Element e) => e.name.startsWith(name));
   }
 }
 
@@ -510,8 +508,7 @@
 
   static bool isAttributeWithValuePresent(_Element baseElement,
       String childElement, String attributeName, String attributeValue) {
-    final Iterable<_Element> allElements = baseElement.allElements(
-        childElement).cast<_Element>();
+    final Iterable<_Element> allElements = baseElement.allElements(childElement);
     for (_Element oneElement in allElements) {
       final String elementAttributeValue = oneElement
           ?.firstAttribute(attributeName)
@@ -562,14 +559,12 @@
     final _Element application = manifest.firstElement('application');
     assert(application != null);
 
-    final Iterable<_Entry> activities = application.allElements('activity');
+    final Iterable<_Element> activities = application.allElements('activity');
 
     _Element launchActivity;
     for (_Element activity in activities) {
       final _Attribute enabled = activity.firstAttribute('android:enabled');
-      final Iterable<_Element> intentFilters = activity
-          .allElements('intent-filter')
-          .cast<_Element>();
+      final Iterable<_Element> intentFilters = activity.allElements('intent-filter');
       final bool isEnabledByDefault = enabled == null;
       final bool isExplicitlyEnabled = enabled != null && enabled.value.contains('0xffffffff');
       if (!(isEnabledByDefault || isExplicitlyEnabled)) {
diff --git a/packages/flutter_tools/lib/src/asset.dart b/packages/flutter_tools/lib/src/asset.dart
index 177d847..1a2503c 100644
--- a/packages/flutter_tools/lib/src/asset.dart
+++ b/packages/flutter_tools/lib/src/asset.dart
@@ -291,10 +291,10 @@
     if (other.runtimeType != runtimeType) {
       return false;
     }
-    final _Asset otherAsset = other;
-    return otherAsset.baseDir == baseDir
-        && otherAsset.relativeUri == relativeUri
-        && otherAsset.entryUri == entryUri;
+    return other is _Asset
+        && other.baseDir == baseDir
+        && other.relativeUri == relativeUri
+        && other.entryUri == entryUri;
   }
 
   @override
@@ -315,7 +315,7 @@
 final Map<String, dynamic> _materialFontsManifest = _readMaterialFontsManifest();
 
 List<Map<String, dynamic>> _getMaterialFonts(String fontSet) {
-  final List<dynamic> fontsList = _materialFontsManifest[fontSet];
+  final List<dynamic> fontsList = _materialFontsManifest[fontSet] as List<dynamic>;
   return fontsList?.map<Map<String, dynamic>>(castStringKeyedMap)?.toList();
 }
 
@@ -324,7 +324,7 @@
 
   for (Map<String, dynamic> family in _getMaterialFonts(fontSet)) {
     for (Map<dynamic, dynamic> font in family['fonts']) {
-      final Uri entryUri = fs.path.toUri(font['asset']);
+      final Uri entryUri = fs.path.toUri(font['asset'] as String);
       result.add(_Asset(
         baseDir: fs.path.join(Cache.flutterRoot, 'bin', 'cache', 'artifacts', 'material_fonts'),
         relativeUri: Uri(path: entryUri.pathSegments.last),
diff --git a/packages/flutter_tools/lib/src/base/async_guard.dart b/packages/flutter_tools/lib/src/base/async_guard.dart
index 1c7d636..515807b 100644
--- a/packages/flutter_tools/lib/src/base/async_guard.dart
+++ b/packages/flutter_tools/lib/src/base/async_guard.dart
@@ -99,9 +99,9 @@
       completer.completeError(e, s);
       return;
     }
-    if (onError is _BinaryOnError) {
+    if (onError is _BinaryOnError<T>) {
       completer.complete(onError(e, s));
-    } else if (onError is _UnaryOnError) {
+    } else if (onError is _UnaryOnError<T>) {
       completer.complete(onError(e));
     }
   }
diff --git a/packages/flutter_tools/lib/src/base/config.dart b/packages/flutter_tools/lib/src/base/config.dart
index 4526cef..7c1a522 100644
--- a/packages/flutter_tools/lib/src/base/config.dart
+++ b/packages/flutter_tools/lib/src/base/config.dart
@@ -5,12 +5,13 @@
 import '../convert.dart';
 import 'context.dart';
 import 'file_system.dart';
+import 'utils.dart';
 
 class Config {
   Config([File configFile]) {
     _configFile = configFile ?? fs.file(fs.path.join(userHomePath(), '.flutter_settings'));
     if (_configFile.existsSync()) {
-      _values = json.decode(_configFile.readAsStringSync());
+      _values = castStringKeyedMap(json.decode(_configFile.readAsStringSync()));
     }
   }
 
diff --git a/packages/flutter_tools/lib/src/base/fingerprint.dart b/packages/flutter_tools/lib/src/base/fingerprint.dart
index 4ff434a..317a256 100644
--- a/packages/flutter_tools/lib/src/base/fingerprint.dart
+++ b/packages/flutter_tools/lib/src/base/fingerprint.dart
@@ -11,6 +11,7 @@
 import '../version.dart';
 import 'file_system.dart';
 import 'platform.dart';
+import 'utils.dart';
 
 typedef FingerprintPathFilter = bool Function(String path);
 
@@ -130,14 +131,14 @@
   /// Throws [ArgumentError], if there is a version mismatch between the
   /// serializing framework and this framework.
   Fingerprint.fromJson(String jsonData) {
-    final Map<String, dynamic> content = json.decode(jsonData);
+    final Map<String, dynamic> content = castStringKeyedMap(json.decode(jsonData));
 
-    final String version = content['version'];
+    final String version = content['version'] as String;
     if (version != FlutterVersion.instance.frameworkRevision) {
       throw ArgumentError('Incompatible fingerprint version: $version');
     }
-    _checksums = content['files']?.cast<String,String>() ?? <String, String>{};
-    _properties = content['properties']?.cast<String,String>() ?? <String, String>{};
+    _checksums = castStringKeyedMap(content['files'])?.cast<String,String>() ?? <String, String>{};
+    _properties = castStringKeyedMap(content['properties'])?.cast<String,String>() ?? <String, String>{};
   }
 
   Map<String, String> _checksums;
@@ -157,9 +158,9 @@
     if (other.runtimeType != runtimeType) {
       return false;
     }
-    final Fingerprint typedOther = other;
-    return _equalMaps(typedOther._checksums, _checksums)
-        && _equalMaps(typedOther._properties, _properties);
+    return other is Fingerprint
+        && _equalMaps(other._checksums, _checksums)
+        && _equalMaps(other._properties, _properties);
   }
 
   bool _equalMaps(Map<String, String> a, Map<String, String> b) {
diff --git a/packages/flutter_tools/lib/src/base/io.dart b/packages/flutter_tools/lib/src/base/io.dart
index 2282d81..29ef5da 100644
--- a/packages/flutter_tools/lib/src/base/io.dart
+++ b/packages/flutter_tools/lib/src/base/io.dart
@@ -198,7 +198,7 @@
     if (stdin is! io.Stdin) {
       return _stdinHasTerminal = false;
     }
-    final io.Stdin ioStdin = stdin;
+    final io.Stdin ioStdin = stdin as io.Stdin;
     if (!ioStdin.hasTerminal) {
       return _stdinHasTerminal = false;
     }
diff --git a/packages/flutter_tools/lib/src/base/os.dart b/packages/flutter_tools/lib/src/base/os.dart
index 56b719b..8945ed5 100644
--- a/packages/flutter_tools/lib/src/base/os.dart
+++ b/packages/flutter_tools/lib/src/base/os.dart
@@ -151,7 +151,7 @@
     if (result.exitCode != 0) {
       return const <File>[];
     }
-    final String stdout = result.stdout;
+    final String stdout = result.stdout as String;
     return stdout.trim().split('\n').map<File>((String path) => fs.file(path.trim())).toList();
   }
 
@@ -240,7 +240,7 @@
     if (result.exitCode != 0) {
       return const <File>[];
     }
-    final List<String> lines = result.stdout.trim().split('\n');
+    final List<String> lines = (result.stdout as String).trim().split('\n');
     if (all) {
       return lines.map<File>((String path) => fs.file(path.trim())).toList();
     }
@@ -254,7 +254,7 @@
       if (entity is! File) {
         continue;
       }
-      final File file = entity;
+      final File file = entity as File;
       final String path = file.fileSystem.path.relative(file.path, from: data.path);
       final List<int> bytes = file.readAsBytesSync();
       archive.addFile(ArchiveFile(path, bytes.length, bytes));
@@ -311,7 +311,7 @@
       if (!destFile.parent.existsSync()) {
         destFile.parent.createSync(recursive: true);
       }
-      destFile.writeAsBytesSync(archiveFile.content);
+      destFile.writeAsBytesSync(archiveFile.content as List<int>);
     }
   }
 
@@ -328,7 +328,7 @@
       final ProcessResult result = processManager.runSync(
           <String>['ver'], runInShell: true);
       if (result.exitCode == 0) {
-        _name = result.stdout.trim();
+        _name = (result.stdout as String).trim();
       } else {
         _name = super.name;
       }
diff --git a/packages/flutter_tools/lib/src/base/process.dart b/packages/flutter_tools/lib/src/base/process.dart
index 593bcd3..55efd27 100644
--- a/packages/flutter_tools/lib/src/base/process.dart
+++ b/packages/flutter_tools/lib/src/base/process.dart
@@ -121,17 +121,17 @@
   final List<String> _command;
 
   int get exitCode => processResult.exitCode;
-  String get stdout => processResult.stdout;
-  String get stderr => processResult.stderr;
+  String get stdout => processResult.stdout as String;
+  String get stderr => processResult.stderr as String;
 
   @override
   String toString() {
     final StringBuffer out = StringBuffer();
-    if (processResult.stdout.isNotEmpty) {
-      out.writeln(processResult.stdout);
+    if (stdout.isNotEmpty) {
+      out.writeln(stdout);
     }
-    if (processResult.stderr.isNotEmpty) {
-      out.writeln(processResult.stderr);
+    if (stderr.isNotEmpty) {
+      out.writeln(stderr);
     }
     return out.toString().trimRight();
   }
diff --git a/packages/flutter_tools/lib/src/base/process_manager.dart b/packages/flutter_tools/lib/src/base/process_manager.dart
index 5929ef9..161ac46 100644
--- a/packages/flutter_tools/lib/src/base/process_manager.dart
+++ b/packages/flutter_tools/lib/src/base/process_manager.dart
@@ -51,5 +51,5 @@
     throwToolExit('Invalid replay-from: $error');
   }
 
-  return manager;
+  return manager as ReplayProcessManager;
 }
diff --git a/packages/flutter_tools/lib/src/base/signals.dart b/packages/flutter_tools/lib/src/base/signals.dart
index aa9c83c..ffd63b5 100644
--- a/packages/flutter_tools/lib/src/base/signals.dart
+++ b/packages/flutter_tools/lib/src/base/signals.dart
@@ -116,7 +116,7 @@
   Future<void> _handleSignal(ProcessSignal s) async {
     for (SignalHandler handler in _handlersList[s]) {
       try {
-        await asyncGuard<void>(() => handler(s));
+        await asyncGuard<void>(() async => handler(s));
       } catch (e) {
         if (_errorStreamController.hasListener) {
           _errorStreamController.add(e);
diff --git a/packages/flutter_tools/lib/src/base/terminal.dart b/packages/flutter_tools/lib/src/base/terminal.dart
index 09bfd59..e4dfb12 100644
--- a/packages/flutter_tools/lib/src/base/terminal.dart
+++ b/packages/flutter_tools/lib/src/base/terminal.dart
@@ -169,7 +169,7 @@
     if (!io.stdinHasTerminal) {
       return;
     }
-    final io.Stdin stdin = io.stdin;
+    final io.Stdin stdin = io.stdin as io.Stdin;
     // The order of setting lineMode and echoMode is important on Windows.
     if (value) {
       stdin.echoMode = false;
diff --git a/packages/flutter_tools/lib/src/base/utils.dart b/packages/flutter_tools/lib/src/base/utils.dart
index f9901c7..00d4e9f 100644
--- a/packages/flutter_tools/lib/src/base/utils.dart
+++ b/packages/flutter_tools/lib/src/base/utils.dart
@@ -251,8 +251,8 @@
 /// Given a data structure which is a Map of String to dynamic values, return
 /// the same structure (`Map<String, dynamic>`) with the correct runtime types.
 Map<String, dynamic> castStringKeyedMap(dynamic untyped) {
-  final Map<dynamic, dynamic> map = untyped;
-  return map.cast<String, dynamic>();
+  final Map<dynamic, dynamic> map = untyped as Map<dynamic, dynamic>;
+  return map?.cast<String, dynamic>();
 }
 
 typedef AsyncCallback = Future<void> Function();
diff --git a/packages/flutter_tools/lib/src/build_info.dart b/packages/flutter_tools/lib/src/build_info.dart
index 56e7907..0aa594c 100644
--- a/packages/flutter_tools/lib/src/build_info.dart
+++ b/packages/flutter_tools/lib/src/build_info.dart
@@ -506,7 +506,7 @@
     return 'build';
   }
 
-  final String buildDir = config.getValue('build-dir') ?? 'build';
+  final String buildDir = config.getValue('build-dir') as String ?? 'build';
   if (fs.path.isAbsolute(buildDir)) {
     throw Exception(
         'build-dir config setting in ${config.configPath} must be relative');
diff --git a/packages/flutter_tools/lib/src/build_runner/build_runner.dart b/packages/flutter_tools/lib/src/build_runner/build_runner.dart
index 53c066c..52b3b75 100644
--- a/packages/flutter_tools/lib/src/build_runner/build_runner.dart
+++ b/packages/flutter_tools/lib/src/build_runner/build_runner.dart
@@ -80,14 +80,14 @@
       stringBuffer.writeln('dependencies:');
       final YamlMap builders = flutterProject.builders;
       if (builders != null) {
-        for (String name in builders.keys) {
+        for (String name in builders.keys.cast<String>()) {
           final Object node = builders[name];
           // For relative paths, make sure it is accounted for
           // parent directories.
           if (node is YamlMap && node['path'] != null) {
-            final String path = node['path'];
+            final String path = node['path'] as String;
             if (fs.path.isRelative(path)) {
-              final String convertedPath = fs.path.join('..', '..', node['path']);
+              final String convertedPath = fs.path.join('..', '..', path);
               stringBuffer.writeln('  $name:');
               stringBuffer.writeln('    path: $convertedPath');
             } else {
diff --git a/packages/flutter_tools/lib/src/build_runner/build_script.dart b/packages/flutter_tools/lib/src/build_runner/build_script.dart
index 581225b..e4ca378 100644
--- a/packages/flutter_tools/lib/src/build_runner/build_script.dart
+++ b/packages/flutter_tools/lib/src/build_runner/build_script.dart
@@ -118,12 +118,12 @@
       'flutter_tools:ddc',
       <Builder Function(BuilderOptions)>[
         (BuilderOptions builderOptions) => KernelBuilder(
-              platformSdk: builderOptions.config['flutterWebSdk'],
+              platformSdk: builderOptions.config['flutterWebSdk'] as String,
               summaryOnly: true,
               sdkKernelPath: path.join('kernel', 'flutter_ddc_sdk.dill'),
               outputExtension: ddcKernelExtension,
               platform: flutterWebPlatform,
-              librariesPath: path.absolute(path.join(builderOptions.config['flutterWebSdk'], 'libraries.json')),
+              librariesPath: path.absolute(path.join(builderOptions.config['flutterWebSdk'] as String, 'libraries.json')),
               kernelTargetName: 'ddc',
               useIncrementalCompiler: true,
               trackUnusedInputs: true,
@@ -132,9 +132,9 @@
               useIncrementalCompiler: true,
               trackUnusedInputs: true,
               platform: flutterWebPlatform,
-              platformSdk: builderOptions.config['flutterWebSdk'],
+              platformSdk: builderOptions.config['flutterWebSdk'] as String,
               sdkKernelPath: path.url.join('kernel', 'flutter_ddc_sdk.dill'),
-              librariesPath: path.absolute(path.join(builderOptions.config['flutterWebSdk'], 'libraries.json')),
+              librariesPath: path.absolute(path.join(builderOptions.config['flutterWebSdk'] as String, 'libraries.json')),
             ),
       ],
       core.toAllPackages(),
@@ -145,9 +145,9 @@
     'flutter_tools:entrypoint',
     <BuilderFactory>[
       (BuilderOptions options) => FlutterWebEntrypointBuilder(
-          options.config[kReleaseFlag] ?? false,
-          options.config[kProfileFlag] ?? false,
-          options.config['flutterWebSdk'],
+          options.config[kReleaseFlag] as bool ?? false,
+          options.config[kProfileFlag] as bool ?? false,
+          options.config['flutterWebSdk'] as String,
       ),
     ],
     core.toRoot(),
diff --git a/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart b/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart
index 2ac3435..a041b86 100644
--- a/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart
+++ b/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart
@@ -227,7 +227,7 @@
     try {
       final vmservice.Response response = await _vmService
           ?.callServiceExtension('ext.flutter.platformOverride');
-      final String currentPlatform = response.json['value'];
+      final String currentPlatform = response.json['value'] as String;
       String nextPlatform;
       switch (currentPlatform) {
         case 'android':
diff --git a/packages/flutter_tools/lib/src/build_runner/web_fs.dart b/packages/flutter_tools/lib/src/build_runner/web_fs.dart
index 688d2d3..509c076 100644
--- a/packages/flutter_tools/lib/src/build_runner/web_fs.dart
+++ b/packages/flutter_tools/lib/src/build_runner/web_fs.dart
@@ -427,7 +427,7 @@
           partFiles = fs.systemTempDirectory.createTempSync('flutter_tool.')
             ..createSync();
           for (ArchiveFile file in archive) {
-            partFiles.childFile(file.name).writeAsBytesSync(file.content);
+            partFiles.childFile(file.name).writeAsBytesSync(file.content as List<int>);
           }
         }
       }
diff --git a/packages/flutter_tools/lib/src/build_system/build_system.dart b/packages/flutter_tools/lib/src/build_system/build_system.dart
index cb0dc84..9677170a 100644
--- a/packages/flutter_tools/lib/src/build_system/build_system.dart
+++ b/packages/flutter_tools/lib/src/build_system/build_system.dart
@@ -13,6 +13,7 @@
 import '../base/context.dart';
 import '../base/file_system.dart';
 import '../base/platform.dart';
+import '../base/utils.dart';
 import '../cache.dart';
 import '../convert.dart';
 import '../globals.dart';
@@ -464,7 +465,7 @@
 
   final BuildSystemConfig buildSystemConfig;
   final Pool resourcePool;
-  final Map<String, AsyncMemoizer<void>> pending = <String, AsyncMemoizer<void>>{};
+  final Map<String, AsyncMemoizer<bool>> pending = <String, AsyncMemoizer<bool>>{};
   final Environment environment;
   final FileHashStore fileCache;
   final Map<String, File> inputFiles = <String, File>{};
@@ -671,7 +672,7 @@
     }
     Map<String, Object> values;
     try {
-      values = json.decode(content);
+      values = castStringKeyedMap(json.decode(content));
     } on FormatException {
       // The json is malformed in some way.
       _dirty = true;
diff --git a/packages/flutter_tools/lib/src/build_system/file_hash_store.dart b/packages/flutter_tools/lib/src/build_system/file_hash_store.dart
index c941bae..ff1f48a 100644
--- a/packages/flutter_tools/lib/src/build_system/file_hash_store.dart
+++ b/packages/flutter_tools/lib/src/build_system/file_hash_store.dart
@@ -10,6 +10,7 @@
 import 'package:pool/pool.dart';
 
 import '../base/file_system.dart';
+import '../base/utils.dart';
 import '../convert.dart';
 import '../globals.dart';
 import 'build_system.dart';
@@ -19,9 +20,9 @@
   FileStorage(this.version, this.files);
 
   factory FileStorage.fromBuffer(Uint8List buffer) {
-    final Map<String, Object> json = jsonDecode(utf8.decode(buffer));
-    final int version = json['version'];
-    final List<Object> rawCachedFiles = json['files'];
+    final Map<String, dynamic> json = castStringKeyedMap(jsonDecode(utf8.decode(buffer)));
+    final int version = json['version'] as int;
+    final List<Map<String, Object>> rawCachedFiles = (json['files'] as List<dynamic>).cast<Map<String, Object>>();
     final List<FileHash> cachedFiles = <FileHash>[
       for (Map<String, Object> rawFile in rawCachedFiles) FileHash.fromJson(rawFile),
     ];
@@ -47,7 +48,7 @@
   FileHash(this.path, this.hash);
 
   factory FileHash.fromJson(Map<String, Object> json) {
-    return FileHash(json['path'], json['hash']);
+    return FileHash(json['path'] as String, json['hash'] as String);
   }
 
   final String path;
@@ -92,7 +93,7 @@
     if (!cacheFile.existsSync()) {
       return;
     }
-    List<int> data;
+    Uint8List data;
     try {
       data = cacheFile.readAsBytesSync();
     } on FileSystemException catch (err) {
@@ -138,7 +139,7 @@
       _kVersion,
       fileHashes,
     );
-    final Uint8List buffer = fileStorage.toBuffer();
+    final List<int> buffer = fileStorage.toBuffer();
     try {
       cacheFile.writeAsBytesSync(buffer);
     } on FileSystemException catch (err) {
diff --git a/packages/flutter_tools/lib/src/build_system/source.dart b/packages/flutter_tools/lib/src/build_system/source.dart
index 43c13cb..0174461 100644
--- a/packages/flutter_tools/lib/src/build_system/source.dart
+++ b/packages/flutter_tools/lib/src/build_system/source.dart
@@ -153,11 +153,11 @@
       } else if (wildcardSegments.length == 1) {
         if (filename.startsWith(wildcardSegments[0]) ||
             filename.endsWith(wildcardSegments[0])) {
-          sources.add(entity.absolute);
+          sources.add(fs.file(entity.absolute));
         }
       } else if (filename.startsWith(wildcardSegments[0])) {
         if (filename.substring(wildcardSegments[0].length).endsWith(wildcardSegments[1])) {
-          sources.add(entity.absolute);
+          sources.add(fs.file(entity.absolute));
         }
       }
     }
diff --git a/packages/flutter_tools/lib/src/build_system/targets/dart.dart b/packages/flutter_tools/lib/src/build_system/targets/dart.dart
index 60165ad..e03a377 100644
--- a/packages/flutter_tools/lib/src/build_system/targets/dart.dart
+++ b/packages/flutter_tools/lib/src/build_system/targets/dart.dart
@@ -390,7 +390,7 @@
 
   final String dartDefinesJson = environment.defines[kDartDefines];
   try {
-    final List<Object> parsedDefines = jsonDecode(dartDefinesJson);
+    final List<Object> parsedDefines = jsonDecode(dartDefinesJson) as List<Object>;
     return parsedDefines.cast<String>();
   } on FormatException catch (_) {
     throw Exception(
diff --git a/packages/flutter_tools/lib/src/cache.dart b/packages/flutter_tools/lib/src/cache.dart
index d83e497..5e1950b 100644
--- a/packages/flutter_tools/lib/src/cache.dart
+++ b/packages/flutter_tools/lib/src/cache.dart
@@ -379,7 +379,7 @@
     final bool includeAllPlatformsState = cache.includeAllPlatforms;
     bool allAvailible = true;
     cache.includeAllPlatforms = includeAllPlatforms;
-    for (CachedArtifact cachedArtifact in _artifacts) {
+    for (ArtifactSet cachedArtifact in _artifacts) {
       if (cachedArtifact is EngineCachedArtifact) {
         allAvailible &= await cachedArtifact.checkForArtifacts(engineVersion);
       }
diff --git a/packages/flutter_tools/lib/src/commands/analyze.dart b/packages/flutter_tools/lib/src/commands/analyze.dart
index 3d8ca6b..7ebe931 100644
--- a/packages/flutter_tools/lib/src/commands/analyze.dart
+++ b/packages/flutter_tools/lib/src/commands/analyze.dart
@@ -72,7 +72,7 @@
   @override
   bool get shouldRunPub {
     // If they're not analyzing the current project.
-    if (!argResults['current-package']) {
+    if (!boolArg('current-package')) {
       return false;
     }
 
@@ -86,7 +86,7 @@
 
   @override
   Future<FlutterCommandResult> runCommand() async {
-    if (argResults['watch']) {
+    if (boolArg('watch')) {
       await AnalyzeContinuously(
         argResults,
         runner.getRepoRoots(),
diff --git a/packages/flutter_tools/lib/src/commands/analyze_base.dart b/packages/flutter_tools/lib/src/commands/analyze_base.dart
index cff8b56..7cbb941 100644
--- a/packages/flutter_tools/lib/src/commands/analyze_base.dart
+++ b/packages/flutter_tools/lib/src/commands/analyze_base.dart
@@ -50,7 +50,7 @@
     printStatus('Analysis benchmark written to $benchmarkOut ($data).');
   }
 
-  bool get isBenchmarking => argResults['benchmark'];
+  bool get isBenchmarking => argResults['benchmark'] as bool;
 }
 
 /// Return true if [fileList] contains a path that resides inside the Flutter repository.
@@ -172,10 +172,18 @@
         // we are analyzing the actual canonical source for this package;
         // make sure we remember that, in case all the packages are actually
         // pointing elsewhere somehow.
-        final yaml.YamlMap pubSpecYaml = yaml.loadYaml(fs.file(pubSpecYamlPath).readAsStringSync());
-        final String packageName = pubSpecYaml['name'];
-        final String packagePath = fs.path.normalize(fs.path.absolute(fs.path.join(directory.path, 'lib')));
-        dependencies.addCanonicalCase(packageName, packagePath, pubSpecYamlPath);
+        final dynamic pubSpecYaml = yaml.loadYaml(fs.file(pubSpecYamlPath).readAsStringSync());
+        if (pubSpecYaml is yaml.YamlMap) {
+          final dynamic packageName = pubSpecYaml['name'];
+          if (packageName is String) {
+            final String packagePath = fs.path.normalize(fs.path.absolute(fs.path.join(directory.path, 'lib')));
+            dependencies.addCanonicalCase(packageName, packagePath, pubSpecYamlPath);
+          } else {
+            throwToolExit('pubspec.yaml is malformed. The name should be a String.');
+          }
+        } else {
+          throwToolExit('pubspec.yaml is malformed.');
+        }
       }
       dependencies.addDependenciesFromPackagesFileIn(directory);
     }
diff --git a/packages/flutter_tools/lib/src/commands/analyze_continuously.dart b/packages/flutter_tools/lib/src/commands/analyze_continuously.dart
index 35647d7..0d11696 100644
--- a/packages/flutter_tools/lib/src/commands/analyze_continuously.dart
+++ b/packages/flutter_tools/lib/src/commands/analyze_continuously.dart
@@ -36,7 +36,7 @@
   Future<void> analyze() async {
     List<String> directories;
 
-    if (argResults['flutter-repo']) {
+    if (argResults['flutter-repo'] as bool) {
       final PackageDependencyTracker dependencies = PackageDependencyTracker();
       dependencies.checkForConflictingDependencies(repoPackages, dependencies);
 
@@ -52,7 +52,7 @@
       analysisTarget = fs.currentDirectory.path;
     }
 
-    final String sdkPath = argResults['dart-sdk'] ?? sdk.dartSdkPath;
+    final String sdkPath = argResults['dart-sdk'] as String ?? sdk.dartSdkPath;
 
     final AnalysisServer server = AnalysisServer(sdkPath, directories);
     server.onAnalyzing.listen((bool isAnalyzing) => _handleAnalysisStatus(server, isAnalyzing));
@@ -106,7 +106,7 @@
       final int undocumentedMembers = errors.where((AnalysisError error) {
         return error.code == 'public_member_api_docs';
       }).length;
-      if (!argResults['dartdocs']) {
+      if (!(argResults['dartdocs'] as bool)) {
         errors.removeWhere((AnalysisError error) => error.code == 'public_member_api_docs');
         issueCount -= undocumentedMembers;
       }
diff --git a/packages/flutter_tools/lib/src/commands/analyze_once.dart b/packages/flutter_tools/lib/src/commands/analyze_once.dart
index 7f7b381..b05acdc 100644
--- a/packages/flutter_tools/lib/src/commands/analyze_once.dart
+++ b/packages/flutter_tools/lib/src/commands/analyze_once.dart
@@ -52,16 +52,16 @@
       }
     }
 
-    if (argResults['flutter-repo']) {
+    if (argResults['flutter-repo'] as bool) {
       // check for conflicting dependencies
       final PackageDependencyTracker dependencies = PackageDependencyTracker();
       dependencies.checkForConflictingDependencies(repoPackages, dependencies);
       directories.addAll(repoRoots);
-      if (argResults.wasParsed('current-package') && argResults['current-package']) {
+      if (argResults.wasParsed('current-package') && (argResults['current-package'] as bool)) {
         directories.add(currentDirectory);
       }
     } else {
-      if (argResults['current-package']) {
+      if (argResults['current-package'] as bool) {
         directories.add(currentDirectory);
       }
     }
@@ -74,7 +74,7 @@
     final Completer<void> analysisCompleter = Completer<void>();
     final List<AnalysisError> errors = <AnalysisError>[];
 
-    final String sdkPath = argResults['dart-sdk'] ?? sdk.dartSdkPath;
+    final String sdkPath = argResults['dart-sdk'] as String ?? sdk.dartSdkPath;
 
     final AnalysisServer server = AnalysisServer(
       sdkPath,
@@ -109,7 +109,7 @@
     final String message = directories.length > 1
         ? '${directories.length} ${directories.length == 1 ? 'directory' : 'directories'}'
         : fs.path.basename(directories.first);
-    final Status progress = argResults['preamble']
+    final Status progress = argResults['preamble'] as bool
         ? logger.startProgress('Analyzing $message...', timeout: timeoutConfiguration.slowOperation)
         : null;
 
@@ -121,7 +121,7 @@
     final int undocumentedMembers = errors.where((AnalysisError error) {
       return error.code == 'public_member_api_docs';
     }).length;
-    if (!argResults['dartdocs']) {
+    if (!(argResults['dartdocs'] as bool)) {
       errors.removeWhere((AnalysisError error) => error.code == 'public_member_api_docs');
     }
 
@@ -134,7 +134,7 @@
     dumpErrors(errors.map<String>((AnalysisError error) => error.toLegacyString()));
 
     // report errors
-    if (errors.isNotEmpty && argResults['preamble']) {
+    if (errors.isNotEmpty && (argResults['preamble'] as bool)) {
       printStatus('');
     }
     errors.sort();
@@ -166,7 +166,7 @@
       throwToolExit('Server error(s) occurred. (ran in ${seconds}s)');
     }
 
-    if (argResults['congratulate']) {
+    if (argResults['congratulate'] as bool) {
       if (undocumentedMembers > 0) {
         printStatus('No issues found! (ran in ${seconds}s; $dartdocMessage)');
       } else {
diff --git a/packages/flutter_tools/lib/src/commands/assemble.dart b/packages/flutter_tools/lib/src/commands/assemble.dart
index 8b83775..f806492 100644
--- a/packages/flutter_tools/lib/src/commands/assemble.dart
+++ b/packages/flutter_tools/lib/src/commands/assemble.dart
@@ -116,7 +116,7 @@
   /// The environmental configuration for a build invocation.
   Environment get environment {
     final FlutterProject flutterProject = FlutterProject.current();
-    String output = argResults['output'];
+    String output = stringArg('output');
     if (output == null) {
       throwToolExit('--output directory is required for assemble.');
     }
@@ -130,7 +130,7 @@
           .childDirectory('.dart_tool')
           .childDirectory('flutter_build'),
       projectDir: flutterProject.directory,
-      defines: _parseDefines(argResults['define']),
+      defines: _parseDefines(stringsArg('define')),
     );
     return result;
   }
@@ -152,7 +152,7 @@
   @override
   Future<FlutterCommandResult> runCommand() async {
     final BuildResult result = await buildSystem.build(target, environment, buildSystemConfig: BuildSystemConfig(
-      resourcePoolSize: argResults['resource-pool-size'],
+      resourcePoolSize: argResults.wasParsed('resource-pool-size') ? int.parse(stringArg('resource-pool-size')) : null,
     ));
     if (!result.success) {
       for (ExceptionMeasurement measurement in result.exceptions.values) {
@@ -166,13 +166,13 @@
     }
     printTrace('build succeeded.');
     if (argResults.wasParsed('build-inputs')) {
-      writeListIfChanged(result.inputFiles, argResults['build-inputs']);
+      writeListIfChanged(result.inputFiles, stringArg('build-inputs'));
     }
     if (argResults.wasParsed('build-outputs')) {
-      writeListIfChanged(result.outputFiles, argResults['build-outputs']);
+      writeListIfChanged(result.outputFiles, stringArg('build-outputs'));
     }
     if (argResults.wasParsed('depfile')) {
-      final File depfileFile = fs.file(argResults['depfile']);
+      final File depfileFile = fs.file(stringArg('depfile'));
       final Depfile depfile = Depfile(result.inputFiles, result.outputFiles);
       depfile.writeToFile(fs.file(depfileFile));
     }
diff --git a/packages/flutter_tools/lib/src/commands/attach.dart b/packages/flutter_tools/lib/src/commands/attach.dart
index ee6a0e0..1e39758 100644
--- a/packages/flutter_tools/lib/src/commands/attach.dart
+++ b/packages/flutter_tools/lib/src/commands/attach.dart
@@ -113,7 +113,7 @@
       return null;
     }
     try {
-      return int.parse(argResults['debug-port']);
+      return int.parse(stringArg('debug-port'));
     } catch (error) {
       throwToolExit('Invalid port for `--debug-port`: $error');
     }
@@ -124,7 +124,7 @@
     if (argResults['debug-uri'] == null) {
       return null;
     }
-    final Uri uri = Uri.parse(argResults['debug-uri']);
+    final Uri uri = Uri.parse(stringArg('debug-uri'));
     if (!uri.hasPort) {
       throwToolExit('Port not specified for `--debug-uri`: $uri');
     }
@@ -132,7 +132,7 @@
   }
 
   String get appId {
-    return argResults['app-id'];
+    return stringArg('app-id');
   }
 
   @override
@@ -166,7 +166,7 @@
 
     await _validateArguments();
 
-    writePidFile(argResults['pid-file']);
+    writePidFile(stringArg('pid-file'));
 
     final Device device = await findTargetDevice();
 
@@ -195,7 +195,7 @@
     }
     final int devicePort = await getDevicePort();
 
-    final Daemon daemon = argResults['machine']
+    final Daemon daemon = boolArg('machine')
       ? Daemon(stdinCommandStream, stdoutCommandResponse,
             notifyingLogger: NotifyingLogger(), logToStdout: true)
       : null;
@@ -210,7 +210,7 @@
     if (devicePort == null && debugUri == null) {
       if (device is FuchsiaDevice) {
         attachLogger = true;
-        final String module = argResults['module'];
+        final String module = stringArg('module');
         if (module == null) {
           throwToolExit('\'--module\' is required for attaching to a Fuchsia device');
         }
@@ -272,12 +272,12 @@
       final FlutterDevice flutterDevice = await FlutterDevice.create(
         device,
         flutterProject: flutterProject,
-        trackWidgetCreation: argResults['track-widget-creation'],
-        fileSystemRoots: argResults['filesystem-root'],
-        fileSystemScheme: argResults['filesystem-scheme'],
-        viewFilter: argResults['isolate-filter'],
-        target: argResults['target'],
-        targetModel: TargetModel(argResults['target-model']),
+        trackWidgetCreation: boolArg('track-widget-creation'),
+        fileSystemRoots: stringsArg('filesystem-root'),
+        fileSystemScheme: stringArg('filesystem-scheme'),
+        viewFilter: stringArg('isolate-filter'),
+        target: stringArg('target'),
+        targetModel: TargetModel(stringArg('target-model')),
         buildMode: getBuildMode(),
         dartDefines: dartDefines,
       );
@@ -290,9 +290,9 @@
             flutterDevices,
             target: targetFile,
             debuggingOptions: debuggingOptions,
-            packagesFilePath: globalResults['packages'],
-            projectRootPath: argResults['project-root'],
-            dillOutputPath: argResults['output-dill'],
+            packagesFilePath: globalResults['packages'] as String,
+            projectRootPath: stringArg('project-root'),
+            dillOutputPath: stringArg('output-dill'),
             ipv6: usesIpv6,
             flutterProject: flutterProject,
           )
diff --git a/packages/flutter_tools/lib/src/commands/build_aar.dart b/packages/flutter_tools/lib/src/commands/build_aar.dart
index f35f665..b59518e 100644
--- a/packages/flutter_tools/lib/src/commands/build_aar.dart
+++ b/packages/flutter_tools/lib/src/commands/build_aar.dart
@@ -72,8 +72,7 @@
     } else {
       usage[CustomDimensions.commandBuildAarProjectType] = 'app';
     }
-    usage[CustomDimensions.commandBuildAarTargetPlatform] =
-        (argResults['target-platform'] as List<String>).join(',');
+    usage[CustomDimensions.commandBuildAarTargetPlatform] = stringsArg('target-platform').join(',');
     return usage;
   }
 
@@ -87,14 +86,14 @@
   @override
   Future<FlutterCommandResult> runCommand() async {
     final Set<AndroidBuildInfo> androidBuildInfo = <AndroidBuildInfo>{};
-    final Iterable<AndroidArch> targetArchitectures = argResults['target-platform']
+    final Iterable<AndroidArch> targetArchitectures = stringsArg('target-platform')
       .map<AndroidArch>(getAndroidArchForName);
 
     for (String buildMode in const <String>['debug', 'profile', 'release']) {
-      if (argResults[buildMode]) {
+      if (boolArg(buildMode)) {
         androidBuildInfo.add(
           AndroidBuildInfo(
-            BuildInfo(BuildMode.fromName(buildMode), argResults['flavor']),
+            BuildInfo(BuildMode.fromName(buildMode), stringArg('flavor')),
             targetArchs: targetArchitectures,
           )
         );
@@ -107,7 +106,7 @@
       project: _getProject(),
       target: '', // Not needed because this command only builds Android's code.
       androidBuildInfo: androidBuildInfo,
-      outputDirectoryPath: argResults['output-dir'],
+      outputDirectoryPath: stringArg('output-dir'),
     );
     return null;
   }
diff --git a/packages/flutter_tools/lib/src/commands/build_aot.dart b/packages/flutter_tools/lib/src/commands/build_aot.dart
index 92a8f86..351d2d3 100644
--- a/packages/flutter_tools/lib/src/commands/build_aot.dart
+++ b/packages/flutter_tools/lib/src/commands/build_aot.dart
@@ -66,9 +66,9 @@
 
   @override
   Future<FlutterCommandResult> runCommand() async {
-    final String targetPlatform = argResults['target-platform'];
+    final String targetPlatform = stringArg('target-platform');
     final TargetPlatform platform = getTargetPlatformForName(targetPlatform);
-    final String outputPath = argResults['output-dir'] ?? getAotBuildDirectory();
+    final String outputPath = stringArg('output-dir') ?? getAotBuildDirectory();
     final BuildMode buildMode = getBuildMode();
     if (platform == null) {
       throwToolExit('Unknown platform: $targetPlatform');
@@ -81,12 +81,12 @@
       outputPath: outputPath,
       buildMode: buildMode,
       mainDartFile: findMainDartFile(targetFile),
-      bitcode: argResults['bitcode'],
-      quiet: argResults['quiet'],
-      reportTimings: argResults['report-timings'],
-      iosBuildArchs: argResults['ios-arch'].map<DarwinArch>(getIOSArchForName),
-      extraFrontEndOptions: argResults[FlutterOptions.kExtraFrontEndOptions],
-      extraGenSnapshotOptions: argResults[FlutterOptions.kExtraGenSnapshotOptions],
+      bitcode: boolArg('bitcode'),
+      quiet: boolArg('quiet'),
+      reportTimings: boolArg('report-timings'),
+      iosBuildArchs: stringsArg('ios-arch').map<DarwinArch>(getIOSArchForName),
+      extraFrontEndOptions: stringsArg(FlutterOptions.kExtraFrontEndOptions),
+      extraGenSnapshotOptions: stringsArg(FlutterOptions.kExtraGenSnapshotOptions),
       dartDefines: dartDefines,
     );
     return null;
diff --git a/packages/flutter_tools/lib/src/commands/build_apk.dart b/packages/flutter_tools/lib/src/commands/build_apk.dart
index 8b000e6..28abedc 100644
--- a/packages/flutter_tools/lib/src/commands/build_apk.dart
+++ b/packages/flutter_tools/lib/src/commands/build_apk.dart
@@ -59,15 +59,15 @@
     final Map<CustomDimensions, String> usage = <CustomDimensions, String>{};
 
     usage[CustomDimensions.commandBuildApkTargetPlatform] =
-        (argResults['target-platform'] as List<String>).join(',');
+        stringsArg('target-platform').join(',');
     usage[CustomDimensions.commandBuildApkSplitPerAbi] =
-        argResults['split-per-abi'].toString();
+        boolArg('split-per-abi').toString();
 
-    if (argResults['release']) {
+    if (boolArg('release')) {
       usage[CustomDimensions.commandBuildApkBuildMode] = 'release';
-    } else if (argResults['debug']) {
+    } else if (boolArg('debug')) {
       usage[CustomDimensions.commandBuildApkBuildMode] = 'debug';
-    } else if (argResults['profile']) {
+    } else if (boolArg('profile')) {
       usage[CustomDimensions.commandBuildApkBuildMode] = 'profile';
     } else {
       // The build defaults to release.
@@ -81,13 +81,13 @@
     final BuildInfo buildInfo = getBuildInfo();
     final AndroidBuildInfo androidBuildInfo = AndroidBuildInfo(
       buildInfo,
-      splitPerAbi: argResults['split-per-abi'],
-      targetArchs: argResults['target-platform'].map<AndroidArch>(getAndroidArchForName),
-      shrink: argResults['shrink'],
+      splitPerAbi: boolArg('split-per-abi'),
+      targetArchs: stringsArg('target-platform').map<AndroidArch>(getAndroidArchForName),
+      shrink: boolArg('shrink'),
     );
 
     if (buildInfo.isRelease && !androidBuildInfo.splitPerAbi && androidBuildInfo.targetArchs.length > 1) {
-      final String targetPlatforms = argResults['target-platform'].join(', ');
+      final String targetPlatforms = stringsArg('target-platform').join(', ');
 
       printStatus('You are building a fat APK that includes binaries for '
                   '$targetPlatforms.', emphasis: true, color: TerminalColor.green);
diff --git a/packages/flutter_tools/lib/src/commands/build_appbundle.dart b/packages/flutter_tools/lib/src/commands/build_appbundle.dart
index 802c180..b7f9a8d 100644
--- a/packages/flutter_tools/lib/src/commands/build_appbundle.dart
+++ b/packages/flutter_tools/lib/src/commands/build_appbundle.dart
@@ -53,13 +53,13 @@
     final Map<CustomDimensions, String> usage = <CustomDimensions, String>{};
 
     usage[CustomDimensions.commandBuildAppBundleTargetPlatform] =
-        (argResults['target-platform'] as List<String>).join(',');
+        stringsArg('target-platform').join(',');
 
-    if (argResults['release']) {
+    if (boolArg('release')) {
       usage[CustomDimensions.commandBuildAppBundleBuildMode] = 'release';
-    } else if (argResults['debug']) {
+    } else if (boolArg('debug')) {
       usage[CustomDimensions.commandBuildAppBundleBuildMode] = 'debug';
-    } else if (argResults['profile']) {
+    } else if (boolArg('profile')) {
       usage[CustomDimensions.commandBuildAppBundleBuildMode] = 'profile';
     } else {
       // The build defaults to release.
@@ -71,8 +71,8 @@
   @override
   Future<FlutterCommandResult> runCommand() async {
     final AndroidBuildInfo androidBuildInfo = AndroidBuildInfo(getBuildInfo(),
-      targetArchs: argResults['target-platform'].map<AndroidArch>(getAndroidArchForName),
-      shrink: argResults['shrink'],
+      targetArchs: stringsArg('target-platform').map<AndroidArch>(getAndroidArchForName),
+      shrink: boolArg('shrink'),
     );
     await androidBuilder.buildAab(
       project: FlutterProject.current(),
diff --git a/packages/flutter_tools/lib/src/commands/build_bundle.dart b/packages/flutter_tools/lib/src/commands/build_bundle.dart
index 72e9be5..1edf8e3 100644
--- a/packages/flutter_tools/lib/src/commands/build_bundle.dart
+++ b/packages/flutter_tools/lib/src/commands/build_bundle.dart
@@ -88,14 +88,14 @@
       return const <CustomDimensions, String>{};
     }
     return <CustomDimensions, String>{
-      CustomDimensions.commandBuildBundleTargetPlatform: argResults['target-platform'],
+      CustomDimensions.commandBuildBundleTargetPlatform: stringArg('target-platform'),
       CustomDimensions.commandBuildBundleIsModule: '${futterProject.isModule}',
     };
   }
 
   @override
   Future<FlutterCommandResult> runCommand() async {
-    final String targetPlatform = argResults['target-platform'];
+    final String targetPlatform = stringArg('target-platform');
     final TargetPlatform platform = getTargetPlatformForName(targetPlatform);
     if (platform == null) {
       throwToolExit('Unknown platform: $targetPlatform');
@@ -127,17 +127,17 @@
       platform: platform,
       buildMode: buildMode,
       mainPath: targetFile,
-      manifestPath: argResults['manifest'],
-      depfilePath: argResults['depfile'],
-      privateKeyPath: argResults['private-key'],
-      assetDirPath: argResults['asset-dir'],
-      precompiledSnapshot: argResults['precompiled'],
-      reportLicensedPackages: argResults['report-licensed-packages'],
-      trackWidgetCreation: argResults['track-widget-creation'],
-      extraFrontEndOptions: argResults[FlutterOptions.kExtraFrontEndOptions],
-      extraGenSnapshotOptions: argResults[FlutterOptions.kExtraGenSnapshotOptions],
-      fileSystemScheme: argResults['filesystem-scheme'],
-      fileSystemRoots: argResults['filesystem-root'],
+      manifestPath: stringArg('manifest'),
+      depfilePath: stringArg('depfile'),
+      privateKeyPath: stringArg('private-key'),
+      assetDirPath: stringArg('asset-dir'),
+      precompiledSnapshot: boolArg('precompiled'),
+      reportLicensedPackages: boolArg('report-licensed-packages'),
+      trackWidgetCreation: boolArg('track-widget-creation'),
+      extraFrontEndOptions: stringsArg(FlutterOptions.kExtraFrontEndOptions),
+      extraGenSnapshotOptions: stringsArg(FlutterOptions.kExtraGenSnapshotOptions),
+      fileSystemScheme: stringArg('filesystem-scheme'),
+      fileSystemRoots: stringsArg('filesystem-root'),
     );
     return null;
   }
diff --git a/packages/flutter_tools/lib/src/commands/build_fuchsia.dart b/packages/flutter_tools/lib/src/commands/build_fuchsia.dart
index 665fbc3..18b93e1 100644
--- a/packages/flutter_tools/lib/src/commands/build_fuchsia.dart
+++ b/packages/flutter_tools/lib/src/commands/build_fuchsia.dart
@@ -70,7 +70,7 @@
       fuchsiaProject: flutterProject.fuchsia,
       target: targetFile,
       buildInfo: buildInfo,
-      runnerPackageSource: argResults['runner-source'],
+      runnerPackageSource: stringArg('runner-source'),
     );
     return null;
   }
diff --git a/packages/flutter_tools/lib/src/commands/build_ios.dart b/packages/flutter_tools/lib/src/commands/build_ios.dart
index b49a938..4a1ed9d 100644
--- a/packages/flutter_tools/lib/src/commands/build_ios.dart
+++ b/packages/flutter_tools/lib/src/commands/build_ios.dart
@@ -60,20 +60,20 @@
 
   @override
   Future<FlutterCommandResult> runCommand() async {
-    final bool forSimulator = argResults['simulator'];
+    final bool forSimulator = boolArg('simulator');
     defaultBuildMode = forSimulator ? BuildMode.debug : BuildMode.release;
 
     if (!platform.isMacOS) {
       throwToolExit('Building for iOS is only supported on the Mac.');
     }
 
-    final BuildableIOSApp app = await applicationPackages.getPackageForPlatform(TargetPlatform.ios);
+    final BuildableIOSApp app = await applicationPackages.getPackageForPlatform(TargetPlatform.ios) as BuildableIOSApp;
 
     if (app == null) {
       throwToolExit('Application not configured for iOS');
     }
 
-    final bool shouldCodesign = argResults['codesign'];
+    final bool shouldCodesign = boolArg('codesign');
 
     if (!forSimulator && !shouldCodesign) {
       printStatus('Warning: Building for device with codesigning disabled. You will '
diff --git a/packages/flutter_tools/lib/src/commands/build_ios_framework.dart b/packages/flutter_tools/lib/src/commands/build_ios_framework.dart
index de1b5df..aeaa0a5 100644
--- a/packages/flutter_tools/lib/src/commands/build_ios_framework.dart
+++ b/packages/flutter_tools/lib/src/commands/build_ios_framework.dart
@@ -94,13 +94,13 @@
   List<BuildMode> get buildModes {
     final List<BuildMode> buildModes = <BuildMode>[];
 
-    if (argResults['debug']) {
+    if (boolArg('debug')) {
       buildModes.add(BuildMode.debug);
     }
-    if (argResults['profile']) {
+    if (boolArg('profile')) {
       buildModes.add(BuildMode.profile);
     }
-    if (argResults['release']) {
+    if (boolArg('release')) {
       buildModes.add(BuildMode.release);
     }
 
@@ -119,10 +119,10 @@
       throwToolExit('Building frameworks for iOS is only supported on the Mac.');
     }
 
-    if (!argResults['universal'] && !argResults['xcframework']) {
+    if (!boolArg('universal') && !boolArg('xcframework')) {
       throwToolExit('--universal or --xcframework is required.');
     }
-    if (argResults['xcframework'] && xcode.majorVersion < 11) {
+    if (boolArg('xcframework') && xcode.majorVersion < 11) {
       throwToolExit('--xcframework requires Xcode 11.');
     }
     if (buildModes.isEmpty) {
@@ -134,14 +134,14 @@
   Future<FlutterCommandResult> runCommand() async {
     Cache.releaseLockEarly();
 
-    final String outputArgument = argResults['output']
+    final String outputArgument = stringArg('output')
         ?? fs.path.join(fs.currentDirectory.path, 'build', 'ios', 'framework');
 
     if (outputArgument.isEmpty) {
       throwToolExit('--output is required.');
     }
 
-    final BuildableIOSApp iosProject = await applicationPackages.getPackageForPlatform(TargetPlatform.ios);
+    final BuildableIOSApp iosProject = await applicationPackages.getPackageForPlatform(TargetPlatform.ios) as BuildableIOSApp;
 
     if (iosProject == null) {
       throwToolExit("Module's iOS folder missing");
@@ -201,7 +201,7 @@
     final Directory fatFlutterFrameworkCopy = modeDirectory.childDirectory(flutterFrameworkFileName);
     copyDirectorySync(fs.directory(engineCacheFlutterFrameworkDirectory), fatFlutterFrameworkCopy);
 
-    if (argResults['xcframework']) {
+    if (boolArg('xcframework')) {
       // Copy universal framework to variant directory.
       final Directory armFlutterFrameworkDirectory = iPhoneBuildOutput.childDirectory(flutterFrameworkFileName);
       final File armFlutterFrameworkBinary = armFlutterFrameworkDirectory.childFile('Flutter');
@@ -249,7 +249,7 @@
       );
     }
 
-    if (!argResults['universal']) {
+    if (!boolArg('universal')) {
       fatFlutterFrameworkCopy.deleteSync(recursive: true);
     }
     status.stop();
@@ -359,8 +359,8 @@
         final String podFrameworkName = podProduct.basename;
         if (fs.path.extension(podFrameworkName) == '.framework') {
           final String binaryName = fs.path.basenameWithoutExtension(podFrameworkName);
-          if (argResults['universal']) {
-            copyDirectorySync(podProduct, modeDirectory.childDirectory(podFrameworkName));
+          if (boolArg('universal')) {
+            copyDirectorySync(podProduct as Directory, modeDirectory.childDirectory(podFrameworkName));
             final List<String> lipoCommand = <String>[
               'xcrun',
               'lipo',
@@ -378,7 +378,7 @@
             );
           }
 
-          if (argResults['xcframework']) {
+          if (boolArg('xcframework')) {
             final List<String> xcframeworkCommand = <String>[
               'xcrun',
               'xcodebuild',
diff --git a/packages/flutter_tools/lib/src/commands/build_web.dart b/packages/flutter_tools/lib/src/commands/build_web.dart
index 60b5863..4ea8189 100644
--- a/packages/flutter_tools/lib/src/commands/build_web.dart
+++ b/packages/flutter_tools/lib/src/commands/build_web.dart
@@ -49,7 +49,7 @@
       throwToolExit('"build web" is not currently supported.');
     }
     final FlutterProject flutterProject = FlutterProject.current();
-    final String target = argResults['target'];
+    final String target = stringArg('target');
     final BuildInfo buildInfo = getBuildInfo();
     if (buildInfo.isDebug) {
       throwToolExit('debug builds cannot be built directly for the web. Try using "flutter run"');
@@ -58,7 +58,7 @@
       flutterProject,
       target,
       buildInfo,
-      argResults['web-initialize-platform'],
+      boolArg('web-initialize-platform'),
       dartDefines,
     );
     return null;
diff --git a/packages/flutter_tools/lib/src/commands/channel.dart b/packages/flutter_tools/lib/src/commands/channel.dart
index e52174e..284b6d8 100644
--- a/packages/flutter_tools/lib/src/commands/channel.dart
+++ b/packages/flutter_tools/lib/src/commands/channel.dart
@@ -39,8 +39,8 @@
     switch (argResults.rest.length) {
       case 0:
         await _listChannels(
-          showAll: argResults['all'],
-          verbose: globalResults['verbose'],
+          showAll: boolArg('all'),
+          verbose: globalResults['verbose'] as bool,
         );
         return null;
       case 1:
diff --git a/packages/flutter_tools/lib/src/commands/config.dart b/packages/flutter_tools/lib/src/commands/config.dart
index 02895d8..06653d3 100644
--- a/packages/flutter_tools/lib/src/commands/config.dart
+++ b/packages/flutter_tools/lib/src/commands/config.dart
@@ -100,12 +100,12 @@
 
   @override
   Future<FlutterCommandResult> runCommand() async {
-    if (argResults['machine']) {
+    if (boolArg('machine')) {
       await handleMachine();
       return null;
     }
 
-    if (argResults['clear-features']) {
+    if (boolArg('clear-features')) {
       for (Feature feature in allFeatures) {
         if (feature.configSetting != null) {
           config.removeValue(feature.configSetting);
@@ -115,18 +115,18 @@
     }
 
     if (argResults.wasParsed('analytics')) {
-      final bool value = argResults['analytics'];
+      final bool value = boolArg('analytics');
       flutterUsage.enabled = value;
       AnalyticsConfigEvent(enabled: value).send();
       printStatus('Analytics reporting ${value ? 'enabled' : 'disabled'}.');
     }
 
     if (argResults.wasParsed('android-sdk')) {
-      _updateConfig('android-sdk', argResults['android-sdk']);
+      _updateConfig('android-sdk', stringArg('android-sdk'));
     }
 
     if (argResults.wasParsed('android-studio-dir')) {
-      _updateConfig('android-studio-dir', argResults['android-studio-dir']);
+      _updateConfig('android-studio-dir', stringArg('android-studio-dir'));
     }
 
     if (argResults.wasParsed('clear-ios-signing-cert')) {
@@ -134,7 +134,7 @@
     }
 
     if (argResults.wasParsed('build-dir')) {
-      final String buildDir = argResults['build-dir'];
+      final String buildDir = stringArg('build-dir');
       if (fs.path.isAbsolute(buildDir)) {
         throwToolExit('build-dir should be a relative path');
       }
@@ -146,7 +146,7 @@
         continue;
       }
       if (argResults.wasParsed(feature.configSetting)) {
-        final bool keyValue = argResults[feature.configSetting];
+        final bool keyValue = boolArg(feature.configSetting);
         config.setValue(feature.configSetting, keyValue);
         printStatus('Setting "${feature.configSetting}" value to "$keyValue".');
       }
diff --git a/packages/flutter_tools/lib/src/commands/create.dart b/packages/flutter_tools/lib/src/commands/create.dart
index 7462a4a..aefbaf3 100644
--- a/packages/flutter_tools/lib/src/commands/create.dart
+++ b/packages/flutter_tools/lib/src/commands/create.dart
@@ -177,9 +177,9 @@
   @override
   Future<Map<CustomDimensions, String>> get usageValues async {
     return <CustomDimensions, String>{
-      CustomDimensions.commandCreateProjectType: argResults['template'],
-      CustomDimensions.commandCreateAndroidLanguage: argResults['android-language'],
-      CustomDimensions.commandCreateIosLanguage: argResults['ios-language'],
+      CustomDimensions.commandCreateProjectType: stringArg('template'),
+      CustomDimensions.commandCreateAndroidLanguage: stringArg('android-language'),
+      CustomDimensions.commandCreateIosLanguage: stringArg('ios-language'),
     };
   }
 
@@ -197,7 +197,13 @@
       if (!metadataFile.existsSync()) {
         return null;
       }
-      return yaml.loadYaml(metadataFile.readAsStringSync());
+      final dynamic metadataYaml = yaml.loadYaml(metadataFile.readAsStringSync());
+      if (metadataYaml is yaml.YamlMap) {
+        return metadataYaml;
+      } else {
+        throwToolExit('pubspec.yaml is malformed.');
+        return null;
+      }
     }
 
     bool exists(List<String> path) {
@@ -207,7 +213,13 @@
     // If it exists, the project type in the metadata is definitive.
     final yaml.YamlMap metadata = loadMetadata(projectDir);
     if (metadata != null && metadata['project_type'] != null) {
-      return _stringToProjectType(metadata['project_type']);
+      final dynamic projectType = metadata['project_type'];
+      if (projectType is String) {
+        return _stringToProjectType(projectType);
+      } else {
+        throwToolExit('.metadata is malformed.');
+        return null;
+      }
     }
 
     // There either wasn't any metadata, or it didn't contain the project type,
@@ -270,7 +282,7 @@
     _ProjectType detectedProjectType;
     final bool metadataExists = projectDir.absolute.childFile('.metadata').existsSync();
     if (argResults['template'] != null) {
-      template = _stringToProjectType(argResults['template']);
+      template = _stringToProjectType(stringArg('template'));
     } else {
       // If the project directory exists and isn't empty, then try to determine the template
       // type from the project directory.
@@ -301,7 +313,7 @@
       // _writeSamplesJson can potentially be long-lived.
       Cache.releaseLockEarly();
 
-      await _writeSamplesJson(argResults['list-samples']);
+      await _writeSamplesJson(stringArg('list-samples'));
       return null;
     }
 
@@ -346,12 +358,12 @@
     String sampleCode;
     if (argResults['sample'] != null) {
       if (argResults['template'] != null &&
-        _stringToProjectType(argResults['template'] ?? 'app') != _ProjectType.app) {
+        _stringToProjectType(stringArg('template') ?? 'app') != _ProjectType.app) {
         throwToolExit('Cannot specify --sample with a project type other than '
           '"${getEnumName(_ProjectType.app)}"');
       }
       // Fetch the sample from the server.
-      sampleCode = await _fetchSampleFromServer(argResults['sample']);
+      sampleCode = await _fetchSampleFromServer(stringArg('sample'));
     }
 
     final _ProjectType template = _getProjectType(projectDir);
@@ -359,7 +371,7 @@
     final bool generatePlugin = template == _ProjectType.plugin;
     final bool generatePackage = template == _ProjectType.package;
 
-    String organization = argResults['org'];
+    String organization = stringArg('org');
     if (!argResults.wasParsed('org')) {
       final FlutterProject project = FlutterProject.fromDirectory(projectDir);
       final Set<String> existingOrganizations = await project.organizationNames;
@@ -373,12 +385,13 @@
       }
     }
 
-    String error = _validateProjectDir(projectDirPath, flutterRoot: flutterRoot, overwrite: argResults['overwrite']);
+    final bool overwrite = boolArg('overwrite');
+    String error = _validateProjectDir(projectDirPath, flutterRoot: flutterRoot, overwrite: overwrite);
     if (error != null) {
       throwToolExit(error);
     }
 
-    final String projectName = argResults['project-name'] ?? fs.path.basename(projectDirPath);
+    final String projectName = stringArg('project-name') ?? fs.path.basename(projectDirPath);
     error = _validateProjectName(projectName);
     if (error != null) {
       throwToolExit(error);
@@ -387,22 +400,22 @@
     final Map<String, dynamic> templateContext = _templateContext(
       organization: organization,
       projectName: projectName,
-      projectDescription: argResults['description'],
+      projectDescription: stringArg('description'),
       flutterRoot: flutterRoot,
-      renderDriverTest: argResults['with-driver-test'],
+      renderDriverTest: boolArg('with-driver-test'),
       withPluginHook: generatePlugin,
-      androidX: argResults['androidx'],
-      androidLanguage: argResults['android-language'],
-      iosLanguage: argResults['ios-language'],
+      androidX: boolArg('androidx'),
+      androidLanguage: stringArg('android-language'),
+      iosLanguage: stringArg('ios-language'),
       web: featureFlags.isWebEnabled,
-      macos: argResults['macos'],
+      macos: boolArg('macos'),
     );
 
     final String relativeDirPath = fs.path.relative(projectDirPath);
     if (!projectDir.existsSync() || projectDir.listSync().isEmpty) {
-      printStatus('Creating project $relativeDirPath... androidx: ${argResults['androidx']}');
+      printStatus('Creating project $relativeDirPath... androidx: ${boolArg('androidx')}');
     } else {
-      if (sampleCode != null && !argResults['overwrite']) {
+      if (sampleCode != null && !overwrite) {
         throwToolExit('Will not overwrite existing project in $relativeDirPath: '
           'must specify --overwrite for samples to overwrite.');
       }
@@ -413,16 +426,16 @@
     int generatedFileCount = 0;
     switch (template) {
       case _ProjectType.app:
-        generatedFileCount += await _generateApp(relativeDir, templateContext, overwrite: argResults['overwrite']);
+        generatedFileCount += await _generateApp(relativeDir, templateContext, overwrite: overwrite);
         break;
       case _ProjectType.module:
-        generatedFileCount += await _generateModule(relativeDir, templateContext, overwrite: argResults['overwrite']);
+        generatedFileCount += await _generateModule(relativeDir, templateContext, overwrite: overwrite);
         break;
       case _ProjectType.package:
-        generatedFileCount += await _generatePackage(relativeDir, templateContext, overwrite: argResults['overwrite']);
+        generatedFileCount += await _generatePackage(relativeDir, templateContext, overwrite: overwrite);
         break;
       case _ProjectType.plugin:
-        generatedFileCount += await _generatePlugin(relativeDir, templateContext, overwrite: argResults['overwrite']);
+        generatedFileCount += await _generatePlugin(relativeDir, templateContext, overwrite: overwrite);
         break;
     }
     if (sampleCode != null) {
@@ -495,15 +508,15 @@
   Future<int> _generateModule(Directory directory, Map<String, dynamic> templateContext, { bool overwrite = false }) async {
     int generatedCount = 0;
     final String description = argResults.wasParsed('description')
-        ? argResults['description']
+        ? stringArg('description')
         : 'A new flutter module project.';
     templateContext['description'] = description;
     generatedCount += _renderTemplate(fs.path.join('module', 'common'), directory, templateContext, overwrite: overwrite);
-    if (argResults['pub']) {
+    if (boolArg('pub')) {
       await pub.get(
         context: PubContext.create,
         directory: directory.path,
-        offline: argResults['offline'],
+        offline: boolArg('offline'),
       );
       final FlutterProject project = FlutterProject.fromDirectory(directory);
       await project.ensureReadyForPlatformSpecificTooling(checkProjects: false);
@@ -514,15 +527,15 @@
   Future<int> _generatePackage(Directory directory, Map<String, dynamic> templateContext, { bool overwrite = false }) async {
     int generatedCount = 0;
     final String description = argResults.wasParsed('description')
-        ? argResults['description']
+        ? stringArg('description')
         : 'A new Flutter package project.';
     templateContext['description'] = description;
     generatedCount += _renderTemplate('package', directory, templateContext, overwrite: overwrite);
-    if (argResults['pub']) {
+    if (boolArg('pub')) {
       await pub.get(
         context: PubContext.createPackage,
         directory: directory.path,
-        offline: argResults['offline'],
+        offline: boolArg('offline'),
       );
     }
     return generatedCount;
@@ -531,23 +544,23 @@
   Future<int> _generatePlugin(Directory directory, Map<String, dynamic> templateContext, { bool overwrite = false }) async {
     int generatedCount = 0;
     final String description = argResults.wasParsed('description')
-        ? argResults['description']
+        ? stringArg('description')
         : 'A new flutter plugin project.';
     templateContext['description'] = description;
     generatedCount += _renderTemplate('plugin', directory, templateContext, overwrite: overwrite);
-    if (argResults['pub']) {
+    if (boolArg('pub')) {
       await pub.get(
         context: PubContext.createPlugin,
         directory: directory.path,
-        offline: argResults['offline'],
+        offline: boolArg('offline'),
       );
     }
     final FlutterProject project = FlutterProject.fromDirectory(directory);
     gradle.updateLocalProperties(project: project, requireAndroidSdk: false);
 
-    final String projectName = templateContext['projectName'];
-    final String organization = templateContext['organization'];
-    final String androidPluginIdentifier = templateContext['androidIdentifier'];
+    final String projectName = templateContext['projectName'] as String;
+    final String organization = templateContext['organization'] as String;
+    final String androidPluginIdentifier = templateContext['androidIdentifier'] as String;
     final String exampleProjectName = projectName + '_example';
     templateContext['projectName'] = exampleProjectName;
     templateContext['androidIdentifier'] = _createAndroidIdentifier(organization, exampleProjectName);
@@ -566,13 +579,13 @@
     final FlutterProject project = FlutterProject.fromDirectory(directory);
     generatedCount += _injectGradleWrapper(project);
 
-    if (argResults['with-driver-test']) {
+    if (boolArg('with-driver-test')) {
       final Directory testDirectory = directory.childDirectory('test_driver');
       generatedCount += _renderTemplate('driver', testDirectory, templateContext, overwrite: overwrite);
     }
 
-    if (argResults['pub']) {
-      await pub.get(context: PubContext.create, directory: directory.path, offline: argResults['offline']);
+    if (boolArg('pub')) {
+      await pub.get(context: PubContext.create, directory: directory.path, offline: boolArg('offline'));
       await project.ensureReadyForPlatformSpecificTooling(checkProjects: false);
     }
 
diff --git a/packages/flutter_tools/lib/src/commands/daemon.dart b/packages/flutter_tools/lib/src/commands/daemon.dart
index 95203b0..8c5d6e4 100644
--- a/packages/flutter_tools/lib/src/commands/daemon.dart
+++ b/packages/flutter_tools/lib/src/commands/daemon.dart
@@ -135,7 +135,7 @@
     }
 
     try {
-      final String method = request['method'];
+      final String method = request['method'] as String;
       if (!method.contains('.')) {
         throw 'method not understood: $method';
       }
@@ -146,7 +146,7 @@
         throw 'no domain for method: $method';
       }
 
-      _domainMap[prefix].handleCommand(name, id, request['params'] ?? const <String, dynamic>{});
+      _domainMap[prefix].handleCommand(name, id, castStringKeyedMap(request['params']) ?? const <String, dynamic>{});
     } catch (error, trace) {
       _send(<String, dynamic>{
         'id': id,
@@ -228,7 +228,7 @@
     if (val != null && val is! String) {
       throw '$name is not a String';
     }
-    return val;
+    return val as String;
   }
 
   bool _getBoolArg(Map<String, dynamic> args, String name, { bool required = false }) {
@@ -239,7 +239,7 @@
     if (val != null && val is! bool) {
       throw '$name is not a bool';
     }
-    return val;
+    return val as bool;
   }
 
   int _getIntArg(Map<String, dynamic> args, String name, { bool required = false }) {
@@ -250,7 +250,7 @@
     if (val != null && val is! int) {
       throw '$name is not an int';
     }
-    return val;
+    return val as int;
   }
 
   void dispose() { }
@@ -681,8 +681,8 @@
       return;
     }
 
-    _discoverers.add(discoverer);
     if (discoverer is PollingDeviceDiscovery) {
+      _discoverers.add(discoverer);
       discoverer.onAdded.listen(_onDeviceEvent('device.added'));
       discoverer.onRemoved.listen(_onDeviceEvent('device.removed'));
     }
@@ -786,7 +786,7 @@
   .where((String line) => line.startsWith('[{') && line.endsWith('}]'))
   .map<Map<String, dynamic>>((String line) {
     line = line.substring(1, line.length - 1);
-    return json.decode(line);
+    return castStringKeyedMap(json.decode(line));
   });
 
 void stdoutCommandResponse(Map<String, dynamic> command) {
@@ -924,7 +924,7 @@
     _logger.close();
   }
 
-  Future<T> _runInZone<T>(AppDomain domain, dynamic method()) {
+  Future<T> _runInZone<T>(AppDomain domain, FutureOr<T> method()) {
     _logger ??= _AppRunLogger(domain, this, parent: logToStdout ? logger : null);
 
     return context.run<T>(
diff --git a/packages/flutter_tools/lib/src/commands/doctor.dart b/packages/flutter_tools/lib/src/commands/doctor.dart
index 7a3f06e..20670e9 100644
--- a/packages/flutter_tools/lib/src/commands/doctor.dart
+++ b/packages/flutter_tools/lib/src/commands/doctor.dart
@@ -44,7 +44,7 @@
   @override
   Future<FlutterCommandResult> runCommand() async {
     if (argResults.wasParsed('check-for-remote-artifacts')) {
-      final String engineRevision = argResults['check-for-remote-artifacts'];
+      final String engineRevision = stringArg('check-for-remote-artifacts');
       if (engineRevision.startsWith(RegExp(r'[a-f0-9]{1,40}'))) {
         final bool success = await doctor.checkRemoteArtifacts(engineRevision);
         if (!success) {
@@ -56,7 +56,7 @@
             'git hash.');
       }
     }
-    final bool success = await doctor.diagnose(androidLicenses: argResults['android-licenses'], verbose: verbose);
+    final bool success = await doctor.diagnose(androidLicenses: boolArg('android-licenses'), verbose: verbose);
     return FlutterCommandResult(success ? ExitStatus.success : ExitStatus.warning);
   }
 }
diff --git a/packages/flutter_tools/lib/src/commands/drive.dart b/packages/flutter_tools/lib/src/commands/drive.dart
index 680a817..c47c6db 100644
--- a/packages/flutter_tools/lib/src/commands/drive.dart
+++ b/packages/flutter_tools/lib/src/commands/drive.dart
@@ -83,9 +83,9 @@
 
   Device _device;
   Device get device => _device;
-  bool get shouldBuild => argResults['build'];
+  bool get shouldBuild => boolArg('build');
 
-  bool get verboseSystemLogs => argResults['verbose-system-logs'];
+  bool get verboseSystemLogs => boolArg('verbose-system-logs');
 
   /// Subscription to log messages printed on the device or simulator.
   // ignore: cancel_subscriptions
@@ -128,7 +128,7 @@
       observatoryUri = result.observatoryUri.toString();
     } else {
       printStatus('Will connect to already running application instance.');
-      observatoryUri = argResults['use-existing-app'];
+      observatoryUri = stringArg('use-existing-app');
     }
 
     Cache.releaseLockEarly();
@@ -141,7 +141,7 @@
       }
       throwToolExit('CAUGHT EXCEPTION: $error\n$stackTrace');
     } finally {
-      if (argResults['keep-app-running'] ?? (argResults['use-existing-app'] != null)) {
+      if (boolArg('keep-app-running') ?? (argResults['use-existing-app'] != null)) {
         printStatus('Leaving the application running.');
       } else {
         printStatus('Stopping application instance.');
@@ -154,7 +154,7 @@
 
   String _getTestFile() {
     if (argResults['driver'] != null) {
-      return argResults['driver'];
+      return stringArg('driver');
     }
 
     // If the --driver argument wasn't provided, then derive the value from
diff --git a/packages/flutter_tools/lib/src/commands/emulators.dart b/packages/flutter_tools/lib/src/commands/emulators.dart
index 53492a2..3fe26a1 100644
--- a/packages/flutter_tools/lib/src/commands/emulators.dart
+++ b/packages/flutter_tools/lib/src/commands/emulators.dart
@@ -44,9 +44,9 @@
     }
 
     if (argResults.wasParsed('launch')) {
-      await _launchEmulator(argResults['launch']);
+      await _launchEmulator(stringArg('launch'));
     } else if (argResults.wasParsed('create')) {
-      await _createEmulator(name: argResults['name']);
+      await _createEmulator(name: stringArg('name'));
     } else {
       final String searchText =
           argResults.rest != null && argResults.rest.isNotEmpty
diff --git a/packages/flutter_tools/lib/src/commands/format.dart b/packages/flutter_tools/lib/src/commands/format.dart
index 24a1511..66fd400 100644
--- a/packages/flutter_tools/lib/src/commands/format.dart
+++ b/packages/flutter_tools/lib/src/commands/format.dart
@@ -68,11 +68,11 @@
     final String dartfmt = sdkBinaryName('dartfmt');
     final List<String> command = <String>[
       dartfmt,
-      if (argResults['dry-run']) '-n',
-      if (argResults['machine']) '-m',
+      if (boolArg('dry-run')) '-n',
+      if (boolArg('machine')) '-m',
       if (argResults['line-length'] != null) '-l ${argResults['line-length']}',
-      if (!argResults['dry-run'] && !argResults['machine']) '-w',
-      if (argResults['set-exit-if-changed']) '--set-exit-if-changed',
+      if (!boolArg('dry-run') && !boolArg('machine')) '-w',
+      if (boolArg('set-exit-if-changed')) '--set-exit-if-changed',
       ...argResults.rest,
     ];
 
diff --git a/packages/flutter_tools/lib/src/commands/generate.dart b/packages/flutter_tools/lib/src/commands/generate.dart
index 5426d37..6dba59f 100644
--- a/packages/flutter_tools/lib/src/commands/generate.dart
+++ b/packages/flutter_tools/lib/src/commands/generate.dart
@@ -42,8 +42,8 @@
     }
     // Check for errors output in the build_runner cache.
     final Directory buildDirectory = flutterProject.dartTool.childDirectory('build');
-    final Directory errorCacheParent = buildDirectory.listSync().firstWhere((FileSystemEntity entity) {
-      return entity is Directory && entity.childDirectory('error_cache').existsSync();
+    final Directory errorCacheParent = buildDirectory.listSync().whereType<Directory>().firstWhere((Directory dir) {
+      return dir.childDirectory('error_cache').existsSync();
     }, orElse: () => null);
     if (errorCacheParent == null) {
       return null;
@@ -51,12 +51,12 @@
     final Directory errorCache = errorCacheParent.childDirectory('error_cache');
     for (File errorFile in errorCache.listSync(recursive: true).whereType<File>()) {
       try {
-        final List<Object> errorData = json.decode(errorFile.readAsStringSync());
-        final List<Object> stackData = errorData[1];
-        printError(errorData.first);
-        printError(stackData[0]);
-        printError(stackData[1]);
-        printError(StackTrace.fromString(stackData[2]).toString());
+        final List<Object> errorData = json.decode(errorFile.readAsStringSync()) as List<Object>;
+        final List<Object> stackData = errorData[1] as List<Object>;
+        printError(errorData.first as String);
+        printError(stackData[0] as String);
+        printError(stackData[1] as String);
+        printError(StackTrace.fromString(stackData[2] as String).toString());
       } catch (err) {
         printError('Error reading error in ${errorFile.path}');
       }
diff --git a/packages/flutter_tools/lib/src/commands/ide_config.dart b/packages/flutter_tools/lib/src/commands/ide_config.dart
index ad10340..9b05dba 100644
--- a/packages/flutter_tools/lib/src/commands/ide_config.dart
+++ b/packages/flutter_tools/lib/src/commands/ide_config.dart
@@ -125,14 +125,9 @@
     }
 
     final Set<String> manifest = <String>{};
-    final List<FileSystemEntity> flutterFiles = _flutterRoot.listSync(recursive: true);
-    for (FileSystemEntity entity in flutterFiles) {
-      final String relativePath = fs.path.relative(entity.path, from: _flutterRoot.absolute.path);
-      if (entity is! File) {
-        continue;
-      }
-
-      final File srcFile = entity;
+    final Iterable<File> flutterFiles = _flutterRoot.listSync(recursive: true).whereType<File>();
+    for (File srcFile in flutterFiles) {
+      final String relativePath = fs.path.relative(srcFile.path, from: _flutterRoot.absolute.path);
 
       // Skip template files in both the ide_templates and templates
       // directories to avoid copying onto themselves.
@@ -163,7 +158,7 @@
           manifest.add('$relativePath${Template.copyTemplateExtension}');
           continue;
         }
-        if (argResults['overwrite']) {
+        if (boolArg('overwrite')) {
           finalDestinationFile.deleteSync();
           printStatus('  $relativeDestination (overwritten)');
         } else {
@@ -184,18 +179,14 @@
     }
 
     // If we're not overwriting, then we're not going to remove missing items either.
-    if (!argResults['overwrite']) {
+    if (!boolArg('overwrite')) {
       return;
     }
 
     // Look for any files under the template dir that don't exist in the manifest and remove
     // them.
-    final List<FileSystemEntity> templateFiles = _templateDirectory.listSync(recursive: true);
-    for (FileSystemEntity entity in templateFiles) {
-      if (entity is! File) {
-        continue;
-      }
-      final File templateFile = entity;
+    final Iterable<File> templateFiles = _templateDirectory.listSync(recursive: true).whereType<File>();
+    for (File templateFile in templateFiles) {
       final String relativePath = fs.path.relative(
         templateFile.absolute.path,
         from: _templateDirectory.absolute.path,
@@ -228,7 +219,7 @@
 
     await Cache.instance.updateAll(<DevelopmentArtifact>{ DevelopmentArtifact.universal });
 
-    if (argResults['update-templates']) {
+    if (boolArg('update-templates')) {
       _handleTemplateUpdate();
       return null;
     }
@@ -246,7 +237,7 @@
     printStatus('Updating IDE configuration for Flutter tree at $dirPath...');
     int generatedCount = 0;
     generatedCount += _renderTemplate(_ideName, dirPath, <String, dynamic>{
-      'withRootModule': argResults['with-root-module'],
+      'withRootModule': boolArg('with-root-module'),
     });
 
     printStatus('Wrote $generatedCount files.');
@@ -262,7 +253,7 @@
     return template.render(
       fs.directory(dirPath),
       context,
-      overwriteExisting: argResults['overwrite'],
+      overwriteExisting: boolArg('overwrite'),
     );
   }
 }
diff --git a/packages/flutter_tools/lib/src/commands/logs.dart b/packages/flutter_tools/lib/src/commands/logs.dart
index 503147c..4921ec7 100644
--- a/packages/flutter_tools/lib/src/commands/logs.dart
+++ b/packages/flutter_tools/lib/src/commands/logs.dart
@@ -42,7 +42,7 @@
 
   @override
   Future<FlutterCommandResult> runCommand() async {
-    if (argResults['clear']) {
+    if (boolArg('clear')) {
       device.clearLogs();
     }
 
diff --git a/packages/flutter_tools/lib/src/commands/make_host_app_editable.dart b/packages/flutter_tools/lib/src/commands/make_host_app_editable.dart
index 668c47f..7cf88b7 100644
--- a/packages/flutter_tools/lib/src/commands/make_host_app_editable.dart
+++ b/packages/flutter_tools/lib/src/commands/make_host_app_editable.dart
@@ -46,8 +46,8 @@
   Future<FlutterCommandResult> runCommand() async {
     await _project.ensureReadyForPlatformSpecificTooling(checkProjects: false);
 
-    final bool isAndroidRequested = argResults['android'];
-    final bool isIOSRequested = argResults['ios'];
+    final bool isAndroidRequested = boolArg('android');
+    final bool isIOSRequested = boolArg('ios');
 
     if (isAndroidRequested == isIOSRequested) {
       // No flags provided, or both flags provided. Make Android and iOS host
diff --git a/packages/flutter_tools/lib/src/commands/packages.dart b/packages/flutter_tools/lib/src/commands/packages.dart
index cf2689c..868a120 100644
--- a/packages/flutter_tools/lib/src/commands/packages.dart
+++ b/packages/flutter_tools/lib/src/commands/packages.dart
@@ -98,7 +98,7 @@
       await pub.get(context: PubContext.pubGet,
         directory: directory,
         upgrade: upgrade ,
-        offline: argResults['offline'],
+        offline: boolArg('offline'),
         checkLastModified: false,
       );
       pubGetTimer.stop();
@@ -203,8 +203,8 @@
   Future<FlutterCommandResult> runCommand() async {
     final List<String> args = <String>[
       ...argResults.rest,
-      if (argResults['dry-run']) '--dry-run',
-      if (argResults['force']) '--force',
+      if (boolArg('dry-run')) '--dry-run',
+      if (boolArg('force')) '--force',
     ];
     Cache.releaseLockEarly();
     await pub.interactively(<String>['publish', ...args]);
diff --git a/packages/flutter_tools/lib/src/commands/precache.dart b/packages/flutter_tools/lib/src/commands/precache.dart
index 0b145d6..49039b1 100644
--- a/packages/flutter_tools/lib/src/commands/precache.dart
+++ b/packages/flutter_tools/lib/src/commands/precache.dart
@@ -59,10 +59,10 @@
 
   @override
   Future<FlutterCommandResult> runCommand() async {
-    if (argResults['all-platforms']) {
+    if (boolArg('all-platforms')) {
       cache.includeAllPlatforms = true;
     }
-    if (argResults['use-unsigned-mac-binaries']) {
+    if (boolArg('use-unsigned-mac-binaries')) {
       cache.useUnsignedMacBinaries = true;
     }
     final Set<DevelopmentArtifact> requiredArtifacts = <DevelopmentArtifact>{};
@@ -74,15 +74,15 @@
       if (artifact.feature != null && !featureFlags.isEnabled(artifact.feature)) {
         continue;
       }
-      if (argResults[artifact.name]) {
+      if (boolArg(artifact.name)) {
         requiredArtifacts.add(artifact);
       }
       // The `android` flag expands to android_gen_snapshot, android_maven, android_internal_build.
-      if (artifact.name.startsWith('android_') && argResults['android']) {
+      if (artifact.name.startsWith('android_') && boolArg('android')) {
         requiredArtifacts.add(artifact);
       }
     }
-    final bool forceUpdate = argResults['force'];
+    final bool forceUpdate = boolArg('force');
     if (forceUpdate || !cache.isUpToDate()) {
       await cache.updateAll(requiredArtifacts);
     } else {
diff --git a/packages/flutter_tools/lib/src/commands/run.dart b/packages/flutter_tools/lib/src/commands/run.dart
index e87b586..aeafa6b 100644
--- a/packages/flutter_tools/lib/src/commands/run.dart
+++ b/packages/flutter_tools/lib/src/commands/run.dart
@@ -70,11 +70,11 @@
     usesIsolateFilterOption(hide: !verboseHelp);
   }
 
-  bool get traceStartup => argResults['trace-startup'];
-  bool get cacheSkSL => argResults['cache-sksl'];
-  bool get dumpSkpOnShaderCompilation => argResults['dump-skp-on-shader-compilation'];
+  bool get traceStartup => boolArg('trace-startup');
+  bool get cacheSkSL => boolArg('cache-sksl');
+  bool get dumpSkpOnShaderCompilation => boolArg('dump-skp-on-shader-compilation');
 
-  String get route => argResults['route'];
+  String get route => stringArg('route');
 }
 
 class RunCommand extends RunCommandBase {
@@ -266,7 +266,7 @@
   }
 
   bool shouldUseHotMode() {
-    final bool hotArg = argResults['hot'] ?? false;
+    final bool hotArg = boolArg('hot') ?? false;
     final bool shouldUseHotMode = hotArg && !traceStartup;
     return getBuildInfo().isDebug && shouldUseHotMode;
   }
@@ -274,8 +274,8 @@
   bool get runningWithPrebuiltApplication =>
       argResults['use-application-binary'] != null;
 
-  bool get stayResident => argResults['resident'];
-  bool get awaitFirstFrameWhenTracing => argResults['await-first-frame-when-tracing'];
+  bool get stayResident => boolArg('resident');
+  bool get awaitFirstFrameWhenTracing => boolArg('await-first-frame-when-tracing');
 
   @override
   Future<void> validateCommand() async {
@@ -298,31 +298,31 @@
     if (buildInfo.isRelease) {
       return DebuggingOptions.disabled(
         buildInfo,
-        initializePlatform: argResults['web-initialize-platform'],
-        hostname: featureFlags.isWebEnabled ? argResults['web-hostname'] : '',
-        port: featureFlags.isWebEnabled ? argResults['web-port'] : '',
+        initializePlatform: boolArg('web-initialize-platform'),
+        hostname: featureFlags.isWebEnabled ? stringArg('web-hostname') : '',
+        port: featureFlags.isWebEnabled ? stringArg('web-port') : '',
       );
     } else {
       return DebuggingOptions.enabled(
         buildInfo,
-        startPaused: argResults['start-paused'],
-        disableServiceAuthCodes: argResults['disable-service-auth-codes'],
-        dartFlags: argResults['dart-flags'] ?? '',
-        useTestFonts: argResults['use-test-fonts'],
-        enableSoftwareRendering: argResults['enable-software-rendering'],
-        skiaDeterministicRendering: argResults['skia-deterministic-rendering'],
-        traceSkia: argResults['trace-skia'],
-        traceSystrace: argResults['trace-systrace'],
+        startPaused: boolArg('start-paused'),
+        disableServiceAuthCodes: boolArg('disable-service-auth-codes'),
+        dartFlags: stringArg('dart-flags') ?? '',
+        useTestFonts: boolArg('use-test-fonts'),
+        enableSoftwareRendering: boolArg('enable-software-rendering'),
+        skiaDeterministicRendering: boolArg('skia-deterministic-rendering'),
+        traceSkia: boolArg('trace-skia'),
+        traceSystrace: boolArg('trace-systrace'),
         dumpSkpOnShaderCompilation: dumpSkpOnShaderCompilation,
         cacheSkSL: cacheSkSL,
         deviceVmServicePort: deviceVmservicePort,
         hostVmServicePort: hostVmservicePort,
-        verboseSystemLogs: argResults['verbose-system-logs'],
-        initializePlatform: argResults['web-initialize-platform'],
-        hostname: featureFlags.isWebEnabled ? argResults['web-hostname'] : '',
-        port: featureFlags.isWebEnabled ? argResults['web-port'] : '',
-        browserLaunch: featureFlags.isWebEnabled ? argResults['web-browser-launch'] : null,
-        vmserviceOutFile: argResults['vmservice-out-file'],
+        verboseSystemLogs: boolArg('verbose-system-logs'),
+        initializePlatform: boolArg('web-initialize-platform'),
+        hostname: featureFlags.isWebEnabled ? stringArg('web-hostname') : '',
+        port: featureFlags.isWebEnabled ? stringArg('web-port') : '',
+        browserLaunch: featureFlags.isWebEnabled ? boolArg('web-browser-launch') : null,
+        vmserviceOutFile: stringArg('vmservice-out-file'),
       );
     }
   }
@@ -335,9 +335,9 @@
     // debug mode.
     final bool hotMode = shouldUseHotMode();
 
-    writePidFile(argResults['pid-file']);
+    writePidFile(stringArg('pid-file'));
 
-    if (argResults['machine']) {
+    if (boolArg('machine')) {
       if (devices.length > 1) {
         throwToolExit('--machine does not support -d all.');
       }
@@ -345,17 +345,17 @@
           notifyingLogger: NotifyingLogger(), logToStdout: true);
       AppInstance app;
       try {
-        final String applicationBinaryPath = argResults['use-application-binary'];
+        final String applicationBinaryPath = stringArg('use-application-binary');
         app = await daemon.appDomain.startApp(
           devices.first, fs.currentDirectory.path, targetFile, route,
           _createDebuggingOptions(), hotMode,
           applicationBinary: applicationBinaryPath == null
               ? null
               : fs.file(applicationBinaryPath),
-          trackWidgetCreation: argResults['track-widget-creation'],
-          projectRootPath: argResults['project-root'],
-          packagesFilePath: globalResults['packages'],
-          dillOutputPath: argResults['output-dill'],
+          trackWidgetCreation: boolArg('track-widget-creation'),
+          projectRootPath: stringArg('project-root'),
+          packagesFilePath: globalResults['packages'] as String,
+          dillOutputPath: stringArg('output-dill'),
           ipv6: ipv6,
         );
       } catch (error) {
@@ -382,7 +382,7 @@
     for (Device device in devices) {
       if (await device.isLocalEmulator) {
         if (await device.supportsHardwareRendering) {
-          final bool enableSoftwareRendering = argResults['enable-software-rendering'] == true;
+          final bool enableSoftwareRendering = boolArg('enable-software-rendering') == true;
           if (enableSoftwareRendering) {
             printStatus(
               'Using software rendering with device ${device.name}. You may get better performance '
@@ -412,8 +412,8 @@
 
     List<String> expFlags;
     if (argParser.options.containsKey(FlutterOptions.kEnableExperiment) &&
-        argResults[FlutterOptions.kEnableExperiment].isNotEmpty) {
-      expFlags = argResults[FlutterOptions.kEnableExperiment];
+        stringsArg(FlutterOptions.kEnableExperiment).isNotEmpty) {
+      expFlags = stringsArg(FlutterOptions.kEnableExperiment);
     }
     final FlutterProject flutterProject = FlutterProject.current();
     final List<FlutterDevice> flutterDevices = <FlutterDevice>[
@@ -421,12 +421,12 @@
         await FlutterDevice.create(
           device,
           flutterProject: flutterProject,
-          trackWidgetCreation: argResults['track-widget-creation'],
-          fileSystemRoots: argResults['filesystem-root'],
-          fileSystemScheme: argResults['filesystem-scheme'],
-          viewFilter: argResults['isolate-filter'],
+          trackWidgetCreation: boolArg('track-widget-creation'),
+          fileSystemRoots: stringsArg('filesystem-root'),
+          fileSystemScheme: stringArg('filesystem-scheme'),
+          viewFilter: stringArg('isolate-filter'),
           experimentalFlags: expFlags,
-          target: argResults['target'],
+          target: stringArg('target'),
           buildMode: getBuildMode(),
           dartDefines: dartDefines,
         ),
@@ -438,19 +438,19 @@
                          await devices.single.targetPlatform == TargetPlatform.web_javascript;
 
     ResidentRunner runner;
-    final String applicationBinaryPath = argResults['use-application-binary'];
+    final String applicationBinaryPath = stringArg('use-application-binary');
     if (hotMode && !webMode) {
       runner = HotRunner(
         flutterDevices,
         target: targetFile,
         debuggingOptions: _createDebuggingOptions(),
-        benchmarkMode: argResults['benchmark'],
+        benchmarkMode: boolArg('benchmark'),
         applicationBinary: applicationBinaryPath == null
             ? null
             : fs.file(applicationBinaryPath),
-        projectRootPath: argResults['project-root'],
-        packagesFilePath: globalResults['packages'],
-        dillOutputPath: argResults['output-dill'],
+        projectRootPath: stringArg('project-root'),
+        packagesFilePath: globalResults['packages'] as String,
+        dillOutputPath: stringArg('output-dill'),
         stayResident: stayResident,
         ipv6: ipv6,
       );
diff --git a/packages/flutter_tools/lib/src/commands/screenshot.dart b/packages/flutter_tools/lib/src/commands/screenshot.dart
index c3f2fcc..ac38459 100644
--- a/packages/flutter_tools/lib/src/commands/screenshot.dart
+++ b/packages/flutter_tools/lib/src/commands/screenshot.dart
@@ -83,7 +83,7 @@
   @override
   Future<FlutterCommandResult> verifyThenRunCommand(String commandPath) async {
     device = await findTargetDevice();
-    validateOptions(argResults[_kType], device, argResults[_kObservatoryUri]);
+    validateOptions(stringArg(_kType), device, stringArg(_kObservatoryUri));
     return super.verifyThenRunCommand(commandPath);
   }
 
@@ -91,10 +91,10 @@
   Future<FlutterCommandResult> runCommand() async {
     File outputFile;
     if (argResults.wasParsed(_kOut)) {
-      outputFile = fs.file(argResults[_kOut]);
+      outputFile = fs.file(stringArg(_kOut));
     }
 
-    switch (argResults[_kType]) {
+    switch (stringArg(_kType)) {
       case _kDeviceType:
         await runScreenshot(outputFile);
         return null;
@@ -123,7 +123,7 @@
     final Map<String, dynamic> skp = await _invokeVmServiceRpc('_flutter.screenshotSkp');
     outputFile ??= getUniqueFile(fs.currentDirectory, 'flutter', 'skp');
     final IOSink sink = outputFile.openWrite();
-    sink.add(base64.decode(skp['skp']));
+    sink.add(base64.decode(skp['skp'] as String));
     await sink.close();
     _showOutputFileInfo(outputFile);
     _ensureOutputIsNotJsonRpcError(outputFile);
@@ -133,14 +133,14 @@
     final Map<String, dynamic> response = await _invokeVmServiceRpc('_flutter.screenshot');
     outputFile ??= getUniqueFile(fs.currentDirectory, 'flutter', 'png');
     final IOSink sink = outputFile.openWrite();
-    sink.add(base64.decode(response['screenshot']));
+    sink.add(base64.decode(response['screenshot'] as String));
     await sink.close();
     _showOutputFileInfo(outputFile);
     _ensureOutputIsNotJsonRpcError(outputFile);
   }
 
   Future<Map<String, dynamic>> _invokeVmServiceRpc(String method) async {
-    final Uri observatoryUri = Uri.parse(argResults[_kObservatoryUri]);
+    final Uri observatoryUri = Uri.parse(stringArg(_kObservatoryUri));
     final VMService vmService = await VMService.connect(observatoryUri);
     return await vmService.vm.invokeRpcRaw(method);
   }
diff --git a/packages/flutter_tools/lib/src/commands/shell_completion.dart b/packages/flutter_tools/lib/src/commands/shell_completion.dart
index 3575532..b5fad2b 100644
--- a/packages/flutter_tools/lib/src/commands/shell_completion.dart
+++ b/packages/flutter_tools/lib/src/commands/shell_completion.dart
@@ -53,7 +53,7 @@
     }
 
     final File outputFile = fs.file(argResults.rest.first);
-    if (outputFile.existsSync() && !argResults['overwrite']) {
+    if (outputFile.existsSync() && !boolArg('overwrite')) {
       throwToolExit(
         'Output file ${outputFile.path} already exists, will not overwrite. '
             'Use --overwrite to force overwriting existing output file.',
diff --git a/packages/flutter_tools/lib/src/commands/test.dart b/packages/flutter_tools/lib/src/commands/test.dart
index 764d600..71f89bf 100644
--- a/packages/flutter_tools/lib/src/commands/test.dart
+++ b/packages/flutter_tools/lib/src/commands/test.dart
@@ -109,7 +109,7 @@
     final Set<DevelopmentArtifact> results = <DevelopmentArtifact>{
       DevelopmentArtifact.universal,
     };
-    if (argResults['platform'] == 'chrome') {
+    if (stringArg('platform') == 'chrome') {
       results.add(DevelopmentArtifact.web);
     }
     return results;
@@ -134,18 +134,18 @@
     if (shouldRunPub) {
       await pub.get(context: PubContext.getVerifyContext(name), skipPubspecYamlCheck: true);
     }
-    final bool buildTestAssets = argResults['test-assets'];
-    final List<String> names = argResults['name'];
-    final List<String> plainNames = argResults['plain-name'];
+    final bool buildTestAssets = boolArg('test-assets');
+    final List<String> names = stringsArg('name');
+    final List<String> plainNames = stringsArg('plain-name');
     final FlutterProject flutterProject = FlutterProject.current();
 
     if (buildTestAssets && flutterProject.manifest.assets.isNotEmpty) {
       await _buildTestAsset();
     }
 
-    Iterable<String> files = argResults.rest.map<String>((String testPath) => fs.path.absolute(testPath)).toList();
+    List<String> files = argResults.rest.map<String>((String testPath) => fs.path.absolute(testPath)).toList();
 
-    final bool startPaused = argResults['start-paused'];
+    final bool startPaused = boolArg('start-paused');
     if (startPaused && files.length != 1) {
       throwToolExit(
         'When using --start-paused, you must specify a single test file to run.',
@@ -153,7 +153,7 @@
       );
     }
 
-    final int jobs = int.tryParse(argResults['concurrency']);
+    final int jobs = int.tryParse(stringArg('concurrency'));
     if (jobs == null || jobs <= 0 || !jobs.isFinite) {
       throwToolExit(
         'Could not parse -j/--concurrency argument. It must be an integer greater than zero.'
@@ -186,14 +186,14 @@
     }
 
     CoverageCollector collector;
-    if (argResults['coverage'] || argResults['merge-coverage']) {
+    if (boolArg('coverage') || boolArg('merge-coverage')) {
       final String projectName = FlutterProject.current().manifest.appName;
       collector = CoverageCollector(
         libraryPredicate: (String libraryName) => libraryName.contains(projectName),
       );
     }
 
-    final bool machine = argResults['machine'];
+    final bool machine = boolArg('machine');
     if (collector != null && machine) {
       throwToolExit("The test command doesn't support --machine and coverage together");
     }
@@ -222,7 +222,7 @@
     }
 
     final bool disableServiceAuthCodes =
-      argResults['disable-service-auth-codes'];
+      boolArg('disable-service-auth-codes');
 
     final int result = await runTests(
       files,
@@ -233,21 +233,21 @@
       enableObservatory: collector != null || startPaused,
       startPaused: startPaused,
       disableServiceAuthCodes: disableServiceAuthCodes,
-      ipv6: argResults['ipv6'],
+      ipv6: boolArg('ipv6'),
       machine: machine,
       buildMode: BuildMode.debug,
-      trackWidgetCreation: argResults['track-widget-creation'],
-      updateGoldens: argResults['update-goldens'],
+      trackWidgetCreation: boolArg('track-widget-creation'),
+      updateGoldens: boolArg('update-goldens'),
       concurrency: jobs,
       buildTestAssets: buildTestAssets,
       flutterProject: flutterProject,
-      web: argResults['platform'] == 'chrome',
+      web: stringArg('platform') == 'chrome',
     );
 
     if (collector != null) {
       final bool collectionResult = await collector.collectCoverageData(
-        argResults['coverage-path'],
-        mergeCoverageData: argResults['merge-coverage'],
+        stringArg('coverage-path'),
+        mergeCoverageData: boolArg('merge-coverage'),
       );
       if (!collectionResult) {
         throwToolExit(null);
diff --git a/packages/flutter_tools/lib/src/commands/unpack.dart b/packages/flutter_tools/lib/src/commands/unpack.dart
index 068db01..2d9263c 100644
--- a/packages/flutter_tools/lib/src/commands/unpack.dart
+++ b/packages/flutter_tools/lib/src/commands/unpack.dart
@@ -58,7 +58,7 @@
     final Set<DevelopmentArtifact> result = <DevelopmentArtifact>{
       DevelopmentArtifact.universal,
     };
-    final TargetPlatform targetPlatform = getTargetPlatformForName(argResults['target-platform']);
+    final TargetPlatform targetPlatform = getTargetPlatformForName(stringArg('target-platform'));
     switch (targetPlatform) {
       case TargetPlatform.windows_x64:
         result.add(DevelopmentArtifact.windows);
@@ -73,8 +73,8 @@
 
   @override
   Future<FlutterCommandResult> runCommand() async {
-    final String targetName = argResults['target-platform'];
-    final String targetDirectory = argResults['cache-dir'];
+    final String targetName = stringArg('target-platform');
+    final String targetDirectory = stringArg('cache-dir');
     if (!fs.directory(targetDirectory).existsSync()) {
       fs.directory(targetDirectory).createSync(recursive: true);
     }
@@ -82,7 +82,7 @@
     final ArtifactUnpacker flutterArtifactFetcher = ArtifactUnpacker(targetPlatform);
     bool success = true;
     if (artifacts is LocalEngineArtifacts) {
-      final LocalEngineArtifacts localEngineArtifacts = artifacts;
+      final LocalEngineArtifacts localEngineArtifacts = artifacts as LocalEngineArtifacts;
       success = flutterArtifactFetcher.copyLocalBuildArtifacts(
         localEngineArtifacts.engineOutPath,
         targetDirectory,
@@ -203,8 +203,8 @@
 
       printTrace('Copied artifacts from $sourceDirectory.');
     } catch (e, stackTrace) {
+      printError(e.message as String);
       printError(stackTrace.toString());
-      printError(e.message);
       return false;
     }
     return true;
diff --git a/packages/flutter_tools/lib/src/commands/update_packages.dart b/packages/flutter_tools/lib/src/commands/update_packages.dart
index 39541cf..ed28878 100644
--- a/packages/flutter_tools/lib/src/commands/update_packages.dart
+++ b/packages/flutter_tools/lib/src/commands/update_packages.dart
@@ -114,11 +114,11 @@
   Future<FlutterCommandResult> runCommand() async {
     final List<Directory> packages = runner.getRepoPackages();
 
-    final bool upgrade = argResults['force-upgrade'];
-    final bool isPrintPaths = argResults['paths'];
-    final bool isPrintTransitiveClosure = argResults['transitive-closure'];
-    final bool isVerifyOnly = argResults['verify-only'];
-    final bool isConsumerOnly = argResults['consumer-only'];
+    final bool upgrade = boolArg('force-upgrade');
+    final bool isPrintPaths = boolArg('paths');
+    final bool isPrintTransitiveClosure = boolArg('transitive-closure');
+    final bool isVerifyOnly = boolArg('verify-only');
+    final bool isConsumerOnly = boolArg('consumer-only');
 
     // "consumer" packages are those that constitute our public API (e.g. flutter, flutter_test, flutter_driver, flutter_localizations).
     if (isConsumerOnly) {
@@ -298,7 +298,7 @@
       }
 
       if (isPrintPaths) {
-        showDependencyPaths(from: argResults['from'], to: argResults['to'], tree: tree);
+        showDependencyPaths(from: stringArg('from'), to: stringArg('to'), tree: tree);
         return null;
       }
 
diff --git a/packages/flutter_tools/lib/src/commands/upgrade.dart b/packages/flutter_tools/lib/src/commands/upgrade.dart
index cf047e0..ace639e 100644
--- a/packages/flutter_tools/lib/src/commands/upgrade.dart
+++ b/packages/flutter_tools/lib/src/commands/upgrade.dart
@@ -59,8 +59,8 @@
   @override
   Future<FlutterCommandResult> runCommand() async {
     await _commandRunner.runCommand(
-      argResults['force'],
-      argResults['continue'],
+      boolArg('force'),
+      boolArg('continue'),
       GitTagVersion.determine(),
       FlutterVersion.instance,
     );
diff --git a/packages/flutter_tools/lib/src/commands/version.dart b/packages/flutter_tools/lib/src/commands/version.dart
index 5906d9f..7e77b96 100644
--- a/packages/flutter_tools/lib/src/commands/version.dart
+++ b/packages/flutter_tools/lib/src/commands/version.dart
@@ -72,7 +72,7 @@
 
     bool withForce = false;
     if (targetVersion < minSupportedVersion) {
-      if (!argResults['force']) {
+      if (!boolArg('force')) {
         printError(
           'Version command is not supported in $targetVersion and it is supported since version $minSupportedVersion'
           'which means if you switch to version $minSupportedVersion then you can not use version command.'
diff --git a/packages/flutter_tools/lib/src/dart/analysis.dart b/packages/flutter_tools/lib/src/dart/analysis.dart
index b5eae82..1f9fab2 100644
--- a/packages/flutter_tools/lib/src/dart/analysis.dart
+++ b/packages/flutter_tools/lib/src/dart/analysis.dart
@@ -85,27 +85,27 @@
 
     final dynamic response = json.decode(line);
 
-    if (response is Map<dynamic, dynamic>) {
+    if (response is Map<String, dynamic>) {
       if (response['event'] != null) {
-        final String event = response['event'];
+        final String event = response['event'] as String;
         final dynamic params = response['params'];
 
-        if (params is Map<dynamic, dynamic>) {
+        if (params is Map<String, dynamic>) {
           if (event == 'server.status') {
-            _handleStatus(response['params']);
+            _handleStatus(castStringKeyedMap(response['params']));
           } else if (event == 'analysis.errors') {
-            _handleAnalysisIssues(response['params']);
+            _handleAnalysisIssues(castStringKeyedMap(response['params']));
           } else if (event == 'server.error') {
-            _handleServerError(response['params']);
+            _handleServerError(castStringKeyedMap(response['params']));
           }
         }
       } else if (response['error'] != null) {
         // Fields are 'code', 'message', and 'stackTrace'.
-        final Map<String, dynamic> error = response['error'];
+        final Map<String, dynamic> error = castStringKeyedMap(response['error']);
         printError(
             'Error response from the server: ${error['code']} ${error['message']}');
         if (error['stackTrace'] != null) {
-          printError(error['stackTrace']);
+          printError(error['stackTrace'] as String);
         }
       }
     }
@@ -114,7 +114,7 @@
   void _handleStatus(Map<String, dynamic> statusInfo) {
     // {"event":"server.status","params":{"analysis":{"isAnalyzing":true}}}
     if (statusInfo['analysis'] != null && !_analyzingController.isClosed) {
-      final bool isAnalyzing = statusInfo['analysis']['isAnalyzing'];
+      final bool isAnalyzing = statusInfo['analysis']['isAnalyzing'] as bool;
       _analyzingController.add(isAnalyzing);
     }
   }
@@ -123,15 +123,15 @@
     // Fields are 'isFatal', 'message', and 'stackTrace'.
     printError('Error from the analysis server: ${error['message']}');
     if (error['stackTrace'] != null) {
-      printError(error['stackTrace']);
+      printError(error['stackTrace'] as String);
     }
     _didServerErrorOccur = true;
   }
 
   void _handleAnalysisIssues(Map<String, dynamic> issueInfo) {
     // {"event":"analysis.errors","params":{"file":"/Users/.../lib/main.dart","errors":[]}}
-    final String file = issueInfo['file'];
-    final List<dynamic> errorsList = issueInfo['errors'];
+    final String file = issueInfo['file'] as String;
+    final List<dynamic> errorsList = issueInfo['errors'] as List<dynamic>;
     final List<AnalysisError> errors = errorsList
         .map<Map<String, dynamic>>(castStringKeyedMap)
         .map<AnalysisError>((Map<String, dynamic> json) => AnalysisError(json))
@@ -171,7 +171,7 @@
   // },"message":"...","hasFix":false}
   Map<String, dynamic> json;
 
-  String get severity => json['severity'];
+  String get severity => json['severity'] as String;
   String get colorSeverity {
     switch(_severityLevel) {
       case _AnalysisSeverity.error:
@@ -185,14 +185,14 @@
     return null;
   }
   _AnalysisSeverity get _severityLevel => _severityMap[severity] ?? _AnalysisSeverity.none;
-  String get type => json['type'];
-  String get message => json['message'];
-  String get code => json['code'];
+  String get type => json['type'] as String;
+  String get message => json['message'] as String;
+  String get code => json['code'] as String;
 
-  String get file => json['location']['file'];
-  int get startLine => json['location']['startLine'];
-  int get startColumn => json['location']['startColumn'];
-  int get offset => json['location']['offset'];
+  String get file => json['location']['file'] as String;
+  int get startLine => json['location']['startLine'] as int;
+  int get startColumn => json['location']['startColumn'] as int;
+  int get offset => json['location']['offset'] as int;
 
   String get messageSentenceFragment {
     if (message.endsWith('.')) {
diff --git a/packages/flutter_tools/lib/src/dart/pub.dart b/packages/flutter_tools/lib/src/dart/pub.dart
index 82cd1d2..0717efa 100644
--- a/packages/flutter_tools/lib/src/dart/pub.dart
+++ b/packages/flutter_tools/lib/src/dart/pub.dart
@@ -166,7 +166,7 @@
         'Running "flutter pub $command" in ${fs.path.basename(directory)}...',
         timeout: timeoutConfiguration.slowOperation,
       );
-      final bool verbose = FlutterCommand.current != null && FlutterCommand.current.globalResults['verbose'];
+      final bool verbose = FlutterCommand.current != null && FlutterCommand.current.globalResults['verbose'] as bool;
       final List<String> args = <String>[
         if (verbose) '--verbose' else '--verbosity=warning',
         ...<String>[command, '--no-precompile'],
diff --git a/packages/flutter_tools/lib/src/devfs.dart b/packages/flutter_tools/lib/src/devfs.dart
index 99b467d..2bfc891 100644
--- a/packages/flutter_tools/lib/src/devfs.dart
+++ b/packages/flutter_tools/lib/src/devfs.dart
@@ -58,7 +58,7 @@
   DevFSFileContent(this.file);
 
   final FileSystemEntity file;
-  FileSystemEntity _linkTarget;
+  File _linkTarget;
   FileStat _fileStat;
 
   File _getFile() {
@@ -69,7 +69,7 @@
       // The link target.
       return fs.file(file.resolveSymbolicLinksSync());
     }
-    return file;
+    return file as File;
   }
 
   void _stat() {
@@ -88,7 +88,7 @@
     if (_fileStat != null && _fileStat.type == FileSystemEntityType.link) {
       // Resolve, stat, and maybe cache the symlink target.
       final String resolved = file.resolveSymbolicLinksSync();
-      final FileSystemEntity linkTarget = fs.file(resolved);
+      final File linkTarget = fs.file(resolved);
       // Stat the link target.
       final FileStat fileStat = linkTarget.statSync();
       if (fileStat.type == FileSystemEntityType.notFound) {
@@ -224,7 +224,7 @@
   @override
   Future<Uri> create(String fsName) async {
     final Map<String, dynamic> response = await vmService.vm.createDevFS(fsName);
-    return Uri.parse(response['uri']);
+    return Uri.parse(response['uri'] as String);
   }
 
   @override
diff --git a/packages/flutter_tools/lib/src/device.dart b/packages/flutter_tools/lib/src/device.dart
index 6fe8a06..fe26849 100644
--- a/packages/flutter_tools/lib/src/device.dart
+++ b/packages/flutter_tools/lib/src/device.dart
@@ -303,7 +303,6 @@
 }
 
 abstract class Device {
-
   Device(this.id, {@required this.category, @required this.platformType, @required this.ephemeral});
 
   final String id;
@@ -356,16 +355,16 @@
   bool isSupportedForProject(FlutterProject flutterProject);
 
   /// Check if a version of the given app is already installed
-  Future<bool> isAppInstalled(ApplicationPackage app);
+  Future<bool> isAppInstalled(covariant ApplicationPackage app);
 
   /// Check if the latest build of the [app] is already installed.
-  Future<bool> isLatestBuildInstalled(ApplicationPackage app);
+  Future<bool> isLatestBuildInstalled(covariant ApplicationPackage app);
 
   /// Install an app package on the current device
-  Future<bool> installApp(ApplicationPackage app);
+  Future<bool> installApp(covariant ApplicationPackage app);
 
   /// Uninstall an app package from the current device
-  Future<bool> uninstallApp(ApplicationPackage app);
+  Future<bool> uninstallApp(covariant ApplicationPackage app);
 
   /// Check if the device is supported by Flutter
   bool isSupported();
@@ -382,7 +381,7 @@
   /// Get a log reader for this device.
   /// If [app] is specified, this will return a log reader specific to that
   /// application. Otherwise, a global log reader will be returned.
-  DeviceLogReader getLogReader({ ApplicationPackage app });
+  DeviceLogReader getLogReader({ covariant ApplicationPackage app });
 
   /// Get the port forwarder for this device.
   DevicePortForwarder get portForwarder;
@@ -398,7 +397,7 @@
   /// [platformArgs] allows callers to pass platform-specific arguments to the
   /// start call. The build mode is not used by all platforms.
   Future<LaunchResult> startApp(
-    ApplicationPackage package, {
+    covariant ApplicationPackage package, {
     String mainPath,
     String route,
     DebuggingOptions debuggingOptions,
@@ -422,7 +421,7 @@
   bool get supportsScreenshot => false;
 
   /// Stop an app package on the current device.
-  Future<bool> stopApp(ApplicationPackage app);
+  Future<bool> stopApp(covariant ApplicationPackage app);
 
   Future<void> takeScreenshot(File outputFile) => Future<void>.error('unimplemented');
 
@@ -582,17 +581,15 @@
 
   final int hostPort;
   final int devicePort;
-  final dynamic context;
+  final Process context;
 
   @override
   String toString() => 'ForwardedPort HOST:$hostPort to DEVICE:$devicePort';
 
   /// Kill subprocess (if present) used in forwarding.
   void dispose() {
-    final Process process = context;
-
-    if (process != null) {
-      process.kill();
+    if (context != null) {
+      context.kill();
     }
   }
 }
diff --git a/packages/flutter_tools/lib/src/doctor.dart b/packages/flutter_tools/lib/src/doctor.dart
index 98ea86e..3150b23 100644
--- a/packages/flutter_tools/lib/src/doctor.dart
+++ b/packages/flutter_tools/lib/src/doctor.dart
@@ -571,9 +571,9 @@
     if (other.runtimeType != runtimeType) {
       return false;
     }
-    final ValidationMessage typedOther = other;
-    return typedOther.message == message
-      && typedOther.type == type;
+    return other is ValidationMessage
+        && other.message == message
+        && other.type == type;
   }
 
   @override
diff --git a/packages/flutter_tools/lib/src/features.dart b/packages/flutter_tools/lib/src/features.dart
index bf1dba9..b5b45e7 100644
--- a/packages/flutter_tools/lib/src/features.dart
+++ b/packages/flutter_tools/lib/src/features.dart
@@ -53,7 +53,7 @@
     }
     bool isEnabled = featureSetting.enabledByDefault;
     if (feature.configSetting != null) {
-      final bool configOverride = Config.instance.getValue(feature.configSetting);
+      final bool configOverride = Config.instance.getValue(feature.configSetting) as bool;
       if (configOverride != null) {
         isEnabled = configOverride;
       }
diff --git a/packages/flutter_tools/lib/src/flutter_manifest.dart b/packages/flutter_tools/lib/src/flutter_manifest.dart
index a2a8e59..90029ae 100644
--- a/packages/flutter_tools/lib/src/flutter_manifest.dart
+++ b/packages/flutter_tools/lib/src/flutter_manifest.dart
@@ -37,10 +37,10 @@
   /// Returns null on missing or invalid manifest
   @visibleForTesting
   static FlutterManifest createFromString(String manifest) {
-    return _createFromYaml(loadYaml(manifest));
+    return _createFromYaml(loadYaml(manifest) as YamlMap);
   }
 
-  static FlutterManifest _createFromYaml(dynamic yamlDocument) {
+  static FlutterManifest _createFromYaml(YamlMap yamlDocument) {
     final FlutterManifest pubspec = FlutterManifest._();
     if (yamlDocument != null && !_validate(yamlDocument)) {
       return null;
@@ -53,7 +53,7 @@
       pubspec._descriptor = <String, dynamic>{};
     }
 
-    final Map<dynamic, dynamic> flutterMap = pubspec._descriptor['flutter'];
+    final Map<dynamic, dynamic> flutterMap = pubspec._descriptor['flutter'] as Map<dynamic, dynamic>;
     if (flutterMap != null) {
       pubspec._flutterDescriptor = flutterMap.cast<String, dynamic>();
     } else {
@@ -73,7 +73,7 @@
   bool get isEmpty => _descriptor.isEmpty;
 
   /// The string value of the top-level `name` property in the `pubspec.yaml` file.
-  String get appName => _descriptor['name'] ?? '';
+  String get appName => _descriptor['name'] as String ?? '';
 
   // Flag to avoid printing multiple invalid version messages.
   bool _hasShowInvalidVersionMsg = false;
@@ -119,14 +119,14 @@
   }
 
   bool get usesMaterialDesign {
-    return _flutterDescriptor['uses-material-design'] ?? false;
+    return _flutterDescriptor['uses-material-design'] as bool ?? false;
   }
 
   /// True if this Flutter module should use AndroidX dependencies.
   ///
   /// If false the deprecated Android Support library will be used.
   bool get usesAndroidX {
-    return _flutterDescriptor['module']['androidX'] ?? false;
+    return _flutterDescriptor['module']['androidX'] as bool ?? false;
   }
 
   /// True if this manifest declares a Flutter module project.
@@ -153,14 +153,14 @@
   /// such declaration.
   String get androidPackage {
     if (isModule) {
-      return _flutterDescriptor['module']['androidPackage'];
+      return _flutterDescriptor['module']['androidPackage'] as String;
     }
     if (isPlugin) {
-      final YamlMap plugin = _flutterDescriptor['plugin'];
+      final YamlMap plugin = _flutterDescriptor['plugin'] as YamlMap;
       if (plugin.containsKey('platforms')) {
-        return plugin['platforms']['android']['package'];
+        return plugin['platforms']['android']['package'] as String;
       } else {
-        return plugin['androidPackage'];
+        return plugin['androidPackage'] as String;
       }
     }
     return null;
@@ -170,7 +170,7 @@
   /// module descriptor. Returns null if there is no such declaration.
   String get iosBundleIdentifier {
     if (isModule) {
-      return _flutterDescriptor['module']['iosBundleIdentifier'];
+      return _flutterDescriptor['module']['iosBundleIdentifier'] as String;
     }
     return null;
   }
@@ -180,7 +180,7 @@
   }
 
   List<Map<String, dynamic>> get _rawFontsDescriptor {
-    final List<dynamic> fontList = _flutterDescriptor['fonts'];
+    final List<dynamic> fontList = _flutterDescriptor['fonts'] as List<dynamic>;
     return fontList == null
         ? const <Map<String, dynamic>>[]
         : fontList.map<Map<String, dynamic>>(castStringKeyedMap).toList();
@@ -189,7 +189,7 @@
   List<Uri> get assets => _assets ??= _computeAssets();
   List<Uri> _assets;
   List<Uri> _computeAssets() {
-    final List<dynamic> assets = _flutterDescriptor['assets'];
+    final List<dynamic> assets = _flutterDescriptor['assets'] as List<dynamic>;
     if (assets == null) {
       return const <Uri>[];
     }
@@ -199,7 +199,7 @@
         printError('Asset manifest contains a null or empty uri.');
         continue;
       }
-      final String stringAsset = asset;
+      final String stringAsset = asset as String;
       try {
         results.add(Uri.parse(Uri.encodeFull(stringAsset)));
       } on FormatException {
@@ -223,8 +223,8 @@
 
     final List<Font> fonts = <Font>[];
     for (Map<String, dynamic> fontFamily in _rawFontsDescriptor) {
-      final List<dynamic> fontFiles = fontFamily['fonts'];
-      final String familyName = fontFamily['family'];
+      final YamlList fontFiles = fontFamily['fonts'] as YamlList;
+      final String familyName = fontFamily['family'] as String;
       if (familyName == null) {
         printError('Warning: Missing family name for font.', emphasis: true);
         continue;
@@ -235,8 +235,8 @@
       }
 
       final List<FontAsset> fontAssets = <FontAsset>[];
-      for (Map<dynamic, dynamic> fontFile in fontFiles) {
-        final String asset = fontFile['asset'];
+      for (Map<dynamic, dynamic> fontFile in fontFiles.cast<Map<dynamic, dynamic>>()) {
+        final String asset = fontFile['asset'] as String;
         if (asset == null) {
           printError('Warning: Missing asset in fonts for $familyName', emphasis: true);
           continue;
@@ -244,12 +244,12 @@
 
         fontAssets.add(FontAsset(
           Uri.parse(asset),
-          weight: fontFile['weight'],
-          style: fontFile['style'],
+          weight: fontFile['weight'] as int,
+          style: fontFile['style'] as String,
         ));
       }
       if (fontAssets.isNotEmpty) {
-        fonts.add(Font(fontFamily['family'], fontAssets));
+        fonts.add(Font(fontFamily['family'] as String, fontAssets));
       }
     }
     return fonts;
@@ -327,7 +327,7 @@
       errors.add('Expected YAML key to be a a string, but got ${kvp.key}.');
       continue;
     }
-    switch (kvp.key) {
+    switch (kvp.key as String) {
       case 'name':
         if (kvp.value is! String) {
           errors.add('Expected "${kvp.key}" to be a string, but got ${kvp.value}.');
@@ -340,7 +340,7 @@
         if (kvp.value is! YamlMap) {
           errors.add('Expected "${kvp.key}" section to be an object or null, but got ${kvp.value}.');
         }
-        _validateFlutter(kvp.value, errors);
+        _validateFlutter(kvp.value as YamlMap, errors);
         break;
       default:
         // additionalProperties are allowed.
@@ -366,7 +366,7 @@
       errors.add('Expected YAML key to be a a string, but got ${kvp.key} (${kvp.value.runtimeType}).');
       continue;
     }
-    switch (kvp.key) {
+    switch (kvp.key as String) {
       case 'uses-material-design':
         if (kvp.value is! bool) {
           errors.add('Expected "${kvp.key}" to be a bool, but got ${kvp.value} (${kvp.value.runtimeType}).');
@@ -382,7 +382,7 @@
         if (kvp.value is! YamlList || kvp.value[0] is! YamlMap) {
           errors.add('Expected "${kvp.key}" to be a list, but got ${kvp.value} (${kvp.value.runtimeType}).');
         } else {
-          _validateFonts(kvp.value, errors);
+          _validateFonts(kvp.value as YamlList, errors);
         }
         break;
       case 'module':
@@ -405,7 +405,7 @@
           errors.add('Expected "${kvp.key}" to be an object, but got ${kvp.value} (${kvp.value.runtimeType}).');
           break;
         }
-        final List<String> pluginErrors = Plugin.validatePluginYaml(kvp.value);
+        final List<String> pluginErrors = Plugin.validatePluginYaml(kvp.value as YamlMap);
         errors.addAll(pluginErrors);
         break;
       default:
@@ -427,7 +427,7 @@
       errors.add('Unexpected child "$fontListEntry" found under "fonts". Expected a map.');
       continue;
     }
-    final YamlMap fontMap = fontListEntry;
+    final YamlMap fontMap = fontListEntry as YamlMap;
     for (dynamic key in fontMap.keys.where((dynamic key) => key != 'family' && key != 'fonts')) {
       errors.add('Unexpected child "$key" found under "fonts".');
     }
@@ -445,12 +445,12 @@
         errors.add('Expected "fonts" to be a list of maps.');
         continue;
       }
-      final YamlMap fontMapList = fontListItem;
+      final YamlMap fontMapList = fontListItem as YamlMap;
       for (final MapEntry<dynamic, dynamic> kvp in fontMapList.entries) {
         if (kvp.key is! String) {
           errors.add('Expected "${kvp.key}" under "fonts" to be a string.');
         }
-        switch(kvp.key) {
+        switch(kvp.key as String) {
           case 'asset':
             if (kvp.value is! String) {
               errors.add('Expected font asset ${kvp.value} ((${kvp.value.runtimeType})) to be a string.');
diff --git a/packages/flutter_tools/lib/src/fuchsia/fuchsia_build.dart b/packages/flutter_tools/lib/src/fuchsia/fuchsia_build.dart
index 9c855d2..32c0bb8 100644
--- a/packages/flutter_tools/lib/src/fuchsia/fuchsia_build.dart
+++ b/packages/flutter_tools/lib/src/fuchsia/fuchsia_build.dart
@@ -10,6 +10,7 @@
 import '../base/common.dart';
 import '../base/file_system.dart';
 import '../base/io.dart';
+import '../base/utils.dart';
 import '../build_info.dart';
 import '../bundle.dart';
 import '../convert.dart';
@@ -87,7 +88,7 @@
 }
 
 void _rewriteCmx(BuildMode mode, String runnerPackageSource, File src, File dst) {
-  final Map<String, dynamic> cmx = json.decode(src.readAsStringSync());
+  final Map<String, dynamic> cmx = castStringKeyedMap(json.decode(src.readAsStringSync()));
   // If the app author has already specified the runner in the cmx file, then
   // do not override it with something else.
   if (cmx.containsKey('runner')) {
diff --git a/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart b/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart
index d627123..381145f 100644
--- a/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart
+++ b/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart
@@ -87,7 +87,7 @@
         : RegExp('INFO: ${_app.name}(\.cmx)?\\(flutter\\): ');
     return Stream<String>.eventTransformed(
       lines,
-      (Sink<String> outout) => _FuchsiaLogSink(outout, matchRegExp, startTime),
+      (EventSink<String> output) => _FuchsiaLogSink(output, matchRegExp, startTime),
     );
   }
 
@@ -710,7 +710,7 @@
     ];
     final ProcessResult result = await processManager.run(command);
     if (result.exitCode != 0) {
-      throwToolExit(result.stderr);
+      throwToolExit('Unforward command failed: $result');
     }
   }
 }
diff --git a/packages/flutter_tools/lib/src/intellij/intellij.dart b/packages/flutter_tools/lib/src/intellij/intellij.dart
index ff42963..7aa378f 100644
--- a/packages/flutter_tools/lib/src/intellij/intellij.dart
+++ b/packages/flutter_tools/lib/src/intellij/intellij.dart
@@ -62,7 +62,7 @@
       final Archive archive =
           ZipDecoder().decodeBytes(fs.file(jarPath).readAsBytesSync());
       final ArchiveFile file = archive.findFile('META-INF/plugin.xml');
-      final String content = utf8.decode(file.content);
+      final String content = utf8.decode(file.content as List<int>);
       const String versionStartTag = '<version>';
       final int start = content.indexOf(versionStartTag);
       final int end = content.indexOf('</version>', start);
diff --git a/packages/flutter_tools/lib/src/ios/code_signing.dart b/packages/flutter_tools/lib/src/ios/code_signing.dart
index 50431dd..517c185 100644
--- a/packages/flutter_tools/lib/src/ios/code_signing.dart
+++ b/packages/flutter_tools/lib/src/ios/code_signing.dart
@@ -208,7 +208,7 @@
   }
 
   if (validCodeSigningIdentities.length > 1) {
-    final String savedCertChoice = config.getValue('ios-signing-cert');
+    final String savedCertChoice = config.getValue('ios-signing-cert') as String;
 
     if (savedCertChoice != null) {
       if (validCodeSigningIdentities.contains(savedCertChoice)) {
diff --git a/packages/flutter_tools/lib/src/ios/devices.dart b/packages/flutter_tools/lib/src/ios/devices.dart
index b70ff9d..97b0380 100644
--- a/packages/flutter_tools/lib/src/ios/devices.dart
+++ b/packages/flutter_tools/lib/src/ios/devices.dart
@@ -158,7 +158,7 @@
   @override
   final String name;
 
-  Map<ApplicationPackage, DeviceLogReader> _logReaders;
+  Map<IOSApp, DeviceLogReader> _logReaders;
 
   DevicePortForwarder _portForwarder;
 
@@ -202,7 +202,7 @@
   }
 
   @override
-  Future<bool> isAppInstalled(ApplicationPackage app) async {
+  Future<bool> isAppInstalled(IOSApp app) async {
     RunResult apps;
     try {
       apps = await processUtils.run(
@@ -219,12 +219,11 @@
   }
 
   @override
-  Future<bool> isLatestBuildInstalled(ApplicationPackage app) async => false;
+  Future<bool> isLatestBuildInstalled(IOSApp app) async => false;
 
   @override
-  Future<bool> installApp(ApplicationPackage app) async {
-    final IOSApp iosApp = app;
-    final Directory bundle = fs.directory(iosApp.deviceBundlePath);
+  Future<bool> installApp(IOSApp app) async {
+    final Directory bundle = fs.directory(app.deviceBundlePath);
     if (!bundle.existsSync()) {
       printError('Could not find application bundle at ${bundle.path}; have you run "flutter build ios"?');
       return false;
@@ -232,7 +231,7 @@
 
     try {
       await processUtils.run(
-        <String>[_installerPath, '-i', iosApp.deviceBundlePath],
+        <String>[_installerPath, '-i', app.deviceBundlePath],
         throwOnError: true,
         environment: Map<String, String>.fromEntries(
           <MapEntry<String, String>>[cache.dyLdLibEntry],
@@ -246,7 +245,7 @@
   }
 
   @override
-  Future<bool> uninstallApp(ApplicationPackage app) async {
+  Future<bool> uninstallApp(IOSApp app) async {
     try {
       await processUtils.run(
         <String>[_installerPath, '-U', app.id],
@@ -267,7 +266,7 @@
 
   @override
   Future<LaunchResult> startApp(
-    ApplicationPackage package, {
+    IOSApp package, {
     String mainPath,
     String route,
     DebuggingOptions debuggingOptions,
@@ -295,7 +294,7 @@
 
       // Step 1: Build the precompiled/DBC application if necessary.
       final XcodeBuildResult buildResult = await buildXcodeProject(
-          app: package,
+          app: package as BuildableIOSApp,
           buildInfo: debuggingOptions.buildInfo,
           targetOverride: mainPath,
           buildForDevice: true,
@@ -317,8 +316,7 @@
     packageId ??= package.id;
 
     // Step 2: Check that the application exists at the specified path.
-    final IOSApp iosApp = package;
-    final Directory bundle = fs.directory(iosApp.deviceBundlePath);
+    final Directory bundle = fs.directory(package.deviceBundlePath);
     if (!bundle.existsSync()) {
       printError('Could not find the built application bundle at ${bundle.path}.');
       return LaunchResult.failed();
@@ -347,7 +345,7 @@
       if (debuggingOptions.dumpSkpOnShaderCompilation) '--dump-skp-on-shader-compilation',
       if (debuggingOptions.verboseSystemLogs) '--verbose-logging',
       if (debuggingOptions.cacheSkSL) '--cache-sksl',
-      if (platformArgs['trace-startup'] ?? false) '--trace-startup',
+      if (platformArgs['trace-startup'] as bool ?? false) '--trace-startup',
     ];
 
     final Status installStatus = logger.startProgress(
@@ -426,7 +424,7 @@
   }
 
   @override
-  Future<bool> stopApp(ApplicationPackage app) async {
+  Future<bool> stopApp(IOSApp app) async {
     // Currently we don't have a way to stop an app running on iOS.
     return false;
   }
@@ -438,14 +436,14 @@
   Future<String> get sdkNameAndVersion async => 'iOS $_sdkVersion';
 
   @override
-  DeviceLogReader getLogReader({ ApplicationPackage app }) {
-    _logReaders ??= <ApplicationPackage, DeviceLogReader>{};
+  DeviceLogReader getLogReader({ IOSApp app }) {
+    _logReaders ??= <IOSApp, DeviceLogReader>{};
     return _logReaders.putIfAbsent(app, () => IOSDeviceLogReader(this, app));
   }
 
   @visibleForTesting
-  void setLogReader(ApplicationPackage app, DeviceLogReader logReader) {
-    _logReaders ??= <ApplicationPackage, DeviceLogReader>{};
+  void setLogReader(IOSApp app, DeviceLogReader logReader) {
+    _logReaders ??= <IOSApp, DeviceLogReader>{};
     _logReaders[app] = logReader;
   }
 
@@ -475,7 +473,7 @@
 
   @override
   void dispose() {
-    _logReaders.forEach((ApplicationPackage application, DeviceLogReader logReader) {
+    _logReaders.forEach((IOSApp application, DeviceLogReader logReader) {
       logReader.dispose();
     });
     _portForwarder?.dispose();
@@ -544,7 +542,7 @@
 
 @visibleForTesting
 class IOSDeviceLogReader extends DeviceLogReader {
-  IOSDeviceLogReader(this.device, ApplicationPackage app) {
+  IOSDeviceLogReader(this.device, IOSApp app) {
     _linesController = StreamController<String>.broadcast(
       onListen: _listenToSysLog,
       onCancel: dispose,
@@ -637,7 +635,7 @@
   // any specific prefix. To properly capture those, we enter "printing" mode
   // after matching a log line from the runner. When in printing mode, we print
   // all lines until we find the start of another log message (from any app).
-  Function _newSyslogLineHandler() {
+  void Function(String line) _newSyslogLineHandler() {
     bool printing = false;
 
     return (String line) {
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart
index 6ee78cb..dd5597f 100644
--- a/packages/flutter_tools/lib/src/ios/mac.dart
+++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -143,7 +143,7 @@
       ],
       environment: executionEnv,
     )).processResult;
-    if (ideviceResult.stdout.contains('Usage: ideviceinfo')) {
+    if ((ideviceResult.stdout as String).contains('Usage: ideviceinfo')) {
       _isWorking = false;
       return _isWorking;
     }
@@ -156,7 +156,7 @@
       ],
       environment: executionEnv,
     )).processResult;
-    if (result.exitCode == 0 && result.stdout.isEmpty) {
+    if (result.exitCode == 0 && (result.stdout as String).isEmpty) {
       _isWorking = true;
     } else {
       // Check that we can look up the names of any attached devices.
@@ -183,7 +183,7 @@
       if (result.exitCode != 0) {
         throw ToolExit('idevice_id returned an error:\n${result.stderr}');
       }
-      return result.stdout;
+      return result.stdout as String;
     } on ProcessException {
       throw ToolExit('Failed to invoke idevice_id. Run flutter doctor.');
     }
@@ -203,17 +203,19 @@
           <MapEntry<String, String>>[cache.dyLdLibEntry]
         ),
       );
-      if (result.exitCode == 255 && result.stdout != null && result.stdout.contains('No device found')) {
-        throw IOSDeviceNotFoundError('ideviceinfo could not find device:\n${result.stdout}. Try unlocking attached devices.');
+      final String stdout = result.stdout as String;
+      final String stderr = result.stderr as String;
+      if (result.exitCode == 255 && stdout != null && stdout.contains('No device found')) {
+        throw IOSDeviceNotFoundError('ideviceinfo could not find device:\n$stdout. Try unlocking attached devices.');
       }
-      if (result.exitCode == 255 && result.stderr != null && result.stderr.contains('Could not connect to lockdownd')) {
-        if (result.stderr.contains('error code -${LockdownReturnCode.pairingDialogResponsePending.code}')) {
+      if (result.exitCode == 255 && stderr != null && stderr.contains('Could not connect to lockdownd')) {
+        if (stderr.contains('error code -${LockdownReturnCode.pairingDialogResponsePending.code}')) {
           throw const IOSDeviceNotTrustedError(
             'Device info unavailable. Is the device asking to "Trust This Computer?"',
             LockdownReturnCode.pairingDialogResponsePending,
           );
         }
-        if (result.stderr.contains('error code -${LockdownReturnCode.invalidHostId.code}')) {
+        if (stderr.contains('error code -${LockdownReturnCode.invalidHostId.code}')) {
           throw const IOSDeviceNotTrustedError(
             'Device info unavailable. Device pairing "trust" may have been revoked.',
             LockdownReturnCode.invalidHostId,
@@ -221,9 +223,9 @@
         }
       }
       if (result.exitCode != 0) {
-        throw ToolExit('ideviceinfo returned an error:\n${result.stderr}');
+        throw ToolExit('ideviceinfo returned an error:\n$stderr');
       }
-      return result.stdout.trim();
+      return stdout.trim();
     } on ProcessException {
       throw ToolExit('Failed to invoke ideviceinfo. Run flutter doctor.');
     }
diff --git a/packages/flutter_tools/lib/src/ios/plist_parser.dart b/packages/flutter_tools/lib/src/ios/plist_parser.dart
index c873c3d..ac08250 100644
--- a/packages/flutter_tools/lib/src/ios/plist_parser.dart
+++ b/packages/flutter_tools/lib/src/ios/plist_parser.dart
@@ -6,6 +6,7 @@
 import '../base/file_system.dart';
 import '../base/io.dart';
 import '../base/process.dart';
+import '../base/utils.dart';
 import '../convert.dart';
 import '../globals.dart';
 
@@ -45,7 +46,7 @@
         args,
         throwOnError: true,
       ).stdout.trim();
-      return json.decode(jsonContent);
+      return castStringKeyedMap(json.decode(jsonContent));
     } on ProcessException catch (error) {
       printTrace('$error');
       return const <String, dynamic>{};
@@ -64,6 +65,6 @@
   String getValueFromFile(String plistFilePath, String key) {
     assert(key != null);
     final Map<String, dynamic> parsed = parseFile(plistFilePath);
-    return parsed[key];
+    return parsed[key] as String;
   }
 }
diff --git a/packages/flutter_tools/lib/src/ios/xcodeproj.dart b/packages/flutter_tools/lib/src/ios/xcodeproj.dart
index 40bdd7d..3d0cac9 100644
--- a/packages/flutter_tools/lib/src/ios/xcodeproj.dart
+++ b/packages/flutter_tools/lib/src/ios/xcodeproj.dart
@@ -192,7 +192,7 @@
   xcodeBuildSettings.add('FLUTTER_BUILD_NUMBER=$buildNumber');
 
   if (artifacts is LocalEngineArtifacts) {
-    final LocalEngineArtifacts localEngineArtifacts = artifacts;
+    final LocalEngineArtifacts localEngineArtifacts = artifacts as LocalEngineArtifacts;
     final String engineOutPath = localEngineArtifacts.engineOutPath;
     xcodeBuildSettings.add('FLUTTER_ENGINE=${fs.path.dirname(fs.path.dirname(engineOutPath))}');
     xcodeBuildSettings.add('LOCAL_ENGINE=${fs.path.basename(engineOutPath)}');
diff --git a/packages/flutter_tools/lib/src/linux/build_linux.dart b/packages/flutter_tools/lib/src/linux/build_linux.dart
index 16aae8d..0c6a84c 100644
--- a/packages/flutter_tools/lib/src/linux/build_linux.dart
+++ b/packages/flutter_tools/lib/src/linux/build_linux.dart
@@ -23,7 +23,7 @@
 export PROJECT_DIR=${linuxProject.project.directory.path}
 ''');
   if (artifacts is LocalEngineArtifacts) {
-    final LocalEngineArtifacts localEngineArtifacts = artifacts;
+    final LocalEngineArtifacts localEngineArtifacts = artifacts as LocalEngineArtifacts;
     final String engineOutPath = localEngineArtifacts.engineOutPath;
     buffer.writeln('export FLUTTER_ENGINE=${fs.path.dirname(fs.path.dirname(engineOutPath))}');
     buffer.writeln('export LOCAL_ENGINE=${fs.path.basename(engineOutPath)}');
diff --git a/packages/flutter_tools/lib/src/linux/linux_doctor.dart b/packages/flutter_tools/lib/src/linux/linux_doctor.dart
index 9ee6915..161de0f 100644
--- a/packages/flutter_tools/lib/src/linux/linux_doctor.dart
+++ b/packages/flutter_tools/lib/src/linux/linux_doctor.dart
@@ -32,7 +32,7 @@
       validationType = ValidationType.missing;
       messages.add(ValidationMessage.error('clang++ is not installed'));
     } else {
-      final String firstLine = clangResult.stdout.split('\n').first.trim();
+      final String firstLine = (clangResult.stdout as String).split('\n').first.trim();
       final String versionString = RegExp(r'[0-9]+\.[0-9]+\.[0-9]+').firstMatch(firstLine).group(0);
       final Version version = Version.parse(versionString);
       if (version >= minimumClangVersion) {
@@ -59,7 +59,7 @@
       validationType = ValidationType.missing;
       messages.add(ValidationMessage.error('make is not installed'));
     } else {
-      final String firstLine = makeResult.stdout.split('\n').first.trim();
+      final String firstLine = (makeResult.stdout as String).split('\n').first.trim();
       messages.add(ValidationMessage(firstLine));
     }
 
diff --git a/packages/flutter_tools/lib/src/macos/application_package.dart b/packages/flutter_tools/lib/src/macos/application_package.dart
index 892c320..0326dcb 100644
--- a/packages/flutter_tools/lib/src/macos/application_package.dart
+++ b/packages/flutter_tools/lib/src/macos/application_package.dart
@@ -43,7 +43,7 @@
   }
 
   /// Look up the executable name for a macOS application bundle.
-  static _ExecutableAndId _executableFromBundle(Directory applicationBundle) {
+  static _ExecutableAndId _executableFromBundle(FileSystemEntity applicationBundle) {
     final FileSystemEntityType entityType = fs.typeSync(applicationBundle.path);
     if (entityType == FileSystemEntityType.notFound) {
       printError('File "${applicationBundle.path}" does not exist.');
@@ -67,8 +67,8 @@
       return null;
     }
     final Map<String, dynamic> propertyValues = PlistParser.instance.parseFile(plistPath);
-    final String id = propertyValues[PlistParser.kCFBundleIdentifierKey];
-    final String executableName = propertyValues[PlistParser.kCFBundleExecutable];
+    final String id = propertyValues[PlistParser.kCFBundleIdentifierKey] as String;
+    final String executableName = propertyValues[PlistParser.kCFBundleExecutable] as String;
     if (id == null) {
       printError('Invalid prebuilt macOS app. Info.plist does not contain bundle identifier');
       return null;
diff --git a/packages/flutter_tools/lib/src/macos/cocoapods.dart b/packages/flutter_tools/lib/src/macos/cocoapods.dart
index 9a7a64f..9900a72 100644
--- a/packages/flutter_tools/lib/src/macos/cocoapods.dart
+++ b/packages/flutter_tools/lib/src/macos/cocoapods.dart
@@ -309,13 +309,15 @@
     );
     status.stop();
     if (logger.isVerbose || result.exitCode != 0) {
-      if (result.stdout.isNotEmpty) {
+      final String stdout = result.stdout as String;
+      if (stdout.isNotEmpty) {
         printStatus('CocoaPods\' output:\n↳');
-        printStatus(result.stdout, indent: 4);
+        printStatus(stdout, indent: 4);
       }
-      if (result.stderr.isNotEmpty) {
+      final String stderr = result.stderr as String;
+      if (stderr.isNotEmpty) {
         printStatus('Error output from CocoaPods:\n↳');
-        printStatus(result.stderr, indent: 4);
+        printStatus(stderr, indent: 4);
       }
     }
     if (result.exitCode != 0) {
@@ -326,7 +328,8 @@
   }
 
   void _diagnosePodInstallFailure(ProcessResult result) {
-    if (result.stdout is String && result.stdout.contains('out-of-date source repos')) {
+    final dynamic stdout = result.stdout;
+    if (stdout is String && stdout.contains('out-of-date source repos')) {
       printError(
         "Error: CocoaPods's specs repository is too out-of-date to satisfy dependencies.\n"
         'To update the CocoaPods specs, run:\n'
diff --git a/packages/flutter_tools/lib/src/persistent_tool_state.dart b/packages/flutter_tools/lib/src/persistent_tool_state.dart
index 71ded3a..257a933 100644
--- a/packages/flutter_tools/lib/src/persistent_tool_state.dart
+++ b/packages/flutter_tools/lib/src/persistent_tool_state.dart
@@ -32,7 +32,7 @@
   final Config _config;
 
   @override
-  bool get redisplayWelcomeMessage => _config.getValue(_kRedisplayWelcomeMessage);
+  bool get redisplayWelcomeMessage => _config.getValue(_kRedisplayWelcomeMessage) as bool;
 
   @override
   set redisplayWelcomeMessage(bool value) {
diff --git a/packages/flutter_tools/lib/src/platform_plugins.dart b/packages/flutter_tools/lib/src/platform_plugins.dart
index 07fc58e..163e804 100644
--- a/packages/flutter_tools/lib/src/platform_plugins.dart
+++ b/packages/flutter_tools/lib/src/platform_plugins.dart
@@ -31,8 +31,8 @@
     assert(validate(yaml));
     return AndroidPlugin(
       name: name,
-      package: yaml['package'],
-      pluginClass: yaml['pluginClass'],
+      package: yaml['package'] as String,
+      pluginClass: yaml['pluginClass'] as String,
       pluginPath: pluginPath,
     );
   }
@@ -144,7 +144,7 @@
     return IOSPlugin(
       name: name,
       classPrefix: '',
-      pluginClass: yaml['pluginClass'],
+      pluginClass: yaml['pluginClass'] as String,
     );
   }
 
@@ -188,7 +188,7 @@
     assert(validate(yaml));
     return MacOSPlugin(
       name: name,
-      pluginClass: yaml['pluginClass'],
+      pluginClass: yaml['pluginClass'] as String,
     );
   }
 
@@ -227,7 +227,7 @@
     assert(validate(yaml));
     return WindowsPlugin(
       name: name,
-      pluginClass: yaml['pluginClass'],
+      pluginClass: yaml['pluginClass'] as String,
     );
   }
 
@@ -267,7 +267,7 @@
     assert(validate(yaml));
     return LinuxPlugin(
       name: name,
-      pluginClass: yaml['pluginClass'],
+      pluginClass: yaml['pluginClass'] as String,
     );
   }
 
@@ -309,8 +309,8 @@
     assert(validate(yaml));
     return WebPlugin(
       name: name,
-      pluginClass: yaml['pluginClass'],
-      fileName: yaml['fileName'],
+      pluginClass: yaml['pluginClass'] as String,
+      fileName: yaml['fileName'] as String,
     );
   }
 
diff --git a/packages/flutter_tools/lib/src/plugins.dart b/packages/flutter_tools/lib/src/plugins.dart
index 936caec..f795cc7 100644
--- a/packages/flutter_tools/lib/src/plugins.dart
+++ b/packages/flutter_tools/lib/src/plugins.dart
@@ -60,7 +60,7 @@
   ///            pluginClass: SamplePlugin
   ///          windows:
   ///            pluginClass: SamplePlugin
-  factory Plugin.fromYaml(String name, String path, dynamic pluginYaml) {
+  factory Plugin.fromYaml(String name, String path, YamlMap pluginYaml) {
     final List<String> errors = validatePluginYaml(pluginYaml);
     if (errors.isNotEmpty) {
       throwToolExit('Invalid plugin specification.\n${errors.join('\n')}');
@@ -74,7 +74,7 @@
   factory Plugin._fromMultiPlatformYaml(String name, String path, dynamic pluginYaml) {
     assert (pluginYaml != null && pluginYaml['platforms'] != null,
             'Invalid multi-platform plugin specification.');
-    final dynamic platformsYaml = pluginYaml['platforms'];
+    final YamlMap platformsYaml = pluginYaml['platforms'] as YamlMap;
 
     assert (_validateMultiPlatformYaml(platformsYaml).isEmpty,
             'Invalid multi-platform plugin specification.');
@@ -84,34 +84,34 @@
     if (platformsYaml[AndroidPlugin.kConfigKey] != null) {
       platforms[AndroidPlugin.kConfigKey] = AndroidPlugin.fromYaml(
         name,
-        platformsYaml[AndroidPlugin.kConfigKey],
+        platformsYaml[AndroidPlugin.kConfigKey] as YamlMap,
         path,
       );
     }
 
     if (platformsYaml[IOSPlugin.kConfigKey] != null) {
       platforms[IOSPlugin.kConfigKey] =
-          IOSPlugin.fromYaml(name, platformsYaml[IOSPlugin.kConfigKey]);
+          IOSPlugin.fromYaml(name, platformsYaml[IOSPlugin.kConfigKey] as YamlMap);
     }
 
     if (platformsYaml[LinuxPlugin.kConfigKey] != null) {
       platforms[LinuxPlugin.kConfigKey] =
-          LinuxPlugin.fromYaml(name, platformsYaml[LinuxPlugin.kConfigKey]);
+          LinuxPlugin.fromYaml(name, platformsYaml[LinuxPlugin.kConfigKey] as YamlMap);
     }
 
     if (platformsYaml[MacOSPlugin.kConfigKey] != null) {
       platforms[MacOSPlugin.kConfigKey] =
-          MacOSPlugin.fromYaml(name, platformsYaml[MacOSPlugin.kConfigKey]);
+          MacOSPlugin.fromYaml(name, platformsYaml[MacOSPlugin.kConfigKey] as YamlMap);
     }
 
     if (platformsYaml[WebPlugin.kConfigKey] != null) {
       platforms[WebPlugin.kConfigKey] =
-          WebPlugin.fromYaml(name, platformsYaml[WebPlugin.kConfigKey]);
+          WebPlugin.fromYaml(name, platformsYaml[WebPlugin.kConfigKey] as YamlMap);
     }
 
     if (platformsYaml[WindowsPlugin.kConfigKey] != null) {
       platforms[WindowsPlugin.kConfigKey] =
-          WindowsPlugin.fromYaml(name, platformsYaml[WindowsPlugin.kConfigKey]);
+          WindowsPlugin.fromYaml(name, platformsYaml[WindowsPlugin.kConfigKey] as YamlMap);
     }
 
     return Plugin(
@@ -123,19 +123,19 @@
 
   factory Plugin._fromLegacyYaml(String name, String path, dynamic pluginYaml) {
     final Map<String, PluginPlatform> platforms = <String, PluginPlatform>{};
-    final String pluginClass = pluginYaml['pluginClass'];
+    final String pluginClass = pluginYaml['pluginClass'] as String;
     if (pluginYaml != null && pluginClass != null) {
-      final String androidPackage = pluginYaml['androidPackage'];
+      final String androidPackage = pluginYaml['androidPackage'] as String;
       if (androidPackage != null) {
         platforms[AndroidPlugin.kConfigKey] = AndroidPlugin(
           name: name,
-          package: pluginYaml['androidPackage'],
+          package: pluginYaml['androidPackage'] as String,
           pluginClass: pluginClass,
           pluginPath: path,
         );
       }
 
-      final String iosPrefix = pluginYaml['iosPrefix'] ?? '';
+      final String iosPrefix = pluginYaml['iosPrefix'] as String ?? '';
       platforms[IOSPlugin.kConfigKey] =
           IOSPlugin(
             name: name,
@@ -158,7 +158,7 @@
           'Invalid plugin specification. There must be only one key: "platforms", found multiple: ${yaml.keys.join(',')}',
         ];
       } else {
-        return _validateMultiPlatformYaml(yaml['platforms']);
+        return _validateMultiPlatformYaml(yaml['platforms'] as YamlMap);
       }
     } else {
       return _validateLegacyYaml(yaml);
@@ -166,25 +166,24 @@
   }
 
   static List<String> _validateMultiPlatformYaml(YamlMap yaml) {
+    bool isInvalid(String key, bool Function(YamlMap) validate) {
+      final dynamic value = yaml[key];
+      return value is YamlMap && !validate(value);
+    }
     final List<String> errors = <String>[];
-    if (yaml.containsKey(AndroidPlugin.kConfigKey) &&
-        !AndroidPlugin.validate(yaml[AndroidPlugin.kConfigKey])) {
+    if (isInvalid(AndroidPlugin.kConfigKey, AndroidPlugin.validate)) {
       errors.add('Invalid "android" plugin specification.');
     }
-    if (yaml.containsKey(IOSPlugin.kConfigKey) &&
-        !IOSPlugin.validate(yaml[IOSPlugin.kConfigKey])) {
+    if (isInvalid(IOSPlugin.kConfigKey, IOSPlugin.validate)) {
       errors.add('Invalid "ios" plugin specification.');
     }
-    if (yaml.containsKey(LinuxPlugin.kConfigKey) &&
-        !LinuxPlugin.validate(yaml[LinuxPlugin.kConfigKey])) {
+    if (isInvalid(LinuxPlugin.kConfigKey, LinuxPlugin.validate)) {
       errors.add('Invalid "linux" plugin specification.');
     }
-    if (yaml.containsKey(MacOSPlugin.kConfigKey) &&
-        !MacOSPlugin.validate(yaml[MacOSPlugin.kConfigKey])) {
+    if (isInvalid(MacOSPlugin.kConfigKey, MacOSPlugin.validate)) {
       errors.add('Invalid "macos" plugin specification.');
     }
-    if (yaml.containsKey(WindowsPlugin.kConfigKey) &&
-        !WindowsPlugin.validate(yaml[WindowsPlugin.kConfigKey])) {
+    if (isInvalid(WindowsPlugin.kConfigKey, WindowsPlugin.validate)) {
       errors.add('Invalid "windows" plugin specification.');
     }
     return errors;
@@ -221,7 +220,7 @@
     return null;
   }
   final dynamic flutterConfig = pubspec['flutter'];
-  if (flutterConfig == null || !flutterConfig.containsKey('plugin')) {
+  if (flutterConfig == null || !(flutterConfig.containsKey('plugin') as bool)) {
     return null;
   }
   final String packageRootPath = fs.path.fromUri(packageRoot);
@@ -229,7 +228,7 @@
   return Plugin.fromYaml(
     name,
     packageRootPath,
-    flutterConfig['plugin'],
+    flutterConfig['plugin'] as YamlMap,
   );
 }
 
@@ -400,7 +399,7 @@
       // If a plugin is using an embedding version older than 2.0 and the app is using 2.0,
       // then add shim for the old plugins.
       for (Map<String, dynamic> plugin in androidPlugins) {
-        if (plugin['supportsEmbeddingV1'] && !plugin['supportsEmbeddingV2']) {
+        if (plugin['supportsEmbeddingV1'] as bool && !(plugin['supportsEmbeddingV2'] as bool)) {
           templateContext['needsShim'] = true;
           if (project.isModule) {
             printStatus(
@@ -420,7 +419,7 @@
     case AndroidEmbeddingVersion.v1:
     default:
       for (Map<String, dynamic> plugin in androidPlugins) {
-        if (!plugin['supportsEmbeddingV1'] && plugin['supportsEmbeddingV2']) {
+        if (!(plugin['supportsEmbeddingV1'] as bool) && plugin['supportsEmbeddingV2'] as bool) {
           throwToolExit(
             'The plugin `${plugin['name']}` requires your app to be migrated to '
             'the Android embedding v2. Follow the steps on https://flutter.dev/go/android-project-migration '
diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart
index 70955e4..80575bf 100644
--- a/packages/flutter_tools/lib/src/project.dart
+++ b/packages/flutter_tools/lib/src/project.dart
@@ -231,12 +231,12 @@
     if (!pubspecFile.existsSync()) {
       return null;
     }
-    final YamlMap pubspec = loadYaml(pubspecFile.readAsStringSync());
+    final YamlMap pubspec = loadYaml(pubspecFile.readAsStringSync()) as YamlMap;
     // If the pubspec file is empty, this will be null.
     if (pubspec == null) {
       return null;
     }
-    return pubspec['builders'];
+    return pubspec['builders'] as YamlMap;
   }
 
   /// Whether there are any builders used by this package.
diff --git a/packages/flutter_tools/lib/src/reporting/events.dart b/packages/flutter_tools/lib/src/reporting/events.dart
index 3ab033c..d57038d 100644
--- a/packages/flutter_tools/lib/src/reporting/events.dart
+++ b/packages/flutter_tools/lib/src/reporting/events.dart
@@ -112,7 +112,7 @@
       flutterUsage.sendEvent(category, parameter, label: label);
       return;
     }
-    final GroupedValidator group = validator;
+    final GroupedValidator group = validator as GroupedValidator;
     for (int i = 0; i < group.subValidators.length; i++) {
       final DoctorValidator v = group.subValidators[i];
       final ValidationResult r = group.subResults[i];
diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart
index 970d332..1886aa1 100644
--- a/packages/flutter_tools/lib/src/run_hot.dart
+++ b/packages/flutter_tools/lib/src/run_hot.dart
@@ -496,8 +496,8 @@
            (reloadReport['success'] == false &&
             (reloadReport['details'] is Map<String, dynamic> &&
              reloadReport['details']['notices'] is List<dynamic> &&
-             reloadReport['details']['notices'].isNotEmpty &&
-             reloadReport['details']['notices'].every(
+             (reloadReport['details']['notices'] as List<dynamic>).isNotEmpty &&
+             (reloadReport['details']['notices'] as List<dynamic>).every(
                (dynamic item) => item is Map<String, dynamic> && item['message'] is String
              )
             )
@@ -509,7 +509,7 @@
       }
       return false;
     }
-    if (!reloadReport['success']) {
+    if (!(reloadReport['success'] as bool)) {
       if (printErrors) {
         printError('Hot reload was rejected:');
         for (Map<String, dynamic> notice in reloadReport['details']['notices']) {
@@ -754,16 +754,16 @@
         // Collect stats only from the first device. If/when run -d all is
         // refactored, we'll probably need to send one hot reload/restart event
         // per device to analytics.
-        firstReloadDetails ??= reloadReport['details'];
-        final int loadedLibraryCount = reloadReport['details']['loadedLibraryCount'];
-        final int finalLibraryCount = reloadReport['details']['finalLibraryCount'];
+        firstReloadDetails ??= castStringKeyedMap(reloadReport['details']);
+        final int loadedLibraryCount = reloadReport['details']['loadedLibraryCount'] as int;
+        final int finalLibraryCount = reloadReport['details']['finalLibraryCount'] as int;
         printTrace('reloaded $loadedLibraryCount of $finalLibraryCount libraries');
         reloadMessage = 'Reloaded $loadedLibraryCount of $finalLibraryCount libraries';
       }
     } on Map<String, dynamic> catch (error, stackTrace) {
       printTrace('Hot reload failed: $error\n$stackTrace');
-      final int errorCode = error['code'];
-      String errorMessage = error['message'];
+      final int errorCode = error['code'] as int;
+      String errorMessage = error['message'] as String;
       if (errorCode == Isolate.kIsolateReloadBarred) {
         errorMessage = 'Unable to hot reload application due to an unrecoverable error in '
                        'the source code. Please address the error and then use "R" to '
@@ -905,10 +905,10 @@
       fullRestart: false,
       reason: reason,
       overallTimeInMs: reloadInMs,
-      finalLibraryCount: firstReloadDetails['finalLibraryCount'],
-      syncedLibraryCount: firstReloadDetails['receivedLibraryCount'],
-      syncedClassesCount: firstReloadDetails['receivedClassesCount'],
-      syncedProceduresCount: firstReloadDetails['receivedProceduresCount'],
+      finalLibraryCount: firstReloadDetails['finalLibraryCount'] as int,
+      syncedLibraryCount: firstReloadDetails['receivedLibraryCount'] as int,
+      syncedClassesCount: firstReloadDetails['receivedClassesCount'] as int,
+      syncedProceduresCount: firstReloadDetails['receivedProceduresCount'] as int,
       syncedBytes: updatedDevFS.syncedBytes,
       invalidatedSourcesCount: updatedDevFS.invalidatedSourcesCount,
       transferTimeInMs: devFSTimer.elapsed.inMilliseconds,
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart
index 2d52f73..a23fa37 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart
@@ -113,7 +113,7 @@
   );
 
   @override
-  FlutterCommandRunner get runner => super.runner;
+  FlutterCommandRunner get runner => super.runner as FlutterCommandRunner;
 
   bool _requiresPubspecYaml = false;
 
@@ -126,7 +126,7 @@
 
   bool _usesIpv6Flag = false;
 
-  bool get shouldRunPub => _usesPubOption && argResults['pub'];
+  bool get shouldRunPub => _usesPubOption && boolArg('pub');
 
   bool get shouldUpdateCache => true;
 
@@ -173,7 +173,7 @@
 
   String get targetFile {
     if (argResults.wasParsed('target')) {
-      return argResults['target'];
+      return stringArg('target');
     }
     if (argResults.rest.isNotEmpty) {
       return argResults.rest.first;
@@ -252,7 +252,7 @@
         '"--host-vmservice-port" may be specified.');
     }
     try {
-      return int.parse(argResults['observatory-port'] ?? argResults['host-vmservice-port']);
+      return int.parse(stringArg('observatory-port') ?? stringArg('host-vmservice-port'));
     } on FormatException catch (error) {
       throwToolExit('Invalid port for `--observatory-port/--host-vmservice-port`: $error');
     }
@@ -267,7 +267,7 @@
       return null;
     }
     try {
-      return int.parse(argResults['device-vmservice-port']);
+      return int.parse(stringArg('device-vmservice-port'));
     } on FormatException catch (error) {
       throwToolExit('Invalid port for `--device-vmservice-port`: $error');
     }
@@ -285,7 +285,7 @@
     _usesIpv6Flag = true;
   }
 
-  bool get ipv6 => _usesIpv6Flag ? argResults['ipv6'] : null;
+  bool get ipv6 => _usesIpv6Flag ? boolArg('ipv6') : null;
 
   void usesBuildNumberOption() {
     argParser.addOption('build-number',
@@ -318,7 +318,7 @@
   }
 
   /// The values passed via the `--dart-define` option.
-  List<String> get dartDefines => argResults['dart-define'];
+  List<String> get dartDefines => stringsArg('dart-define');
 
   void usesIsolateFilterOption({ @required bool hide }) {
     argParser.addOption('isolate-filter',
@@ -382,18 +382,18 @@
   }
 
   BuildMode getBuildMode() {
-    final bool debugResult = _excludeDebug ? false : argResults['debug'];
-    final List<bool> modeFlags = <bool>[debugResult, argResults['profile'], argResults['release']];
+    final bool debugResult = !_excludeDebug && boolArg('debug');
+    final List<bool> modeFlags = <bool>[debugResult, boolArg('profile'), boolArg('release')];
     if (modeFlags.where((bool flag) => flag).length > 1) {
       throw UsageException('Only one of --debug, --profile, or --release can be specified.', null);
     }
     if (debugResult) {
       return BuildMode.debug;
     }
-    if (argResults['profile']) {
+    if (boolArg('profile')) {
       return BuildMode.profile;
     }
-    if (argResults['release']) {
+    if (boolArg('release')) {
       return BuildMode.release;
     }
     return _defaultBuildMode;
@@ -419,21 +419,20 @@
   }
 
   BuildInfo getBuildInfo() {
-    final bool trackWidgetCreation = argParser.options.containsKey('track-widget-creation')
-        ? argResults['track-widget-creation']
-        : false;
+    final bool trackWidgetCreation = argParser.options.containsKey('track-widget-creation') &&
+      boolArg('track-widget-creation');
 
-    final String buildNumber = argParser.options.containsKey('build-number') && argResults['build-number'] != null
-        ? argResults['build-number']
+    final String buildNumber = argParser.options.containsKey('build-number')
+        ? stringArg('build-number')
         : null;
 
     String extraFrontEndOptions =
         argParser.options.containsKey(FlutterOptions.kExtraFrontEndOptions)
-            ? argResults[FlutterOptions.kExtraFrontEndOptions]
+            ? stringArg(FlutterOptions.kExtraFrontEndOptions)
             : null;
     if (argParser.options.containsKey(FlutterOptions.kEnableExperiment) &&
         argResults[FlutterOptions.kEnableExperiment] != null) {
-      for (String expFlag in argResults[FlutterOptions.kEnableExperiment]) {
+      for (String expFlag in stringsArg(FlutterOptions.kEnableExperiment)) {
         final String flag = '--enable-experiment=' + expFlag;
         if (extraFrontEndOptions != null) {
           extraFrontEndOptions += ',' + flag;
@@ -445,20 +444,22 @@
 
     return BuildInfo(getBuildMode(),
       argParser.options.containsKey('flavor')
-        ? argResults['flavor']
+        ? stringArg('flavor')
         : null,
       trackWidgetCreation: trackWidgetCreation,
       extraFrontEndOptions: extraFrontEndOptions,
       extraGenSnapshotOptions: argParser.options.containsKey(FlutterOptions.kExtraGenSnapshotOptions)
-          ? argResults[FlutterOptions.kExtraGenSnapshotOptions]
+          ? stringArg(FlutterOptions.kExtraGenSnapshotOptions)
           : null,
       fileSystemRoots: argParser.options.containsKey(FlutterOptions.kFileSystemRoot)
-          ? argResults[FlutterOptions.kFileSystemRoot] : null,
+          ? stringsArg(FlutterOptions.kFileSystemRoot)
+          : null,
       fileSystemScheme: argParser.options.containsKey(FlutterOptions.kFileSystemScheme)
-          ? argResults[FlutterOptions.kFileSystemScheme] : null,
+          ? stringArg(FlutterOptions.kFileSystemScheme)
+          : null,
       buildNumber: buildNumber,
       buildName: argParser.options.containsKey('build-name')
-          ? argResults['build-name']
+          ? stringArg('build-name')
           : null,
     );
   }
@@ -471,7 +472,7 @@
   /// tracking of the command.
   Future<String> get usagePath async {
     if (parent is FlutterCommand) {
-      final FlutterCommand commandParent = parent;
+      final FlutterCommand commandParent = parent as FlutterCommand;
       final String path = await commandParent.usagePath;
       // Don't report for parents that return null for usagePath.
       return path == null ? null : '$path/$name';
@@ -683,7 +684,7 @@
       }
 
       // Validate the current package map only if we will not be running "pub get" later.
-      if (parent?.name != 'pub' && !(_usesPubOption && argResults['pub'])) {
+      if (parent?.name != 'pub' && !(_usesPubOption && boolArg('pub'))) {
         final String error = PackageMap(PackageMap.globalPackagesPath).checkValid();
         if (error != null) {
           throw ToolExit(error);
@@ -700,6 +701,15 @@
   }
 
   ApplicationPackageStore applicationPackages;
+
+  /// Gets the parsed command-line option named [name] as `bool`.
+  bool boolArg(String name) => argResults[name] as bool;
+
+  /// Gets the parsed command-line option named [name] as `String`.
+  String stringArg(String name) => argResults[name] as String;
+
+  /// Gets the parsed command-line option named [name] as `List<String>`.
+  List<String> stringsArg(String name) => argResults[name] as List<String>;
 }
 
 /// A mixin which applies an implementation of [requiredArtifacts] that only
@@ -735,7 +745,7 @@
   Future<Set<DevelopmentArtifact>> get requiredArtifacts async {
     // If there is no specified target device, fallback to the default
     // confiugration.
-    final String rawTargetPlatform = argResults['target-platform'];
+    final String rawTargetPlatform = stringArg('target-platform');
     final TargetPlatform targetPlatform = getTargetPlatformForName(rawTargetPlatform);
     if (targetPlatform == null) {
       return super.requiredArtifacts;
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
index 81227cd..3ee6850 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
@@ -212,7 +212,7 @@
     } catch (error) {
       // we don't have a logger at the time this is run
       // (which is why we don't use printTrace here)
-      print(userMessages.runnerNoRoot(error));
+      print(userMessages.runnerNoRoot('$error'));
     }
     return '.';
   }
@@ -224,7 +224,7 @@
       // override this function so we can call tryArgsCompletion instead, so the
       // completion package can interrogate the argParser, and as part of that,
       // it calls argParser.parse(args) itself and returns the result.
-      return tryArgsCompletion(args, argParser);
+      return tryArgsCompletion(args.toList(), argParser);
     } on ArgParserException catch (error) {
       if (error.commands.isEmpty) {
         usageException(error.message);
@@ -258,7 +258,7 @@
     };
 
     // Check for verbose.
-    if (topLevelResults['verbose']) {
+    if (topLevelResults['verbose'] as bool) {
       // Override the logger.
       contextOverrides[Logger] = VerboseLogger(logger);
     }
@@ -269,7 +269,7 @@
     int wrapColumn;
     if (topLevelResults.wasParsed('wrap-column')) {
       try {
-        wrapColumn = int.parse(topLevelResults['wrap-column']);
+        wrapColumn = int.parse(topLevelResults['wrap-column'] as String);
         if (wrapColumn < 0) {
           throwToolExit(userMessages.runnerWrapColumnInvalid(topLevelResults['wrap-column']));
         }
@@ -281,23 +281,23 @@
     // If we're not writing to a terminal with a defined width, then don't wrap
     // anything, unless the user explicitly said to.
     final bool useWrapping = topLevelResults.wasParsed('wrap')
-        ? topLevelResults['wrap']
-        : io.stdio.terminalColumns == null ? false : topLevelResults['wrap'];
+        ? topLevelResults['wrap'] as bool
+        : io.stdio.terminalColumns != null && topLevelResults['wrap'] as bool;
     contextOverrides[OutputPreferences] = OutputPreferences(
       wrapText: useWrapping,
-      showColor: topLevelResults['color'],
+      showColor: topLevelResults['color'] as bool,
       wrapColumn: wrapColumn,
     );
 
-    if (topLevelResults['show-test-device'] ||
+    if (topLevelResults['show-test-device'] as bool ||
         topLevelResults['device-id'] == FlutterTesterDevices.kTesterDeviceId) {
       FlutterTesterDevices.showFlutterTesterDevice = true;
     }
 
-    String recordTo = topLevelResults['record-to'];
-    String replayFrom = topLevelResults['replay-from'];
+    String recordTo = topLevelResults['record-to'] as String;
+    String replayFrom = topLevelResults['replay-from'] as String;
 
-    if (topLevelResults['bug-report']) {
+    if (topLevelResults['bug-report'] as bool) {
       // --bug-report implies --record-to=<tmp_path>
       final Directory tempDir = const LocalFileSystem()
           .systemTempDirectory
@@ -353,7 +353,7 @@
 
     // We must set Cache.flutterRoot early because other features use it (e.g.
     // enginePath's initializer uses it).
-    final String flutterRoot = topLevelResults['flutter-root'] ?? defaultFlutterRoot;
+    final String flutterRoot = topLevelResults['flutter-root'] as String ?? defaultFlutterRoot;
     Cache.flutterRoot = fs.path.normalize(fs.path.absolute(flutterRoot));
 
     // Set up the tooling configuration.
@@ -369,13 +369,13 @@
         return MapEntry<Type, Generator>(type, () => value);
       }),
       body: () async {
-        logger.quiet = topLevelResults['quiet'];
+        logger.quiet = topLevelResults['quiet'] as bool;
 
         if (platform.environment['FLUTTER_ALREADY_LOCKED'] != 'true') {
           await Cache.lock();
         }
 
-        if (topLevelResults['suppress-analytics']) {
+        if (topLevelResults['suppress-analytics'] as bool) {
           flutterUsage.suppressAnalytics = true;
         }
 
@@ -387,21 +387,21 @@
           printError('Please ensure you have permissions in the artifact cache directory.');
           throwToolExit('Failed to write the version file');
         }
-        if (topLevelResults.command?.name != 'upgrade' && topLevelResults['version-check']) {
+        if (topLevelResults.command?.name != 'upgrade' && topLevelResults['version-check'] as bool) {
           await FlutterVersion.instance.checkFlutterVersionFreshness();
         }
 
         if (topLevelResults.wasParsed('packages')) {
-          PackageMap.globalPackagesPath = fs.path.normalize(fs.path.absolute(topLevelResults['packages']));
+          PackageMap.globalPackagesPath = fs.path.normalize(fs.path.absolute(topLevelResults['packages'] as String));
         }
 
         // See if the user specified a specific device.
-        deviceManager.specifiedDeviceId = topLevelResults['device-id'];
+        deviceManager.specifiedDeviceId = topLevelResults['device-id'] as String;
 
-        if (topLevelResults['version']) {
+        if (topLevelResults['version'] as bool) {
           flutterUsage.sendCommand('version');
           String status;
-          if (topLevelResults['machine']) {
+          if (topLevelResults['machine'] as bool) {
             status = const JsonEncoder.withIndent('  ').convert(FlutterVersion.instance.toJson());
           } else {
             status = FlutterVersion.instance.toString();
@@ -410,7 +410,7 @@
           return;
         }
 
-        if (topLevelResults['machine']) {
+        if (topLevelResults['machine'] as bool) {
           throwToolExit('The --machine flag is only valid with the --version flag.', exitCode: 2);
         }
         await super.runCommand(topLevelResults);
@@ -426,7 +426,7 @@
   }
 
   String _findEnginePath(ArgResults globalResults) {
-    String engineSourcePath = globalResults['local-engine-src-path'] ?? platform.environment[kFlutterEngineEnvironmentVariableName];
+    String engineSourcePath = globalResults['local-engine-src-path'] as String ?? platform.environment[kFlutterEngineEnvironmentVariableName];
 
     if (engineSourcePath == null && globalResults['local-engine'] != null) {
       try {
@@ -478,7 +478,7 @@
   EngineBuildPaths _findEngineBuildPath(ArgResults globalResults, String enginePath) {
     String localEngine;
     if (globalResults['local-engine'] != null) {
-      localEngine = globalResults['local-engine'];
+      localEngine = globalResults['local-engine'] as String;
     } else {
       throwToolExit(userMessages.runnerLocalEngineRequired, exitCode: 2);
     }
diff --git a/packages/flutter_tools/lib/src/template.dart b/packages/flutter_tools/lib/src/template.dart
index e8ffe45..25d6861 100644
--- a/packages/flutter_tools/lib/src/template.dart
+++ b/packages/flutter_tools/lib/src/template.dart
@@ -90,25 +90,25 @@
       final Match match = _kTemplateLanguageVariant.matchAsPrefix(relativeDestinationPath);
       if (match != null) {
         final String platform = match.group(1);
-        final String language = context['${platform}Language'];
+        final String language = context['${platform}Language'] as String;
         if (language != match.group(2)) {
           return null;
         }
         relativeDestinationPath = relativeDestinationPath.replaceAll('$platform-$language.tmpl', platform);
       }
       // Only build a web project if explicitly asked.
-      final bool web = context['web'];
+      final bool web = context['web'] as bool;
       if (relativeDestinationPath.contains('web') && !web) {
         return null;
       }
       // Only build a macOS project if explicitly asked.
-      final bool macOS = context['macos'];
+      final bool macOS = context['macos'] as bool;
       if (relativeDestinationPath.startsWith('macos.tmpl') && !macOS) {
         return null;
       }
-      final String projectName = context['projectName'];
-      final String androidIdentifier = context['androidIdentifier'];
-      final String pluginClass = context['pluginClass'];
+      final String projectName = context['projectName'] as String;
+      final String androidIdentifier = context['androidIdentifier'] as String;
+      final String pluginClass = context['pluginClass'] as String;
       final String destinationDirPath = destination.absolute.path;
       final String pathSeparator = fs.path.separator;
       String finalDestinationPath = fs.path
@@ -130,7 +130,7 @@
     }
 
     _templateFilePaths.forEach((String relativeDestinationPath, String absoluteSourcePath) {
-      final bool withRootModule = context['withRootModule'] ?? false;
+      final bool withRootModule = context['withRootModule'] as bool ?? false;
       if (!withRootModule && absoluteSourcePath.contains('flutter_root')) {
         return;
       }
diff --git a/packages/flutter_tools/lib/src/test/coverage_collector.dart b/packages/flutter_tools/lib/src/test/coverage_collector.dart
index ed3bdf6..06b1fbc 100644
--- a/packages/flutter_tools/lib/src/test/coverage_collector.dart
+++ b/packages/flutter_tools/lib/src/test/coverage_collector.dart
@@ -12,6 +12,7 @@
 import '../base/os.dart';
 import '../base/platform.dart';
 import '../base/process.dart';
+import '../base/utils.dart';
 import '../dart/package_map.dart';
 import '../globals.dart';
 import '../vmservice.dart';
@@ -22,7 +23,7 @@
 class CoverageCollector extends TestWatcher {
   CoverageCollector({this.libraryPredicate});
 
-  Map<String, dynamic> _globalHitmap;
+  Map<String, Map<int, int>> _globalHitmap;
   bool Function(String) libraryPredicate;
 
   @override
@@ -31,7 +32,7 @@
     await collectCoverage(event.process, event.observatoryUri);
   }
 
-  void _addHitmap(Map<String, dynamic> hitmap) {
+  void _addHitmap(Map<String, Map<int, int>> hitmap) {
     if (_globalHitmap == null) {
       _globalHitmap = hitmap;
     } else {
@@ -55,7 +56,7 @@
     assert(data != null);
 
     print('($observatoryUri): collected coverage data; merging...');
-    _addHitmap(coverage.createHitmap(data['coverage']));
+    _addHitmap(coverage.createHitmap(data['coverage'] as List<dynamic>));
     print('($observatoryUri): done merging coverage data into global coverage map.');
   }
 
@@ -87,7 +88,7 @@
     assert(data != null);
 
     printTrace('pid $pid ($observatoryUri): collected coverage data; merging...');
-    _addHitmap(coverage.createHitmap(data['coverage']));
+    _addHitmap(coverage.createHitmap(data['coverage'] as List<dynamic>));
     printTrace('pid $pid ($observatoryUri): done merging coverage data into global coverage map.');
   }
 
@@ -205,10 +206,10 @@
       continue;
     }
     for (Map<String, dynamic> script in scriptList['scripts']) {
-      if (!libraryPredicate(script['uri'])) {
+      if (!libraryPredicate(script['uri'] as String)) {
         continue;
       }
-      final String scriptId = script['id'];
+      final String scriptId = script['id'] as String;
       futures.add(
         isolateRef.invokeRpcRaw('getSourceReport', params: <String, dynamic>{
           'forceCompile': true,
@@ -246,19 +247,19 @@
   for (String scriptId in scripts.keys) {
     final Map<String, dynamic> sourceReport = sourceReports[scriptId];
     for (Map<String, dynamic> range in sourceReport['ranges']) {
-      final Map<String, dynamic> coverage = range['coverage'];
+      final Map<String, dynamic> coverage = castStringKeyedMap(range['coverage']);
       // Coverage reports may sometimes be null for a Script.
       if (coverage == null) {
         continue;
       }
-      final Map<String, dynamic> scriptRef = sourceReport['scripts'][range['scriptIndex']];
-      final String uri = scriptRef['uri'];
+      final Map<String, dynamic> scriptRef = castStringKeyedMap(sourceReport['scripts'][range['scriptIndex']]);
+      final String uri = scriptRef['uri'] as String;
 
       hitMaps[uri] ??= <int, int>{};
       final Map<int, int> hitMap = hitMaps[uri];
-      final List<dynamic> hits = coverage['hits'];
-      final List<dynamic> misses = coverage['misses'];
-      final List<dynamic> tokenPositions = scripts[scriptRef['id']]['tokenPosTable'];
+      final List<int> hits = (coverage['hits'] as List<dynamic>).cast<int>();
+      final List<int> misses = (coverage['misses'] as List<dynamic>).cast<int>();
+      final List<dynamic> tokenPositions = scripts[scriptRef['id']]['tokenPosTable'] as List<dynamic>;
       // The token positions can be null if the script has no coverable lines.
       if (tokenPositions == null) {
         continue;
@@ -291,7 +292,7 @@
   int max = tokenPositions.length;
   while (min < max) {
     final int mid = min + ((max - min) >> 1);
-    final List<dynamic> row = tokenPositions[mid];
+    final List<int> row = (tokenPositions[mid] as List<dynamic>).cast<int>();
     if (row[1] > position) {
       max = mid;
     } else {
diff --git a/packages/flutter_tools/lib/src/test/flutter_platform.dart b/packages/flutter_tools/lib/src/test/flutter_platform.dart
index 0983e13..0fed5a3 100644
--- a/packages/flutter_tools/lib/src/test/flutter_platform.dart
+++ b/packages/flutter_tools/lib/src/test/flutter_platform.dart
@@ -428,7 +428,7 @@
             webSocket.complete(WebSocketTransformer.upgrade(request));
           }
         },
-        onError: (dynamic error, dynamic stack) {
+        onError: (dynamic error, StackTrace stack) {
           // If you reach here, it's unlikely we're going to be able to really handle this well.
           printTrace('test $ourTestCount: test harness socket server experienced an unexpected error: $error');
           if (!controllerSinkClosed) {
@@ -595,7 +595,7 @@
               testSocket.add(json.encode(event));
             },
             onDone: harnessDone.complete,
-            onError: (dynamic error, dynamic stack) {
+            onError: (dynamic error, StackTrace stack) {
               // If you reach here, it's unlikely we're going to be able to really handle this well.
               printError('test harness controller stream experienced an unexpected error\ntest: $testPath\nerror: $error');
               if (!controllerSinkClosed) {
@@ -611,12 +611,11 @@
           final Completer<void> testDone = Completer<void>();
           final StreamSubscription<dynamic> testToHarness = testSocket.listen(
             (dynamic encodedEvent) {
-              assert(encodedEvent
-                  is String); // we shouldn't ever get binary messages
-              controller.sink.add(json.decode(encodedEvent));
+              assert(encodedEvent is String); // we shouldn't ever get binary messages
+              controller.sink.add(json.decode(encodedEvent as String));
             },
             onDone: testDone.complete,
-            onError: (dynamic error, dynamic stack) {
+            onError: (dynamic error, StackTrace stack) {
               // If you reach here, it's unlikely we're going to be able to really handle this well.
               printError('test socket stream experienced an unexpected error\ntest: $testPath\nerror: $error');
               if (!controllerSinkClosed) {
@@ -970,10 +969,11 @@
       (List<dynamic> futureResults) {
         assert(futureResults.length == 2);
         assert(futureResults.first == null);
-        if (futureResults.last is _AsyncError) {
-          _done.completeError(futureResults.last.error, futureResults.last.stack);
+        final dynamic lastResult = futureResults.last;
+        if (lastResult is _AsyncError) {
+          _done.completeError(lastResult.error, lastResult.stack);
         } else {
-          assert(futureResults.last == null);
+          assert(lastResult == null);
           _done.complete();
         }
       },
diff --git a/packages/flutter_tools/lib/src/tracing.dart b/packages/flutter_tools/lib/src/tracing.dart
index bba004a..6a57959 100644
--- a/packages/flutter_tools/lib/src/tracing.dart
+++ b/packages/flutter_tools/lib/src/tracing.dart
@@ -96,11 +96,11 @@
 
   int extractInstantEventTimestamp(String eventName) {
     final List<Map<String, dynamic>> events =
-        List<Map<String, dynamic>>.from(timeline['traceEvents']);
+        List<Map<String, dynamic>>.from(timeline['traceEvents'] as List<Map<String, dynamic>>);
     final Map<String, dynamic> event = events.firstWhere(
       (Map<String, dynamic> event) => event['name'] == eventName, orElse: () => null,
     );
-    return event == null ? null : event['ts'];
+    return event == null ? null : (event['ts'] as int);
   }
 
   String message = 'No useful metrics were gathered.';
diff --git a/packages/flutter_tools/lib/src/version.dart b/packages/flutter_tools/lib/src/version.dart
index c3d9364..5c7702a 100644
--- a/packages/flutter_tools/lib/src/version.dart
+++ b/packages/flutter_tools/lib/src/version.dart
@@ -434,7 +434,7 @@
       // Attempt to parse stamp JSON.
       try {
         final dynamic jsonObject = json.decode(versionCheckStamp);
-        if (jsonObject is Map) {
+        if (jsonObject is Map<String, dynamic>) {
           return fromJson(jsonObject);
         } else {
           printTrace('Warning: expected version stamp to be a Map but found: $jsonObject');
@@ -452,7 +452,7 @@
   static VersionCheckStamp fromJson(Map<String, dynamic> jsonObject) {
     DateTime readDateTime(String property) {
       return jsonObject.containsKey(property)
-          ? DateTime.parse(jsonObject[property])
+          ? DateTime.parse(jsonObject[property] as String)
           : null;
     }
 
@@ -536,7 +536,7 @@
   final ProcessResult results = processManager.runSync(command, workingDirectory: Cache.flutterRoot);
 
   if (results.exitCode == 0) {
-    return results.stdout.trim();
+    return (results.stdout as String).trim();
   }
 
   if (!lenient) {
@@ -564,7 +564,7 @@
   final ProcessResult results = await processManager.run(command, workingDirectory: Cache.flutterRoot);
 
   if (results.exitCode == 0) {
-    return results.stdout.trim();
+    return (results.stdout as String).trim();
   }
 
   throw VersionCheckError(
diff --git a/packages/flutter_tools/lib/src/vmservice.dart b/packages/flutter_tools/lib/src/vmservice.dart
index c324953..58a3931 100644
--- a/packages/flutter_tools/lib/src/vmservice.dart
+++ b/packages/flutter_tools/lib/src/vmservice.dart
@@ -118,14 +118,14 @@
     _peer.listen().catchError(_connectionError.completeError);
 
     _peer.registerMethod('streamNotify', (rpc.Parameters event) {
-      _handleStreamNotify(event.asMap);
+      _handleStreamNotify(event.asMap.cast<String, dynamic>());
     });
 
     if (reloadSources != null) {
       _peer.registerMethod('reloadSources', (rpc.Parameters params) async {
-        final String isolateId = params['isolateId'].value;
-        final bool force = params.asMap['force'] ?? false;
-        final bool pause = params.asMap['pause'] ?? false;
+        final String isolateId = params['isolateId'].value as String;
+        final bool force = params.asMap['force'] as bool ?? false;
+        final bool pause = params.asMap['pause'] as bool ?? false;
 
         if (isolateId.isEmpty) {
           throw rpc.RpcException.invalidParams('Invalid \'isolateId\': $isolateId');
@@ -150,11 +150,11 @@
       // currently in the same way as hot reload, it leaves the tool free
       // to change to a more efficient implementation in the future.
       _peer.registerMethod('reloadMethod', (rpc.Parameters params) async {
-        final String isolateId = params['isolateId'].value;
-        final String libraryId = params['library'].value;
-        final String classId = params['class'].value;
-        final String methodId = params['method'].value;
-        final String methodBody = params['methodBody'].value;
+        final String isolateId = params['isolateId'].value as String;
+        final String libraryId = params['library'].value as String;
+        final String classId = params['class'].value as String;
+        final String methodId = params['method'].value as String;
+        final String methodBody = params['methodBody'].value as String;
 
         if (libraryId.isEmpty) {
           throw rpc.RpcException.invalidParams('Invalid \'libraryId\': $libraryId');
@@ -189,7 +189,7 @@
 
     if (restart != null) {
       _peer.registerMethod('hotRestart', (rpc.Parameters params) async {
-        final bool pause = params.asMap['pause'] ?? false;
+        final bool pause = params.asMap['pause'] as bool ?? false;
 
         if (pause is! bool) {
           throw rpc.RpcException.invalidParams('Invalid \'pause\': $pause');
@@ -396,9 +396,9 @@
   }
 
   void _handleStreamNotify(Map<String, dynamic> data) {
-    final String streamId = data['streamId'];
-    final Map<String, dynamic> eventData = data['event'];
-    final Map<String, dynamic> eventIsolate = eventData['isolate'];
+    final String streamId = data['streamId'] as String;
+    final Map<String, dynamic> eventData = castStringKeyedMap(data['event']);
+    final Map<String, dynamic> eventIsolate = castStringKeyedMap(eventData['isolate']);
 
     // Log event information.
     printTrace('Notification from VM: $data');
@@ -406,8 +406,8 @@
     ServiceEvent event;
     if (eventIsolate != null) {
       // getFromMap creates the Isolate if necessary.
-      final Isolate isolate = vm.getFromMap(eventIsolate);
-      event = ServiceObject._fromMap(isolate, eventData);
+      final Isolate isolate = vm.getFromMap(eventIsolate) as Isolate;
+      event = ServiceObject._fromMap(isolate, eventData) as ServiceEvent;
       if (event.kind == ServiceEvent.kIsolateExit) {
         vm._isolateCache.remove(isolate.id);
         vm._buildIsolateList();
@@ -418,7 +418,7 @@
       }
     } else {
       // The event doesn't have an isolate, so it is owned by the VM.
-      event = ServiceObject._fromMap(vm, eventData);
+      event = ServiceObject._fromMap(vm, eventData) as ServiceEvent;
     }
     _getEventController(streamId).add(event);
   }
@@ -511,7 +511,7 @@
       throw VMServiceObjectLoadError('Expected a service map', map);
     }
 
-    final String type = _stripRef(map['type']);
+    final String type = _stripRef(map['type'] as String);
 
     ServiceObject serviceObject;
     switch (type) {
@@ -598,7 +598,7 @@
       _inProgressReload = completer.future;
       try {
         final Map<String, dynamic> response = await _fetchDirect();
-        if (_stripRef(response['type']) == 'Sentinel') {
+        if (_stripRef(response['type'] as String) == 'Sentinel') {
           // An object may have been collected.
           completer.complete(ServiceObject._fromMap(owner, response));
         } else {
@@ -618,25 +618,25 @@
   /// Update [this] using [map] as a source. [map] can be a service reference.
   void updateFromMap(Map<String, dynamic> map) {
     // Don't allow the type to change on an object update.
-    final bool mapIsRef = _hasRef(map['type']);
-    final String mapType = _stripRef(map['type']);
+    final bool mapIsRef = _hasRef(map['type'] as String);
+    final String mapType = _stripRef(map['type'] as String);
 
     if ((_type != null) && (_type != mapType)) {
       throw VMServiceObjectLoadError('ServiceObject types must not change',
                                          map);
     }
     _type = mapType;
-    _vmType = map.containsKey('_vmType') ? _stripRef(map['_vmType']) : _type;
+    _vmType = map.containsKey('_vmType') ? _stripRef(map['_vmType'] as String) : _type;
 
     _canCache = map['fixedId'] == true;
     if ((_id != null) && (_id != map['id']) && _canCache) {
       throw VMServiceObjectLoadError('ServiceObject id changed', map);
     }
-    _id = map['id'];
+    _id = map['id'] as String;
 
     // Copy name properties.
-    _name = map['name'];
-    _vmName = map.containsKey('_vmName') ? map['_vmName'] : _name;
+    _name = map['name'] as String;
+    _vmName = map.containsKey('_vmName') ? map['_vmName'] as String : _name;
 
     // We have now updated all common properties, let the subclasses update
     // their specific properties.
@@ -695,22 +695,22 @@
   void _update(Map<String, dynamic> map, bool mapIsRef) {
     _loaded = true;
     _upgradeCollection(map, owner);
-    _kind = map['kind'];
+    _kind = map['kind'] as String;
     assert(map['isolate'] == null || owner == map['isolate']);
     _timestamp =
-        DateTime.fromMillisecondsSinceEpoch(map['timestamp']);
+        DateTime.fromMillisecondsSinceEpoch(map['timestamp'] as int);
     if (map['extensionKind'] != null) {
-      _extensionKind = map['extensionKind'];
-      _extensionData = map['extensionData'];
+      _extensionKind = map['extensionKind'] as String;
+      _extensionData = castStringKeyedMap(map['extensionData']);
     }
     // map['timelineEvents'] is List<dynamic> which can't be assigned to
     // List<Map<String, dynamic>> directly. Unfortunately, we previously didn't
     // catch this exception because json_rpc_2 is hiding all these exceptions
     // on a Stream.
-    final List<dynamic> dynamicList = map['timelineEvents'];
+    final List<dynamic> dynamicList = map['timelineEvents'] as List<dynamic>;
     _timelineEvents = dynamicList?.cast<Map<String, dynamic>>();
 
-     final String base64Bytes = map['bytes'];
+     final String base64Bytes = map['bytes'] as String;
      if (base64Bytes != null) {
        _message = utf8.decode(base64.decode(base64Bytes)).trim();
      }
@@ -774,15 +774,15 @@
     _upgradeCollection(map, this);
     _loaded = true;
 
-    _pid = map['pid'];
+    _pid = map['pid'] as int;
     if (map['_heapAllocatedMemoryUsage'] != null) {
-      _heapAllocatedMemoryUsage = map['_heapAllocatedMemoryUsage'];
+      _heapAllocatedMemoryUsage = map['_heapAllocatedMemoryUsage'] as int;
     }
-    _maxRSS = map['_maxRSS'];
-    _embedder = map['_embedder'];
+    _maxRSS = map['_maxRSS'] as int;
+    _embedder = map['_embedder'] as String;
 
     // Remove any isolates which are now dead from the isolate cache.
-    _removeDeadIsolates(map['isolates'].cast<Isolate>());
+    _removeDeadIsolates((map['isolates'] as List<dynamic>).cast<Isolate>());
   }
 
   final Map<String, ServiceObject> _cache = <String,ServiceObject>{};
@@ -858,14 +858,14 @@
     if (map == null) {
       return null;
     }
-    final String type = _stripRef(map['type']);
+    final String type = _stripRef(map['type'] as String);
     if (type == 'VM') {
       // Update this VM object.
       updateFromMap(map);
       return this;
     }
 
-    final String mapId = map['id'];
+    final String mapId = map['id'] as String;
 
     switch (type) {
       case 'Isolate':
@@ -873,7 +873,7 @@
         Isolate isolate = _isolateCache[mapId];
         if (isolate == null) {
           // Add new isolate to the cache.
-          isolate = ServiceObject._fromMap(this, map);
+          isolate = ServiceObject._fromMap(this, map) as Isolate;
           _isolateCache[mapId] = isolate;
           _buildIsolateList();
 
@@ -890,7 +890,7 @@
         FlutterView view = _viewCache[mapId];
         if (view == null) {
           // Add new view to the cache.
-          view = ServiceObject._fromMap(this, map);
+          view = ServiceObject._fromMap(this, map) as FlutterView;
           _viewCache[mapId] = view;
         } else {
           view.updateFromMap(map);
@@ -958,7 +958,7 @@
       params: params,
       truncateLogs: truncateLogs,
     );
-    final ServiceObject serviceObject = ServiceObject._fromMap(this, response);
+    final T serviceObject = ServiceObject._fromMap(this, response) as T;
     if ((serviceObject != null) && (serviceObject._canCache)) {
       final String serviceObjectId = serviceObject.id;
       _cache.putIfAbsent(serviceObjectId, () => serviceObject);
@@ -973,7 +973,7 @@
 
   /// List the development file system son the device.
   Future<List<String>> listDevFS() async {
-    return (await invokeRpcRaw('_listDevFS'))['fsNames'];
+    return (await invokeRpcRaw('_listDevFS'))['fsNames'] as List<String>;
   }
 
   // Write one file into a file system.
@@ -1003,12 +1003,12 @@
         'path': path,
       },
     );
-    return base64.decode(response['fileContents']);
+    return base64.decode(response['fileContents'] as String);
   }
 
   /// The complete list of a file system.
   Future<List<String>> listDevFSFiles(String fsName) async {
-    return (await invokeRpcRaw('_listDevFSFiles', params: <String, dynamic>{'fsName': fsName}))['files'];
+    return (await invokeRpcRaw('_listDevFSFiles', params: <String, dynamic>{'fsName': fsName}))['files'] as List<String>;
   }
 
   /// Delete an existing file system.
@@ -1120,22 +1120,22 @@
 
   @override
   void _update(Map<String, dynamic> map, bool mapIsRef) {
-    _used = map['used'];
-    _capacity = map['capacity'];
-    _external = map['external'];
-    _collections = map['collections'];
-    _totalCollectionTimeInSeconds = map['time'];
-    _averageCollectionPeriodInMillis = map['avgCollectionPeriodMillis'];
+    _used = map['used'] as int;
+    _capacity = map['capacity'] as int;
+    _external = map['external'] as int;
+    _collections = map['collections'] as int;
+    _totalCollectionTimeInSeconds = map['time'] as double;
+    _averageCollectionPeriodInMillis = map['avgCollectionPeriodMillis'] as double;
   }
 }
 
 /// An isolate running inside the VM. Instances of the Isolate class are always
 /// canonicalized.
 class Isolate extends ServiceObjectOwner {
-  Isolate._empty(ServiceObjectOwner owner) : super._empty(owner);
+  Isolate._empty(VM owner) : super._empty(owner);
 
   @override
-  VM get vm => owner;
+  VM get vm => owner as VM;
 
   @override
   VMService get vmService => vm.vmService;
@@ -1162,13 +1162,13 @@
     if (map == null) {
       return null;
     }
-    final String mapType = _stripRef(map['type']);
+    final String mapType = _stripRef(map['type'] as String);
     if (mapType == 'Isolate') {
       // There are sometimes isolate refs in ServiceEvents.
       return vm.getFromMap(map);
     }
 
-    final String mapId = map['id'];
+    final String mapId = map['id'] as String;
     ServiceObject serviceObject = (mapId != null) ? _cache[mapId] : null;
     if (serviceObject != null) {
       serviceObject.updateFromMap(map);
@@ -1208,9 +1208,9 @@
 
   void _updateHeaps(Map<String, dynamic> map, bool mapIsRef) {
     _newSpace ??= HeapSpace._empty(this);
-    _newSpace._update(map['new'], mapIsRef);
+    _newSpace._update(castStringKeyedMap(map['new']), mapIsRef);
     _oldSpace ??= HeapSpace._empty(this);
-    _oldSpace._update(map['old'], mapIsRef);
+    _oldSpace._update(castStringKeyedMap(map['old']), mapIsRef);
   }
 
   @override
@@ -1220,14 +1220,14 @@
     }
     _loaded = true;
 
-    final int startTimeMillis = map['startTime'];
+    final int startTimeMillis = map['startTime'] as int;
     startTime = DateTime.fromMillisecondsSinceEpoch(startTimeMillis);
 
     _upgradeCollection(map, this);
 
-    pauseEvent = map['pauseEvent'];
+    pauseEvent = map['pauseEvent'] as ServiceEvent;
 
-    _updateHeaps(map['_heaps'], mapIsRef);
+    _updateHeaps(castStringKeyedMap(map['_heaps']), mapIsRef);
   }
 
   static const int kIsolateReloadBarred = 1005;
@@ -1362,7 +1362,7 @@
     final Map<String, dynamic> result =
       await invokeFlutterExtensionRpcRaw('ext.flutter.saveCompilationTrace');
     if (result != null && result['value'] is List<dynamic>) {
-      return result['value'].cast<int>();
+      return (result['value'] as List<dynamic>).cast<int>();
     }
     return null;
   }
@@ -1378,7 +1378,7 @@
       params: platform != null ? <String, dynamic>{'value': platform} : <String, String>{},
     );
     if (result != null && result['value'] is String) {
-      return result['value'];
+      return result['value'] as String;
     }
     return 'unknown';
   }
@@ -1459,7 +1459,7 @@
   void _update(Map<String, dynamic> map, bool mapIsRef) {
     _loaded = !mapIsRef;
     _upgradeCollection(map, owner);
-    _uiIsolate = map['isolate'];
+    _uiIsolate = map['isolate'] as Isolate;
   }
 
   // TODO(johnmccutchan): Report errors when running failed.
diff --git a/packages/flutter_tools/lib/src/vmservice_record_replay.dart b/packages/flutter_tools/lib/src/vmservice_record_replay.dart
index 3bb7b23..433a628 100644
--- a/packages/flutter_tools/lib/src/vmservice_record_replay.dart
+++ b/packages/flutter_tools/lib/src/vmservice_record_replay.dart
@@ -9,6 +9,7 @@
 
 import 'base/io.dart';
 import 'base/process.dart';
+import 'base/utils.dart';
 import 'convert.dart';
 import 'globals.dart';
 
@@ -57,14 +58,14 @@
 
   factory _Message.fromRecording(Map<String, dynamic> recordingData) {
     return recordingData[_kType] == _kRequest
-        ? _Request(recordingData[_kData])
-        : _Response(recordingData[_kData]);
+        ? _Request(castStringKeyedMap(recordingData[_kData]))
+        : _Response(castStringKeyedMap(recordingData[_kData]));
   }
 
   final String type;
   final Map<String, dynamic> data;
 
-  int get id => data[_kId];
+  int get id => data[_kId] as int;
 
   /// Allows [JsonEncoder] to properly encode objects of this type.
   Map<String, dynamic> toJson() {
@@ -94,13 +95,13 @@
 /// A VM service JSON-rpc request (sent to the VM).
 class _Request extends _Message {
   _Request(Map<String, dynamic> data) : super(_kRequest, data);
-  _Request.fromString(String data) : this(json.decoder.convert(data));
+  _Request.fromString(String data) : this(castStringKeyedMap(json.decode(data)));
 }
 
 /// A VM service JSON-rpc response (from the VM).
 class _Response extends _Message {
   _Response(Map<String, dynamic> data) : super(_kResponse, data);
-  _Response.fromString(String data) : this(json.decoder.convert(data));
+  _Response.fromString(String data) : this(castStringKeyedMap(json.decode(data)));
 }
 
 /// A matching request/response pair.
@@ -204,17 +205,17 @@
   static Map<int, _Transaction> _loadTransactions(Directory location) {
     final File file = _getManifest(location);
     final String jsonData = file.readAsStringSync();
-    final Iterable<_Message> messages = json.decoder.convert(jsonData).map<_Message>(_toMessage);
+    final Iterable<_Message> messages = (json.decode(jsonData) as List<Map<String, dynamic>>).map<_Message>(_toMessage);
     final Map<int, _Transaction> transactions = <int, _Transaction>{};
     for (_Message message in messages) {
       final _Transaction transaction =
           transactions.putIfAbsent(message.id, () => _Transaction());
       if (message.type == _kRequest) {
         assert(transaction.request == null);
-        transaction.request = message;
+        transaction.request = message as _Request;
       } else {
         assert(transaction.response == null);
-        transaction.response = message;
+        transaction.response = message as _Response;
       }
     }
     return transactions;
diff --git a/packages/flutter_tools/lib/src/vscode/vscode.dart b/packages/flutter_tools/lib/src/vscode/vscode.dart
index d04ea6b..bf236fa 100644
--- a/packages/flutter_tools/lib/src/vscode/vscode.dart
+++ b/packages/flutter_tools/lib/src/vscode/vscode.dart
@@ -5,6 +5,7 @@
 import '../base/common.dart';
 import '../base/file_system.dart';
 import '../base/platform.dart';
+import '../base/utils.dart';
 import '../base/version.dart';
 import '../convert.dart';
 import '../doctor.dart';
@@ -223,8 +224,8 @@
       return null;
     }
     final String jsonString = fs.file(packageJsonPath).readAsStringSync();
-    final Map<String, dynamic> jsonObject = json.decode(jsonString);
-    return jsonObject['version'];
+    final Map<String, dynamic> jsonObject = castStringKeyedMap(json.decode(jsonString));
+    return jsonObject['version'] as String;
   }
 }
 
diff --git a/packages/flutter_tools/lib/src/vscode/vscode_validator.dart b/packages/flutter_tools/lib/src/vscode/vscode_validator.dart
index 8fc6434..a2ae546 100644
--- a/packages/flutter_tools/lib/src/vscode/vscode_validator.dart
+++ b/packages/flutter_tools/lib/src/vscode/vscode_validator.dart
@@ -32,7 +32,7 @@
 
     return ValidationResult(
       validationType,
-      _vsCode.validationMessages,
+      _vsCode.validationMessages.toList(),
       statusInfo: vsCodeVersionText,
     );
   }
diff --git a/packages/flutter_tools/lib/src/web/chrome.dart b/packages/flutter_tools/lib/src/web/chrome.dart
index 3e58930..4903c15 100644
--- a/packages/flutter_tools/lib/src/web/chrome.dart
+++ b/packages/flutter_tools/lib/src/web/chrome.dart
@@ -210,8 +210,8 @@
       final HttpClient client = HttpClient();
       final HttpClientRequest request = await client.getUrl(base.resolve('/json/list'));
       final HttpClientResponse response = await request.close();
-      final List<dynamic> jsonObject = await json.fuse(utf8).decoder.bind(response).single;
-      return base.resolve(jsonObject.first['devtoolsFrontendUrl']);
+      final List<dynamic> jsonObject = await json.fuse(utf8).decoder.bind(response).single as List<dynamic>;
+      return base.resolve(jsonObject.first['devtoolsFrontendUrl'] as String);
     } catch (_) {
       // If we fail to talk to the remote debugger protocol, give up and return
       // the raw URL rather than crashing.
diff --git a/packages/flutter_tools/lib/src/web/devfs_web.dart b/packages/flutter_tools/lib/src/web/devfs_web.dart
index a3348d8..efbc418 100644
--- a/packages/flutter_tools/lib/src/web/devfs_web.dart
+++ b/packages/flutter_tools/lib/src/web/devfs_web.dart
@@ -12,6 +12,7 @@
 import '../base/common.dart';
 import '../base/file_system.dart';
 import '../base/io.dart';
+import '../base/utils.dart';
 import '../build_info.dart';
 import '../bundle.dart';
 import '../compile.dart';
@@ -167,15 +168,15 @@
     final List<String> modules = <String>[];
     final Uint8List codeBytes = codeFile.readAsBytesSync();
     final Uint8List sourcemapBytes = sourcemapFile.readAsBytesSync();
-    final Map<String, Object> manifest = json.decode(manifestFile.readAsStringSync());
+    final Map<String, dynamic> manifest = castStringKeyedMap(json.decode(manifestFile.readAsStringSync()));
     for (String filePath in manifest.keys) {
       if (filePath == null) {
         printTrace('Invalid manfiest file: $filePath');
         continue;
       }
-      final Map<String, Object> offsets = manifest[filePath];
-      final List<Object> codeOffsets = offsets['code'];
-      final List<Object> sourcemapOffsets = offsets['sourcemap'];
+      final Map<String, dynamic> offsets = castStringKeyedMap(manifest[filePath]);
+      final List<int> codeOffsets = (offsets['code'] as List<dynamic>).cast<int>();
+      final List<int> sourcemapOffsets = (offsets['sourcemap'] as List<dynamic>).cast<int>();
       if (codeOffsets.length != 2 || sourcemapOffsets.length != 2) {
         printTrace('Invalid manifest byte offsets: $offsets');
         continue;
diff --git a/packages/flutter_tools/lib/src/web/web_device.dart b/packages/flutter_tools/lib/src/web/web_device.dart
index fb44abf..c0f851a 100644
--- a/packages/flutter_tools/lib/src/web/web_device.dart
+++ b/packages/flutter_tools/lib/src/web/web_device.dart
@@ -100,7 +100,7 @@
         r'reg', 'query', 'HKEY_CURRENT_USER\\Software\\Google\\Chrome\\BLBeacon', '/v', 'version',
       ]);
       if (result.exitCode == 0) {
-        final List<String> parts = result.stdout.split(RegExp(r'\s+'));
+        final List<String> parts = (result.stdout as String).split(RegExp(r'\s+'));
         if (parts.length > 2) {
           version = 'Google Chrome ' + parts[parts.length - 2];
         }
@@ -112,7 +112,7 @@
         '--version',
       ]);
       if (result.exitCode == 0) {
-        version = result.stdout;
+        version = result.stdout as String;
       }
     }
     return version.trim();
@@ -130,7 +130,7 @@
   }) async {
     // See [ResidentWebRunner.run] in flutter_tools/lib/src/resident_web_runner.dart
     // for the web initialization and server logic.
-    final String url = platformArgs['uri'];
+    final String url = platformArgs['uri'] as String;
     if (debuggingOptions.browserLaunch) {
       _chrome = await chromeLauncher.launch(url,
         dataDir: fs.currentDirectory
@@ -249,7 +249,7 @@
     bool prebuiltApplication = false,
     bool ipv6 = false,
   }) async {
-    final String url = platformArgs['uri'];
+    final String url = platformArgs['uri'] as String;
     printStatus('$mainPath is being served at $url', emphasis: true);
     logger.sendEvent('app.webLaunchUrl', <String, dynamic>{'url': url, 'launched': false});
     return LaunchResult.succeeded(observatoryUri: null);
diff --git a/packages/flutter_tools/lib/src/windows/build_windows.dart b/packages/flutter_tools/lib/src/windows/build_windows.dart
index 1843001..d8a33b6 100644
--- a/packages/flutter_tools/lib/src/windows/build_windows.dart
+++ b/packages/flutter_tools/lib/src/windows/build_windows.dart
@@ -27,7 +27,7 @@
     environment['FLUTTER_TARGET'] = target;
   }
   if (artifacts is LocalEngineArtifacts) {
-    final LocalEngineArtifacts localEngineArtifacts = artifacts;
+    final LocalEngineArtifacts localEngineArtifacts = artifacts as LocalEngineArtifacts;
     final String engineOutPath = localEngineArtifacts.engineOutPath;
     environment['FLUTTER_ENGINE'] = fs.path.dirname(fs.path.dirname(engineOutPath));
     environment['LOCAL_ENGINE'] = fs.path.basename(engineOutPath);
diff --git a/packages/flutter_tools/lib/src/windows/visual_studio.dart b/packages/flutter_tools/lib/src/windows/visual_studio.dart
index 6a48b94..0c00751 100644
--- a/packages/flutter_tools/lib/src/windows/visual_studio.dart
+++ b/packages/flutter_tools/lib/src/windows/visual_studio.dart
@@ -27,7 +27,7 @@
   /// The name of the Visual Studio install.
   ///
   /// For instance: "Visual Studio Community 2017".
-  String get displayName => _bestVisualStudioDetails[_displayNameKey];
+  String get displayName => _bestVisualStudioDetails[_displayNameKey] as String;
 
   /// The user-friendly version number of the Visual Studio install.
   ///
@@ -36,16 +36,16 @@
     if (_bestVisualStudioDetails[_catalogKey] == null) {
       return null;
     }
-    return _bestVisualStudioDetails[_catalogKey][_catalogDisplayVersionKey];
+    return _bestVisualStudioDetails[_catalogKey][_catalogDisplayVersionKey] as String;
   }
 
   /// The directory where Visual Studio is installed.
-  String get installLocation => _bestVisualStudioDetails[_installationPathKey];
+  String get installLocation => _bestVisualStudioDetails[_installationPathKey] as String;
 
   /// The full version of the Visual Studio install.
   ///
   /// For instance: "15.4.27004.2002".
-  String get fullVersion => _bestVisualStudioDetails[_fullVersionKey];
+  String get fullVersion => _bestVisualStudioDetails[_fullVersionKey] as String;
 
   // Properties that determine the status of the installation. There might be
   // Visual Studio versions that don't include them, so default to a "valid" value to
@@ -58,7 +58,7 @@
     if (_bestVisualStudioDetails.isEmpty) {
       return false;
     }
-    return _bestVisualStudioDetails[_isCompleteKey] ?? true;
+    return _bestVisualStudioDetails[_isCompleteKey] as bool ?? true;
   }
 
   /// True if Visual Studio is launchable.
@@ -68,14 +68,14 @@
     if (_bestVisualStudioDetails.isEmpty) {
       return false;
     }
-    return _bestVisualStudioDetails[_isLaunchableKey] ?? true;
+    return _bestVisualStudioDetails[_isLaunchableKey] as bool ?? true;
   }
 
     /// True if the Visual Studio installation is as pre-release version.
-  bool get isPrerelease => _bestVisualStudioDetails[_isPrereleaseKey] ?? false;
+  bool get isPrerelease => _bestVisualStudioDetails[_isPrereleaseKey] as bool ?? false;
 
   /// True if a reboot is required to complete the Visual Studio installation.
-  bool get isRebootRequired => _bestVisualStudioDetails[_isRebootRequiredKey] ?? false;
+  bool get isRebootRequired => _bestVisualStudioDetails[_isRebootRequiredKey] as bool ?? false;
 
   /// The name of the recommended Visual Studio installer workload.
   String get workloadDescription => 'Desktop development with C++';
@@ -97,7 +97,7 @@
       return null;
     }
     return fs.path.join(
-      _usableVisualStudioDetails[_installationPathKey],
+      _usableVisualStudioDetails[_installationPathKey] as String,
       'VC',
       'Auxiliary',
       'Build',
@@ -199,7 +199,7 @@
       ]);
       if (whereResult.exitCode == 0) {
         final List<Map<String, dynamic>> installations =
-            json.decode(whereResult.stdout).cast<Map<String, dynamic>>();
+            (json.decode(whereResult.stdout) as List<dynamic>).cast<Map<String, dynamic>>();
         if (installations.isNotEmpty) {
           return installations[0];
         }
@@ -220,15 +220,15 @@
   /// of Visual Studio might not include them.
   bool installationHasIssues(Map<String, dynamic>installationDetails) {
     assert(installationDetails != null);
-    if (installationDetails[_isCompleteKey] != null && !installationDetails[_isCompleteKey]) {
+    if (installationDetails[_isCompleteKey] != null && !(installationDetails[_isCompleteKey] as bool)) {
       return true;
     }
 
-    if (installationDetails[_isLaunchableKey] != null && !installationDetails[_isLaunchableKey]) {
+    if (installationDetails[_isLaunchableKey] != null && !(installationDetails[_isLaunchableKey] as bool)) {
       return true;
     }
 
-    if (installationDetails[_isRebootRequiredKey] != null && installationDetails[_isRebootRequiredKey]) {
+    if (installationDetails[_isRebootRequiredKey] != null && installationDetails[_isRebootRequiredKey] as bool) {
       return true;
     }
 
diff --git a/packages/flutter_tools/test/general.shard/ios/devices_test.dart b/packages/flutter_tools/test/general.shard/ios/devices_test.dart
index 20f48c6..dabdc54 100644
--- a/packages/flutter_tools/test/general.shard/ios/devices_test.dart
+++ b/packages/flutter_tools/test/general.shard/ios/devices_test.dart
@@ -91,8 +91,8 @@
 
     group('.dispose()', () {
       IOSDevice device;
-      MockApplicationPackage appPackage1;
-      MockApplicationPackage appPackage2;
+      MockIOSApp appPackage1;
+      MockIOSApp appPackage2;
       IOSDeviceLogReader logReader1;
       IOSDeviceLogReader logReader2;
       MockProcess mockProcess1;
@@ -119,8 +119,8 @@
       }
 
       setUp(() {
-        appPackage1 = MockApplicationPackage();
-        appPackage2 = MockApplicationPackage();
+        appPackage1 = MockIOSApp();
+        appPackage2 = MockIOSApp();
         when(appPackage1.name).thenReturn('flutterApp1');
         when(appPackage2.name).thenReturn('flutterApp2');
         mockProcess1 = MockProcess();