Use --packages rather than --package-root

The .packages file is replacing the packages directory of symlinks.
diff --git a/packages/flutter_tools/lib/src/artifacts.dart b/packages/flutter_tools/lib/src/artifacts.dart
index 2c5e375..bbf2e52 100644
--- a/packages/flutter_tools/lib/src/artifacts.dart
+++ b/packages/flutter_tools/lib/src/artifacts.dart
@@ -165,27 +165,8 @@
     return null;
   }
 
-  // These values are initialized by FlutterCommandRunner on startup.
+  // Initialized by FlutterCommandRunner on startup.
   static String flutterRoot;
-  static String packageRoot = 'packages';
-
-  static bool get isPackageRootValid {
-    return FileSystemEntity.isDirectorySync(packageRoot);
-  }
-
-  static void ensurePackageRootIsValid() {
-    if (!isPackageRootValid) {
-      String message = '$packageRoot is not a valid directory.';
-      if (packageRoot == 'packages') {
-        if (FileSystemEntity.isFileSync('pubspec.yaml'))
-          message += '\nDid you run `pub get` in this directory?';
-        else
-          message += '\nDid you run this command from the same directory as your pubspec.yaml file?';
-      }
-      printError(message);
-      throw new ProcessExit(2);
-    }
-  }
 
   static String _engineRevision;
 
diff --git a/packages/flutter_tools/lib/src/commands/test.dart b/packages/flutter_tools/lib/src/commands/test.dart
index 4828cbb..cf5d98d 100644
--- a/packages/flutter_tools/lib/src/commands/test.dart
+++ b/packages/flutter_tools/lib/src/commands/test.dart
@@ -11,6 +11,7 @@
 import '../artifacts.dart';
 import '../build_configuration.dart';
 import '../globals.dart';
+import '../package_map.dart';
 import '../runner/flutter_command.dart';
 import '../test/flutter_platform.dart' as loader;
 
@@ -99,8 +100,8 @@
 
     // If we're running the flutter tests, we want to use the packages directory
     // from the flutter package in order to find the proper shell binary.
-    if (runFlutterTests && ArtifactStore.packageRoot == 'packages')
-      ArtifactStore.packageRoot = path.join(ArtifactStore.flutterRoot, 'packages', 'flutter', 'packages');
+    if (runFlutterTests)
+      PackageMap.instance = new PackageMap(path.join(ArtifactStore.flutterRoot, 'packages', 'flutter', '.packages'));
 
     Directory testDir = runFlutterTests ? _flutterUnitTestDir : _currentPackageTestDir;
 
diff --git a/packages/flutter_tools/lib/src/ios/simulators.dart b/packages/flutter_tools/lib/src/ios/simulators.dart
index 2703232..7d28f4e 100644
--- a/packages/flutter_tools/lib/src/ios/simulators.dart
+++ b/packages/flutter_tools/lib/src/ios/simulators.dart
@@ -467,7 +467,7 @@
     List<String> args = <String>[
       "--flx=${path.absolute(path.join('build', 'app.flx'))}",
       "--dart-main=${path.absolute(mainPath)}",
-      "--package-root=${path.absolute('packages')}",
+      "--packages=${path.absolute('.packages')}",
     ];
 
     if (checked)
diff --git a/packages/flutter_tools/lib/src/package_map.dart b/packages/flutter_tools/lib/src/package_map.dart
new file mode 100644
index 0000000..473a10e
--- /dev/null
+++ b/packages/flutter_tools/lib/src/package_map.dart
@@ -0,0 +1,42 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:package_config/packages_file.dart' as packages_file;
+import 'package:path/path.dart' as path;
+
+const String _kPackages = '.packages';
+
+Map<String, Uri> _parse(String packagesPath) {
+  List<int> source = new File(packagesPath).readAsBytesSync();
+  return packages_file.parse(source, new Uri.file(packagesPath));
+}
+
+class PackageMap {
+  PackageMap(this.packagesPath);
+
+  final String packagesPath;
+
+  Map<String, Uri> get map {
+    if (_map == null)
+      _map = _parse(packagesPath);
+    return _map;
+  }
+  Map<String, Uri> _map;
+
+  static PackageMap instance;
+
+  String checkValid() {
+    if (FileSystemEntity.isFileSync(packagesPath))
+      return null;
+    String message = '$packagesPath does not exist.';
+    String pubspecPath = path.absolute(path.dirname(packagesPath), 'pubspec.yaml');
+    if (FileSystemEntity.isFileSync(pubspecPath))
+      message += '\nDid you run `pub get` in this directory?';
+    else
+      message += '\nDid you run this command from the same directory as your pubspec.yaml file?';
+    return message;
+  }
+}
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart
index 522563c..9aa4d3a 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart
@@ -7,12 +7,13 @@
 
 import 'package:args/command_runner.dart';
 
-import '../dart/pub.dart';
 import '../application_package.dart';
 import '../build_configuration.dart';
+import '../dart/pub.dart';
 import '../device.dart';
 import '../flx.dart' as flx;
 import '../globals.dart';
+import '../package_map.dart';
 import '../toolchain.dart';
 import 'flutter_command_runner.dart';
 
@@ -147,6 +148,12 @@
       }
     }
 
+    String error = PackageMap.instance.checkValid();
+    if (error != null) {
+      printError(error);
+      return false;
+    }
+
     return true;
   }
 
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 12677af0..2350e4a 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
@@ -9,13 +9,14 @@
 import 'package:args/command_runner.dart';
 import 'package:path/path.dart' as path;
 
-import '../android/android_sdk.dart';
 import '../artifacts.dart';
+import '../android/android_sdk.dart';
 import '../base/context.dart';
 import '../base/logger.dart';
 import '../base/process.dart';
 import '../build_configuration.dart';
 import '../globals.dart';
+import '../package_map.dart';
 import 'version.dart';
 
 const String kFlutterRootEnvironmentVariableName = 'FLUTTER_ROOT'; // should point to //flutter/ (root of flutter/flutter repo)
@@ -41,13 +42,13 @@
         help: 'Reports the version of this tool.');
 
     String packagesHelp;
-    if (ArtifactStore.isPackageRootValid)
-      packagesHelp = '\n(defaults to "${ArtifactStore.packageRoot}")';
+    if (FileSystemEntity.isFileSync('.packages'))
+      packagesHelp = '\n(defaults to ".packages")';
     else
-      packagesHelp = '\n(required, since the current directory does not contain a "packages" subdirectory)';
-    argParser.addOption('package-root',
+      packagesHelp = '\n(required, since the current directory does not contain a ".packages" file)';
+    argParser.addOption('packages',
         hide: !verboseHelp,
-        help: 'Path to your packages directory.$packagesHelp');
+        help: 'Path to your ".packages" file.$packagesHelp');
     argParser.addOption('flutter-root',
         help: 'The root directory of the Flutter repository (uses \$$kFlutterRootEnvironmentVariableName if set).',
               defaultsTo: _defaultFlutterRoot);
@@ -184,8 +185,9 @@
     // we must set ArtifactStore.flutterRoot early because other features use it
     // (e.g. enginePath's initialiser uses it)
     ArtifactStore.flutterRoot = path.normalize(path.absolute(globalResults['flutter-root']));
-    if (globalResults.wasParsed('package-root'))
-      ArtifactStore.packageRoot = path.normalize(path.absolute(globalResults['package-root']));
+    PackageMap.instance = new PackageMap(path.normalize(path.absolute(
+      globalResults.wasParsed('packages') ? globalResults['packages'] : '.packages'
+    )));
 
     // See if the user specified a specific device.
     deviceManager.specifiedDeviceId = globalResults['device-id'];
@@ -219,16 +221,13 @@
     bool isRelease = globalResults['release'];
 
     if (engineSourcePath == null && (isDebug || isRelease)) {
-      if (ArtifactStore.isPackageRootValid) {
-        Directory engineDir = new Directory(path.join(ArtifactStore.packageRoot, kFlutterEnginePackageName));
-        try {
-          String realEnginePath = engineDir.resolveSymbolicLinksSync();
-          engineSourcePath = path.dirname(path.dirname(path.dirname(path.dirname(realEnginePath))));
-          bool dirExists = FileSystemEntity.isDirectorySync(path.join(engineSourcePath, 'out'));
-          if (engineSourcePath == '/' || engineSourcePath.isEmpty || !dirExists)
-            engineSourcePath = null;
-        } on FileSystemException { }
-      }
+      try {
+        Uri engineUri = PackageMap.instance.map[kFlutterEnginePackageName];
+        engineSourcePath = path.dirname(path.dirname(path.dirname(path.dirname(engineUri.path))));
+        bool dirExists = FileSystemEntity.isDirectorySync(path.join(engineSourcePath, 'out'));
+        if (engineSourcePath == '/' || engineSourcePath.isEmpty || !dirExists)
+          engineSourcePath = null;
+      } on FileSystemException { } on FormatException { }
 
       if (engineSourcePath == null)
         engineSourcePath = _tryEnginePath(path.join(ArtifactStore.flutterRoot, '../engine/src'));
diff --git a/packages/flutter_tools/lib/src/services.dart b/packages/flutter_tools/lib/src/services.dart
index 552acef..1fc1fe8 100644
--- a/packages/flutter_tools/lib/src/services.dart
+++ b/packages/flutter_tools/lib/src/services.dart
@@ -11,6 +11,7 @@
 
 import 'artifacts.dart';
 import 'globals.dart';
+import 'package_map.dart';
 
 const String _kFlutterManifestPath = 'flutter.yaml';
 const String _kFlutterServicesManifestPath = 'flutter_services.yaml';
@@ -28,22 +29,25 @@
 Future<Null> parseServiceConfigs(
   List<Map<String, String>> services, { List<File> jars }
 ) async {
-  if (!ArtifactStore.isPackageRootValid) {
-    printTrace("Artifact store invalid while parsing service configs");
+  Map<String, Uri> packageMap;
+  try {
+    packageMap = PackageMap.instance.map;
+  } on FormatException catch(e) {
+    printTrace('Invalid ".packages" file while parsing service configs:\n$e');
     return;
   }
 
   dynamic manifest = _loadYamlFile(_kFlutterManifestPath);
   if (manifest == null || manifest['services'] == null) {
-    printTrace("No services specified in the manifest");
+    printTrace('No services specified in the manifest');
     return;
   }
 
   for (String service in manifest['services']) {
-    String serviceRoot = '${ArtifactStore.packageRoot}/$service';
+    String serviceRoot = packageMap[service].path;
     dynamic serviceConfig = _loadYamlFile('$serviceRoot/$_kFlutterServicesManifestPath');
     if (serviceConfig == null) {
-      printStatus("No $_kFlutterServicesManifestPath found for service '$serviceRoot'. Skipping.");
+      printStatus('No $_kFlutterServicesManifestPath found for service "$serviceRoot". Skipping.');
       continue;
     }
 
diff --git a/packages/flutter_tools/lib/src/test/flutter_platform.dart b/packages/flutter_tools/lib/src/test/flutter_platform.dart
index f2db417..b890b44 100644
--- a/packages/flutter_tools/lib/src/test/flutter_platform.dart
+++ b/packages/flutter_tools/lib/src/test/flutter_platform.dart
@@ -14,7 +14,7 @@
 import 'package:test/src/runner/plugin/platform.dart'; // ignore: implementation_imports
 import 'package:test/src/runner/plugin/hack_register_platform.dart' as hack; // ignore: implementation_imports
 
-import '../artifacts.dart';
+import '../package_map.dart';
 
 final String _kSkyShell = Platform.environment['SKY_SHELL'];
 const String _kHost = '127.0.0.1';
@@ -44,12 +44,12 @@
   return new _ServerInfo(server, 'ws://$_kHost:${server.port}$_kPath', socket.future);
 }
 
-Future<Process> _startProcess(String mainPath, { String packageRoot }) {
+Future<Process> _startProcess(String mainPath, { String packages }) {
   assert(shellPath != null || _kSkyShell != null); // Please provide the path to the shell in the SKY_SHELL environment variable.
   return Process.start(shellPath ?? _kSkyShell, [
     '--enable-checked-mode',
     '--non-interactive',
-    '--package-root=$packageRoot',
+    '--packages=$packages',
     mainPath,
   ]);
 }
@@ -90,8 +90,7 @@
 ''');
 
     Process process = await _startProcess(
-      listenerFile.path,
-      packageRoot: path.absolute(ArtifactStore.packageRoot)
+      listenerFile.path, packages: PackageMap.instance.packagesPath
     );
 
     void finalize() {
diff --git a/packages/flutter_tools/lib/src/toolchain.dart b/packages/flutter_tools/lib/src/toolchain.dart
index 9f4a9a5..25015d4 100644
--- a/packages/flutter_tools/lib/src/toolchain.dart
+++ b/packages/flutter_tools/lib/src/toolchain.dart
@@ -10,6 +10,7 @@
 import 'artifacts.dart';
 import 'base/process.dart';
 import 'build_configuration.dart';
+import 'package_map.dart';
 
 class SnapshotCompiler {
   SnapshotCompiler(this._path);
@@ -25,7 +26,7 @@
     final List<String> args = [
       _path,
       mainPath,
-      '--package-root=${ArtifactStore.packageRoot}',
+      '--packages=${PackageMap.instance.packagesPath}',
       '--snapshot=$snapshotPath'
     ];
     if (depfilePath != null)