diff --git a/packages/flutter_tools/lib/src/asset.dart b/packages/flutter_tools/lib/src/asset.dart
new file mode 100644
index 0000000..d681ca7
--- /dev/null
+++ b/packages/flutter_tools/lib/src/asset.dart
@@ -0,0 +1,418 @@
+// 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:async';
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:json_schema/json_schema.dart';
+import 'package:path/path.dart' as path;
+import 'package:yaml/yaml.dart';
+
+import 'cache.dart';
+import 'dart/package_map.dart';
+import 'globals.dart';
+
+/// An entry in an asset bundle.
+class AssetBundleEntry {
+  /// An entry backed by a File.
+  AssetBundleEntry.fromFile(this.archivePath, this.file)
+      : _contents = null;
+
+  /// An entry backed by a String.
+  AssetBundleEntry.fromString(this.archivePath, this._contents)
+      : file = null;
+
+  /// The path within the bundle.
+  final String archivePath;
+
+  /// The payload.
+  List<int> contentsAsBytes() {
+    if (_contents != null) {
+      return UTF8.encode(_contents);
+    } else {
+      return file.readAsBytesSync();
+    }
+  }
+
+  bool get isStringEntry => _contents != null;
+
+  final File file;
+  final String _contents;
+}
+
+/// A bundle of assets.
+class AssetBundle {
+  final Set<AssetBundleEntry> entries = new Set<AssetBundleEntry>();
+
+  static const String defaultManifestPath = 'flutter.yaml';
+  static const String defaultWorkingDirPath = 'build/flx';
+  static const String _kFontSetMaterial = 'material';
+  static const String _kFontSetRoboto = 'roboto';
+
+  Future<int> build({String manifestPath: defaultManifestPath,
+                     String workingDirPath: defaultWorkingDirPath,
+                     bool includeRobotoFonts: true}) async {
+    Object manifest = _loadFlutterYamlManifest(manifestPath);
+    if (manifest != null) {
+     int result = await _validateFlutterYamlManifest(manifest);
+     if (result != 0)
+       return result;
+    }
+    Map<String, dynamic> manifestDescriptor = manifest;
+    assert(manifestDescriptor != null);
+    String assetBasePath = path.dirname(path.absolute(manifestPath));
+
+    final PackageMap packageMap =
+        new PackageMap(path.join(assetBasePath, '.packages'));
+
+    Map<_Asset, List<_Asset>> assetVariants = _parseAssets(
+      packageMap,
+      manifestDescriptor,
+      assetBasePath,
+      excludeDirs: <String>[workingDirPath, path.join(assetBasePath, 'build')]
+    );
+
+    if (assetVariants == null)
+      return 1;
+
+    final bool usesMaterialDesign = (manifestDescriptor != null) &&
+        manifestDescriptor['uses-material-design'];
+
+    for (_Asset asset in assetVariants.keys) {
+      AssetBundleEntry assetEntry = _createAssetEntry(asset);
+      if (assetEntry == null)
+        return 1;
+      entries.add(assetEntry);
+
+      for (_Asset variant in assetVariants[asset]) {
+        AssetBundleEntry variantEntry = _createAssetEntry(variant);
+        if (variantEntry == null)
+          return 1;
+        entries.add(variantEntry);
+      }
+    }
+
+    List<_Asset> materialAssets = <_Asset>[];
+    if (usesMaterialDesign) {
+      materialAssets.addAll(_getMaterialAssets(_kFontSetMaterial));
+      if (includeRobotoFonts)
+        materialAssets.addAll(_getMaterialAssets(_kFontSetRoboto));
+    }
+    for (_Asset asset in materialAssets) {
+      AssetBundleEntry assetEntry = _createAssetEntry(asset);
+      if (assetEntry == null)
+        return 1;
+      entries.add(assetEntry);
+    }
+
+    entries.add(_createAssetManifest(assetVariants));
+
+    AssetBundleEntry fontManifest =
+        _createFontManifest(manifestDescriptor, usesMaterialDesign, includeRobotoFonts);
+    if (fontManifest != null)
+      entries.add(fontManifest);
+
+    // TODO(ianh): Only do the following line if we've changed packages
+    entries.add(await _obtainLicenses(packageMap, assetBasePath));
+
+    return 0;
+  }
+
+  void dump() {
+    print('Dumping AssetBundle:');
+    for (AssetBundleEntry entry in entries) {
+      print(entry.archivePath);
+    }
+  }
+}
+
+class _Asset {
+  _Asset({ this.base, String assetEntry, this.relativePath, this.source }) {
+    this._assetEntry = assetEntry;
+  }
+
+  String _assetEntry;
+
+  final String base;
+
+  /// The entry to list in the generated asset manifest.
+  String get assetEntry => _assetEntry ?? relativePath;
+
+  /// Where the resource is on disk relative to [base].
+  final String relativePath;
+
+  final String source;
+
+  File get assetFile {
+    return new File(source != null ? '$base/$source' : '$base/$relativePath');
+  }
+
+  bool get assetFileExists => assetFile.existsSync();
+
+  /// The delta between what the assetEntry is and the relativePath (e.g.,
+  /// packages/flutter_gallery).
+  String get symbolicPrefix {
+    if (_assetEntry == null || _assetEntry == relativePath)
+      return null;
+    int index = _assetEntry.indexOf(relativePath);
+    return index == -1 ? null : _assetEntry.substring(0, index);
+  }
+
+  @override
+  String toString() => 'asset: $assetEntry';
+}
+
+Map<String, dynamic> _readMaterialFontsManifest() {
+  String fontsPath = path.join(path.absolute(Cache.flutterRoot),
+      'packages', 'flutter_tools', 'schema', 'material_fonts.yaml');
+
+  return loadYaml(new File(fontsPath).readAsStringSync());
+}
+
+final Map<String, dynamic> _materialFontsManifest = _readMaterialFontsManifest();
+
+List<Map<String, dynamic>> _getMaterialFonts(String fontSet) {
+  return _materialFontsManifest[fontSet];
+}
+
+List<_Asset> _getMaterialAssets(String fontSet) {
+  List<_Asset> result = <_Asset>[];
+
+  for (Map<String, dynamic> family in _getMaterialFonts(fontSet)) {
+    for (Map<String, dynamic> font in family['fonts']) {
+      String assetKey = font['asset'];
+      result.add(new _Asset(
+        base: '${Cache.flutterRoot}/bin/cache/artifacts/material_fonts',
+        source: path.basename(assetKey),
+        relativePath: assetKey
+      ));
+    }
+  }
+
+  return result;
+}
+
+final String _licenseSeparator = '\n' + ('-' * 80) + '\n';
+
+/// Returns a AssetBundleEntry representing the license file.
+Future<AssetBundleEntry> _obtainLicenses(
+  PackageMap packageMap,
+  String assetBase
+) async {
+  // Read the LICENSE file from each package in the .packages file,
+  // splitting each one into each component license (so that we can
+  // de-dupe if possible).
+  // For the sky_engine package we assume each license starts with
+  // package names. For the other packages we assume that each
+  // license is raw.
+  final Map<String, Set<String>> packageLicenses = <String, Set<String>>{};
+  for (String packageName in packageMap.map.keys) {
+    final Uri package = packageMap.map[packageName];
+    if (package != null && package.scheme == 'file') {
+      final File file = new File.fromUri(package.resolve('../LICENSE'));
+      if (file.existsSync()) {
+        final List<String> rawLicenses =
+            (await file.readAsString()).split(_licenseSeparator);
+        for (String rawLicense in rawLicenses) {
+          String licenseText;
+          List<String> packageNames;
+          if (packageName == 'sky_engine') {
+            final int split = rawLicense.indexOf('\n\n');
+            if (split >= 0) {
+              packageNames = rawLicense.substring(0, split).split('\n');
+              licenseText = rawLicense.substring(split + 2);
+            }
+          }
+          if (licenseText == null) {
+            licenseText = rawLicense;
+            packageNames = <String>[packageName];
+          }
+          packageLicenses.putIfAbsent(rawLicense, () => new Set<String>())
+            ..addAll(packageNames);
+        }
+      }
+    }
+  }
+
+  final List<String> combinedLicensesList = packageLicenses.keys.map(
+    (String license) {
+      List<String> packageNames = packageLicenses[license].toList()
+       ..sort();
+      return packageNames.join('\n') + '\n\n' + license;
+    }
+  ).toList();
+  combinedLicensesList.sort();
+
+  final String combinedLicenses = combinedLicensesList.join(_licenseSeparator);
+
+  return new AssetBundleEntry.fromString('LICENSE', combinedLicenses);
+}
+
+
+/// Create a [AssetBundleEntry] from the given [_Asset]; the asset must exist.
+AssetBundleEntry _createAssetEntry(_Asset asset) {
+  assert(asset.assetFileExists);
+  return new AssetBundleEntry.fromFile(asset.assetEntry, asset.assetFile);
+}
+
+AssetBundleEntry _createAssetManifest(Map<_Asset, List<_Asset>> assetVariants) {
+  Map<String, List<String>> json = <String, List<String>>{};
+  for (_Asset main in assetVariants.keys) {
+    List<String> variants = <String>[];
+    for (_Asset variant in assetVariants[main])
+      variants.add(variant.relativePath);
+    json[main.relativePath] = variants;
+  }
+  return new AssetBundleEntry.fromString('AssetManifest.json', JSON.encode(json));
+}
+
+AssetBundleEntry _createFontManifest(Map<String, dynamic> manifestDescriptor,
+                             bool usesMaterialDesign,
+                             bool includeRobotoFonts) {
+  List<Map<String, dynamic>> fonts = <Map<String, dynamic>>[];
+  if (usesMaterialDesign) {
+    fonts.addAll(_getMaterialFonts(AssetBundle._kFontSetMaterial));
+    if (includeRobotoFonts)
+      fonts.addAll(_getMaterialFonts(AssetBundle._kFontSetRoboto));
+  }
+  if (manifestDescriptor != null && manifestDescriptor.containsKey('fonts'))
+    fonts.addAll(manifestDescriptor['fonts']);
+  if (fonts.isEmpty)
+    return null;
+  return new AssetBundleEntry.fromString('FontManifest.json', JSON.encode(fonts));
+}
+
+/// Given an assetBase location and a flutter.yaml manifest, return a map of
+/// assets to asset variants.
+///
+/// Returns `null` on missing assets.
+Map<_Asset, List<_Asset>> _parseAssets(
+  PackageMap packageMap,
+  Map<String, dynamic> manifestDescriptor,
+  String assetBase, {
+  List<String> excludeDirs: const <String>[]
+}) {
+  Map<_Asset, List<_Asset>> result = <_Asset, List<_Asset>>{};
+
+  if (manifestDescriptor == null)
+    return result;
+
+  excludeDirs = excludeDirs.map(
+    (String exclude) => path.absolute(exclude) + Platform.pathSeparator).toList();
+
+  if (manifestDescriptor.containsKey('assets')) {
+    for (String asset in manifestDescriptor['assets']) {
+      _Asset baseAsset = _resolveAsset(packageMap, assetBase, asset);
+
+      if (!baseAsset.assetFileExists) {
+        printError('Error: unable to locate asset entry in flutter.yaml: "$asset".');
+        return null;
+      }
+
+      List<_Asset> variants = <_Asset>[];
+      result[baseAsset] = variants;
+
+      // Find asset variants
+      String assetPath = baseAsset.assetFile.path;
+      String assetFilename = path.basename(assetPath);
+      Directory assetDir = new Directory(path.dirname(assetPath));
+
+      List<FileSystemEntity> files = assetDir.listSync(recursive: true);
+
+      for (FileSystemEntity entity in files) {
+        if (!FileSystemEntity.isFileSync(entity.path))
+          continue;
+
+        // Exclude any files in the given directories.
+        if (excludeDirs.any((String exclude) => entity.path.startsWith(exclude)))
+          continue;
+
+        if (path.basename(entity.path) == assetFilename && entity.path != assetPath) {
+          String key = path.relative(entity.path, from: baseAsset.base);
+          String assetEntry;
+          if (baseAsset.symbolicPrefix != null)
+            assetEntry = path.join(baseAsset.symbolicPrefix, key);
+          variants.add(new _Asset(base: baseAsset.base, assetEntry: assetEntry, relativePath: key));
+        }
+      }
+    }
+  }
+
+  // Add assets referenced in the fonts section of the manifest.
+  if (manifestDescriptor.containsKey('fonts')) {
+    for (Map<String, dynamic> family in manifestDescriptor['fonts']) {
+      List<Map<String, dynamic>> fonts = family['fonts'];
+      if (fonts == null) continue;
+
+      for (Map<String, dynamic> font in fonts) {
+        String asset = font['asset'];
+        if (asset == null) continue;
+
+        _Asset baseAsset = _resolveAsset(packageMap, assetBase, asset);
+        if (!baseAsset.assetFileExists) {
+          printError('Error: unable to locate asset entry in flutter.yaml: "$asset".');
+          return null;
+        }
+
+        result[baseAsset] = <_Asset>[];
+      }
+    }
+  }
+
+  return result;
+}
+
+_Asset _resolveAsset(
+  PackageMap packageMap,
+  String assetBase,
+  String asset
+) {
+  if (asset.startsWith('packages/') && !FileSystemEntity.isFileSync(path.join(assetBase, asset))) {
+    // Convert packages/flutter_gallery_assets/clouds-0.png to clouds-0.png.
+    String packageKey = asset.substring(9);
+    String relativeAsset = asset;
+
+    int index = packageKey.indexOf('/');
+    if (index != -1) {
+      relativeAsset = packageKey.substring(index + 1);
+      packageKey = packageKey.substring(0, index);
+    }
+
+    Uri uri = packageMap.map[packageKey];
+    if (uri != null && uri.scheme == 'file') {
+      File file = new File.fromUri(uri);
+      return new _Asset(base: file.path, assetEntry: asset, relativePath: relativeAsset);
+    }
+  }
+
+  return new _Asset(base: assetBase, relativePath: asset);
+}
+
+dynamic _loadFlutterYamlManifest(String manifestPath) {
+  if (manifestPath == null || !FileSystemEntity.isFileSync(manifestPath))
+    return null;
+  String manifestDescriptor = new File(manifestPath).readAsStringSync();
+  return loadYaml(manifestDescriptor);
+}
+
+Future<int> _validateFlutterYamlManifest(Object manifest) async {
+  String schemaPath = path.join(path.absolute(Cache.flutterRoot),
+      'packages', 'flutter_tools', 'schema', 'flutter_yaml.json');
+  Schema schema = await Schema.createSchemaFromUrl('file://$schemaPath');
+
+  Validator validator = new Validator(schema);
+  if (validator.validate(manifest)) {
+    return 0;
+  } else {
+    if (validator.errors.length == 1) {
+      printError('Error in flutter.yaml: ${validator.errors.first}');
+    } else {
+      printError('Error in flutter.yaml:');
+      printError('  ' + validator.errors.join('\n  '));
+    }
+
+    return 1;
+  }
+}
diff --git a/packages/flutter_tools/lib/src/devfs.dart b/packages/flutter_tools/lib/src/devfs.dart
index 4ac4df2..de56314 100644
--- a/packages/flutter_tools/lib/src/devfs.dart
+++ b/packages/flutter_tools/lib/src/devfs.dart
@@ -9,23 +9,37 @@
 import 'package:path/path.dart' as path;
 
 import 'dart/package_map.dart';
+import 'asset.dart';
 import 'globals.dart';
 import 'observatory.dart';
 
 // A file that has been added to a DevFS.
 class DevFSEntry {
-  DevFSEntry(this.devicePath, this.file);
+  DevFSEntry(this.devicePath, this.file)
+      : bundleEntry = null;
+
+  DevFSEntry.bundle(this.devicePath, AssetBundleEntry bundleEntry)
+      : bundleEntry = bundleEntry,
+        file = bundleEntry.file;
 
   final String devicePath;
+  final AssetBundleEntry bundleEntry;
+
   final File file;
   FileStat _fileStat;
-
+  // When we updated the DevFS, did we see this entry?
+  bool _wasSeen = false;
   DateTime get lastModified => _fileStat?.modified;
   bool get stillExists {
+    if (_isSourceEntry)
+      return true;
     _stat();
     return _fileStat.type != FileSystemEntityType.NOT_FOUND;
   }
   bool get isModified {
+    if (_isSourceEntry)
+      return true;
+
     if (_fileStat == null) {
       _stat();
       return true;
@@ -36,8 +50,18 @@
   }
 
   void _stat() {
+    if (_isSourceEntry)
+      return;
     _fileStat = file.statSync();
   }
+
+  bool get _isSourceEntry => file == null;
+
+  Future<List<int>> contentsAsBytes() async {
+    if (_isSourceEntry)
+      return bundleEntry.contentsAsBytes();
+    return file.readAsBytes();
+  }
 }
 
 
@@ -46,6 +70,7 @@
   Future<Uri> create(String fsName);
   Future<dynamic> destroy(String fsName);
   Future<dynamic> writeFile(String fsName, DevFSEntry entry);
+  Future<dynamic> deleteFile(String fsName, DevFSEntry entry);
   Future<dynamic> writeSource(String fsName,
                               String devicePath,
                               String contents);
@@ -74,7 +99,7 @@
   Future<dynamic> writeFile(String fsName, DevFSEntry entry) async {
     List<int> bytes;
     try {
-      bytes = await entry.file.readAsBytes();
+      bytes = await entry.contentsAsBytes();
     } catch (e) {
       return e;
     }
@@ -92,6 +117,11 @@
   }
 
   @override
+  Future<dynamic> deleteFile(String fsName, DevFSEntry entry) async {
+    // TODO(johnmccutchan): Add file deletion to the devFS protocol.
+  }
+
+  @override
   Future<dynamic> writeSource(String fsName,
                               String devicePath,
                               String contents) async {
@@ -135,7 +165,11 @@
     return await _operations.destroy(fsName);
   }
 
-  Future<dynamic> update() async {
+  Future<dynamic> update([AssetBundle bundle = null]) async {
+    // Mark all entries as not seen.
+    _entries.forEach((String path, DevFSEntry entry) {
+      entry._wasSeen = false;
+    });
     printTrace('DevFS: Starting sync from $rootDirectory');
     // Send the root and lib directories.
     Directory directory = rootDirectory;
@@ -162,6 +196,27 @@
         }
       }
     }
+    if (bundle != null) {
+      // Synchronize asset bundle.
+      for (AssetBundleEntry entry in bundle.entries) {
+        // We write the assets into 'build/flx' so that they are in the
+        // same location in DevFS and the iOS simulator.
+        final String devicePath = path.join('build/flx', entry.archivePath);
+        _syncBundleEntry(devicePath, entry);
+      }
+    }
+    // Handle deletions.
+    final List<String> toRemove = new List<String>();
+    _entries.forEach((String path, DevFSEntry entry) {
+      if (!entry._wasSeen) {
+        _deleteEntry(path, entry);
+        toRemove.add(path);
+      }
+    });
+    for (int i = 0; i < toRemove.length; i++) {
+      _entries.remove(toRemove[i]);
+    }
+    // Send the assets.
     printTrace('DevFS: Waiting for sync of ${_pendingWrites.length} files '
                'to finish');
     await Future.wait(_pendingWrites);
@@ -175,6 +230,10 @@
     logger.flush();
   }
 
+  void _deleteEntry(String path, DevFSEntry entry) {
+    _pendingWrites.add(_operations.deleteFile(fsName, entry));
+  }
+
   void _syncFile(String devicePath, File file) {
     DevFSEntry entry = _entries[devicePath];
     if (entry == null) {
@@ -182,6 +241,7 @@
       entry = new DevFSEntry(devicePath, file);
       _entries[devicePath] = entry;
     }
+    entry._wasSeen = true;
     bool needsWrite = entry.isModified;
     if (needsWrite) {
       Future<dynamic> pendingWrite = _operations.writeFile(fsName, entry);
@@ -193,13 +253,29 @@
     }
   }
 
-  bool _shouldIgnore(String path) {
+  void _syncBundleEntry(String devicePath, AssetBundleEntry assetBundleEntry) {
+    DevFSEntry entry = _entries[devicePath];
+    if (entry == null) {
+      // New file.
+      entry = new DevFSEntry.bundle(devicePath, assetBundleEntry);
+      _entries[devicePath] = entry;
+    }
+    entry._wasSeen = true;
+    Future<dynamic> pendingWrite = _operations.writeFile(fsName, entry);
+    if (pendingWrite != null) {
+      _pendingWrites.add(pendingWrite);
+    } else {
+      printTrace('DevFS: Failed to sync "$devicePath"');
+    }
+  }
+
+  bool _shouldIgnore(String devicePath) {
     List<String> ignoredPrefixes = <String>['android/',
                                             'build/',
                                             'ios/',
                                             'packages/analyzer'];
     for (String ignoredPrefix in ignoredPrefixes) {
-      if (path.startsWith(ignoredPrefix))
+      if (devicePath.startsWith(ignoredPrefix))
         return true;
     }
     return false;
diff --git a/packages/flutter_tools/lib/src/flx.dart b/packages/flutter_tools/lib/src/flx.dart
index f9ac4b1..7c052be 100644
--- a/packages/flutter_tools/lib/src/flx.dart
+++ b/packages/flutter_tools/lib/src/flx.dart
@@ -3,16 +3,13 @@
 // found in the LICENSE file.
 
 import 'dart:async';
-import 'dart:convert';
 import 'dart:io';
 
-import 'package:json_schema/json_schema.dart';
 import 'package:path/path.dart' as path;
-import 'package:yaml/yaml.dart';
 
+import 'asset.dart';
 import 'base/file_system.dart' show ensureDirectoryExists;
 import 'base/process.dart';
-import 'cache.dart';
 import 'dart/package_map.dart';
 import 'globals.dart';
 import 'toolchain.dart';
@@ -29,9 +26,6 @@
 
 const String _kSnapshotKey = 'snapshot_blob.bin';
 
-const String _kFontSetMaterial = 'material';
-const String _kFontSetRoboto = 'roboto';
-
 Future<int> createSnapshot({
   String mainPath,
   String snapshotPath,
@@ -54,293 +48,6 @@
   return runCommandAndStreamOutput(args);
 }
 
-class _Asset {
-  _Asset({ this.base, String assetEntry, this.relativePath, this.source }) {
-    this._assetEntry = assetEntry;
-  }
-
-  String _assetEntry;
-
-  final String base;
-
-  /// The entry to list in the generated asset manifest.
-  String get assetEntry => _assetEntry ?? relativePath;
-
-  /// Where the resource is on disk relative to [base].
-  final String relativePath;
-
-  final String source;
-
-  File get assetFile {
-    return new File(source != null ? '$base/$source' : '$base/$relativePath');
-  }
-
-  bool get assetFileExists => assetFile.existsSync();
-
-  /// The delta between what the assetEntry is and the relativePath (e.g.,
-  /// packages/flutter_gallery).
-  String get symbolicPrefix {
-    if (_assetEntry == null || _assetEntry == relativePath)
-      return null;
-    int index = _assetEntry.indexOf(relativePath);
-    return index == -1 ? null : _assetEntry.substring(0, index);
-  }
-
-  @override
-  String toString() => 'asset: $assetEntry';
-}
-
-Map<String, dynamic> _readMaterialFontsManifest() {
-  String fontsPath = path.join(path.absolute(Cache.flutterRoot),
-      'packages', 'flutter_tools', 'schema', 'material_fonts.yaml');
-
-  return loadYaml(new File(fontsPath).readAsStringSync());
-}
-
-final Map<String, dynamic> _materialFontsManifest = _readMaterialFontsManifest();
-
-List<Map<String, dynamic>> _getMaterialFonts(String fontSet) {
-  return _materialFontsManifest[fontSet];
-}
-
-List<_Asset> _getMaterialAssets(String fontSet) {
-  List<_Asset> result = <_Asset>[];
-
-  for (Map<String, dynamic> family in _getMaterialFonts(fontSet)) {
-    for (Map<String, dynamic> font in family['fonts']) {
-      String assetKey = font['asset'];
-      result.add(new _Asset(
-        base: '${Cache.flutterRoot}/bin/cache/artifacts/material_fonts',
-        source: path.basename(assetKey),
-        relativePath: assetKey
-      ));
-    }
-  }
-
-  return result;
-}
-
-/// Given an assetBase location and a flutter.yaml manifest, return a map of
-/// assets to asset variants.
-///
-/// Returns `null` on missing assets.
-Map<_Asset, List<_Asset>> _parseAssets(
-  PackageMap packageMap,
-  Map<String, dynamic> manifestDescriptor,
-  String assetBase, {
-  List<String> excludeDirs: const <String>[]
-}) {
-  Map<_Asset, List<_Asset>> result = <_Asset, List<_Asset>>{};
-
-  if (manifestDescriptor == null)
-    return result;
-
-  excludeDirs = excludeDirs.map(
-    (String exclude) => path.absolute(exclude) + Platform.pathSeparator).toList();
-
-  if (manifestDescriptor.containsKey('assets')) {
-    for (String asset in manifestDescriptor['assets']) {
-      _Asset baseAsset = _resolveAsset(packageMap, assetBase, asset);
-
-      if (!baseAsset.assetFileExists) {
-        printError('Error: unable to locate asset entry in flutter.yaml: "$asset".');
-        return null;
-      }
-
-      List<_Asset> variants = <_Asset>[];
-      result[baseAsset] = variants;
-
-      // Find asset variants
-      String assetPath = baseAsset.assetFile.path;
-      String assetFilename = path.basename(assetPath);
-      Directory assetDir = new Directory(path.dirname(assetPath));
-
-      List<FileSystemEntity> files = assetDir.listSync(recursive: true);
-
-      for (FileSystemEntity entity in files) {
-        if (!FileSystemEntity.isFileSync(entity.path))
-          continue;
-
-        // Exclude any files in the given directories.
-        if (excludeDirs.any((String exclude) => entity.path.startsWith(exclude)))
-          continue;
-
-        if (path.basename(entity.path) == assetFilename && entity.path != assetPath) {
-          String key = path.relative(entity.path, from: baseAsset.base);
-          String assetEntry;
-          if (baseAsset.symbolicPrefix != null)
-            assetEntry = path.join(baseAsset.symbolicPrefix, key);
-          variants.add(new _Asset(base: baseAsset.base, assetEntry: assetEntry, relativePath: key));
-        }
-      }
-    }
-  }
-
-  // Add assets referenced in the fonts section of the manifest.
-  if (manifestDescriptor.containsKey('fonts')) {
-    for (Map<String, dynamic> family in manifestDescriptor['fonts']) {
-      List<Map<String, dynamic>> fonts = family['fonts'];
-      if (fonts == null) continue;
-
-      for (Map<String, dynamic> font in fonts) {
-        String asset = font['asset'];
-        if (asset == null) continue;
-
-        _Asset baseAsset = _resolveAsset(packageMap, assetBase, asset);
-        if (!baseAsset.assetFileExists) {
-          printError('Error: unable to locate asset entry in flutter.yaml: "$asset".');
-          return null;
-        }
-
-        result[baseAsset] = <_Asset>[];
-      }
-    }
-  }
-
-  return result;
-}
-
-final String _licenseSeparator = '\n' + ('-' * 80) + '\n';
-
-/// Returns a ZipEntry representing the license file.
-Future<ZipEntry> _obtainLicenses(
-  PackageMap packageMap,
-  String assetBase
-) async {
-  // Read the LICENSE file from each package in the .packages file,
-  // splitting each one into each component license (so that we can
-  // de-dupe if possible).
-  // For the sky_engine package we assume each license starts with
-  // package names. For the other packages we assume that each
-  // license is raw.
-  final Map<String, Set<String>> packageLicenses = <String, Set<String>>{};
-  for (String packageName in packageMap.map.keys) {
-    final Uri package = packageMap.map[packageName];
-    if (package != null && package.scheme == 'file') {
-      final File file = new File.fromUri(package.resolve('../LICENSE'));
-      if (file.existsSync()) {
-        final List<String> rawLicenses = (await file.readAsString()).split(_licenseSeparator);
-        for (String rawLicense in rawLicenses) {
-          String licenseText;
-          List<String> packageNames;
-          if (packageName == 'sky_engine') {
-            final int split = rawLicense.indexOf('\n\n');
-            if (split >= 0) {
-              packageNames = rawLicense.substring(0, split).split('\n');
-              licenseText = rawLicense.substring(split + 2);
-            }
-          }
-          if (licenseText == null) {
-            licenseText = rawLicense;
-            packageNames = <String>[packageName];
-          }
-          packageLicenses.putIfAbsent(rawLicense, () => new Set<String>())
-            ..addAll(packageNames);
-        }
-      }
-    }
-  }
-
-  final List<String> combinedLicensesList = packageLicenses.keys.map(
-    (String license) {
-      List<String> packageNames = packageLicenses[license].toList()
-       ..sort();
-      return packageNames.join('\n') + '\n\n' + license;
-    }
-  ).toList();
-  combinedLicensesList.sort();
-
-  final String combinedLicenses = combinedLicensesList.join(_licenseSeparator);
-
-  return new ZipEntry.fromString('LICENSE', combinedLicenses);
-}
-
-_Asset _resolveAsset(
-  PackageMap packageMap,
-  String assetBase,
-  String asset
-) {
-  if (asset.startsWith('packages/') && !FileSystemEntity.isFileSync(path.join(assetBase, asset))) {
-    // Convert packages/flutter_gallery_assets/clouds-0.png to clouds-0.png.
-    String packageKey = asset.substring(9);
-    String relativeAsset = asset;
-
-    int index = packageKey.indexOf('/');
-    if (index != -1) {
-      relativeAsset = packageKey.substring(index + 1);
-      packageKey = packageKey.substring(0, index);
-    }
-
-    Uri uri = packageMap.map[packageKey];
-    if (uri != null && uri.scheme == 'file') {
-      File file = new File.fromUri(uri);
-      return new _Asset(base: file.path, assetEntry: asset, relativePath: relativeAsset);
-    }
-  }
-
-  return new _Asset(base: assetBase, relativePath: asset);
-}
-
-dynamic _loadManifest(String manifestPath) {
-  if (manifestPath == null || !FileSystemEntity.isFileSync(manifestPath))
-    return null;
-  String manifestDescriptor = new File(manifestPath).readAsStringSync();
-  return loadYaml(manifestDescriptor);
-}
-
-Future<int> _validateManifest(Object manifest) async {
-  String schemaPath = path.join(path.absolute(Cache.flutterRoot),
-      'packages', 'flutter_tools', 'schema', 'flutter_yaml.json');
-  Schema schema = await Schema.createSchemaFromUrl('file://$schemaPath');
-
-  Validator validator = new Validator(schema);
-  if (validator.validate(manifest)) {
-    return 0;
-  } else {
-    if (validator.errors.length == 1) {
-      printError('Error in flutter.yaml: ${validator.errors.first}');
-    } else {
-      printError('Error in flutter.yaml:');
-      printError('  ' + validator.errors.join('\n  '));
-    }
-
-    return 1;
-  }
-}
-
-/// Create a [ZipEntry] from the given [_Asset]; the asset must exist.
-ZipEntry _createAssetEntry(_Asset asset) {
-  assert(asset.assetFileExists);
-  return new ZipEntry.fromFile(asset.assetEntry, asset.assetFile);
-}
-
-ZipEntry _createAssetManifest(Map<_Asset, List<_Asset>> assetVariants) {
-  Map<String, List<String>> json = <String, List<String>>{};
-  for (_Asset main in assetVariants.keys) {
-    List<String> variants = <String>[];
-    for (_Asset variant in assetVariants[main])
-      variants.add(variant.relativePath);
-    json[main.relativePath] = variants;
-  }
-  return new ZipEntry.fromString('AssetManifest.json', JSON.encode(json));
-}
-
-ZipEntry _createFontManifest(Map<String, dynamic> manifestDescriptor,
-                             bool usesMaterialDesign,
-                             bool includeRobotoFonts) {
-  List<Map<String, dynamic>> fonts = <Map<String, dynamic>>[];
-  if (usesMaterialDesign) {
-    fonts.addAll(_getMaterialFonts(_kFontSetMaterial));
-    if (includeRobotoFonts)
-      fonts.addAll(_getMaterialFonts(_kFontSetRoboto));
-  }
-  if (manifestDescriptor != null && manifestDescriptor.containsKey('fonts'))
-    fonts.addAll(manifestDescriptor['fonts']);
-  if (fonts.isEmpty)
-    return null;
-  return new ZipEntry.fromString('FontManifest.json', JSON.encode(fonts));
-}
-
 /// Build the flx in the build/ directory and return `localBundlePath` on success.
 ///
 /// Return `null` on failure.
@@ -362,19 +69,6 @@
   return result == 0 ? localBundlePath : null;
 }
 
-/// The result from [buildInTempDir]. Note that this object should be disposed after use.
-class DirectoryResult {
-  DirectoryResult(this.directory, this.localBundlePath);
-
-  final Directory directory;
-  final String localBundlePath;
-
-  /// Call this to delete the temporary directory.
-  void dispose() {
-    directory.deleteSync(recursive: true);
-  }
-}
-
 Future<int> build({
   String mainPath: defaultMainPath,
   String manifestPath: defaultManifestPath,
@@ -386,16 +80,6 @@
   bool precompiledSnapshot: false,
   bool includeRobotoFonts: true
 }) async {
-  Object manifest = _loadManifest(manifestPath);
-  if (manifest != null) {
-    int result = await _validateManifest(manifest);
-    if (result != 0)
-      return result;
-  }
-  Map<String, dynamic> manifestDescriptor = manifest;
-
-  String assetBasePath = path.dirname(path.absolute(manifestPath));
-
   File snapshotFile;
 
   if (!precompiledSnapshot) {
@@ -417,9 +101,8 @@
   }
 
   return assemble(
-    manifestDescriptor: manifestDescriptor,
+    manifestPath: manifestPath,
     snapshotFile: snapshotFile,
-    assetBasePath: assetBasePath,
     outputPath: outputPath,
     privateKeyPath: privateKeyPath,
     workingDirPath: workingDirPath,
@@ -428,9 +111,8 @@
 }
 
 Future<int> assemble({
-  Map<String, dynamic> manifestDescriptor: const <String, dynamic>{},
+  String manifestPath,
   File snapshotFile,
-  String assetBasePath: defaultAssetBasePath,
   String outputPath: defaultFlxOutputPath,
   String privateKeyPath: defaultPrivateKeyPath,
   String workingDirPath: defaultWorkingDirPath,
@@ -438,61 +120,22 @@
 }) async {
   printTrace('Building $outputPath');
 
-  final PackageMap packageMap = new PackageMap(path.join(assetBasePath, '.packages'));
-
-  Map<_Asset, List<_Asset>> assetVariants = _parseAssets(
-    packageMap,
-    manifestDescriptor,
-    assetBasePath,
-    excludeDirs: <String>[workingDirPath, path.join(assetBasePath, 'build')]
-  );
-
-  if (assetVariants == null)
-    return 1;
-
-  final bool usesMaterialDesign = manifestDescriptor != null &&
-    manifestDescriptor['uses-material-design'] == true;
+  // Build the asset bundle.
+  AssetBundle assetBundle = new AssetBundle();
+  int result = await assetBundle.build(manifestPath: manifestPath,
+                                       workingDirPath: workingDirPath,
+                                       includeRobotoFonts: includeRobotoFonts);
+  if (result != 0) {
+    return result;
+  }
 
   ZipBuilder zipBuilder = new ZipBuilder();
 
+  // Add all entries from the asset bundle.
+  zipBuilder.entries.addAll(assetBundle.entries);
+
   if (snapshotFile != null)
-    zipBuilder.addEntry(new ZipEntry.fromFile(_kSnapshotKey, snapshotFile));
-
-  for (_Asset asset in assetVariants.keys) {
-    ZipEntry assetEntry = _createAssetEntry(asset);
-    if (assetEntry == null)
-      return 1;
-    zipBuilder.addEntry(assetEntry);
-
-    for (_Asset variant in assetVariants[asset]) {
-      ZipEntry variantEntry = _createAssetEntry(variant);
-      if (variantEntry == null)
-        return 1;
-      zipBuilder.addEntry(variantEntry);
-    }
-  }
-
-  List<_Asset> materialAssets = <_Asset>[];
-  if (usesMaterialDesign) {
-    materialAssets.addAll(_getMaterialAssets(_kFontSetMaterial));
-    if (includeRobotoFonts)
-      materialAssets.addAll(_getMaterialAssets(_kFontSetRoboto));
-  }
-  for (_Asset asset in materialAssets) {
-    ZipEntry assetEntry = _createAssetEntry(asset);
-    if (assetEntry == null)
-      return 1;
-    zipBuilder.addEntry(assetEntry);
-  }
-
-  zipBuilder.addEntry(_createAssetManifest(assetVariants));
-
-  ZipEntry fontManifest = _createFontManifest(manifestDescriptor, usesMaterialDesign, includeRobotoFonts);
-  if (fontManifest != null)
-    zipBuilder.addEntry(fontManifest);
-
-  // TODO(ianh): Only do the following line if we've changed packages
-  zipBuilder.addEntry(await _obtainLicenses(packageMap, assetBasePath));
+    zipBuilder.addEntry(new AssetBundleEntry.fromFile(_kSnapshotKey, snapshotFile));
 
   ensureDirectoryExists(outputPath);
 
diff --git a/packages/flutter_tools/lib/src/zip.dart b/packages/flutter_tools/lib/src/zip.dart
index b1edc90..1c7b79b 100644
--- a/packages/flutter_tools/lib/src/zip.dart
+++ b/packages/flutter_tools/lib/src/zip.dart
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'dart:convert' show UTF8;
 import 'dart:io';
 
 import 'package:archive/archive.dart';
 import 'package:path/path.dart' as path;
 
+import 'asset.dart';
 import 'base/process.dart';
 
 abstract class ZipBuilder {
@@ -21,30 +21,13 @@
 
   ZipBuilder._();
 
-  List<ZipEntry> entries = <ZipEntry>[];
+  List<AssetBundleEntry> entries = <AssetBundleEntry>[];
 
-  void addEntry(ZipEntry entry) => entries.add(entry);
+  void addEntry(AssetBundleEntry entry) => entries.add(entry);
 
   void createZip(File outFile, Directory zipBuildDir);
 }
 
-class ZipEntry {
-  ZipEntry.fromFile(this.archivePath, File file) {
-    this._file = file;
-  }
-
-  ZipEntry.fromString(this.archivePath, String contents) {
-    this._contents = contents;
-  }
-
-  final String archivePath;
-
-  File _file;
-  String _contents;
-
-  bool get isStringEntry => _contents != null;
-}
-
 class _ArchiveZipBuilder extends ZipBuilder {
   _ArchiveZipBuilder() : super._();
 
@@ -52,14 +35,9 @@
   void createZip(File outFile, Directory zipBuildDir) {
     Archive archive = new Archive();
 
-    for (ZipEntry entry in entries) {
-      if (entry.isStringEntry) {
-        List<int> data = UTF8.encode(entry._contents);
-        archive.addFile(new ArchiveFile.noCompress(entry.archivePath, data.length, data));
-      } else {
-        List<int> data = entry._file.readAsBytesSync();
-        archive.addFile(new ArchiveFile(entry.archivePath, data.length, data));
-      }
+    for (AssetBundleEntry entry in entries) {
+      List<int> data = entry.contentsAsBytes();
+      archive.addFile(new ArchiveFile.noCompress(entry.archivePath, data.length, data));
     }
 
     List<int> zipData = new ZipEncoder().encode(archive);
@@ -79,18 +57,11 @@
       zipBuildDir.deleteSync(recursive: true);
     zipBuildDir.createSync(recursive: true);
 
-    for (ZipEntry entry in entries) {
-      if (entry.isStringEntry) {
-        List<int> data = UTF8.encode(entry._contents);
-        File file = new File(path.join(zipBuildDir.path, entry.archivePath));
-        file.parent.createSync(recursive: true);
-        file.writeAsBytesSync(data);
-      } else {
-        List<int> data = entry._file.readAsBytesSync();
-        File file = new File(path.join(zipBuildDir.path, entry.archivePath));
-        file.parent.createSync(recursive: true);
-        file.writeAsBytesSync(data);
-      }
+    for (AssetBundleEntry entry in entries) {
+      List<int> data = entry.contentsAsBytes();
+      File file = new File(path.join(zipBuildDir.path, entry.archivePath));
+      file.parent.createSync(recursive: true);
+      file.writeAsBytesSync(data);
     }
 
     if (_getCompressedNames().isNotEmpty) {
@@ -112,13 +83,13 @@
 
   Iterable<String> _getCompressedNames() {
     return entries
-      .where((ZipEntry entry) => !entry.isStringEntry)
-      .map((ZipEntry entry) => entry.archivePath);
+      .where((AssetBundleEntry entry) => !entry.isStringEntry)
+      .map((AssetBundleEntry entry) => entry.archivePath);
   }
 
   Iterable<String> _getStoredNames() {
     return entries
-      .where((ZipEntry entry) => entry.isStringEntry)
-      .map((ZipEntry entry) => entry.archivePath);
+      .where((AssetBundleEntry entry) => entry.isStringEntry)
+      .map((AssetBundleEntry entry) => entry.archivePath);
   }
 }
