Version 1.17.0-dev.1.0

Merge commit 'a96e92050836b642c0d0df362b0763c821e243a2' to dev
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 78daa6f..2825ef5 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -8204,6 +8204,13 @@
     _identifier = _becomeParentOf(identifier);
   }
 
+  /**
+   * Initialize a newly created prefixed identifier that does not take ownership
+   * of the components. The resulting node is only for temporary use, such as by
+   * resolution.
+   */
+  PrefixedIdentifierImpl.temp(this._prefix, this._identifier) : period = null;
+
   @override
   Token get beginToken => _prefix.beginToken;
 
diff --git a/pkg/analyzer/lib/src/dart/resolver/scope.dart b/pkg/analyzer/lib/src/dart/resolver/scope.dart
index 54086d9..f646167 100644
--- a/pkg/analyzer/lib/src/dart/resolver/scope.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/scope.dart
@@ -128,6 +128,13 @@
     // Check enclosing scope.
     return enclosingScope.internalLookup(identifier, name, referencingLibrary);
   }
+
+  @override
+  Element _internalLookupPrefixed(Identifier identifier, String prefix,
+      String name, LibraryElement referencingLibrary) {
+    return enclosingScope._internalLookupPrefixed(
+        identifier, prefix, name, referencingLibrary);
+  }
 }
 
 /**
@@ -347,6 +354,12 @@
   List<Namespace> _importedNamespaces;
 
   /**
+   * A table mapping prefixes that have been referenced to a map from the names
+   * that have been referenced to the element associated with the prefixed name.
+   */
+  Map<String, Map<String, Element>> _definedPrefixedNames;
+
+  /**
    * Initialize a newly created scope representing the names imported into the
    * [_definingLibrary]. The [errorListener] is the listener that is to be
    * informed when an error is encountered.
@@ -436,6 +449,18 @@
   }
 
   /**
+   * Add the given [element] to this scope without checking for duplication or
+   * hiding.
+   */
+  void _definePrefixedNameWithoutChecking(
+      String prefix, String name, Element element) {
+    _definedPrefixedNames ??= new HashMap<String, Map<String, Element>>();
+    Map<String, Element> unprefixedNames = _definedPrefixedNames.putIfAbsent(
+        prefix, () => new HashMap<String, Element>());
+    unprefixedNames[name] = element;
+  }
+
+  /**
    * Return the name of the library that defines given [element].
    */
   String _getLibraryName(Element element) {
@@ -482,6 +507,68 @@
     return buffer.toString();
   }
 
+  @override
+  Element _internalLookupPrefixed(Identifier identifier, String prefix,
+      String name, LibraryElement referencingLibrary) {
+    Element foundElement = _localPrefixedLookup(prefix, name);
+    if (foundElement != null) {
+      return foundElement;
+    }
+    for (int i = 0; i < _importedNamespaces.length; i++) {
+      Namespace nameSpace = _importedNamespaces[i];
+      Element element = nameSpace.getPrefixed(prefix, name);
+      if (element != null) {
+        if (foundElement == null) {
+          foundElement = element;
+        } else if (!identical(foundElement, element)) {
+          foundElement = MultiplyDefinedElementImpl.fromElements(
+              _definingLibrary.context, foundElement, element);
+        }
+      }
+    }
+    Element element = foundElement;
+    if (element is MultiplyDefinedElementImpl) {
+      foundElement = _removeSdkElements(identifier, name, element);
+    }
+    if (foundElement is MultiplyDefinedElementImpl) {
+      String foundEltName = foundElement.displayName;
+      List<Element> conflictingMembers = foundElement.conflictingElements;
+      int count = conflictingMembers.length;
+      List<String> libraryNames = new List<String>(count);
+      for (int i = 0; i < count; i++) {
+        libraryNames[i] = _getLibraryName(conflictingMembers[i]);
+      }
+      libraryNames.sort();
+      errorListener.onError(new AnalysisError(
+          getSource(identifier),
+          identifier.offset,
+          identifier.length,
+          StaticWarningCode.AMBIGUOUS_IMPORT, [
+        foundEltName,
+        StringUtilities.printListOfQuotedNames(libraryNames)
+      ]));
+      return foundElement;
+    }
+    if (foundElement != null) {
+      _definePrefixedNameWithoutChecking(prefix, name, foundElement);
+    }
+    return foundElement;
+  }
+
+  /**
+   * Return the element with which the given [prefix] and [name] are associated,
+   * or `null` if the name is not defined within this scope.
+   */
+  Element _localPrefixedLookup(String prefix, String name) {
+    if (_definedPrefixedNames != null) {
+      Map<String, Element> unprefixedNames = _definedPrefixedNames[prefix];
+      if (unprefixedNames != null) {
+        return unprefixedNames[name];
+      }
+    }
+    return null;
+  }
+
   /**
    * Given a collection of elements (captured by the [foundElement]) that the
    * [identifier] (with the given [name]) resolved to, remove from the list all
@@ -630,9 +717,16 @@
 
   /**
    * Return the element in this namespace that is available to the containing
-   * scope using the given name.
+   * scope using the given name, or `null` if there is no such element.
    */
   Element get(String name) => _definedNames[name];
+
+  /**
+   * Return the element in this namespace whose name is the result of combining
+   * the [prefix] and the [name], separated by a period, or `null` if there is
+   * no such element.
+   */
+  Element getPrefixed(String prefix, String name) => null;
 }
 
 /**
@@ -679,7 +773,10 @@
     }
     HashMap<String, Element> exportedNames = _getExportMapping(importedLibrary);
     exportedNames = _applyCombinators(exportedNames, element.combinators);
-    exportedNames = _applyPrefix(exportedNames, element.prefix);
+    PrefixElement prefix = element.prefix;
+    if (prefix != null) {
+      return new PrefixedNamespace(prefix.name, exportedNames);
+    }
     return new Namespace(exportedNames);
   }
 
@@ -765,24 +862,6 @@
   }
 
   /**
-   * Apply the prefix defined by the [prefixElement] to all of the names in the
-   * table of [definedNames].
-   */
-  HashMap<String, Element> _applyPrefix(
-      HashMap<String, Element> definedNames, PrefixElement prefixElement) {
-    if (prefixElement != null) {
-      String prefix = prefixElement.name;
-      HashMap<String, Element> newNames = new HashMap<String, Element>();
-      definedNames.forEach((String name, Element element) {
-        newNames["$prefix.$name"] = element;
-      });
-      return newNames;
-    } else {
-      return definedNames;
-    }
-  }
-
-  /**
    * Create a mapping table representing the export namespace of the given
    * [library]. The set of [visitedElements] contains the libraries that do not
    * need to be visited when processing the export directives of the given
@@ -869,6 +948,64 @@
 }
 
 /**
+ * A mapping of identifiers to the elements represented by those identifiers.
+ * Namespaces are the building blocks for scopes.
+ */
+class PrefixedNamespace implements Namespace {
+  /**
+   * The prefix that is prepended to each of the defined names.
+   */
+  final String _prefix;
+
+  /**
+   * The length of the prefix.
+   */
+  final int _length;
+
+  /**
+   * A table mapping names that are defined in this namespace to the element
+   * representing the thing declared with that name.
+   */
+  final HashMap<String, Element> _definedNames;
+
+  /**
+   * Initialize a newly created namespace to have the names resulting from
+   * prefixing each of the [_definedNames] with the given [_prefix] (and a
+   * period).
+   */
+  PrefixedNamespace(String prefix, this._definedNames)
+      : _prefix = prefix,
+        _length = prefix.length;
+
+  @override
+  Map<String, Element> get definedNames {
+    Map<String, Element> definedNames = <String, Element>{};
+    _definedNames.forEach((String name, Element element) {
+      definedNames["$_prefix.$name"] = element;
+    });
+    return definedNames;
+  }
+
+  @override
+  Element get(String name) {
+    if (name.startsWith(_prefix)) {
+      if (name.codeUnitAt(_length) == '.'.codeUnitAt(0)) {
+        return _definedNames[name.substring(_length + 1)];
+      }
+    }
+    return null;
+  }
+
+  @override
+  Element getPrefixed(String prefix, String name) {
+    if (prefix == _prefix) {
+      return _definedNames[name];
+    }
+    return null;
+  }
+}
+
+/**
  * A name scope used by the resolver to determine which names are visible at any
  * given point in the code.
  */
@@ -1009,8 +1146,13 @@
    * [referencingLibrary] is the library that contains the reference to the
    * name, used to implement library-level privacy.
    */
-  Element lookup(Identifier identifier, LibraryElement referencingLibrary) =>
-      internalLookup(identifier, identifier.name, referencingLibrary);
+  Element lookup(Identifier identifier, LibraryElement referencingLibrary) {
+    if (identifier is PrefixedIdentifier) {
+      return _internalLookupPrefixed(identifier, identifier.prefix.name,
+          identifier.identifier.name, referencingLibrary);
+    }
+    return internalLookup(identifier, identifier.name, referencingLibrary);
+  }
 
   /**
    * Return the name that will be used to look up the given [element].
@@ -1026,6 +1168,17 @@
   }
 
   /**
+   * Return the element with which the given [prefix] and [name] are associated,
+   * or `null` if the name is not defined within this scope. The [identifier] is
+   * the identifier node to lookup element for, used to report correct kind of a
+   * problem and associate problem with. The [referencingLibrary] is the library
+   * that contains the reference to the name, used to implement library-level
+   * privacy.
+   */
+  Element _internalLookupPrefixed(Identifier identifier, String prefix,
+      String name, LibraryElement referencingLibrary);
+
+  /**
    * Return `true` if the given [name] is a library-private name.
    */
   static bool isPrivateName(String name) =>
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index b37ebea..833e55e 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -12,7 +12,12 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/ast/ast.dart'
-    show ChildEntities, IdentifierImpl;
+    show
+        ChildEntities,
+        IdentifierImpl,
+        PrefixedIdentifierImpl,
+        SimpleIdentifierImpl;
+import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/engine.dart';
@@ -879,8 +884,11 @@
     if (prefixElement is PrefixElement) {
       Element element = _resolver.nameScope.lookup(node, _definingLibrary);
       if (element == null && identifier.inSetterContext()) {
-        element = _resolver.nameScope.lookup(
-            new SyntheticIdentifier("${node.name}=", node), _definingLibrary);
+        Identifier setterName = new PrefixedIdentifierImpl.temp(
+            node.prefix,
+            new SimpleIdentifierImpl(new StringToken(TokenType.STRING,
+                "${node.identifier.name}=", node.identifier.offset - 1)));
+        element = _resolver.nameScope.lookup(setterName, _definingLibrary);
       }
       if (element == null) {
         if (identifier.inSetterContext()) {
@@ -1379,8 +1387,10 @@
     for (ImportElement importElement in _definingLibrary.imports) {
       PrefixElement prefixElement = importElement.prefix;
       if (prefixElement != null) {
-        Identifier prefixedIdentifier = new SyntheticIdentifier(
-            "${prefixElement.name}.${identifier.name}", identifier);
+        Identifier prefixedIdentifier = new PrefixedIdentifierImpl.temp(
+            new SimpleIdentifierImpl(new StringToken(TokenType.STRING,
+                prefixElement.name, prefixElement.nameOffset)),
+            identifier);
         Element importedElement =
             nameScope.lookup(prefixedIdentifier, _definingLibrary);
         if (importedElement != null) {
@@ -2183,8 +2193,8 @@
         // prefixed identifier for an imported top-level function or top-level
         // getter that returns a function.
         //
-        String name = "${target.name}.$methodName";
-        Identifier functionName = new SyntheticIdentifier(name, methodName);
+        Identifier functionName =
+            new PrefixedIdentifierImpl.temp(target, methodName);
         Element element =
             _resolver.nameScope.lookup(functionName, _definingLibrary);
         if (element != null) {
diff --git a/pkg/analyzer/tool/summary/build_sdk_summaries.dart b/pkg/analyzer/tool/summary/build_sdk_summaries.dart
index 01fa8fe..8a9adb8 100644
--- a/pkg/analyzer/tool/summary/build_sdk_summaries.dart
+++ b/pkg/analyzer/tool/summary/build_sdk_summaries.dart
@@ -183,7 +183,7 @@
     // Prepare SDK.
     //
     DirectoryBasedDartSdk sdk =
-        new DirectoryBasedDartSdk(new JavaFile(sdkPath));
+        new DirectoryBasedDartSdk(new JavaFile(sdkPath), strongMode);
     sdk.useSummary = false;
     sdk.analysisOptions = new AnalysisOptionsImpl()..strongMode = strongMode;
     context = sdk.context;
@@ -192,7 +192,9 @@
     //
     Set<String> uriSet =
         sdk.sdkLibraries.map((SdkLibrary library) => library.shortName).toSet();
-    uriSet.add('dart:html/nativewrappers.dart');
+    if (!strongMode) {
+      uriSet.add('dart:html/nativewrappers.dart');
+    }
     uriSet.add('dart:html_common/html_common_dart2js.dart');
     //
     // Serialize each SDK library.
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index d360c18..173c27c 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -16,8 +16,7 @@
 import '../compiler_new.dart' as api;
 import 'common/tasks.dart' show GenericTask, Measurer;
 import 'common.dart';
-import 'common/backend_api.dart' show
-    Backend;
+import 'common/backend_api.dart' show Backend;
 import 'compiler.dart';
 import 'diagnostics/messages.dart' show Message;
 import 'elements/elements.dart' as elements;
@@ -55,7 +54,8 @@
             options: options,
             outputProvider: outputProvider,
             environment: new _Environment(options.environment),
-            makeBackend: makeBackend, makeReporter: makeReporter) {
+            makeBackend: makeBackend,
+            makeReporter: makeReporter) {
     _Environment env = environment;
     env.compiler = this;
     tasks.addAll([
diff --git a/pkg/compiler/lib/src/common/backend_api.dart b/pkg/compiler/lib/src/common/backend_api.dart
index 6b809e9..e7f3632 100644
--- a/pkg/compiler/lib/src/common/backend_api.dart
+++ b/pkg/compiler/lib/src/common/backend_api.dart
@@ -24,7 +24,8 @@
         LibraryElement,
         MetadataAnnotation,
         MethodElement;
-import '../enqueue.dart' show Enqueuer, EnqueueTask, CodegenEnqueuer, ResolutionEnqueuer;
+import '../enqueue.dart'
+    show Enqueuer, EnqueueTask, CodegenEnqueuer, ResolutionEnqueuer;
 import '../io/code_output.dart' show CodeBuffer;
 import '../io/source_information.dart' show SourceInformationStrategy;
 import '../js_backend/backend_helpers.dart' as js_backend show BackendHelpers;
@@ -38,14 +39,10 @@
 import '../tree/tree.dart' show Node, Send;
 import '../universe/call_structure.dart' show CallStructure;
 import '../universe/world_impact.dart' show ImpactStrategy, WorldImpact;
-import 'codegen.dart' show
-    CodegenWorkItem;
-import 'registry.dart' show
-    Registry;
-import 'tasks.dart' show
-    CompilerTask;
-import 'work.dart' show
-    ItemCompilationContext;
+import 'codegen.dart' show CodegenWorkItem;
+import 'registry.dart' show Registry;
+import 'tasks.dart' show CompilerTask;
+import 'work.dart' show ItemCompilationContext;
 
 abstract class Backend {
   final Compiler compiler;
@@ -55,6 +52,9 @@
   /// Returns true if the backend supports reflection.
   bool get supportsReflection;
 
+  /// Returns true if the backend supports reflection.
+  bool get supportsAsyncAwait;
+
   /// The [ConstantSystem] used to interpret compile-time constants for this
   /// backend.
   ConstantSystem get constantSystem;
diff --git a/pkg/compiler/lib/src/compile_time_constants.dart b/pkg/compiler/lib/src/compile_time_constants.dart
index c4fe193..629d457 100644
--- a/pkg/compiler/lib/src/compile_time_constants.dart
+++ b/pkg/compiler/lib/src/compile_time_constants.dart
@@ -16,7 +16,7 @@
 import 'core_types.dart' show CoreTypes;
 import 'dart_types.dart';
 import 'elements/elements.dart';
-import 'elements/modelx.dart' show FunctionElementX;
+import 'elements/modelx.dart' show FieldElementX, FunctionElementX;
 import 'resolution/tree_elements.dart' show TreeElements;
 import 'resolution/operators.dart';
 import 'tree/tree.dart';
@@ -34,10 +34,8 @@
   ConstantValue getConstantValue(ConstantExpression expression);
 
   /// Returns the constant value for the initializer of [element].
+  @deprecated
   ConstantValue getConstantValueForVariable(VariableElement element);
-
-  /// Returns the constant for the initializer of [element].
-  ConstantExpression getConstantForVariable(VariableElement element);
 }
 
 /// A class that can compile and provide constants for variables, nodes and
@@ -54,7 +52,7 @@
 
   /// Computes the compile-time constant for the variable initializer,
   /// if possible.
-  void compileVariable(VariableElement element);
+  ConstantExpression compileVariable(VariableElement element);
 
   /// Compiles the constant for [node].
   ///
@@ -156,15 +154,11 @@
   CoreTypes get coreTypes => compiler.coreTypes;
 
   @override
+  @deprecated
   ConstantValue getConstantValueForVariable(VariableElement element) {
     return getConstantValue(initialVariableValues[element.declaration]);
   }
 
-  @override
-  ConstantExpression getConstantForVariable(VariableElement element) {
-    return initialVariableValues[element.declaration];
-  }
-
   ConstantExpression compileConstant(VariableElement element) {
     return internalCompileVariable(element, true, true);
   }
@@ -1278,12 +1272,13 @@
     Map<FieldElement, AstConstant> fieldConstants =
         <FieldElement, AstConstant>{};
     classElement.implementation.forEachInstanceField(
-        (ClassElement enclosing, FieldElement field) {
+        (ClassElement enclosing, FieldElementX field) {
       AstConstant fieldValue = fieldValues[field];
       if (fieldValue == null) {
         // Use the default value.
         ConstantExpression fieldExpression =
             handler.internalCompileVariable(field, true, false);
+        field.constant = fieldExpression;
         fieldValue = new AstConstant.fromDefaultValue(
             field, fieldExpression, handler.getConstantValue(fieldExpression));
         // TODO(het): If the field value doesn't typecheck due to the type
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 4999d44..4020814 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -444,22 +444,31 @@
   /// for [library].
   Future onLibraryScanned(LibraryElement library, LibraryLoader loader) {
     Uri uri = library.canonicalUri;
-    if (uri == Uris.dart_core) {
-      initializeCoreClasses();
-      identicalFunction = coreLibrary.find('identical');
-    } else if (uri == Uris.dart_mirrors) {
-      mirrorSystemClass = findRequiredElement(library, 'MirrorSystem');
-      mirrorsUsedClass = findRequiredElement(library, 'MirrorsUsed');
-    } else if (uri == Uris.dart_async) {
-      asyncLibrary = library;
-      deferredLibraryClass = findRequiredElement(library, 'DeferredLibrary');
-      _coreTypes.futureClass = findRequiredElement(library, 'Future');
-      _coreTypes.streamClass = findRequiredElement(library, 'Stream');
-    } else if (uri == Uris.dart__native_typed_data) {
-      typedDataClass = findRequiredElement(library, 'NativeTypedData');
-    } else if (uri == js_backend.BackendHelpers.DART_JS_HELPER) {
-      patchAnnotationClass = findRequiredElement(library, '_Patch');
-      nativeAnnotationClass = findRequiredElement(library, 'Native');
+    // If the script of the library is synthesized, the library does not exist
+    // and we do not try to load the helpers.
+    //
+    // This could for example happen if dart:async is disabled, then loading it
+    // should not try to find the given element.
+    // TODO(johnniwinther): This should just be library.isSynthesized, but that
+    // does not work yet for deserialized elements.
+    if (!library.compilationUnit.script.isSynthesized) {
+      if (uri == Uris.dart_core) {
+        initializeCoreClasses();
+        identicalFunction = coreLibrary.find('identical');
+      } else if (uri == Uris.dart_mirrors) {
+        mirrorSystemClass = findRequiredElement(library, 'MirrorSystem');
+        mirrorsUsedClass = findRequiredElement(library, 'MirrorsUsed');
+      } else if (uri == Uris.dart_async) {
+        asyncLibrary = library;
+        deferredLibraryClass = findRequiredElement(library, 'DeferredLibrary');
+        _coreTypes.futureClass = findRequiredElement(library, 'Future');
+        _coreTypes.streamClass = findRequiredElement(library, 'Stream');
+      } else if (uri == Uris.dart__native_typed_data) {
+        typedDataClass = findRequiredElement(library, 'NativeTypedData');
+      } else if (uri == js_backend.BackendHelpers.DART_JS_HELPER) {
+        patchAnnotationClass = findRequiredElement(library, '_Patch');
+        nativeAnnotationClass = findRequiredElement(library, 'Native');
+      }
     }
     return backend.onLibraryScanned(library, loader);
   }
@@ -1259,8 +1268,9 @@
         // errors instead of using a map.
         element = mainFunction;
       }
-      elementsWithCompileTimeErrors.
-          putIfAbsent(element, () => <DiagnosticMessage>[]).add(message);
+      elementsWithCompileTimeErrors
+          .putIfAbsent(element, () => <DiagnosticMessage>[])
+          .add(message);
     }
   }
 
diff --git a/pkg/compiler/lib/src/constants/constructors.dart b/pkg/compiler/lib/src/constants/constructors.dart
index b8e7471..c0e09b6 100644
--- a/pkg/compiler/lib/src/constants/constructors.dart
+++ b/pkg/compiler/lib/src/constants/constructors.dart
@@ -99,13 +99,13 @@
     StringBuffer sb = new StringBuffer();
     sb.write("{'type': $type");
     defaultValues.forEach((key, ConstantExpression expression) {
-      sb.write(",\n 'default:${key}': ${expression.getText()}");
+      sb.write(",\n 'default:${key}': ${expression.toDartText()}");
     });
     fieldMap.forEach((FieldElement field, ConstantExpression expression) {
-      sb.write(",\n 'field:${field}': ${expression.getText()}");
+      sb.write(",\n 'field:${field}': ${expression.toDartText()}");
     });
     if (superConstructorInvocation != null) {
-      sb.write(",\n 'constructor: ${superConstructorInvocation.getText()}");
+      sb.write(",\n 'constructor: ${superConstructorInvocation.toDartText()}");
     }
     sb.write("}");
     return sb.toString();
@@ -189,9 +189,9 @@
     StringBuffer sb = new StringBuffer();
     sb.write("{'type': ${thisConstructorInvocation.type}");
     defaultValues.forEach((key, ConstantExpression expression) {
-      sb.write(",\n 'default:${key}': ${expression.getText()}");
+      sb.write(",\n 'default:${key}': ${expression.toDartText()}");
     });
-    sb.write(",\n 'constructor': ${thisConstructorInvocation.getText()}");
+    sb.write(",\n 'constructor': ${thisConstructorInvocation.toDartText()}");
     sb.write("}");
     return sb.toString();
   }
@@ -237,7 +237,7 @@
   String toString() {
     StringBuffer sb = new StringBuffer();
     sb.write("{");
-    sb.write("'constructor': ${targetConstructorInvocation.getText()}");
+    sb.write("'constructor': ${targetConstructorInvocation.toDartText()}");
     sb.write("}");
     return sb.toString();
   }
diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart
index d476dd6b..aa284cd 100644
--- a/pkg/compiler/lib/src/constants/expressions.dart
+++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -82,12 +82,23 @@
   /// environment values.
   DartType getKnownType(CoreTypes coreTypes) => null;
 
-  String getText() {
+  /// Returns a text string resembling the Dart code creating this constant.
+  String toDartText() {
     ConstExpPrinter printer = new ConstExpPrinter();
     accept(printer);
     return printer.toString();
   }
 
+  /// Returns a text string showing the structure of this constant.
+  String toStructuredText() {
+    StringBuffer sb = new StringBuffer();
+    _createStructuredText(sb);
+    return sb.toString();
+  }
+
+  /// Writes the structure of the constant into [sb].
+  void _createStructuredText(StringBuffer sb);
+
   int _computeHashCode();
 
   int get hashCode {
@@ -108,9 +119,10 @@
   }
 
   String toString() {
-    assertDebugMode('Use ConstantExpression.getText() instead of '
+    assertDebugMode('Use ConstantExpression.toDartText() or '
+        'ConstantExpression.toStructuredText() instead of '
         'ConstantExpression.toString()');
-    return getText();
+    return toDartText();
   }
 }
 
@@ -130,6 +142,11 @@
   }
 
   @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('Erroneous()');
+  }
+
+  @override
   int _computeHashCode() => 13;
 
   @override
@@ -149,6 +166,11 @@
   }
 
   @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('Synthetic(value=${value.toStructuredText()})');
+  }
+
+  @override
   int _computeHashCode() => 13 * value.hashCode;
 
   accept(ConstantExpressionVisitor visitor, [context]) {
@@ -182,6 +204,11 @@
   }
 
   @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('Bool(value=${primitiveValue})');
+  }
+
+  @override
   ConstantValue evaluate(
       Environment environment, ConstantSystem constantSystem) {
     return constantSystem.createBool(primitiveValue);
@@ -212,6 +239,11 @@
   }
 
   @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('Int(value=${primitiveValue})');
+  }
+
+  @override
   ConstantValue evaluate(
       Environment environment, ConstantSystem constantSystem) {
     return constantSystem.createInt(primitiveValue);
@@ -242,6 +274,11 @@
   }
 
   @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('Double(value=${primitiveValue})');
+  }
+
+  @override
   ConstantValue evaluate(
       Environment environment, ConstantSystem constantSystem) {
     return constantSystem.createDouble(primitiveValue);
@@ -272,6 +309,11 @@
   }
 
   @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('String(value=${primitiveValue})');
+  }
+
+  @override
   ConstantValue evaluate(
       Environment environment, ConstantSystem constantSystem) {
     return constantSystem.createString(new DartString.literal(primitiveValue));
@@ -300,6 +342,11 @@
   }
 
   @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('Null()');
+  }
+
+  @override
   ConstantValue evaluate(
       Environment environment, ConstantSystem constantSystem) {
     return constantSystem.createNull();
@@ -331,6 +378,18 @@
   }
 
   @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('List(type=$type,values=[');
+    String delimiter = '';
+    for (ConstantExpression value in values) {
+      sb.write(delimiter);
+      value._createStructuredText(sb);
+      delimiter = ',';
+    }
+    sb.write('])');
+  }
+
+  @override
   ConstantValue evaluate(
       Environment environment, ConstantSystem constantSystem) {
     return constantSystem.createList(type,
@@ -380,6 +439,20 @@
   }
 
   @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('Map(type=$type,entries=[');
+    for (int index = 0; index < keys.length; index++) {
+      if (index > 0) {
+        sb.write(',');
+      }
+      keys[index]._createStructuredText(sb);
+      sb.write('->');
+      values[index]._createStructuredText(sb);
+    }
+    sb.write('])');
+  }
+
+  @override
   ConstantValue evaluate(
       Environment environment, ConstantSystem constantSystem) {
     return constantSystem.createMap(
@@ -439,6 +512,19 @@
     return visitor.visitConstructed(this, context);
   }
 
+  @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('Constructored(type=$type,constructor=$target,'
+        'callStructure=$callStructure,arguments=[');
+    String delimiter = '';
+    for (ConstantExpression value in arguments) {
+      sb.write(delimiter);
+      value._createStructuredText(sb);
+      delimiter = ',';
+    }
+    sb.write('])');
+  }
+
   Map<FieldElement, ConstantExpression> computeInstanceFields() {
     return target.constantConstructor
         .computeInstanceFields(arguments, callStructure);
@@ -499,6 +585,18 @@
     return visitor.visitConcatenate(this, context);
   }
 
+  @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('Concatenate(expressions=[');
+    String delimiter = '';
+    for (ConstantExpression value in expressions) {
+      sb.write(delimiter);
+      value._createStructuredText(sb);
+      delimiter = ',';
+    }
+    sb.write('])');
+  }
+
   ConstantExpression apply(NormalizedArguments arguments) {
     return new ConcatenateConstantExpression(
         expressions.map((a) => a.apply(arguments)).toList());
@@ -567,6 +665,11 @@
   }
 
   @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('Symbol(name=$name)');
+  }
+
+  @override
   int _computeHashCode() => 13 * name.hashCode;
 
   @override
@@ -601,6 +704,11 @@
   }
 
   @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('Type(type=$type)');
+  }
+
+  @override
   ConstantValue evaluate(
       Environment environment, ConstantSystem constantSystem) {
     return constantSystem.createType(environment.compiler, type);
@@ -631,6 +739,11 @@
   }
 
   @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('Variable(element=$element)');
+  }
+
+  @override
   ConstantValue evaluate(
       Environment environment, ConstantSystem constantSystem) {
     return element.constant.evaluate(environment, constantSystem);
@@ -658,6 +771,11 @@
   }
 
   @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('Function(element=$element)');
+  }
+
+  @override
   ConstantValue evaluate(
       Environment environment, ConstantSystem constantSystem) {
     return new FunctionConstantValue(element);
@@ -692,6 +810,15 @@
   }
 
   @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('Binary(left=');
+    left._createStructuredText(sb);
+    sb.write(',op=$operator,right=');
+    right._createStructuredText(sb);
+    sb.write(')');
+  }
+
+  @override
   ConstantValue evaluate(
       Environment environment, ConstantSystem constantSystem) {
     return constantSystem.lookupBinary(operator).fold(
@@ -807,6 +934,15 @@
   }
 
   @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('Identical(left=');
+    left._createStructuredText(sb);
+    sb.write(',right=');
+    right._createStructuredText(sb);
+    sb.write(')');
+  }
+
+  @override
   ConstantValue evaluate(
       Environment environment, ConstantSystem constantSystem) {
     return constantSystem.identity.fold(
@@ -851,6 +987,13 @@
   }
 
   @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('Unary(op=$operator,expression=');
+    expression._createStructuredText(sb);
+    sb.write(')');
+  }
+
+  @override
   ConstantValue evaluate(
       Environment environment, ConstantSystem constantSystem) {
     return constantSystem
@@ -899,6 +1042,13 @@
   }
 
   @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('StringLength(expression=');
+    expression._createStructuredText(sb);
+    sb.write(')');
+  }
+
+  @override
   ConstantValue evaluate(
       Environment environment, ConstantSystem constantSystem) {
     ConstantValue value = expression.evaluate(environment, constantSystem);
@@ -943,6 +1093,17 @@
     return visitor.visitConditional(this, context);
   }
 
+  @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('Conditional(condition=');
+    condition._createStructuredText(sb);
+    sb.write(',true=');
+    trueExp._createStructuredText(sb);
+    sb.write(',false=');
+    falseExp._createStructuredText(sb);
+    sb.write(')');
+  }
+
   ConstantExpression apply(NormalizedArguments arguments) {
     return new ConditionalConstantExpression(condition.apply(arguments),
         trueExp.apply(arguments), falseExp.apply(arguments));
@@ -1005,6 +1166,11 @@
     return visitor.visitPositional(this, context);
   }
 
+  @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('Positional(index=$index)');
+  }
+
   ConstantExpression apply(NormalizedArguments arguments) {
     return arguments.getPositionalArgument(index);
   }
@@ -1036,6 +1202,11 @@
     return visitor.visitNamed(this, context);
   }
 
+  @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('Named(name=$name)');
+  }
+
   ConstantExpression apply(NormalizedArguments arguments) {
     return arguments.getNamedArgument(name);
   }
@@ -1086,6 +1257,15 @@
   }
 
   @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('bool.fromEnvironment(name=');
+    name._createStructuredText(sb);
+    sb.write(',defaultValue=');
+    defaultValue._createStructuredText(sb);
+    sb.write(')');
+  }
+
+  @override
   ConstantValue evaluate(
       Environment environment, ConstantSystem constantSystem) {
     ConstantValue nameConstantValue =
@@ -1136,6 +1316,15 @@
   }
 
   @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('int.fromEnvironment(name=');
+    name._createStructuredText(sb);
+    sb.write(',defaultValue=');
+    defaultValue._createStructuredText(sb);
+    sb.write(')');
+  }
+
+  @override
   ConstantValue evaluate(
       Environment environment, ConstantSystem constantSystem) {
     ConstantValue nameConstantValue =
@@ -1188,6 +1377,15 @@
   }
 
   @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('String.fromEnvironment(name=');
+    name._createStructuredText(sb);
+    sb.write(',defaultValue=');
+    defaultValue._createStructuredText(sb);
+    sb.write(')');
+  }
+
+  @override
   ConstantValue evaluate(
       Environment environment, ConstantSystem constantSystem) {
     ConstantValue nameConstantValue =
@@ -1231,6 +1429,13 @@
   ConstantExpressionKind get kind => ConstantExpressionKind.DEFERRED;
 
   @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('Deferred(prefix=$prefix,expression=');
+    expression._createStructuredText(sb);
+    sb.write(')');
+  }
+
+  @override
   ConstantValue evaluate(
       Environment environment, ConstantSystem constantSystem) {
     return expression.evaluate(environment, constantSystem);
diff --git a/pkg/compiler/lib/src/constants/values.dart b/pkg/compiler/lib/src/constants/values.dart
index 40bda63..fd0f5dd 100644
--- a/pkg/compiler/lib/src/constants/values.dart
+++ b/pkg/compiler/lib/src/constants/values.dart
@@ -78,15 +78,16 @@
   /// For the synthetic constants, [DeferredConstantValue],
   /// [SyntheticConstantValue], [InterceptorConstantValue] the unparse is
   /// descriptive only.
-  String unparse();
+  String toDartText();
 
   /// Returns a structured representation of this constant suited for debugging.
-  String toStructuredString();
+  String toStructuredText();
 
   String toString() {
-    assertDebugMode("Use Constant.unparse() or Constant.toStructuredString() "
-        "instead of Constant.toString().");
-    return toStructuredString();
+    assertDebugMode("Use ConstantValue.toDartText() or "
+        "ConstantValue.toStructuredText() "
+        "instead of ConstantValue.toString().");
+    return toStructuredText();
   }
 }
 
@@ -116,7 +117,7 @@
 
   accept(ConstantValueVisitor visitor, arg) => visitor.visitFunction(this, arg);
 
-  String unparse() {
+  String toDartText() {
     if (element.isStatic) {
       return '${element.enclosingClass.name}.${element.name}';
     } else {
@@ -124,8 +125,8 @@
     }
   }
 
-  String toStructuredString() {
-    return 'FunctionConstant(${unparse()})';
+  String toStructuredText() {
+    return 'FunctionConstant(${toDartText()})';
   }
 }
 
@@ -151,7 +152,7 @@
   DartString toDartString();
 
   /// This value in Dart syntax.
-  String unparse() => primitiveValue.toString();
+  String toDartText() => primitiveValue.toString();
 }
 
 class NullConstantValue extends PrimitiveConstantValue {
@@ -175,7 +176,7 @@
 
   accept(ConstantValueVisitor visitor, arg) => visitor.visitNull(this, arg);
 
-  String toStructuredString() => 'NullConstant';
+  String toStructuredText() => 'NullConstant';
 }
 
 abstract class NumConstantValue extends PrimitiveConstantValue {
@@ -256,7 +257,7 @@
 
   accept(ConstantValueVisitor visitor, arg) => visitor.visitInt(this, arg);
 
-  String toStructuredString() => 'IntConstant(${unparse()})';
+  String toStructuredText() => 'IntConstant(${toDartText()})';
 }
 
 class DoubleConstantValue extends NumConstantValue {
@@ -318,7 +319,7 @@
 
   accept(ConstantValueVisitor visitor, arg) => visitor.visitDouble(this, arg);
 
-  String toStructuredString() => 'DoubleConstant(${unparse()})';
+  String toStructuredText() => 'DoubleConstant(${toDartText()})';
 }
 
 abstract class BoolConstantValue extends PrimitiveConstantValue {
@@ -336,7 +337,7 @@
 
   accept(ConstantValueVisitor visitor, arg) => visitor.visitBool(this, arg);
 
-  String toStructuredString() => 'BoolConstant(${unparse()})';
+  String toStructuredText() => 'BoolConstant(${toDartText()})';
 }
 
 class TrueConstantValue extends BoolConstantValue {
@@ -413,9 +414,9 @@
   accept(ConstantValueVisitor visitor, arg) => visitor.visitString(this, arg);
 
   // TODO(johnniwinther): Ensure correct escaping.
-  String unparse() => '"${primitiveValue.slowToString()}"';
+  String toDartText() => '"${primitiveValue.slowToString()}"';
 
-  String toStructuredString() => 'StringConstant(${unparse()})';
+  String toStructuredText() => 'StringConstant(${toDartText()})';
 }
 
 abstract class ObjectConstantValue extends ConstantValue {
@@ -455,9 +456,9 @@
 
   accept(ConstantValueVisitor visitor, arg) => visitor.visitType(this, arg);
 
-  String unparse() => '$representedType';
+  String toDartText() => '$representedType';
 
-  String toStructuredString() => 'TypeConstant(${representedType})';
+  String toStructuredText() => 'TypeConstant(${representedType})';
 }
 
 class ListConstantValue extends ObjectConstantValue {
@@ -490,26 +491,26 @@
 
   accept(ConstantValueVisitor visitor, arg) => visitor.visitList(this, arg);
 
-  String unparse() {
+  String toDartText() {
     StringBuffer sb = new StringBuffer();
     _unparseTypeArguments(sb);
     sb.write('[');
     for (int i = 0; i < length; i++) {
       if (i > 0) sb.write(',');
-      sb.write(entries[i].unparse());
+      sb.write(entries[i].toDartText());
     }
     sb.write(']');
     return sb.toString();
   }
 
-  String toStructuredString() {
+  String toStructuredText() {
     StringBuffer sb = new StringBuffer();
     sb.write('ListConstant(');
     _unparseTypeArguments(sb);
     sb.write('[');
     for (int i = 0; i < length; i++) {
       if (i > 0) sb.write(', ');
-      sb.write(entries[i].toStructuredString());
+      sb.write(entries[i].toStructuredText());
     }
     sb.write('])');
     return sb.toString();
@@ -565,30 +566,30 @@
 
   accept(ConstantValueVisitor visitor, arg) => visitor.visitMap(this, arg);
 
-  String unparse() {
+  String toDartText() {
     StringBuffer sb = new StringBuffer();
     _unparseTypeArguments(sb);
     sb.write('{');
     for (int i = 0; i < length; i++) {
       if (i > 0) sb.write(',');
-      sb.write(keys[i].unparse());
+      sb.write(keys[i].toDartText());
       sb.write(':');
-      sb.write(values[i].unparse());
+      sb.write(values[i].toDartText());
     }
     sb.write('}');
     return sb.toString();
   }
 
-  String toStructuredString() {
+  String toStructuredText() {
     StringBuffer sb = new StringBuffer();
     sb.write('MapConstant(');
     _unparseTypeArguments(sb);
     sb.write('{');
     for (int i = 0; i < length; i++) {
       if (i > 0) sb.write(', ');
-      sb.write(keys[i].toStructuredString());
+      sb.write(keys[i].toStructuredText());
       sb.write(': ');
-      sb.write(values[i].toStructuredString());
+      sb.write(values[i].toStructuredText());
     }
     sb.write('})');
     return sb.toString();
@@ -619,11 +620,11 @@
 
   DartType getType(CoreTypes types) => const DynamicType();
 
-  String unparse() {
+  String toDartText() {
     return 'interceptor($dispatchedType)';
   }
 
-  String toStructuredString() {
+  String toStructuredText() {
     return 'InterceptorConstant(${dispatchedType.getStringAsDeclared("o")})';
   }
 }
@@ -650,9 +651,9 @@
 
   DartType getType(CoreTypes types) => const DynamicType();
 
-  String unparse() => 'synthetic($kind, $payload)';
+  String toDartText() => 'synthetic($kind, $payload)';
 
-  String toStructuredString() => 'SyntheticConstant($kind, $payload)';
+  String toStructuredText() => 'SyntheticConstant($kind, $payload)';
 }
 
 class ConstructedConstantValue extends ObjectConstantValue {
@@ -689,7 +690,7 @@
     return visitor.visitConstructed(this, arg);
   }
 
-  String unparse() {
+  String toDartText() {
     StringBuffer sb = new StringBuffer();
     sb.write(type.name);
     _unparseTypeArguments(sb);
@@ -699,14 +700,14 @@
       if (i > 0) sb.write(',');
       sb.write(field.name);
       sb.write('=');
-      sb.write(value.unparse());
+      sb.write(value.toDartText());
       i++;
     });
     sb.write(')');
     return sb.toString();
   }
 
-  String toStructuredString() {
+  String toStructuredText() {
     StringBuffer sb = new StringBuffer();
     sb.write('ConstructedConstant(');
     sb.write(type);
@@ -716,7 +717,7 @@
       if (i > 0) sb.write(',');
       sb.write(field.name);
       sb.write('=');
-      sb.write(value.toStructuredString());
+      sb.write(value.toStructuredText());
       i++;
     });
     sb.write('))');
@@ -748,9 +749,9 @@
 
   DartType getType(CoreTypes types) => referenced.getType(types);
 
-  String unparse() => 'deferred(${referenced.unparse()})';
+  String toDartText() => 'deferred(${referenced.toDartText()})';
 
-  String toStructuredString() => 'DeferredConstant($referenced)';
+  String toStructuredText() => 'DeferredConstant($referenced)';
 }
 
 /// A constant value resulting from a non constant or erroneous constant
@@ -771,8 +772,8 @@
   DartType getType(CoreTypes types) => const DynamicType();
 
   @override
-  String toStructuredString() => 'NonConstant';
+  String toStructuredText() => 'NonConstant';
 
   @override
-  String unparse() => '>>non-constant<<';
+  String toDartText() => '>>non-constant<<';
 }
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
index bc77a98..49d3353 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
@@ -1681,7 +1681,7 @@
   }
 
   ConstantValue getConstantForVariable(VariableElement element) {
-    return irBuilder.state.constants.getConstantValueForVariable(element);
+    return irBuilder.state.constants.getConstantValue(element.constant);
   }
 
   ir.Primitive buildConstantExpression(
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
index 185f011..1402b1d8 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
@@ -464,11 +464,11 @@
   // tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart).
 
   String _failWith(ConstantValue constant) {
-    throw 'Stringification not supported for ${constant.toStructuredString()}';
+    throw 'Stringification not supported for ${constant.toStructuredText()}';
   }
 
   String visitFunction(FunctionConstantValue constant, _) {
-    return '(Function "${constant.unparse()}")';
+    return '(Function "${constant.toDartText()}")';
   }
 
   String visitNull(NullConstantValue constant, _) {
@@ -476,19 +476,19 @@
   }
 
   String visitInt(IntConstantValue constant, _) {
-    return '(Int ${constant.unparse()})';
+    return '(Int ${constant.toDartText()})';
   }
 
   String visitDouble(DoubleConstantValue constant, _) {
-    return '(Double ${constant.unparse()})';
+    return '(Double ${constant.toDartText()})';
   }
 
   String visitBool(BoolConstantValue constant, _) {
-    return '(Bool ${constant.unparse()})';
+    return '(Bool ${constant.toDartText()})';
   }
 
   String visitString(StringConstantValue constant, _) {
-    return '(String ${constant.unparse()})';
+    return '(String ${constant.toDartText()})';
   }
 
   String visitList(ListConstantValue constant, _) {
@@ -508,7 +508,7 @@
   }
 
   String visitConstructed(ConstructedConstantValue constant, _) {
-    return '(Constructed "${constant.unparse()}")';
+    return '(Constructed "${constant.toDartText()}")';
   }
 
   String visitType(TypeConstantValue constant, _) {
@@ -516,11 +516,11 @@
   }
 
   String visitInterceptor(InterceptorConstantValue constant, _) {
-    return '(Interceptor "${constant.unparse()}")';
+    return '(Interceptor "${constant.toDartText()}")';
   }
 
   String visitSynthetic(SyntheticConstantValue constant, _) {
-    return '(Synthetic "${constant.unparse()}")';
+    return '(Synthetic "${constant.toDartText()}")';
   }
 
   String visitDeferred(DeferredConstantValue constant, _) {
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
index 7b7e1e4..f70c586 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
@@ -246,7 +246,7 @@
   }
 
   visitConstant(cps_ir.Constant node) {
-    return "Constant ${node.value.toStructuredString()}";
+    return "Constant ${node.value.toStructuredText()}";
   }
 
   visitParameter(cps_ir.Parameter node) {
diff --git a/pkg/compiler/lib/src/cps_ir/inline.dart b/pkg/compiler/lib/src/cps_ir/inline.dart
index 9454e38..89af4dc 100644
--- a/pkg/compiler/lib/src/cps_ir/inline.dart
+++ b/pkg/compiler/lib/src/cps_ir/inline.dart
@@ -377,7 +377,7 @@
           ++nameIndex;
         } else {
           Constant defaultValue = cps.makeConstant(
-              backend.constants.getConstantValueForVariable(formal));
+              backend.constants.getConstantValue(formal.constant));
           defaultValue.type = typeSystem.getParameterType(formal);
           arguments.add(defaultValue);
         }
@@ -391,7 +391,7 @@
           arguments.add(parameters[parameterIndex++]);
         } else {
           Constant defaultValue = cps.makeConstant(
-              backend.constants.getConstantValueForVariable(formal));
+              backend.constants.getConstantValue(formal.constant));
           defaultValue.type = typeSystem.getParameterType(formal);
           arguments.add(defaultValue);
         }
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
index 50a73e0..4ee963c 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -3361,7 +3361,7 @@
       case NOTHING:
         return "Nothing";
       case CONSTANT:
-        return "Constant: ${constant.unparse()}: $type";
+        return "Constant: ${constant.toDartText()}: $type";
       case NONCONST:
         return "Non-constant: $type";
       default:
diff --git a/pkg/compiler/lib/src/dart_backend/backend.dart b/pkg/compiler/lib/src/dart_backend/backend.dart
index 3501182..d8cef91 100644
--- a/pkg/compiler/lib/src/dart_backend/backend.dart
+++ b/pkg/compiler/lib/src/dart_backend/backend.dart
@@ -20,6 +20,8 @@
 
   bool get supportsReflection => true;
 
+  bool get supportsAsyncAwait => true;
+
   // TODO(zarah) Maybe change this to a command-line option.
   // Right now, it is set by the tests.
   bool useMirrorHelperLibrary = false;
@@ -473,11 +475,6 @@
   }
 
   @override
-  ConstantExpression getConstantForVariable(VariableElement element) {
-    return constantCompiler.getConstantForVariable(element);
-  }
-
-  @override
   ConstantExpression getConstantForNode(Node node, TreeElements elements) {
     return constantCompiler.getConstantForNode(node, elements);
   }
@@ -507,9 +504,10 @@
     });
   }
 
-  void compileVariable(VariableElement element) {
-    measure(() {
-      constantCompiler.compileVariable(element);
+  @override
+  ConstantExpression compileVariable(VariableElement element) {
+    return measure(() {
+      return constantCompiler.compileVariable(element);
     });
   }
 
diff --git a/pkg/compiler/lib/src/dart_backend/backend_ast_nodes.dart b/pkg/compiler/lib/src/dart_backend/backend_ast_nodes.dart
index 81c17c3..1c8abd0 100644
--- a/pkg/compiler/lib/src/dart_backend/backend_ast_nodes.dart
+++ b/pkg/compiler/lib/src/dart_backend/backend_ast_nodes.dart
@@ -852,7 +852,7 @@
           write(v.toString());
         }
       } else {
-        write(e.value.unparse());
+        write(e.value.toDartText());
       }
     } else if (e is LiteralList) {
       if (e.isConst) {
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index 5ce0d30..db57839 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -887,7 +887,7 @@
     _constantToOutputUnit.forEach((ConstantValue value, OutputUnit output) {
       constantMap
           .putIfAbsent(output, () => <String>[])
-          .add(value.toStructuredString());
+          .add(value.toStructuredText());
     });
 
     StringBuffer sb = new StringBuffer();
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index f442dd1..083068e 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -89,6 +89,7 @@
   ASSIGNING_METHOD,
   ASSIGNING_METHOD_IN_SUPER,
   ASSIGNING_TYPE,
+  ASYNC_AWAIT_NOT_SUPPORTED,
   ASYNC_KEYWORD_AS_IDENTIFIER,
   ASYNC_MODIFIER_ON_ABSTRACT_METHOD,
   ASYNC_MODIFIER_ON_CONSTRUCTOR,
@@ -3239,6 +3240,11 @@
 """
           ]),
 
+      MessageKind.ASYNC_AWAIT_NOT_SUPPORTED:
+        const MessageTemplate(MessageKind.ASYNC_AWAIT_NOT_SUPPORTED,
+            "The async/sync* syntax is not supported on the current platform."),
+
+
       MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD: const MessageTemplate(
           MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD,
           "The modifier '#{modifier}' is not allowed on an abstract method.",
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index 854feb1..0ee0093 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -139,7 +139,7 @@
     _elementToInfo[element] = info;
     if (element.isConst) {
       var value = compiler.backend.constantCompilerTask
-          .getConstantValueForVariable(element);
+          .getConstantValue(element.constant);
       if (value != null) {
         info.initializer = _constantToInfo[value];
       }
diff --git a/pkg/compiler/lib/src/elements/elements.dart b/pkg/compiler/lib/src/elements/elements.dart
index 54ecf63..a6683cf 100644
--- a/pkg/compiler/lib/src/elements/elements.dart
+++ b/pkg/compiler/lib/src/elements/elements.dart
@@ -996,8 +996,11 @@
 
   Expression get initializer;
 
-  /// The constant expression defining the value of the variable if `const`,
-  /// `null` otherwise.
+  /// The constant expression defining the (initial) value of the variable.
+  ///
+  /// If the variable is `const` the value is always non-null, possibly an
+  /// [ErroneousConstantExpression], otherwise, the value is null when the
+  /// initializer isn't a constant expression.
   ConstantExpression get constant;
 }
 
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index 5a4cc108..3a1e981 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -1397,7 +1397,7 @@
       ConstantVariableMixin originVariable = origin;
       return originVariable.constant;
     }
-    assert(invariant(this, constantCache != null,
+    assert(invariant(this, !isConst || constantCache != null,
         message: "Constant has not been computed for $this."));
     return constantCache;
   }
@@ -1411,8 +1411,8 @@
     assert(invariant(this, constantCache == null || constantCache == value,
         message: "Constant has already been computed for $this. "
             "Existing constant: "
-            "${constantCache != null ? constantCache.getText() : ''}, "
-            "New constant: ${value != null ? value.getText() : ''}."));
+            "${constantCache != null ? constantCache.toDartText() : ''}, "
+            "New constant: ${value != null ? value.toDartText() : ''}."));
     constantCache = value;
   }
 }
diff --git a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
index b148b11..d13b124 100644
--- a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
@@ -1299,8 +1299,9 @@
         element.isField &&
         Elements.isStaticOrTopLevelField(element) &&
         compiler.world.fieldNeverChanges(element)) {
+      FieldElement fieldElement = element;
       ConstantValue value =
-          compiler.backend.constants.getConstantValueForVariable(element);
+          compiler.backend.constants.getConstantValue(fieldElement.constant);
       if (value != null && value.isInt) {
         IntConstantValue intValue = value;
         return intValue.primitiveValue;
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_dump.dart b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
index a651852..3e68725 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
@@ -434,7 +434,7 @@
   }
   if (type is ValueTypeMask) {
     String baseType = formatType(type.forwardTo);
-    String value = type.value.toStructuredString();
+    String value = type.value.toStructuredText();
     return '$baseType=$value';
   }
   return '$type'; // Fall back on toString if not supported here.
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
index 1cfc52a..2936432 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -850,8 +850,8 @@
           if (type is! ListTypeInformation && type is! MapTypeInformation) {
             // For non-container types, the constant handler does
             // constant folding that could give more precise results.
-            ConstantValue value =
-                compiler.backend.constants.getConstantValueForVariable(element);
+            ConstantValue value = compiler.backend.constants
+                .getConstantValue(fieldElement.constant);
             if (value != null) {
               if (value.isFunction) {
                 FunctionConstantValue functionConstant = value;
diff --git a/pkg/compiler/lib/src/io/position_information.dart b/pkg/compiler/lib/src/io/position_information.dart
index 38df221..3b01a6f 100644
--- a/pkg/compiler/lib/src/io/position_information.dart
+++ b/pkg/compiler/lib/src/io/position_information.dart
@@ -8,7 +8,8 @@
 library dart2js.source_information.position;
 
 import '../common.dart';
-import '../elements/elements.dart' show AstElement, FieldElement, ResolvedAst, ResolvedAstKind;
+import '../elements/elements.dart'
+    show AstElement, FieldElement, ResolvedAst, ResolvedAstKind;
 import '../js/js.dart' as js;
 import '../js/js_debug.dart';
 import '../js/js_source_mapping.dart';
@@ -150,14 +151,14 @@
   SourceInformation buildDeclaration(ResolvedAst resolvedAst) {
     if (resolvedAst.kind != ResolvedAstKind.PARSED) {
       SourceSpan span = resolvedAst.element.sourcePosition;
-      return new PositionSourceInformation(new OffsetSourceLocation(
-          sourceFile, span.begin, name));
+      return new PositionSourceInformation(
+          new OffsetSourceLocation(sourceFile, span.begin, name));
     } else {
       return new PositionSourceInformation(
-          new OffsetSourceLocation(sourceFile,
-              resolvedAst.node.getBeginToken().charOffset, name),
-          new OffsetSourceLocation(sourceFile,
-              resolvedAst.node.getEndToken().charOffset, name));
+          new OffsetSourceLocation(
+              sourceFile, resolvedAst.node.getBeginToken().charOffset, name),
+          new OffsetSourceLocation(
+              sourceFile, resolvedAst.node.getEndToken().charOffset, name));
     }
   }
 
diff --git a/pkg/compiler/lib/src/io/start_end_information.dart b/pkg/compiler/lib/src/io/start_end_information.dart
index b749d8a..ccc4d6b 100644
--- a/pkg/compiler/lib/src/io/start_end_information.dart
+++ b/pkg/compiler/lib/src/io/start_end_information.dart
@@ -9,7 +9,8 @@
 
 import '../common.dart';
 import '../diagnostics/messages.dart' show MessageTemplate;
-import '../elements/elements.dart' show AstElement, ResolvedAst, ResolvedAstKind;
+import '../elements/elements.dart'
+    show AstElement, ResolvedAst, ResolvedAstKind;
 import '../js/js.dart' as js;
 import '../js/js_source_mapping.dart';
 import '../tokens/token.dart' show Token;
@@ -80,8 +81,7 @@
     // checks below.
     SourceLocation sourcePosition, endSourcePosition;
     if (begin < sourceFile.length) {
-      sourcePosition =
-          new OffsetSourceLocation(sourceFile, begin, name);
+      sourcePosition = new OffsetSourceLocation(sourceFile, begin, name);
     }
     if (end < sourceFile.length) {
       endSourcePosition = new OffsetSourceLocation(sourceFile, end, name);
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 0e8c98e..83cab66 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -227,6 +227,8 @@
 
   bool get supportsReflection => emitter.emitter.supportsReflection;
 
+  bool get supportsAsyncAwait => true;
+
   final Annotations annotations;
 
   /// Set of classes that need to be considered for reflection although not
@@ -1457,8 +1459,8 @@
       String messageText = message.message.computeMessage();
       jsAst.LiteralString messageLiteral =
           js.escapedString("Compile time error in $element: $messageText");
-      generatedCode[element] = js(
-          "function () { throw new Error(#); }", [messageLiteral]);
+      generatedCode[element] =
+          js("function () { throw new Error(#); }", [messageLiteral]);
       return const CodegenImpact();
     }
     var kind = element.kind;
@@ -1471,8 +1473,9 @@
       return const CodegenImpact();
     }
     if (kind.category == ElementCategory.VARIABLE) {
+      VariableElement variableElement = element;
       ConstantValue initialValue =
-          constants.getConstantValueForVariable(element);
+          constants.getConstantValue(variableElement.constant);
       if (initialValue != null) {
         registerCompileTimeConstant(initialValue, work.registry);
         addCompileTimeConstantForEmission(initialValue);
diff --git a/pkg/compiler/lib/src/js_backend/codegen/glue.dart b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
index 096573f..1650174 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/glue.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
@@ -269,7 +269,7 @@
   }
 
   ConstantValue getDefaultParameterValue(ParameterElement elem) {
-    return _backend.constants.getConstantValueForVariable(elem);
+    return _backend.constants.getConstantValue(elem.constant);
   }
 
   TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) {
diff --git a/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart b/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
index f300312..3bc94e5 100644
--- a/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
@@ -36,11 +36,6 @@
   }
 
   @override
-  ConstantExpression getConstantForVariable(VariableElement element) {
-    return dartConstantCompiler.getConstantForVariable(element);
-  }
-
-  @override
   ConstantExpression compileConstant(VariableElement element) {
     return measure(() {
       // TODO(het): Only report errors from one of the constant compilers
@@ -58,9 +53,10 @@
     });
   }
 
-  void compileVariable(VariableElement element) {
-    measure(() {
-      jsConstantCompiler.compileVariable(element);
+  @override
+  ConstantExpression compileVariable(VariableElement element) {
+    return measure(() {
+      return jsConstantCompiler.compileVariable(element);
     });
   }
 
@@ -248,6 +244,21 @@
       element.node.accept(new ForgetConstantNodeVisitor(this));
     }
   }
+
+  ConstantValue getConstantValue(ConstantExpression expression) {
+    ConstantValue value = super.getConstantValue(expression);
+    if (value == null &&
+        expression != null &&
+        expression.kind == ConstantExpressionKind.ERRONEOUS) {
+      // TODO(johnniwinther): When the Dart constant system sees a constant
+      // expression as erroneous but the JavaScript constant system finds it ok
+      // we have store a constant value for the erroneous constant expression.
+      // Ensure the computed constant expressions are always the same; that only
+      // the constant values may be different.
+      value = new NullConstantValue();
+    }
+    return value;
+  }
 }
 
 class ForgetConstantElementVisitor
diff --git a/pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart b/pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart
index ee4272a..2db7b35 100644
--- a/pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart
@@ -155,7 +155,7 @@
     // At this point, the lookupMapVersionVariable should be resolved and it's
     // constant value should be available.
     StringConstantValue value =
-        backend.constants.getConstantValueForVariable(lookupMapVersionVariable);
+        backend.constants.getConstantValue(lookupMapVersionVariable.constant);
     if (value == null) {
       reporter.reportInfo(lookupMapVersionVariable,
           MessageKind.UNRECOGNIZED_VERSION_OF_LOOKUP_MAP);
@@ -308,7 +308,7 @@
       for (var info in _lookupMaps.values) {
         for (var key in info.unusedEntries.keys) {
           if (count != 0) sb.write(',');
-          sb.write(key.unparse());
+          sb.write(key.toDartText());
           count++;
         }
       }
diff --git a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
index 0fc56db..cbc18bc 100644
--- a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
@@ -213,7 +213,7 @@
           (targetParameterMap == null) ? element : targetParameterMap[element];
       ConstantValue constant = (parameter == null)
           ? null
-          : _backend.constants.getConstantValueForVariable(parameter);
+          : _backend.constants.getConstantValue(parameter.constant);
       jsAst.Expression expression = (constant == null)
           ? new jsAst.LiteralNull()
           : _emitter.constantReference(constant);
diff --git a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
index bc1de29..fa01ef9 100644
--- a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
@@ -98,7 +98,7 @@
           parametersBuffer[optionalParameterStart + index] =
               new jsAst.Parameter(jsName);
         } else {
-          ConstantValue value = handler.getConstantValueForVariable(element);
+          ConstantValue value = handler.getConstantValue(element.constant);
           if (value == null) {
             argumentsBuffer[count] =
                 emitter.constantReference(new NullConstantValue());
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index 145070f..da33e20 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -690,14 +690,14 @@
       optionalParameterDefaultValues = new Map<String, ConstantValue>();
       signature.forEachOptionalParameter((ParameterElement parameter) {
         ConstantValue def =
-            backend.constants.getConstantValueForVariable(parameter);
+            backend.constants.getConstantValue(parameter.constant);
         optionalParameterDefaultValues[parameter.name] = def;
       });
     } else {
       optionalParameterDefaultValues = <ConstantValue>[];
       signature.forEachOptionalParameter((ParameterElement parameter) {
         ConstantValue def =
-            backend.constants.getConstantValueForVariable(parameter);
+            backend.constants.getConstantValue(parameter.constant);
         optionalParameterDefaultValues.add(def);
       });
     }
diff --git a/pkg/compiler/lib/src/mirrors/dart2js_instance_mirrors.dart b/pkg/compiler/lib/src/mirrors/dart2js_instance_mirrors.dart
index 039f5af..0c90060 100644
--- a/pkg/compiler/lib/src/mirrors/dart2js_instance_mirrors.dart
+++ b/pkg/compiler/lib/src/mirrors/dart2js_instance_mirrors.dart
@@ -73,9 +73,9 @@
 
   String toString() {
     if (_constant != null) {
-      return _constant.getText();
+      return _constant.toDartText();
     } else {
-      return _value.unparse();
+      return _value.toDartText();
     }
   }
 
diff --git a/pkg/compiler/lib/src/mirrors/dart2js_member_mirrors.dart b/pkg/compiler/lib/src/mirrors/dart2js_member_mirrors.dart
index 88ffbf9..8278525 100644
--- a/pkg/compiler/lib/src/mirrors/dart2js_member_mirrors.dart
+++ b/pkg/compiler/lib/src/mirrors/dart2js_member_mirrors.dart
@@ -190,8 +190,7 @@
       // TODO(johnniwinther): Get the constant from the [TreeElements]
       // associated with the enclosing method.
       ParameterElement parameter = _element;
-      ConstantExpression constant =
-          mirrorSystem.compiler.constants.getConstantForVariable(parameter);
+      ConstantExpression constant = parameter.constant;
       assert(invariant(parameter, constant != null,
           message: "Missing constant for parameter "
               "$parameter with default value."));
diff --git a/pkg/compiler/lib/src/mirrors/dart2js_mirrors.dart b/pkg/compiler/lib/src/mirrors/dart2js_mirrors.dart
index 9ca158b..406502a 100644
--- a/pkg/compiler/lib/src/mirrors/dart2js_mirrors.dart
+++ b/pkg/compiler/lib/src/mirrors/dart2js_mirrors.dart
@@ -463,7 +463,7 @@
 
   static ConstantExpression initializerSyntaxOf(Dart2JsFieldMirror variable) {
     Compiler compiler = variable.mirrorSystem.compiler;
-    return compiler.constants.getConstantForVariable(variable._variable);
+    return variable._variable.constant;
   }
 
   static ConstantExpression defaultValueSyntaxOf(
@@ -471,7 +471,7 @@
     if (!parameter.hasDefaultValue) return null;
     ParameterElement parameterElement = parameter._element;
     Compiler compiler = parameter.mirrorSystem.compiler;
-    return compiler.constants.getConstantForVariable(parameterElement);
+    return parameterElement.constant;
   }
 
   static Mirror getMirrorFromElement(Dart2JsMirror mirror, Element element) {
diff --git a/pkg/compiler/lib/src/resolution/class_hierarchy.dart b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
index adaa177..4079c78 100644
--- a/pkg/compiler/lib/src/resolution/class_hierarchy.dart
+++ b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
@@ -212,9 +212,9 @@
           new SynthesizedConstructorElementX.forDefault(superMember, element);
       if (superMember.isMalformed) {
         ErroneousElement erroneousElement = superMember;
-        compiler.registerCompiletimeError(constructor,
-            reporter.createMessage(node,
-                erroneousElement.messageKind,
+        compiler.registerCompiletimeError(
+            constructor,
+            reporter.createMessage(node, erroneousElement.messageKind,
                 erroneousElement.messageArguments));
       }
       element.setDefaultConstructor(constructor, reporter);
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index e349185..c8d9293 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -3536,13 +3536,18 @@
   }
 
   ResolutionResult visitYield(Yield node) {
-    if (!currentAsyncMarker.isYielding) {
-      reporter.reportErrorMessage(node, MessageKind.INVALID_YIELD);
-    }
-    if (currentAsyncMarker.isAsync) {
-      coreClasses.streamClass.ensureResolved(resolution);
+    if (!compiler.backend.supportsAsyncAwait) {
+      reporter.reportErrorMessage(node.yieldToken,
+          MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
     } else {
-      coreClasses.iterableClass.ensureResolved(resolution);
+      if (!currentAsyncMarker.isYielding) {
+        reporter.reportErrorMessage(node, MessageKind.INVALID_YIELD);
+      }
+      if (currentAsyncMarker.isAsync) {
+        coreClasses.streamClass.ensureResolved(resolution);
+      } else {
+        coreClasses.iterableClass.ensureResolved(resolution);
+      }
     }
     visit(node.expression);
     return const NoneResult();
@@ -3672,10 +3677,15 @@
   }
 
   ResolutionResult visitAwait(Await node) {
-    if (!currentAsyncMarker.isAsync) {
-      reporter.reportErrorMessage(node, MessageKind.INVALID_AWAIT);
+    if (!compiler.backend.supportsAsyncAwait) {
+      reporter.reportErrorMessage(node.awaitToken,
+          MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
+    } else {
+      if (!currentAsyncMarker.isAsync) {
+        reporter.reportErrorMessage(node, MessageKind.INVALID_AWAIT);
+      }
+      coreClasses.futureClass.ensureResolved(resolution);
     }
-    coreClasses.futureClass.ensureResolved(resolution);
     visit(node.expression);
     return const NoneResult();
   }
@@ -4194,14 +4204,20 @@
   }
 
   ResolutionResult visitAsyncForIn(AsyncForIn node) {
-    if (!currentAsyncMarker.isAsync) {
-      reporter.reportErrorMessage(
-          node.awaitToken, MessageKind.INVALID_AWAIT_FOR_IN);
+    if (!compiler.backend.supportsAsyncAwait) {
+      reporter.reportErrorMessage(node.awaitToken,
+          MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
+    } else {
+      if (!currentAsyncMarker.isAsync) {
+        reporter.reportErrorMessage(
+            node.awaitToken, MessageKind.INVALID_AWAIT_FOR_IN);
+      }
+      registry.registerFeature(Feature.ASYNC_FOR_IN);
+      registry.registerDynamicUse(
+          new DynamicUse(Selectors.current, null));
+      registry.registerDynamicUse(
+          new DynamicUse(Selectors.moveNext, null));
     }
-    registry.registerFeature(Feature.ASYNC_FOR_IN);
-    registry.registerDynamicUse(new DynamicUse(Selectors.current, null));
-    registry.registerDynamicUse(new DynamicUse(Selectors.moveNext, null));
-
     visit(node.expression);
 
     Scope blockScope = new BlockScope(scope);
diff --git a/pkg/compiler/lib/src/resolution/registry.dart b/pkg/compiler/lib/src/resolution/registry.dart
index 0301e8c..7008c9a 100644
--- a/pkg/compiler/lib/src/resolution/registry.dart
+++ b/pkg/compiler/lib/src/resolution/registry.dart
@@ -129,7 +129,7 @@
     if (_constantLiterals != null) {
       sb.write('\n const-literals:');
       for (ConstantExpression constant in _constantLiterals) {
-        sb.write('\n  ${constant.getText()}');
+        sb.write('\n  ${constant.toDartText()}');
       }
     }
     if (_constSymbolNames != null) {
diff --git a/pkg/compiler/lib/src/resolution/resolution.dart b/pkg/compiler/lib/src/resolution/resolution.dart
index 58d038b..1439518 100644
--- a/pkg/compiler/lib/src/resolution/resolution.dart
+++ b/pkg/compiler/lib/src/resolution/resolution.dart
@@ -143,51 +143,56 @@
     FunctionExpression functionExpression = element.node;
     AsyncModifier asyncModifier = functionExpression.asyncModifier;
     if (asyncModifier != null) {
-      if (asyncModifier.isAsynchronous) {
-        element.asyncMarker = asyncModifier.isYielding
-            ? AsyncMarker.ASYNC_STAR
-            : AsyncMarker.ASYNC;
+      if (!compiler.backend.supportsAsyncAwait) {
+        reporter.reportErrorMessage(functionExpression.asyncModifier,
+            MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
       } else {
-        element.asyncMarker = AsyncMarker.SYNC_STAR;
-      }
-      if (element.isAbstract) {
-        reporter.reportErrorMessage(
-            asyncModifier,
-            MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD,
-            {'modifier': element.asyncMarker});
-      } else if (element.isConstructor) {
-        reporter.reportErrorMessage(
-            asyncModifier,
-            MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR,
-            {'modifier': element.asyncMarker});
-      } else {
-        if (element.isSetter) {
+        if (asyncModifier.isAsynchronous) {
+          element.asyncMarker = asyncModifier.isYielding
+              ? AsyncMarker.ASYNC_STAR
+              : AsyncMarker.ASYNC;
+        } else {
+          element.asyncMarker = AsyncMarker.SYNC_STAR;
+        }
+        if (element.isAbstract) {
           reporter.reportErrorMessage(
               asyncModifier,
-              MessageKind.ASYNC_MODIFIER_ON_SETTER,
+              MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD,
               {'modifier': element.asyncMarker});
-        }
-        if (functionExpression.body.asReturn() != null &&
-            element.asyncMarker.isYielding) {
+        } else if (element.isConstructor) {
           reporter.reportErrorMessage(
               asyncModifier,
-              MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY,
+              MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR,
               {'modifier': element.asyncMarker});
+        } else {
+          if (element.isSetter) {
+            reporter.reportErrorMessage(
+                asyncModifier,
+                MessageKind.ASYNC_MODIFIER_ON_SETTER,
+                {'modifier': element.asyncMarker});
+          }
+          if (functionExpression.body.asReturn() != null &&
+              element.asyncMarker.isYielding) {
+            reporter.reportErrorMessage(
+                asyncModifier,
+                MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY,
+                {'modifier': element.asyncMarker});
+          }
         }
-      }
-      switch (element.asyncMarker) {
-        case AsyncMarker.ASYNC:
-          registry.registerFeature(Feature.ASYNC);
-          coreClasses.futureClass.ensureResolved(resolution);
-          break;
-        case AsyncMarker.ASYNC_STAR:
-          registry.registerFeature(Feature.ASYNC_STAR);
-          coreClasses.streamClass.ensureResolved(resolution);
-          break;
-        case AsyncMarker.SYNC_STAR:
-          registry.registerFeature(Feature.SYNC_STAR);
-          coreClasses.iterableClass.ensureResolved(resolution);
-          break;
+        switch (element.asyncMarker) {
+          case AsyncMarker.ASYNC:
+            registry.registerFeature(Feature.ASYNC);
+            coreClasses.futureClass.ensureResolved(resolution);
+            break;
+          case AsyncMarker.ASYNC_STAR:
+            registry.registerFeature(Feature.ASYNC_STAR);
+            coreClasses.streamClass.ensureResolved(resolution);
+            break;
+          case AsyncMarker.SYNC_STAR:
+            registry.registerFeature(Feature.SYNC_STAR);
+            coreClasses.iterableClass.ensureResolved(resolution);
+            break;
+        }
       }
     }
   }
@@ -376,7 +381,7 @@
         if (element.modifiers.isConst) {
           element.constant = constantCompiler.compileConstant(element);
         } else {
-          constantCompiler.compileVariable(element);
+          element.constant = constantCompiler.compileVariable(element);
         }
       });
       if (initializer != null) {
diff --git a/pkg/compiler/lib/src/resolution/resolution_result.dart b/pkg/compiler/lib/src/resolution/resolution_result.dart
index 3e36fa7..b034712 100644
--- a/pkg/compiler/lib/src/resolution/resolution_result.dart
+++ b/pkg/compiler/lib/src/resolution/resolution_result.dart
@@ -90,7 +90,7 @@
 
   ResultKind get kind => ResultKind.CONSTANT;
 
-  String toString() => 'ConstantResult(${constant.getText()})';
+  String toString() => 'ConstantResult(${constant.toDartText()})';
 }
 
 class NoneResult extends ResolutionResult {
diff --git a/pkg/compiler/lib/src/resolution/send_structure.dart b/pkg/compiler/lib/src/resolution/send_structure.dart
index 53c0356..4b6d187 100644
--- a/pkg/compiler/lib/src/resolution/send_structure.dart
+++ b/pkg/compiler/lib/src/resolution/send_structure.dart
@@ -2263,7 +2263,7 @@
           break;
         default:
           throw new SpannableAssertionFailure(
-              node, "Unexpected constant kind $kind: ${constant.getText()}");
+              node, "Unexpected constant kind $kind: ${constant.toDartText()}");
       }
       return new ConstInvokeStructure(kind, constant);
     }
@@ -2297,7 +2297,7 @@
               node, constant, arg);
         default:
           throw new SpannableAssertionFailure(
-              node, "Unexpected constant kind $kind: ${constant.getText()}");
+              node, "Unexpected constant kind $kind: ${constant.toDartText()}");
       }
     }
   }
diff --git a/pkg/compiler/lib/src/serialization/constant_serialization.dart b/pkg/compiler/lib/src/serialization/constant_serialization.dart
index afaa3b4..b041347 100644
--- a/pkg/compiler/lib/src/serialization/constant_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/constant_serialization.dart
@@ -170,7 +170,7 @@
   @override
   void visitDeferred(DeferredConstantExpression exp, ObjectEncoder encoder) {
     throw new UnsupportedError(
-        "ConstantSerializer.visitDeferred: ${exp.getText()}");
+        "ConstantSerializer.visitDeferred: ${exp.toDartText()}");
   }
 }
 
diff --git a/pkg/compiler/lib/src/serialization/element_serialization.dart b/pkg/compiler/lib/src/serialization/element_serialization.dart
index e3d1526..6f5dc4d 100644
--- a/pkg/compiler/lib/src/serialization/element_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/element_serialization.dart
@@ -398,8 +398,8 @@
     encoder.setType(Key.TYPE, element.type);
     encoder.setBool(Key.IS_FINAL, element.isFinal);
     encoder.setBool(Key.IS_CONST, element.isConst);
-    if (element.isConst) {
-      ConstantExpression constant = element.constant;
+    ConstantExpression constant = element.constant;
+    if (constant != null) {
       encoder.setConstant(Key.CONSTANT, constant);
     }
     SerializerUtil.serializeParentRelation(element, encoder);
diff --git a/pkg/compiler/lib/src/serialization/json_serializer.dart b/pkg/compiler/lib/src/serialization/json_serializer.dart
index 55ec647..32c6500 100644
--- a/pkg/compiler/lib/src/serialization/json_serializer.dart
+++ b/pkg/compiler/lib/src/serialization/json_serializer.dart
@@ -113,7 +113,7 @@
 
   @override
   void visitConstant(ConstantValue value, String indentation) {
-    buffer.write('Constant(${value.id}):${value.constant.getText()}');
+    buffer.write('Constant(${value.id}):${value.constant.toDartText()}');
   }
 
   @override
diff --git a/pkg/compiler/lib/src/serialization/modelz.dart b/pkg/compiler/lib/src/serialization/modelz.dart
index 5122259..e77d5c0 100644
--- a/pkg/compiler/lib/src/serialization/modelz.dart
+++ b/pkg/compiler/lib/src/serialization/modelz.dart
@@ -497,8 +497,10 @@
     _file = value;
   }
 
+  // TODO(johnniwinther): Decide if it is meaningful to serialize erroneous
+  // elements.
   @override
-  bool get isSynthesized => throw new UnsupportedError('ScriptZ.isSynthesized');
+  bool get isSynthesized => false;
 
   @override
   String get name {
@@ -1291,6 +1293,7 @@
         TypedElementMixin,
         MemberElementMixin
     implements FieldElement {
+  bool _isConst;
   ConstantExpression _constant;
 
   FieldElementZ(ObjectDecoder decoder) : super(decoder);
@@ -1306,14 +1309,22 @@
   @override
   bool get isFinal => _decoder.getBool(Key.IS_FINAL);
 
+  void _ensureConstant() {
+    if (_isConst == null) {
+      _isConst = _decoder.getBool(Key.IS_CONST);
+      _constant = _decoder.getConstant(Key.CONSTANT, isOptional: true);
+    }
+  }
+
   @override
-  bool get isConst => _decoder.getBool(Key.IS_CONST);
+  bool get isConst {
+    _ensureConstant();
+    return _isConst;
+  }
 
   @override
   ConstantExpression get constant {
-    if (isConst && _constant == null) {
-      _constant = _decoder.getConstant(Key.CONSTANT);
-    }
+    _ensureConstant();
     return _constant;
   }
 
diff --git a/pkg/compiler/lib/src/serialization/values.dart b/pkg/compiler/lib/src/serialization/values.dart
index 637123c..f23a6f0 100644
--- a/pkg/compiler/lib/src/serialization/values.dart
+++ b/pkg/compiler/lib/src/serialization/values.dart
@@ -67,7 +67,7 @@
 
   accept(ValueVisitor visitor, arg) => visitor.visitConstant(this, arg);
 
-  String toString() => constant.getText();
+  String toString() => constant.toDartText();
 }
 
 abstract class PrimitiveValue implements Value {
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index acfdef0..e927971 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -123,7 +123,7 @@
           signature.forEachOptionalParameter((ParameterElement parameter) {
             // This ensures the default value will be computed.
             ConstantValue constant =
-                backend.constants.getConstantValueForVariable(parameter);
+                backend.constants.getConstantValue(parameter.constant);
             work.registry.registerCompileTimeConstant(constant);
           });
         }
@@ -1595,9 +1595,9 @@
   HInstruction handleConstantForOptionalParameterJsInterop(Element parameter) =>
       null;
 
-  HInstruction handleConstantForOptionalParameter(Element parameter) {
+  HInstruction handleConstantForOptionalParameter(ParameterElement parameter) {
     ConstantValue constantValue =
-        backend.constants.getConstantValueForVariable(parameter);
+        backend.constants.getConstantValue(parameter.constant);
     assert(invariant(parameter, constantValue != null,
         message: 'No constant computed for $parameter'));
     return graph.addConstant(constantValue, compiler);
@@ -3505,8 +3505,7 @@
 
   /// Read a static or top level [field].
   void generateStaticFieldGet(ast.Send node, FieldElement field) {
-    ConstantExpression constant =
-        backend.constants.getConstantForVariable(field);
+    ConstantExpression constant = field.constant;
     SourceInformation sourceInformation =
         sourceInformationBuilder.buildGet(node);
     if (constant != null) {
diff --git a/pkg/compiler/lib/src/ssa/codegen_helpers.dart b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
index 254e577..681056f 100644
--- a/pkg/compiler/lib/src/ssa/codegen_helpers.dart
+++ b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
@@ -353,7 +353,7 @@
           input is! HPhi &&
           input is! HLocalValue &&
           !input.isJsStatement()) {
-        if (input.isPure()) {
+        if (isEffectivelyPure(input)) {
           // Only consider a pure input if it is in the same loop.
           // Otherwise, we might move GVN'ed instruction back into the
           // loop.
@@ -382,6 +382,25 @@
     }
   }
 
+  // Some non-pure instructions may be treated as pure. HLocalGet depends on
+  // assignments, but we can ignore the initializing assignment since it will by
+  // construction always precede a use.
+  bool isEffectivelyPure(HInstruction instruction) {
+    if (instruction is HLocalGet) return !isAssignedLocal(instruction.local);
+    return instruction.isPure();
+  }
+
+  bool isAssignedLocal(HLocalValue local) {
+    // [HLocalValue]s have an initializing assignment which is guaranteed to
+    // precede the use, except for [HParameterValue]s which are 'assigned' at
+    // entry.
+    int initializingAssignmentCount = (local is HParameterValue) ? 0 : 1;
+    return local.usedBy
+        .where((user) => user is HLocalSet)
+        .skip(initializingAssignmentCount)
+        .isNotEmpty;
+  }
+
   void visitInstruction(HInstruction instruction) {
     // A code motion invariant instruction is dealt before visiting it.
     assert(!instruction.isCodeMotionInvariant());
@@ -481,7 +500,7 @@
     // Pop instructions from expectedInputs until instruction is found.
     // Return true if it is found, or false if not.
     bool findInInputsAndPopNonMatching(HInstruction instruction) {
-      assert(!instruction.isPure());
+      assert(!isEffectivelyPure(instruction));
       while (!expectedInputs.isEmpty) {
         HInstruction nextInput = expectedInputs.removeLast();
         assert(!generateAtUseSite.contains(nextInput));
@@ -504,7 +523,7 @@
         markAsGenerateAtUseSite(instruction);
         continue;
       }
-      if (instruction.isPure()) {
+      if (isEffectivelyPure(instruction)) {
         if (pureInputs.contains(instruction)) {
           tryGenerateAtUseSite(instruction);
         } else {
@@ -550,7 +569,7 @@
           // push expected-inputs from left-to right, and the `pure` function
           // invocation is "more left" (i.e. before) the first argument of `f`.
           // With that approach we end up with:
-          //   t3 = pure(foo();
+          //   t3 = pure(foo());
           //   f(bar(), t3);
           //   use(t3);
           //
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 4b55e48..c9a4c2a 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -2209,7 +2209,7 @@
   HConstant.internal(this.constant, TypeMask constantType)
       : super(<HInstruction>[], constantType);
 
-  toString() => 'literal: ${constant.toStructuredString()}';
+  toString() => 'literal: ${constant.toStructuredText()}';
   accept(HVisitor visitor) => visitor.visitConstant(this);
 
   bool isConstant() => true;
@@ -2265,6 +2265,17 @@
 class HParameterValue extends HLocalValue {
   HParameterValue(Entity variable, type) : super(variable, type);
 
+  // [HParameterValue]s are either the value of the parameter (in fully SSA
+  // converted code), or the mutable variable containing the value (in
+  // incompletely SSA converted code, e.g. methods containing exceptions).
+  bool usedAsVariable() {
+    for (HInstruction user in usedBy) {
+      if (user is HLocalGet) return true;
+      if (user is HLocalSet && user.local == this) return true;
+    }
+    return false;
+  }
+
   toString() => 'parameter ${sourceElement.name}';
   accept(HVisitor visitor) => visitor.visitParameterValue(this);
 }
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 7d01871..a4ee039 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -247,14 +247,9 @@
   }
 
   HInstruction visitParameterValue(HParameterValue node) {
-    // It is possible for the parameter value to be assigned to in the function
-    // body. If that happens then we should not forward the constant value to
-    // its uses since since the uses reachable from the assignment may have
-    // values in addition to the constant passed to the function.
-    if (node.usedBy
-        .any((user) => user is HLocalSet && identical(user.local, node))) {
-      return node;
-    }
+    // If the parameter is used as a mutable variable we cannot replace the
+    // variable with a value.
+    if (node.usedAsVariable()) return node;
     propagateConstantValueToUses(node);
     return node;
   }
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index 64e4c30..7564176 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -200,7 +200,19 @@
       }
     }
     if (inputType != outputType) {
-      input.replaceAllUsersDominatedBy(instruction.next, instruction);
+      // Replace dominated uses of input with uses of this HTypeConversion so
+      // the uses benefit from the stronger type.
+      //
+      // The dependency on the checked value also improves the generated
+      // JavaScript. Many checks are compiled to a function call expression that
+      // returns the checked result, so the check can be generated as a
+      // subexpression rather than a separate statement.
+      //
+      // Do not replace local accesses, since the local must be a HLocalValue,
+      // not a HTypeConversion.
+      if (!(input is HParameterValue && input.usedAsVariable())) {
+        input.replaceAllUsersDominatedBy(instruction.next, instruction);
+      }
     }
     return outputType;
   }
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
index 7a11f83..bb025f0 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
@@ -295,7 +295,7 @@
   accept(ExpressionVisitor visitor) => visitor.visitConstant(this);
   accept1(ExpressionVisitor1 visitor, arg) => visitor.visitConstant(this, arg);
 
-  String toString() => 'Constant(value=${value.toStructuredString()})';
+  String toString() => 'Constant(value=${value.toStructuredText()})';
 }
 
 class This extends Expression {
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
index effd18d..486ee13 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
@@ -417,7 +417,7 @@
   }
 
   String visitConstant(Constant node) {
-    return "${node.value.toStructuredString()}";
+    return "${node.value.toStructuredText()}";
   }
 
   String visitThis(This node) {
diff --git a/pkg/compiler/lib/src/typechecker.dart b/pkg/compiler/lib/src/typechecker.dart
index e186ee4..5de81a6 100644
--- a/pkg/compiler/lib/src/typechecker.dart
+++ b/pkg/compiler/lib/src/typechecker.dart
@@ -1715,7 +1715,11 @@
 
   DartType visitAwait(Await node) {
     DartType expressionType = analyze(node.expression);
-    return types.flatten(expressionType);
+    if (compiler.backend.supportsAsyncAwait) {
+      return types.flatten(expressionType);
+    } else {
+      return const DynamicType();
+    }
   }
 
   DartType visitYield(Yield node) {
@@ -1838,29 +1842,31 @@
   visitAsyncForIn(AsyncForIn node) {
     DartType elementType = computeForInElementType(node);
     DartType expressionType = analyze(node.expression);
-    DartType streamOfDynamic = coreTypes.streamType();
-    if (!types.isAssignable(expressionType, streamOfDynamic)) {
-      reportMessage(node.expression, MessageKind.NOT_ASSIGNABLE,
-          {'fromType': expressionType, 'toType': streamOfDynamic},
-          isHint: true);
-    } else {
-      InterfaceType interfaceType =
-          Types.computeInterfaceType(resolution, expressionType);
-      if (interfaceType != null) {
-        InterfaceType streamType =
-            interfaceType.asInstanceOf(streamOfDynamic.element);
-        if (streamType != null) {
-          DartType streamElementType = streamType.typeArguments.first;
-          if (!types.isAssignable(streamElementType, elementType)) {
-            reportMessage(
-                node.expression,
-                MessageKind.FORIN_NOT_ASSIGNABLE,
-                {
-                  'currentType': streamElementType,
-                  'expressionType': expressionType,
-                  'elementType': elementType
-                },
-                isHint: true);
+    if (compiler.backend.supportsAsyncAwait) {
+      DartType streamOfDynamic = coreTypes.streamType();
+      if (!types.isAssignable(expressionType, streamOfDynamic)) {
+        reportMessage(node.expression, MessageKind.NOT_ASSIGNABLE,
+            {'fromType': expressionType, 'toType': streamOfDynamic},
+            isHint: true);
+      } else {
+        InterfaceType interfaceType =
+            Types.computeInterfaceType(resolution, expressionType);
+        if (interfaceType != null) {
+          InterfaceType streamType =
+              interfaceType.asInstanceOf(streamOfDynamic.element);
+          if (streamType != null) {
+            DartType streamElementType = streamType.typeArguments.first;
+            if (!types.isAssignable(streamElementType, elementType)) {
+              reportMessage(
+                  node.expression,
+                  MessageKind.FORIN_NOT_ASSIGNABLE,
+                  {
+                    'currentType': streamElementType,
+                    'expressionType': expressionType,
+                    'elementType': elementType
+                  },
+                  isHint: true);
+            }
           }
         }
       }
@@ -1953,8 +1959,10 @@
         List<FieldElement> unreferencedFields = <FieldElement>[];
         EnumClassElement enumClass = expressionType.element;
         enumClass.enumValues.forEach((EnumConstantElement field) {
-          ConstantValue constantValue =
-              compiler.constants.getConstantValueForVariable(field);
+          // TODO(johnniwinther): Ensure that the enum constant is computed at
+          // this point.
+          ConstantValue constantValue = compiler.resolver.constantCompiler
+              .getConstantValueForVariable(field);
           if (constantValue == null) {
             // The field might not have been resolved.
             unreferencedFields.add(field);
diff --git a/pkg/compiler/lib/src/types/value_type_mask.dart b/pkg/compiler/lib/src/types/value_type_mask.dart
index ba40f24..1be16ba 100644
--- a/pkg/compiler/lib/src/types/value_type_mask.dart
+++ b/pkg/compiler/lib/src/types/value_type_mask.dart
@@ -40,6 +40,6 @@
   }
 
   String toString() {
-    return 'Value mask: [${value.unparse()}] type: $forwardTo';
+    return 'Value mask: [${value.toDartText()}] type: $forwardTo';
   }
 }
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index d4fb651..8e4975b 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -524,15 +524,15 @@
   Api::CheckAndFinalizePendingClasses(thread);
 
   // Write snapshot with object content.
-  FullSnapshotWriter writer(&vm_isolate_snapshot_buffer,
+  FullSnapshotWriter writer(Snapshot::kCore,
+                            &vm_isolate_snapshot_buffer,
                             &isolate_snapshot_buffer,
                             &malloc_allocator,
                             NULL, /* instructions_writer */
-                            false, /* snapshot_code */
                             true /* vm_isolate_is_symbolic */);
   writer.WriteFullSnapshot();
   const Snapshot* snapshot = Snapshot::SetupFromBuffer(isolate_snapshot_buffer);
-  ASSERT(snapshot->kind() == Snapshot::kFull);
+  ASSERT(snapshot->kind() == Snapshot::kCore);
   benchmark->set_score(snapshot->length());
 }
 
@@ -561,15 +561,15 @@
   Api::CheckAndFinalizePendingClasses(thread);
 
   // Write snapshot with object content.
-  FullSnapshotWriter writer(&vm_isolate_snapshot_buffer,
+  FullSnapshotWriter writer(Snapshot::kCore,
+                            &vm_isolate_snapshot_buffer,
                             &isolate_snapshot_buffer,
                             &malloc_allocator,
                             NULL, /* instructions_writer */
-                            false, /* snapshot_code */
                             true /* vm_isolate_is_symbolic */);
   writer.WriteFullSnapshot();
   const Snapshot* snapshot = Snapshot::SetupFromBuffer(isolate_snapshot_buffer);
-  ASSERT(snapshot->kind() == Snapshot::kFull);
+  ASSERT(snapshot->kind() == Snapshot::kCore);
   benchmark->set_score(snapshot->length());
 }
 
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index d005cee..3fe6df5 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -214,8 +214,9 @@
       if (snapshot == NULL) {
         return "Invalid vm isolate snapshot seen.";
       }
-      ASSERT(snapshot->kind() == Snapshot::kFull);
-      VmIsolateSnapshotReader reader(snapshot->content(),
+      ASSERT(Snapshot::IsFull(snapshot->kind()));
+      VmIsolateSnapshotReader reader(snapshot->kind(),
+                                     snapshot->content(),
                                      snapshot->length(),
                                      instructions_snapshot,
                                      data_snapshot,
@@ -482,11 +483,12 @@
           String::New("Invalid snapshot."));
       return ApiError::New(message);
     }
-    ASSERT(snapshot->kind() == Snapshot::kFull);
+    ASSERT(Snapshot::IsFull(snapshot->kind()));
     if (FLAG_trace_isolates) {
       OS::Print("Size of isolate snapshot = %" Pd "\n", snapshot->length());
     }
-    IsolateSnapshotReader reader(snapshot->content(),
+    IsolateSnapshotReader reader(snapshot->kind(),
+                                 snapshot->content(),
                                  snapshot->length(),
                                  Dart::instructions_snapshot_buffer(),
                                  Dart::data_snapshot_buffer(),
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index c0a2fc5..9dcaa4b 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1493,11 +1493,11 @@
   I->heap()->IterateObjects(&check_canonical);
 #endif  // #if defined(DEBUG).
 
-  FullSnapshotWriter writer(vm_isolate_snapshot_buffer,
+  FullSnapshotWriter writer(Snapshot::kCore,
+                            vm_isolate_snapshot_buffer,
                             isolate_snapshot_buffer,
                             ApiReallocate,
                             NULL, /* instructions_writer */
-                            false, /* snapshot_code */
                             true /* vm_isolate_is_symbolic */);
   writer.WriteFullSnapshot();
   *vm_isolate_snapshot_size = writer.VmIsolateSnapshotSize();
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index 58a5c6a..13eeead 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -29,7 +29,7 @@
 #define FLAG_LIST(P, R, D, C)                                                  \
 P(always_megamorphic_calls, bool, false,                                       \
   "Instance call always as megamorphic.")                                      \
-C(background_compilation, false, true, bool, true,                             \
+P(background_compilation, bool, true,                                          \
   "Run optimizing compilation in background")                                  \
 R(background_compilation_stop_alot, false, bool, false,                        \
   "Stress test system: stop background compiler often.")                       \
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 6632df8..9d448ab 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -79,6 +79,7 @@
     FLAG_inlining_constant_arguments_max_size_threshold = 100;
     FLAG_inlining_constant_arguments_min_size_threshold = 30;
 
+    FLAG_background_compilation = false;
     FLAG_always_megamorphic_calls = true;
     FLAG_collect_dynamic_function_names = true;
     FLAG_fields_may_be_reset = true;
@@ -95,7 +96,6 @@
 
 #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
     // Set flags affecting runtime accordingly for dart_noopt.
-    FLAG_background_compilation = false;
     FLAG_collect_code = false;
     FLAG_support_debugger = false;
     FLAG_deoptimize_alot = false;  // Used in some tests.
@@ -114,7 +114,6 @@
 
 #ifdef DART_PRECOMPILED_RUNTIME
 
-COMPILE_ASSERT(!FLAG_background_compilation);
 COMPILE_ASSERT(!FLAG_collect_code);
 COMPILE_ASSERT(!FLAG_deoptimize_alot);  // Used in some tests.
 COMPILE_ASSERT(!FLAG_enable_mirrors);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index cc566b7..ff46fbf 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -6418,6 +6418,23 @@
     Heap::Space space) const {
   AbstractType& other_param_type =
       AbstractType::Handle(other.ParameterTypeAt(other_parameter_position));
+
+  // TODO(regis): Remove this debugging code.
+  if (other_param_type.IsNull()) {
+    const Class& owner = Class::Handle(Owner());
+    const Class& other_owner = Class::Handle(other.Owner());
+    THR_Print("*** null other_param_type ***\n");
+    THR_Print("parameter_position: %" Pd "\n", parameter_position);
+    THR_Print("other_parameter_position: %" Pd "\n", other_parameter_position);
+    THR_Print("function: %s\n", ToCString());
+    THR_Print("function owner: %s\n", owner.ToCString());
+    THR_Print("other function: %s\n", other.ToCString());
+    THR_Print("other function owner: %s\n", other_owner.ToCString());
+    AbstractType& param_type =
+        AbstractType::Handle(ParameterTypeAt(parameter_position));
+    THR_Print("param_type: %s\n", param_type.ToCString());
+  }
+
   if (!other_param_type.IsInstantiated()) {
     other_param_type =
         other_param_type.InstantiateFrom(other_type_arguments,
@@ -6432,6 +6449,21 @@
   }
   AbstractType& param_type =
       AbstractType::Handle(ParameterTypeAt(parameter_position));
+
+  // TODO(regis): Remove this debugging code.
+  if (param_type.IsNull()) {
+    const Class& owner = Class::Handle(Owner());
+    const Class& other_owner = Class::Handle(other.Owner());
+    THR_Print("*** null param_type ***\n");
+    THR_Print("parameter_position: %" Pd "\n", parameter_position);
+    THR_Print("other_parameter_position: %" Pd "\n", other_parameter_position);
+    THR_Print("function: %s\n", ToCString());
+    THR_Print("function owner: %s\n", owner.ToCString());
+    THR_Print("other function: %s\n", other.ToCString());
+    THR_Print("other function owner: %s\n", other_owner.ToCString());
+    THR_Print("other_param_type: %s\n", other_param_type.ToCString());
+  }
+
   if (!param_type.IsInstantiated()) {
     param_type = param_type.InstantiateFrom(type_arguments,
                                             bound_error,
@@ -15515,6 +15547,7 @@
 
 bool AbstractType::IsInstantiated(TrailPtr trail) const {
   // AbstractType is an abstract class.
+#if !defined(PRODUCT)
   // TODO(srdjan) : Remove temporary code.
 NOT_IN_PRODUCT(
   Profiler::DumpStackTrace(true);  // Only native stack trace.
@@ -15522,6 +15555,7 @@
   if (Compiler::IsBackgroundCompilation()) {
     UNREACHABLE();
   }
+#endif
   UNREACHABLE();
   return false;
 }
@@ -16338,14 +16372,13 @@
 
 
 bool Type::HasResolvedTypeClass() const {
-  const Object& type_class = Object::Handle(raw_ptr()->type_class_);
-  return !type_class.IsNull() && type_class.IsClass();
+  return (raw_ptr()->type_class_->GetClassId() == kClassCid);
 }
 
 
 RawClass* Type::type_class() const {
-  ASSERT(HasResolvedTypeClass());
 #ifdef DEBUG
+  ASSERT(HasResolvedTypeClass());
   Class& type_class = Class::Handle();
   type_class ^= raw_ptr()->type_class_;
   return type_class.raw();
@@ -16356,8 +16389,8 @@
 
 
 RawUnresolvedClass* Type::unresolved_class() const {
-  ASSERT(!HasResolvedTypeClass());
 #ifdef DEBUG
+  ASSERT(!HasResolvedTypeClass());
   UnresolvedClass& unresolved_class = UnresolvedClass::Handle();
   unresolved_class ^= raw_ptr()->type_class_;
   ASSERT(!unresolved_class.IsNull());
@@ -16494,7 +16527,7 @@
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   if (arguments() != other_type.arguments()) {
-  const Class& cls = Class::Handle(zone, type_class());
+    const Class& cls = Class::Handle(zone, type_class());
     const intptr_t num_type_params = cls.NumTypeParameters(thread);
     // Shortcut unnecessary handle allocation below if non-generic.
     if (num_type_params > 0) {
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 92be955..534e516 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -564,9 +564,6 @@
   RawFunction* handle_message_function_;
   RawArray* library_load_error_table_;
   RawArray* compile_time_constants_;
-  RawObject** to_snapshot() {
-    return reinterpret_cast<RawObject**>(&compile_time_constants_);
-  }
   RawArray* unique_dynamic_targets_;
   RawGrowableObjectArray* token_objects_;
   RawArray* token_objects_map_;
@@ -576,6 +573,20 @@
   RawObject** to() {
     return reinterpret_cast<RawObject**>(&megamorphic_miss_function_);
   }
+  RawObject** to_snapshot(Snapshot::Kind kind) {
+    switch (kind) {
+      case Snapshot::kCore:
+        return reinterpret_cast<RawObject**>(&compile_time_constants_);
+      case Snapshot::kAppWithJIT:
+      case Snapshot::kAppNoJIT:
+        return to();
+      case Snapshot::kScript:
+      case Snapshot::kMessage:
+        break;
+    }
+    UNREACHABLE();
+    return NULL;
+  }
 
   friend class FullSnapshotWriter;
   friend class SnapshotReader;
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 14446d9..6404df4 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -11832,7 +11832,7 @@
           }
           // A type parameter cannot be parameterized, so make the type
           // malformed if type arguments have previously been parsed.
-          if (!TypeArguments::Handle(Z, type->arguments()).IsNull()) {
+          if (type->arguments() != TypeArguments::null()) {
             *type = ClassFinalizer::NewFinalizedMalformedType(
                 Error::Handle(Z),  // No previous error.
                 script_,
@@ -11873,12 +11873,13 @@
     }
   }
   // Resolve type arguments, if any.
-  const TypeArguments& arguments = TypeArguments::Handle(Z, type->arguments());
-  if (!arguments.IsNull()) {
+  if (type->arguments() != TypeArguments::null()) {
+    const TypeArguments& arguments =
+        TypeArguments::Handle(Z, type->arguments());
     const intptr_t num_arguments = arguments.Length();
+    AbstractType& type_argument = AbstractType::Handle(Z);
     for (intptr_t i = 0; i < num_arguments; i++) {
-      AbstractType& type_argument = AbstractType::Handle(Z,
-                                                         arguments.TypeAt(i));
+      type_argument ^= arguments.TypeAt(i);
       ResolveTypeFromClass(scope_class, finalization, &type_argument);
       arguments.SetTypeAt(i, type_argument);
     }
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 2e67ee2..ff32dcd 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -661,6 +661,7 @@
   friend class SnapshotReader;
   friend class SnapshotWriter;
   friend class String;
+  friend class Type;  // GetClassId
   friend class TypedData;
   friend class TypedDataView;
   friend class WeakProperty;  // StorePointer
@@ -921,14 +922,25 @@
     // restore the value back to the original initial value.
     RawInstance* saved_value_;  // Saved initial value - static fields.
   } initializer_;
-  RawObject** to_precompiled_snapshot() {
-    return reinterpret_cast<RawObject**>(&ptr()->initializer_);
-  }
   RawArray* dependent_code_;
   RawSmi* guarded_list_length_;
   RawObject** to() {
     return reinterpret_cast<RawObject**>(&ptr()->guarded_list_length_);
   }
+  RawObject** to_snapshot(Snapshot::Kind kind) {
+    switch (kind) {
+      case Snapshot::kCore:
+      case Snapshot::kScript:
+        return to();
+      case Snapshot::kAppWithJIT:
+      case Snapshot::kAppNoJIT:
+        return reinterpret_cast<RawObject**>(&ptr()->initializer_);
+      case Snapshot::kMessage:
+        break;
+    }
+    UNREACHABLE();
+    return NULL;
+  }
 
   TokenPosition token_pos_;
   classid_t guarded_cid_;
@@ -992,15 +1004,23 @@
 
   RawObject** from() { return reinterpret_cast<RawObject**>(&ptr()->url_); }
   RawString* url_;
-  RawObject** to_precompiled_snapshot() {
-    return reinterpret_cast<RawObject**>(&ptr()->url_);
-  }
   RawTokenStream* tokens_;
-  RawObject** to_snapshot() {
-    return reinterpret_cast<RawObject**>(&ptr()->tokens_);
-  }
   RawString* source_;
   RawObject** to() { return reinterpret_cast<RawObject**>(&ptr()->source_); }
+  RawObject** to_snapshot(Snapshot::Kind kind) {
+    switch (kind) {
+      case Snapshot::kAppNoJIT:
+        return reinterpret_cast<RawObject**>(&ptr()->url_);
+      case Snapshot::kCore:
+      case Snapshot::kAppWithJIT:
+      case Snapshot::kScript:
+        return reinterpret_cast<RawObject**>(&ptr()->tokens_);
+      case Snapshot::kMessage:
+        break;
+    }
+    UNREACHABLE();
+    return NULL;
+  }
 
   int32_t line_offset_;
   int32_t col_offset_;
@@ -1471,13 +1491,24 @@
   RawArray* ic_data_;  // Contains class-ids, target and count.
   RawString* target_name_;  // Name of target function.
   RawArray* args_descriptor_;  // Arguments descriptor.
-  RawObject** to_precompiled_snapshot() {
-    return reinterpret_cast<RawObject**>(&ptr()->args_descriptor_);
-  }
   RawObject* owner_;  // Parent/calling function or original IC of cloned IC.
   RawObject** to() {
     return reinterpret_cast<RawObject**>(&ptr()->owner_);
   }
+  RawObject** to_snapshot(Snapshot::Kind kind) {
+    switch (kind) {
+      case Snapshot::kAppNoJIT:
+        return reinterpret_cast<RawObject**>(&ptr()->args_descriptor_);
+      case Snapshot::kCore:
+      case Snapshot::kScript:
+      case Snapshot::kAppWithJIT:
+        return to();
+      case Snapshot::kMessage:
+        break;
+    }
+    UNREACHABLE();
+    return NULL;
+  }
   int32_t deopt_id_;     // Deoptimization id corresponding to this IC.
   uint32_t state_bits_;  // Number of arguments tested in IC, deopt reasons,
                          // range feedback.
@@ -1589,15 +1620,26 @@
   RawObject** from() { return reinterpret_cast<RawObject**>(&ptr()->name_); }
   RawString* name_;               // Library prefix name.
   RawLibrary* importer_;          // Library which declares this prefix.
-  RawObject** to_precompiled_snapshot() {
-    return reinterpret_cast<RawObject**>(&ptr()->importer_);
-  }
   RawArray* imports_;             // Libraries imported with this prefix.
   RawArray* dependent_code_;      // Code that refers to deferred, unloaded
                                   // library prefix.
   RawObject** to() {
     return reinterpret_cast<RawObject**>(&ptr()->dependent_code_);
   }
+  RawObject** to_snapshot(Snapshot::Kind kind) {
+    switch (kind) {
+      case Snapshot::kCore:
+      case Snapshot::kScript:
+        return to();
+      case Snapshot::kAppWithJIT:
+      case Snapshot::kAppNoJIT:
+        return reinterpret_cast<RawObject**>(&ptr()->importer_);
+      case Snapshot::kMessage:
+        break;
+    }
+    UNREACHABLE();
+    return NULL;
+  }
   uint16_t num_imports_;          // Number of library entries in libraries_.
   bool is_deferred_load_;
   bool is_loaded_;
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 40c1e34..2b715b2 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -13,13 +13,13 @@
 namespace dart {
 
 #define NEW_OBJECT(type)                                                       \
-  ((kind == Snapshot::kFull) ? reader->New##type() : type::New())
+  ((Snapshot::IsFull(kind)) ? reader->New##type() : type::New())
 
 #define NEW_OBJECT_WITH_LEN(type, len)                                         \
-  ((kind == Snapshot::kFull) ? reader->New##type(len) : type::New(len))
+  ((Snapshot::IsFull(kind)) ? reader->New##type(len) : type::New(len))
 
 #define NEW_OBJECT_WITH_LEN_SPACE(type, len, kind)                             \
-  ((kind == Snapshot::kFull) ?                                                 \
+  ((Snapshot::IsFull(kind)) ?                                                  \
   reader->New##type(len) : type::New(len, HEAP_SPACE(kind)))
 
 #define OFFSET_OF_FROM(obj)                                                    \
@@ -46,13 +46,13 @@
 
   Class& cls = Class::ZoneHandle(reader->zone(), Class::null());
   bool is_in_fullsnapshot = reader->Read<bool>();
-  if ((kind == Snapshot::kFull) ||
+  if (Snapshot::IsFull(kind) ||
       (kind == Snapshot::kScript && !is_in_fullsnapshot)) {
     // Read in the base information.
     classid_t class_id = reader->ReadClassIDValue();
 
     // Allocate class object of specified kind.
-    if (kind == Snapshot::kFull) {
+    if (Snapshot::IsFull(kind)) {
       cls = reader->NewClass(class_id);
     } else {
       if (class_id < kNumPredefinedCids) {
@@ -79,7 +79,7 @@
 
     // Set all the object fields.
     READ_OBJECT_FIELDS(cls, cls.raw()->from(), cls.raw()->to(), kAsReference);
-    ASSERT(!cls.IsInFullSnapshot() || (kind == Snapshot::kFull));
+    ASSERT(!cls.IsInFullSnapshot() || (Snapshot::IsFull(kind)));
   } else {
     cls ^= reader->ReadClassId(object_id);
     ASSERT((kind == Snapshot::kMessage) || cls.IsInFullSnapshot());
@@ -107,7 +107,7 @@
   // to be interpreted.
   writer->Write<bool>(is_in_fullsnapshot);
 
-  if ((kind == Snapshot::kFull) ||
+  if (Snapshot::IsFull(kind) ||
       (kind == Snapshot::kScript && !is_in_fullsnapshot)) {
     // Write out all the non object pointer fields.
     // NOTE: cpp_vtable_ is not written.
@@ -225,7 +225,7 @@
   Type& type = Type::ZoneHandle(reader->zone(), NEW_OBJECT(Type));
   bool is_canonical = RawObject::IsCanonical(tags);
   bool defer_canonicalization = is_canonical &&
-      (kind != Snapshot::kFull && typeclass_is_in_fullsnapshot);
+      (!Snapshot::IsFull(kind) && typeclass_is_in_fullsnapshot);
   reader->AddBackRef(object_id, &type, kIsDeserialized, defer_canonicalization);
 
   // Set all non object fields.
@@ -446,14 +446,14 @@
   TypeArguments& type_arguments = TypeArguments::ZoneHandle(
       reader->zone(), NEW_OBJECT_WITH_LEN_SPACE(TypeArguments, len, kind));
   bool is_canonical = RawObject::IsCanonical(tags);
-  bool defer_canonicalization = is_canonical && (kind != Snapshot::kFull);
+  bool defer_canonicalization = is_canonical && (!Snapshot::IsFull(kind));
   reader->AddBackRef(object_id,
                      &type_arguments,
                      kIsDeserialized,
                      defer_canonicalization);
 
   // Set the instantiations field, which is only read from a full snapshot.
-  if (kind == Snapshot::kFull) {
+  if (Snapshot::IsFull(kind)) {
     *(reader->ArrayHandle()) ^= reader->ReadObjectImpl(kAsInlinedObject);
     type_arguments.set_instantiations(*(reader->ArrayHandle()));
   } else {
@@ -495,7 +495,7 @@
   writer->Write<RawObject*>(ptr()->length_);
 
   // Write out the instantiations field, but only in a full snapshot.
-  if (kind == Snapshot::kFull) {
+  if (Snapshot::IsFull(kind)) {
     writer->WriteObjectImpl(ptr()->instantiations_, kAsInlinedObject);
   }
 
@@ -522,7 +522,7 @@
   // Set all the object fields.
   READ_OBJECT_FIELDS(cls, cls.raw()->from(), cls.raw()->to(), kAsReference);
 
-  ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
+  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
   return cls.raw();
 }
 
@@ -532,7 +532,7 @@
                             Snapshot::Kind kind,
                             bool as_reference) {
   ASSERT(writer != NULL);
-  ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
+  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -552,7 +552,7 @@
                               Snapshot::Kind kind,
                               bool as_reference) {
   ASSERT(reader != NULL);
-  ASSERT(kind == Snapshot::kFull);
+  ASSERT(Snapshot::IsFull(kind));
 
   // Allocate closure object.
   Closure& closure = Closure::ZoneHandle(
@@ -607,7 +607,7 @@
                                       Snapshot::Kind kind,
                                       bool as_reference) {
   ASSERT(reader != NULL);
-  ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
+  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
 
   // Allocate closure data object.
   ClosureData& data = ClosureData::ZoneHandle(
@@ -628,7 +628,7 @@
                              Snapshot::Kind kind,
                              bool as_reference) {
   ASSERT(writer != NULL);
-  ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
+  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -666,7 +666,7 @@
                                               Snapshot::Kind kind,
                                               bool as_reference) {
   ASSERT(reader != NULL);
-  ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
+  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
 
   // Allocate redirection data object.
   RedirectionData& data = RedirectionData::ZoneHandle(
@@ -687,7 +687,7 @@
                                  Snapshot::Kind kind,
                                  bool as_reference) {
   ASSERT(writer != NULL);
-  ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
+  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -708,10 +708,10 @@
                                 Snapshot::Kind kind,
                                 bool as_reference) {
   ASSERT(reader != NULL);
-  ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
+  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
 
   bool is_in_fullsnapshot = reader->Read<bool>();
-  if ((kind == Snapshot::kFull) || !is_in_fullsnapshot) {
+  if ((Snapshot::IsFull(kind)) || !is_in_fullsnapshot) {
     // Allocate function object.
     Function& func = Function::ZoneHandle(
         reader->zone(), NEW_OBJECT(Function));
@@ -726,7 +726,7 @@
     func.set_kind_tag(reader->Read<uint32_t>());
     func.set_token_pos(TokenPosition::SnapshotDecode(token_pos));
     func.set_end_token_pos(TokenPosition::SnapshotDecode(end_token_pos));
-    if (reader->snapshot_code()) {
+    if (Snapshot::IncludesCode(kind)) {
       func.set_usage_counter(0);
       func.set_deoptimization_counter(0);
       func.set_optimized_instruction_count(0);
@@ -744,7 +744,7 @@
                        func.raw()->from(), func.raw()->to_snapshot(),
                        kAsReference);
     // Initialize all fields that are not part of the snapshot.
-    if (reader->snapshot_code()) {
+    if (Snapshot::IncludesCode(kind)) {
       func.ClearICDataArray();
       func.ClearCode();
       // Read the code object and fixup entry point.
@@ -773,7 +773,7 @@
                           Snapshot::Kind kind,
                           bool as_reference) {
   ASSERT(writer != NULL);
-  ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
+  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
   bool is_in_fullsnapshot = false;
   bool owner_is_class = false;
   if ((kind == Snapshot::kScript) && !Function::IsSignatureFunction(this)) {
@@ -798,7 +798,7 @@
   // to be interpreted.
   writer->Write<bool>(is_in_fullsnapshot);
 
-  if (kind == Snapshot::kFull || !is_in_fullsnapshot) {
+  if (Snapshot::IsFull(kind) || !is_in_fullsnapshot) {
     bool is_optimized = Code::IsOptimized(ptr()->code_);
 
     // Write out all the non object fields.
@@ -807,7 +807,7 @@
     writer->Write<int16_t>(ptr()->num_fixed_parameters_);
     writer->Write<int16_t>(ptr()->num_optional_parameters_);
     writer->Write<uint32_t>(ptr()->kind_tag_);
-    if (writer->snapshot_code()) {
+    if (Snapshot::IncludesCode(kind)) {
       // Omit fields used to support de/reoptimization.
     } else {
       if (is_optimized) {
@@ -823,7 +823,7 @@
     // Write out all the object pointer fields.
     SnapshotWriterVisitor visitor(writer, kAsReference);
     visitor.VisitPointers(from(), to_snapshot());
-    if (writer->snapshot_code()) {
+    if (Snapshot::IncludesCode(kind)) {
       ASSERT(ptr()->ic_data_array_ == Array::null());
       ASSERT((ptr()->code_ == ptr()->unoptimized_code_) ||
              (ptr()->unoptimized_code_ == Code::null()));
@@ -846,14 +846,14 @@
                           Snapshot::Kind kind,
                           bool as_reference) {
   ASSERT(reader != NULL);
-  ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
+  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
 
   // Allocate field object.
   Field& field = Field::ZoneHandle(reader->zone(), NEW_OBJECT(Field));
   reader->AddBackRef(object_id, &field, kIsDeserialized);
 
   // Set all non object fields.
-  if (reader->snapshot_code()) {
+  if (Snapshot::IncludesCode(kind)) {
     field.set_token_pos(TokenPosition::kNoSource);
     ASSERT(!FLAG_use_field_guards);
   } else {
@@ -865,11 +865,9 @@
   field.set_kind_bits(reader->Read<uint8_t>());
 
   // Set all the object fields.
-  RawObject** toobj = reader->snapshot_code()
-      ? field.raw()->to_precompiled_snapshot()
-      : field.raw()->to();
   READ_OBJECT_FIELDS(field,
-                     field.raw()->from(), toobj,
+                     field.raw()->from(),
+                     field.raw()->to_snapshot(kind),
                      kAsReference);
 
   if (!FLAG_use_field_guards) {
@@ -890,7 +888,7 @@
                        Snapshot::Kind kind,
                        bool as_reference) {
   ASSERT(writer != NULL);
-  ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
+  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -900,7 +898,7 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out all the non object fields.
-  if (!writer->snapshot_code()) {
+  if (!Snapshot::IncludesCode(kind)) {
     writer->Write<int32_t>(ptr()->token_pos_.SnapshotEncode());
     writer->Write<int32_t>(ptr()->guarded_cid_);
     writer->Write<int32_t>(ptr()->is_nullable_);
@@ -915,7 +913,7 @@
   writer->WriteObjectImpl(ptr()->type_, kAsReference);
   // Write out the initial static value or field offset.
   if (Field::StaticBit::decode(ptr()->kind_bits_)) {
-    if (writer->snapshot_code()) {
+    if (Snapshot::IncludesCode(kind)) {
       // For precompiled static fields, the value was already reset and
       // initializer_ now contains a Function.
       writer->WriteObjectImpl(ptr()->value_.static_value_, kAsReference);
@@ -927,12 +925,12 @@
     writer->WriteObjectImpl(ptr()->value_.offset_, kAsReference);
   }
   // Write out the initializer function or saved initial value.
-  if (writer->snapshot_code()) {
+  if (Snapshot::IncludesCode(kind)) {
     writer->WriteObjectImpl(ptr()->initializer_.precompiled_, kAsReference);
   } else {
     writer->WriteObjectImpl(ptr()->initializer_.saved_value_, kAsReference);
   }
-  if (!writer->snapshot_code()) {
+  if (!Snapshot::IncludesCode(kind)) {
     // Write out the dependent code.
     writer->WriteObjectImpl(ptr()->dependent_code_, kAsReference);
     // Write out the guarded list length.
@@ -996,7 +994,7 @@
                                       Snapshot::Kind kind,
                                       bool as_reference) {
   ASSERT(reader != NULL);
-  ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
+  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
 
   // Read the length so that we can determine number of tokens to read.
   intptr_t len = reader->ReadSmiValue();
@@ -1030,7 +1028,7 @@
                              Snapshot::Kind kind,
                              bool as_reference) {
   ASSERT(writer != NULL);
-  ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
+  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -1058,7 +1056,7 @@
                             Snapshot::Kind kind,
                             bool as_reference) {
   ASSERT(reader != NULL);
-  ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
+  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
 
   // Allocate script object.
   Script& script = Script::ZoneHandle(reader->zone(), NEW_OBJECT(Script));
@@ -1079,10 +1077,7 @@
   // Set all the object fields.
   // TODO(5411462): Need to assert No GC can happen here, even though
   // allocations may happen.
-  RawObject** toobj = reader->snapshot_code()
-      ? script.raw()->to_precompiled_snapshot()
-      : script.raw()->to_snapshot();
-  intptr_t num_flds = (toobj - script.raw()->from());
+  intptr_t num_flds = (script.raw()->to_snapshot(kind) - script.raw()->from());
   for (intptr_t i = 0; i <= num_flds; i++) {
     (*reader->PassiveObjectHandle()) = reader->ReadObjectImpl(kAsReference);
     script.StorePointer((script.raw()->from() + i),
@@ -1099,7 +1094,7 @@
                         bool as_reference) {
   ASSERT(writer != NULL);
   ASSERT(tokens_ != TokenStream::null());
-  ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
+  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -1115,9 +1110,7 @@
 
   // Write out all the object pointer fields.
   SnapshotWriterVisitor visitor(writer, kAsReference);
-  RawObject** toobj = writer->snapshot_code() ? to_precompiled_snapshot()
-                                              : to_snapshot();
-  visitor.VisitPointers(from(), toobj);
+  visitor.VisitPointers(from(), to_snapshot(kind));
 }
 
 
@@ -1155,7 +1148,7 @@
                             reader->Read<bool>());
     library.StoreNonPointer(&library.raw_ptr()->debuggable_,
                             reader->Read<bool>());
-    if (kind == Snapshot::kFull) {
+    if (Snapshot::IsFull(kind)) {
       is_in_fullsnapshot = true;
     }
     library.StoreNonPointer(&library.raw_ptr()->is_in_fullsnapshot_,
@@ -1175,7 +1168,7 @@
     }
     // Initialize cache of resolved names.
     const intptr_t kInitialNameCacheSize = 64;
-    if (kind != Snapshot::kFull) {
+    if (!Snapshot::IsFull(kind)) {
       // The cache of resolved names in library scope is not serialized.
       library.InitResolvedNamesCache(kInitialNameCacheSize);
       library.Register();
@@ -1213,7 +1206,7 @@
     // Write out library URL so that it can be looked up when reading.
     writer->WriteObjectImpl(ptr()->url_, kAsInlinedObject);
   } else {
-    ASSERT((kind == Snapshot::kFull) || !ptr()->is_in_fullsnapshot_);
+    ASSERT((Snapshot::IsFull(kind)) || !ptr()->is_in_fullsnapshot_);
     // Write out all non object fields.
     ASSERT(ptr()->index_ != static_cast<classid_t>(-1));
     writer->WriteClassIDValue(ptr()->index_);
@@ -1241,7 +1234,7 @@
                                           Snapshot::Kind kind,
                                           bool as_reference) {
   ASSERT(reader != NULL);
-  ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
+  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
 
   // Allocate library prefix object.
   LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(
@@ -1256,13 +1249,11 @@
   prefix.StoreNonPointer(&prefix.raw_ptr()->is_loaded_, reader->Read<bool>());
 
   // Set all the object fields.
-  RawObject** toobj = reader->snapshot_code()
-      ? prefix.raw()->to_precompiled_snapshot()
-      : prefix.raw()->to();
   READ_OBJECT_FIELDS(prefix,
-                     prefix.raw()->from(), toobj,
+                     prefix.raw()->from(),
+                     prefix.raw()->to_snapshot(kind),
                      kAsReference);
-  if (reader->snapshot_code()) {
+  if (Snapshot::IncludesCode(kind)) {
     prefix.StorePointer(&prefix.raw_ptr()->imports_,
                         Array::null());
     prefix.StorePointer(&prefix.raw_ptr()->dependent_code_,
@@ -1278,7 +1269,7 @@
                                Snapshot::Kind kind,
                                bool as_reference) {
   ASSERT(writer != NULL);
-  ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
+  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -1294,9 +1285,7 @@
 
   // Write out all the object pointer fields.
   SnapshotWriterVisitor visitor(writer, kAsReference);
-  RawObject** toobj = writer->snapshot_code() ? to_precompiled_snapshot()
-                                              : to();
-  visitor.VisitPointers(from(), toobj);
+  visitor.VisitPointers(from(), to_snapshot(kind));
 }
 
 
@@ -1306,7 +1295,7 @@
                                   Snapshot::Kind kind,
                                   bool as_reference) {
   ASSERT(reader != NULL);
-  ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
+  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
 
   // Allocate Namespace object.
   Namespace& ns = Namespace::ZoneHandle(
@@ -1325,7 +1314,7 @@
                            Snapshot::Kind kind,
                            bool as_reference) {
   ASSERT(writer != NULL);
-  ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
+  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -1358,8 +1347,8 @@
                         intptr_t tags,
                         Snapshot::Kind kind,
                         bool as_reference) {
-  ASSERT(reader->snapshot_code());
-  ASSERT(kind == Snapshot::kFull);
+  ASSERT(Snapshot::IncludesCode(kind));
+  ASSERT(Snapshot::IsFull(kind));
 
   Code& result = Code::ZoneHandle(reader->zone(), NEW_OBJECT_WITH_LEN(Code, 0));
   reader->AddBackRef(object_id, &result, kIsDeserialized);
@@ -1437,8 +1426,8 @@
                       intptr_t object_id,
                       Snapshot::Kind kind,
                       bool as_reference) {
-  ASSERT(writer->snapshot_code());
-  ASSERT(kind == Snapshot::kFull);
+  ASSERT(Snapshot::IncludesCode(kind));
+  ASSERT(Snapshot::IsFull(kind));
 
   intptr_t pointer_offsets_length =
       Code::PtrOffBits::decode(ptr()->state_bits_);
@@ -1500,8 +1489,8 @@
                                     intptr_t tags,
                                     Snapshot::Kind kind,
                                     bool as_reference) {
-  ASSERT(reader->snapshot_code());
-  ASSERT(kind == Snapshot::kFull);
+  ASSERT(Snapshot::IncludesCode(kind));
+  ASSERT(Snapshot::IsFull(kind));
 
   intptr_t len = reader->Read<intptr_t>();
   ObjectPool* result = NULL;
@@ -1563,8 +1552,8 @@
                             intptr_t object_id,
                             Snapshot::Kind kind,
                             bool as_reference) {
-  ASSERT(writer->snapshot_code());
-  ASSERT(kind == Snapshot::kFull);
+  ASSERT(Snapshot::IncludesCode(kind));
+  ASSERT(Snapshot::IsFull(kind));
   intptr_t tags = writer->GetObjectTags(this);
   intptr_t length = ptr()->length_;
 
@@ -1633,8 +1622,8 @@
                                           intptr_t tags,
                                           Snapshot::Kind kind,
                                           bool as_reference) {
-  ASSERT(reader->snapshot_code());
-  ASSERT(kind == Snapshot::kFull);
+  ASSERT(Snapshot::IncludesCode(kind));
+  ASSERT(Snapshot::IsFull(kind));
 
   intptr_t offset = reader->Read<int32_t>();
   PcDescriptors& result = PcDescriptors::ZoneHandle(reader->zone());
@@ -1649,8 +1638,8 @@
                                intptr_t object_id,
                                Snapshot::Kind kind,
                                bool as_reference) {
-  ASSERT(writer->snapshot_code());
-  ASSERT(kind == Snapshot::kFull);
+  ASSERT(Snapshot::IncludesCode(kind));
+  ASSERT(Snapshot::IsFull(kind));
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -1666,8 +1655,8 @@
                                           intptr_t tags,
                                           Snapshot::Kind kind,
                                           bool as_reference) {
-  ASSERT(reader->snapshot_code());
-  ASSERT(kind == Snapshot::kFull);
+  ASSERT(Snapshot::IncludesCode(kind));
+  ASSERT(Snapshot::IsFull(kind));
 
   const int32_t length = reader->Read<int32_t>();
   CodeSourceMap& result =
@@ -1690,8 +1679,8 @@
                                intptr_t object_id,
                                Snapshot::Kind kind,
                                bool as_reference) {
-  ASSERT(writer->snapshot_code());
-  ASSERT(kind == Snapshot::kFull);
+  ASSERT(Snapshot::IncludesCode(kind));
+  ASSERT(Snapshot::IsFull(kind));
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -1711,8 +1700,8 @@
                                 intptr_t tags,
                                 Snapshot::Kind kind,
                                 bool as_reference) {
-  ASSERT(reader->snapshot_code());
-  ASSERT(kind == Snapshot::kFull);
+  ASSERT(Snapshot::IncludesCode(kind));
+  ASSERT(Snapshot::IsFull(kind));
 
   intptr_t offset = reader->Read<int32_t>();
   Stackmap& result = Stackmap::ZoneHandle(reader->zone());
@@ -1727,8 +1716,8 @@
                           intptr_t object_id,
                           Snapshot::Kind kind,
                           bool as_reference) {
-  ASSERT(writer->snapshot_code());
-  ASSERT(kind == Snapshot::kFull);
+  ASSERT(Snapshot::IncludesCode(kind));
+  ASSERT(Snapshot::IsFull(kind));
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -1744,8 +1733,8 @@
                                                       intptr_t tags,
                                                       Snapshot::Kind kind,
                                                       bool as_reference) {
-  ASSERT(reader->snapshot_code());
-  ASSERT(kind == Snapshot::kFull);
+  ASSERT(Snapshot::IncludesCode(kind));
+  ASSERT(Snapshot::IsFull(kind));
 
   const int32_t num_entries = reader->Read<int32_t>();
 
@@ -1777,8 +1766,8 @@
                                      intptr_t object_id,
                                      Snapshot::Kind kind,
                                      bool as_reference) {
-  ASSERT(writer->snapshot_code());
-  ASSERT(kind == Snapshot::kFull);
+  ASSERT(Snapshot::IncludesCode(kind));
+  ASSERT(Snapshot::IsFull(kind));
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -1801,8 +1790,8 @@
                                                   intptr_t tags,
                                                   Snapshot::Kind kind,
                                                   bool as_reference) {
-  ASSERT(reader->snapshot_code());
-  ASSERT(kind == Snapshot::kFull);
+  ASSERT(Snapshot::IncludesCode(kind));
+  ASSERT(Snapshot::IsFull(kind));
 
   const int32_t num_entries = reader->Read<int32_t>();
   ExceptionHandlers& result =
@@ -1832,8 +1821,8 @@
                                    intptr_t object_id,
                                    Snapshot::Kind kind,
                                    bool as_reference) {
-  ASSERT(writer->snapshot_code());
-  ASSERT(kind == Snapshot::kFull);
+  ASSERT(Snapshot::IncludesCode(kind));
+  ASSERT(Snapshot::IsFull(kind));
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -1916,7 +1905,7 @@
   bool is_implicit = reader->Read<bool>();
   if (is_implicit) {
     ContextScope& context_scope = ContextScope::ZoneHandle();
-    if (kind == Snapshot::kFull) {
+    if (Snapshot::IsFull(kind)) {
       context_scope = reader->NewContextScope(1);
       context_scope.set_is_implicit(true);
     } else {
@@ -1975,7 +1964,7 @@
                             intptr_t tags,
                             Snapshot::Kind kind,
                             bool as_reference) {
-  ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
+  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
 
   ICData& result = ICData::ZoneHandle(reader->zone(), NEW_OBJECT(ICData));
   reader->AddBackRef(object_id, &result, kIsDeserialized);
@@ -1987,13 +1976,11 @@
 #endif
 
   // Set all the object fields.
-  RawObject** toobj = reader->snapshot_code()
-      ? result.raw()->to_precompiled_snapshot()
-      : result.raw()->to();
   READ_OBJECT_FIELDS(result,
-                     result.raw()->from(), toobj,
+                     result.raw()->from(),
+                     result.raw()->to_snapshot(kind),
                      kAsReference);
-  if (reader->snapshot_code()) {
+  if (kind == Snapshot::kAppNoJIT) {
     result.set_owner(Function::Handle(reader->zone()));
   }
 
@@ -2005,7 +1992,7 @@
                         intptr_t object_id,
                         Snapshot::Kind kind,
                         bool as_reference) {
-  ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
+  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -2025,9 +2012,7 @@
   // In precompiled snapshots, omit the owner field. The owner field may
   // refer to a function which was always inlined and no longer needed.
   SnapshotWriterVisitor visitor(writer, kAsReference);
-  RawObject** toobj = writer->snapshot_code() ? to_precompiled_snapshot()
-                                              : to();
-  visitor.VisitPointers(from(), toobj);
+  visitor.VisitPointers(from(), to_snapshot(kind));
 }
 
 
@@ -2036,8 +2021,8 @@
                                                 intptr_t tags,
                                                 Snapshot::Kind kind,
                                                 bool as_reference) {
-  ASSERT(reader->snapshot_code());
-  ASSERT(kind == Snapshot::kFull);
+  ASSERT(Snapshot::IncludesCode(kind));
+  ASSERT(Snapshot::IsFull(kind));
 
   MegamorphicCache& result =
       MegamorphicCache::ZoneHandle(reader->zone(),
@@ -2059,8 +2044,8 @@
                                   intptr_t object_id,
                                   Snapshot::Kind kind,
                                   bool as_reference) {
-  ASSERT(writer->snapshot_code());
-  ASSERT(kind == Snapshot::kFull);
+  ASSERT(Snapshot::IncludesCode(kind));
+  ASSERT(Snapshot::IsFull(kind));
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -2083,8 +2068,8 @@
                                                 intptr_t tags,
                                                 Snapshot::Kind kind,
                                                 bool as_reference) {
-  ASSERT(reader->snapshot_code());
-  ASSERT(kind == Snapshot::kFull);
+  ASSERT(Snapshot::IncludesCode(kind));
+  ASSERT(Snapshot::IsFull(kind));
 
   SubtypeTestCache& result =
       SubtypeTestCache::ZoneHandle(reader->zone(),
@@ -2106,8 +2091,8 @@
                                   intptr_t object_id,
                                   Snapshot::Kind kind,
                                   bool as_reference) {
-  ASSERT(writer->snapshot_code());
-  ASSERT(kind == Snapshot::kFull);
+  ASSERT(Snapshot::IncludesCode(kind));
+  ASSERT(Snapshot::IsFull(kind));
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -2292,7 +2277,7 @@
   // Create an Instance object or get canonical one if it is a canonical
   // constant.
   Instance& obj = Instance::ZoneHandle(reader->zone(), Instance::null());
-  if (kind == Snapshot::kFull) {
+  if (Snapshot::IsFull(kind)) {
     obj = reader->NewInstance();
     // Set the canonical bit.
     if (RawObject::IsCanonical(tags)) {
@@ -2348,7 +2333,7 @@
 
   // Create a Mint object or get canonical one if it is a canonical constant.
   Mint& mint = Mint::ZoneHandle(reader->zone(), Mint::null());
-  if (kind == Snapshot::kFull) {
+  if (Snapshot::IsFull(kind)) {
     mint = reader->NewMint(value);
     // Set the canonical bit.
     if (RawObject::IsCanonical(tags)) {
@@ -2410,7 +2395,7 @@
   // When reading a script snapshot or a message snapshot we always have
   // to canonicalize the object.
   if (RawObject::IsCanonical(tags)) {
-    if (kind == Snapshot::kFull) {
+    if (Snapshot::IsFull(kind)) {
       // Set the canonical bit.
       obj.SetCanonical();
     } else {
@@ -2454,7 +2439,7 @@
 
   // Create a Double object or get canonical one if it is a canonical constant.
   Double& dbl = Double::ZoneHandle(reader->zone(), Double::null());
-  if (kind == Snapshot::kFull) {
+  if (Snapshot::IsFull(kind)) {
     dbl = reader->NewDouble(value);
     // Set the canonical bit.
     if (RawObject::IsCanonical(tags)) {
@@ -2551,8 +2536,8 @@
                                           intptr_t tags,
                                           Snapshot::Kind kind,
                                           bool as_reference) {
-  if (reader->snapshot_code()) {
-    ASSERT(kind == Snapshot::kFull);
+  if (Snapshot::IncludesCode(kind)) {
+    ASSERT(Snapshot::IsFull(kind));
     intptr_t offset = reader->Read<int32_t>();
     String& result = String::ZoneHandle(reader->zone());
     result ^= reader->GetObjectAt(offset);
@@ -2565,7 +2550,7 @@
   intptr_t hash = reader->ReadSmiValue();
   String& str_obj = String::ZoneHandle(reader->zone(), String::null());
 
-  if (kind == Snapshot::kFull) {
+  if (Snapshot::IsFull(kind)) {
     // We currently only expect the Dart mutator to read snapshots.
     reader->isolate()->AssertCurrentThreadIsMutator();
     ASSERT(Thread::Current()->no_safepoint_scope_depth() != 0);
@@ -2600,7 +2585,7 @@
   intptr_t hash = reader->ReadSmiValue();
   String& str_obj = String::ZoneHandle(reader->zone(), String::null());
 
-  if (kind == Snapshot::kFull) {
+  if (Snapshot::IsFull(kind)) {
     RawTwoByteString* obj = reader->NewTwoByteString(len);
     str_obj = obj;
     if (RawObject::IsCanonical(tags)) {
@@ -2666,9 +2651,9 @@
                                intptr_t object_id,
                                Snapshot::Kind kind,
                                bool as_reference) {
-  if (writer->snapshot_code()) {
-    ASSERT(writer->snapshot_code());
-    ASSERT(kind == Snapshot::kFull);
+  if (Snapshot::IncludesCode(kind)) {
+    ASSERT(Snapshot::IncludesCode(kind));
+    ASSERT(Snapshot::IsFull(kind));
     // Assert that hash is computed.
     if (ptr()->hash_ == NULL) {
       ptr()->hash_ = Smi::New(String::Hash(ptr()->data(),
@@ -2838,7 +2823,7 @@
     // Read all the individual elements for inlined objects.
     reader->ArrayReadFrom(object_id, *array, len, tags);
     if (RawObject::IsCanonical(tags)) {
-      if (kind == Snapshot::kFull) {
+      if (Snapshot::IsFull(kind)) {
         array->SetCanonical();
       } else {
         *array ^= array->CheckAndCanonicalize(reader->thread(), NULL);
@@ -2888,7 +2873,7 @@
   // Read the length so that we can determine instance size to allocate.
   GrowableObjectArray& array = GrowableObjectArray::ZoneHandle(
       reader->zone(), GrowableObjectArray::null());
-  if (kind == Snapshot::kFull) {
+  if (Snapshot::IsFull(kind)) {
     array = reader->NewGrowableObjectArray();
   } else {
     array = GrowableObjectArray::New(0, HEAP_SPACE(kind));
@@ -2947,14 +2932,14 @@
 
   LinkedHashMap& map = LinkedHashMap::ZoneHandle(
       reader->zone(), LinkedHashMap::null());
-  if ((kind == Snapshot::kFull && !reader->snapshot_code()) ||
+  if ((Snapshot::IsFull(kind) && !Snapshot::IncludesCode(kind)) ||
       kind == Snapshot::kScript) {
     // The immutable maps that seed map literals are not yet VM-internal, so
     // we don't reach this.
     UNREACHABLE();
   } else {
     // Since the map might contain itself as a key or value, allocate first.
-    if (kind == Snapshot::kFull) {
+    if (Snapshot::IsFull(kind)) {
       map = reader->NewLinkedHashMap();
     } else {
       map = LinkedHashMap::NewUninitialized(HEAP_SPACE(kind));
@@ -3006,7 +2991,7 @@
                                intptr_t object_id,
                                Snapshot::Kind kind,
                                bool as_reference) {
-  if ((kind == Snapshot::kFull && !writer->snapshot_code()) ||
+  if ((Snapshot::IsFull(kind) && !Snapshot::IncludesCode(kind)) ||
       kind == Snapshot::kScript) {
     // The immutable maps that seed map literals are not yet VM-internal, so
     // we don't reach this.
@@ -3069,7 +3054,7 @@
   // Create a Float32x4 object.
   Float32x4& simd = Float32x4::ZoneHandle(reader->zone(),
                                           Float32x4::null());
-  if (kind == Snapshot::kFull) {
+  if (Snapshot::IsFull(kind)) {
     simd = reader->NewFloat32x4(value0, value1, value2, value3);
   } else {
     simd = Float32x4::New(value0, value1, value2, value3, HEAP_SPACE(kind));
@@ -3115,7 +3100,7 @@
   // Create a Float32x4 object.
   Int32x4& simd = Int32x4::ZoneHandle(reader->zone(), Int32x4::null());
 
-  if (kind == Snapshot::kFull) {
+  if (Snapshot::IsFull(kind)) {
     simd = reader->NewInt32x4(value0, value1, value2, value3);
   } else {
     simd = Int32x4::New(value0, value1, value2, value3, HEAP_SPACE(kind));
@@ -3159,7 +3144,7 @@
   // Create a Float64x2 object.
   Float64x2& simd = Float64x2::ZoneHandle(reader->zone(),
                                           Float64x2::null());
-  if (kind == Snapshot::kFull) {
+  if (Snapshot::IsFull(kind)) {
     simd = reader->NewFloat64x2(value0, value1);
   } else {
     simd = Float64x2::New(value0, value1, HEAP_SPACE(kind));
@@ -3204,7 +3189,7 @@
   intptr_t cid = RawObject::ClassIdTag::decode(tags);
   intptr_t len = reader->ReadSmiValue();
   TypedData& result = TypedData::ZoneHandle(reader->zone(),
-      (kind == Snapshot::kFull) ? reader->NewTypedData(cid, len)
+      (Snapshot::IsFull(kind)) ? reader->NewTypedData(cid, len)
                                 : TypedData::New(cid, len, HEAP_SPACE(kind)));
   reader->AddBackRef(object_id, &result, kIsDeserialized);
 
@@ -3253,7 +3238,7 @@
   // When reading a script snapshot or a message snapshot we always have
   // to canonicalize the object.
   if (RawObject::IsCanonical(tags)) {
-    if (kind == Snapshot::kFull) {
+    if (Snapshot::IsFull(kind)) {
       // Set the canonical bit.
       result.SetCanonical();
     } else {
@@ -3272,7 +3257,7 @@
                                                   intptr_t tags,
                                                   Snapshot::Kind kind,
                                                   bool as_reference) {
-  ASSERT(kind != Snapshot::kFull);
+  ASSERT(!Snapshot::IsFull(kind));
   intptr_t cid = RawObject::ClassIdTag::decode(tags);
   intptr_t length = reader->ReadSmiValue();
   uint8_t* data = reinterpret_cast<uint8_t*>(reader->ReadRawPointerValue());
@@ -3482,13 +3467,13 @@
                                 intptr_t tags,
                                 Snapshot::Kind kind,
                                 bool as_reference) {
-  ASSERT(kind == Snapshot::kMessage || reader->snapshot_code());
+  ASSERT(kind == Snapshot::kMessage || Snapshot::IncludesCode(kind));
 
   uint64_t id = reader->Read<uint64_t>();
   uint64_t origin_id = reader->Read<uint64_t>();
 
   SendPort& result = SendPort::ZoneHandle(reader->zone());
-  if (reader->snapshot_code()) {
+  if (Snapshot::IncludesCode(kind)) {
     // TODO(rmacnak): Reset fields in precompiled snapshots and assert
     // this is unreachable.
   } else {
@@ -3520,7 +3505,7 @@
                                     intptr_t tags,
                                     Snapshot::Kind kind,
                                     bool as_reference) {
-  if (kind == Snapshot::kFull) {
+  if (Snapshot::IsFull(kind)) {
     Stacktrace& result = Stacktrace::ZoneHandle(reader->zone(),
                                                 reader->NewStacktrace());
     reader->AddBackRef(object_id, &result, kIsDeserialized);
@@ -3544,7 +3529,7 @@
                             intptr_t object_id,
                             Snapshot::Kind kind,
                             bool as_reference) {
-  if (kind == Snapshot::kFull) {
+  if (Snapshot::IsFull(kind)) {
     ASSERT(writer != NULL);
     ASSERT(this == Isolate::Current()->object_store()->
            preallocated_stack_trace());
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 4729798..6107c53 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -182,7 +182,6 @@
       instructions_buffer_(instructions_buffer),
       data_buffer_(data_buffer),
       kind_(kind),
-      snapshot_code_(instructions_buffer != NULL),
       thread_(thread),
       zone_(thread->zone()),
       heap_(isolate()->heap()),
@@ -205,7 +204,7 @@
       megamorphic_cache_(MegamorphicCache::Handle(zone_)),
       error_(UnhandledException::Handle(zone_)),
       max_vm_isolate_object_id_(
-          (kind == Snapshot::kFull) ?
+          (Snapshot::IsFull(kind)) ?
               Object::vm_isolate_snapshot_object_table().Length() : 0),
       backward_references_(backward_refs),
       instructions_reader_(NULL) {
@@ -228,7 +227,7 @@
         (*backward_references_)[i].set_state(kIsDeserialized);
       }
     }
-    if (kind() != Snapshot::kFull) {
+    if (!Snapshot::IsFull(kind())) {
       ProcessDeferredCanonicalizations();
     }
     return obj.raw();
@@ -242,7 +241,7 @@
 
 
 RawClass* SnapshotReader::ReadClassId(intptr_t object_id) {
-  ASSERT(kind_ != Snapshot::kFull);
+  ASSERT(!Snapshot::IsFull(kind_));
   // Read the class header information and lookup the class.
   intptr_t class_header = Read<int32_t>();
   ASSERT((class_header & kSmiTagMask) != kSmiTag);
@@ -307,7 +306,7 @@
 
 RawObject* SnapshotReader::ReadStaticImplicitClosure(intptr_t object_id,
                                                      intptr_t class_header) {
-  ASSERT(kind_ != Snapshot::kFull);
+  ASSERT(!Snapshot::IsFull(kind_));
 
   // First create a function object and associate it with the specified
   // 'object_id'.
@@ -488,7 +487,7 @@
     instance_size = cls_.instance_size();
     ASSERT(instance_size > 0);
     // Allocate the instance and read in all the fields for the object.
-    if (kind_ == Snapshot::kFull) {
+    if (Snapshot::IsFull(kind_)) {
       *result ^= AllocateUninitialized(cls_.id(), instance_size);
     } else {
       *result ^= Object::Allocate(cls_.id(), instance_size, HEAP_SPACE(kind_));
@@ -530,7 +529,7 @@
       // snapshot (kFull, kScript) with asserts.
       offset += kWordSize;
     }
-    if (kind_ == Snapshot::kFull) {
+    if (Snapshot::IsFull(kind_)) {
       // We create an uninitialized object in the case of full snapshots, so
       // we need to initialize any remaining padding area with the Null object.
       while (offset < instance_size) {
@@ -539,7 +538,7 @@
       }
     }
     if (RawObject::IsCanonical(tags)) {
-      if (kind_ == Snapshot::kFull) {
+      if (Snapshot::IsFull(kind_)) {
         result->SetCanonical();
       } else {
         *result = result->CheckAndCanonicalize(thread(), NULL);
@@ -592,7 +591,7 @@
 
 
 RawApiError* SnapshotReader::ReadFullSnapshot() {
-  ASSERT(kind_ == Snapshot::kFull);
+  ASSERT(Snapshot::IsFull(kind_));
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   ASSERT(isolate != NULL);
@@ -614,9 +613,8 @@
     HeapLocker hl(thread, old_space());
 
     // Read in all the objects stored in the object store.
-    RawObject** toobj = snapshot_code() ? object_store->to()
-                                        : object_store->to_snapshot();
-    intptr_t num_flds = (toobj - object_store->from());
+    intptr_t num_flds =
+        (object_store->to_snapshot(kind_) - object_store->from());
     for (intptr_t i = 0; i <= num_flds; i++) {
       *(object_store->from() + i) = ReadObjectImpl(kAsInlinedObject);
     }
@@ -627,7 +625,7 @@
       }
     }
 
-    if (snapshot_code()) {
+    if (Snapshot::IncludesCode(kind_)) {
       ICData& ic = ICData::Handle(thread->zone());
       Object& funcOrCode = Object::Handle(thread->zone());
       Code& code = Code::Handle(thread->zone());
@@ -724,7 +722,7 @@
     OS::SNPrint(message_buffer,
                 kMessageBufferSize,
                 "Wrong %s snapshot version, expected '%s' found '%s'",
-                (kind_ == Snapshot::kFull) ? "full" : "script",
+                (Snapshot::IsFull(kind_)) ? "full" : "script",
                 Version::SnapshotString(),
                 actual_version);
     free(actual_version);
@@ -739,7 +737,7 @@
 
 
 #define ALLOC_NEW_OBJECT_WITH_LEN(type, length)                                \
-  ASSERT(kind_ == Snapshot::kFull);                                            \
+  ASSERT(Snapshot::IsFull(kind_));                                            \
   ASSERT_NO_SAFEPOINT_SCOPE();                                                 \
   Raw##type* obj = reinterpret_cast<Raw##type*>(                               \
       AllocateUninitialized(k##type##Cid, type::InstanceSize(length)));        \
@@ -773,7 +771,7 @@
 
 
 RawObjectPool* SnapshotReader::NewObjectPool(intptr_t len) {
-  ASSERT(kind_ == Snapshot::kFull);
+  ASSERT(Snapshot::IsFull(kind_));
   ASSERT_NO_SAFEPOINT_SCOPE();
   RawObjectPool* obj = reinterpret_cast<RawObjectPool*>(
       AllocateUninitialized(kObjectPoolCid, ObjectPool::InstanceSize(len)));
@@ -784,7 +782,7 @@
 
 RawLocalVarDescriptors* SnapshotReader::NewLocalVarDescriptors(
     intptr_t num_entries) {
-  ASSERT(kind_ == Snapshot::kFull);
+  ASSERT(Snapshot::IsFull(kind_));
   ASSERT_NO_SAFEPOINT_SCOPE();
   RawLocalVarDescriptors* obj = reinterpret_cast<RawLocalVarDescriptors*>(
       AllocateUninitialized(kLocalVarDescriptorsCid,
@@ -796,7 +794,7 @@
 
 RawExceptionHandlers* SnapshotReader::NewExceptionHandlers(
     intptr_t num_entries) {
-  ASSERT(kind_ == Snapshot::kFull);
+  ASSERT(Snapshot::IsFull(kind_));
   ASSERT_NO_SAFEPOINT_SCOPE();
   RawExceptionHandlers* obj = reinterpret_cast<RawExceptionHandlers*>(
       AllocateUninitialized(kExceptionHandlersCid,
@@ -807,7 +805,7 @@
 
 
 RawPcDescriptors* SnapshotReader::NewPcDescriptors(intptr_t len) {
-  ASSERT(kind_ == Snapshot::kFull);
+  ASSERT(Snapshot::IsFull(kind_));
   ASSERT_NO_SAFEPOINT_SCOPE();
   RawPcDescriptors* obj = reinterpret_cast<RawPcDescriptors*>(
       AllocateUninitialized(kPcDescriptorsCid,
@@ -818,7 +816,7 @@
 
 
 RawCodeSourceMap* SnapshotReader::NewCodeSourceMap(intptr_t len) {
-  ASSERT(kind_ == Snapshot::kFull);
+  ASSERT(Snapshot::IsFull(kind_));
   ASSERT_NO_SAFEPOINT_SCOPE();
   RawCodeSourceMap* obj = reinterpret_cast<RawCodeSourceMap*>(
       AllocateUninitialized(kCodeSourceMapCid,
@@ -829,7 +827,7 @@
 
 
 RawStackmap* SnapshotReader::NewStackmap(intptr_t len) {
-  ASSERT(kind_ == Snapshot::kFull);
+  ASSERT(Snapshot::IsFull(kind_));
   ASSERT_NO_SAFEPOINT_SCOPE();
   RawStackmap* obj = reinterpret_cast<RawStackmap*>(
       AllocateUninitialized(kStackmapCid, Stackmap::InstanceSize(len)));
@@ -839,7 +837,7 @@
 
 
 RawContextScope* SnapshotReader::NewContextScope(intptr_t num_variables) {
-  ASSERT(kind_ == Snapshot::kFull);
+  ASSERT(Snapshot::IsFull(kind_));
   ASSERT_NO_SAFEPOINT_SCOPE();
   RawContextScope* obj = reinterpret_cast<RawContextScope*>(
       AllocateUninitialized(kContextScopeCid,
@@ -851,7 +849,7 @@
 
 RawCode* SnapshotReader::NewCode(intptr_t pointer_offsets_length) {
   ASSERT(pointer_offsets_length == 0);
-  ASSERT(kind_ == Snapshot::kFull);
+  ASSERT(Snapshot::IsFull(kind_));
   ASSERT_NO_SAFEPOINT_SCOPE();
   RawCode* obj = reinterpret_cast<RawCode*>(
       AllocateUninitialized(kCodeCid, Code::InstanceSize(0)));
@@ -860,7 +858,7 @@
 
 
 RawTokenStream* SnapshotReader::NewTokenStream(intptr_t len) {
-  ASSERT(kind_ == Snapshot::kFull);
+  ASSERT(Snapshot::IsFull(kind_));
   ASSERT_NO_SAFEPOINT_SCOPE();
   stream_ = reinterpret_cast<RawTokenStream*>(
       AllocateUninitialized(kTokenStreamCid, TokenStream::InstanceSize()));
@@ -878,7 +876,7 @@
 
 
 RawContext* SnapshotReader::NewContext(intptr_t num_variables) {
-  ASSERT(kind_ == Snapshot::kFull);
+  ASSERT(Snapshot::IsFull(kind_));
   ASSERT_NO_SAFEPOINT_SCOPE();
   RawContext* obj = reinterpret_cast<RawContext*>(
       AllocateUninitialized(kContextCid, Context::InstanceSize(num_variables)));
@@ -888,7 +886,7 @@
 
 
 RawClass* SnapshotReader::NewClass(intptr_t class_id) {
-  ASSERT(kind_ == Snapshot::kFull);
+  ASSERT(Snapshot::IsFull(kind_));
   ASSERT_NO_SAFEPOINT_SCOPE();
   if (class_id < kNumPredefinedCids) {
     ASSERT((class_id >= kInstanceCid) &&
@@ -907,7 +905,7 @@
 
 
 RawInstance* SnapshotReader::NewInstance() {
-  ASSERT(kind_ == Snapshot::kFull);
+  ASSERT(Snapshot::IsFull(kind_));
   ASSERT_NO_SAFEPOINT_SCOPE();
   RawInstance* obj = reinterpret_cast<RawInstance*>(
       AllocateUninitialized(kInstanceCid, Instance::InstanceSize()));
@@ -916,7 +914,7 @@
 
 
 RawMint* SnapshotReader::NewMint(int64_t value) {
-  ASSERT(kind_ == Snapshot::kFull);
+  ASSERT(Snapshot::IsFull(kind_));
   ASSERT_NO_SAFEPOINT_SCOPE();
   RawMint* obj = reinterpret_cast<RawMint*>(
       AllocateUninitialized(kMintCid, Mint::InstanceSize()));
@@ -926,7 +924,7 @@
 
 
 RawDouble* SnapshotReader::NewDouble(double value) {
-  ASSERT(kind_ == Snapshot::kFull);
+  ASSERT(Snapshot::IsFull(kind_));
   ASSERT_NO_SAFEPOINT_SCOPE();
   RawDouble* obj = reinterpret_cast<RawDouble*>(
       AllocateUninitialized(kDoubleCid, Double::InstanceSize()));
@@ -936,7 +934,7 @@
 
 
 RawTypedData* SnapshotReader::NewTypedData(intptr_t class_id, intptr_t len) {
-  ASSERT(kind_ == Snapshot::kFull);
+  ASSERT(Snapshot::IsFull(kind_));
   ASSERT_NO_SAFEPOINT_SCOPE();
   const intptr_t lengthInBytes = len * TypedData::ElementSizeInBytes(class_id);
   RawTypedData* obj = reinterpret_cast<RawTypedData*>(
@@ -947,7 +945,7 @@
 
 
 #define ALLOC_NEW_OBJECT(type)                                                 \
-  ASSERT(kind_ == Snapshot::kFull);                                            \
+  ASSERT(Snapshot::IsFull(kind_));                                            \
   ASSERT_NO_SAFEPOINT_SCOPE();                                                 \
   return reinterpret_cast<Raw##type*>(                                         \
       AllocateUninitialized(k##type##Cid, type::InstanceSize()));              \
@@ -1080,7 +1078,7 @@
 
 RawFloat32x4* SnapshotReader::NewFloat32x4(float v0, float v1, float v2,
                                            float v3) {
-  ASSERT(kind_ == Snapshot::kFull);
+  ASSERT(Snapshot::IsFull(kind_));
   ASSERT_NO_SAFEPOINT_SCOPE();
   RawFloat32x4* obj = reinterpret_cast<RawFloat32x4*>(
       AllocateUninitialized(kFloat32x4Cid, Float32x4::InstanceSize()));
@@ -1094,7 +1092,7 @@
 
 RawInt32x4* SnapshotReader::NewInt32x4(uint32_t v0, uint32_t v1, uint32_t v2,
                                        uint32_t v3) {
-  ASSERT(kind_ == Snapshot::kFull);
+  ASSERT(Snapshot::IsFull(kind_));
   ASSERT_NO_SAFEPOINT_SCOPE();
   RawInt32x4* obj = reinterpret_cast<RawInt32x4*>(
       AllocateUninitialized(kInt32x4Cid, Int32x4::InstanceSize()));
@@ -1107,7 +1105,7 @@
 
 
 RawFloat64x2* SnapshotReader::NewFloat64x2(double v0, double v1) {
-  ASSERT(kind_ == Snapshot::kFull);
+  ASSERT(Snapshot::IsFull(kind_));
   ASSERT_NO_SAFEPOINT_SCOPE();
   RawFloat64x2* obj = reinterpret_cast<RawFloat64x2*>(
       AllocateUninitialized(kFloat64x2Cid, Float64x2::InstanceSize()));
@@ -1138,7 +1136,7 @@
   if (Smi::IsValid(value)) {
     return Smi::New(static_cast<intptr_t>(value));
   }
-  if (kind_ == Snapshot::kFull) {
+  if (Snapshot::IsFull(kind_)) {
     return NewMint(value);
   }
   return Mint::NewCanonical(value);
@@ -1530,7 +1528,7 @@
   if (IsObjectStoreClassId(class_id)) {
     return isolate()->class_table()->At(class_id);  // get singleton class.
   }
-  if (kind_ != Snapshot::kFull) {
+  if (!Snapshot::IsFull(kind_)) {
     if (IsObjectStoreTypeId(object_id)) {
       return GetType(object_store(), object_id);  // return type obj.
     }
@@ -1548,7 +1546,7 @@
 void SnapshotReader::AddPatchRecord(intptr_t object_id,
                                     intptr_t patch_object_id,
                                     intptr_t patch_offset) {
-  if (patch_object_id != kInvalidPatchIndex && kind() != Snapshot::kFull) {
+  if (patch_object_id != kInvalidPatchIndex && !Snapshot::IsFull(kind())) {
     ASSERT(object_id >= kMaxPredefinedObjectIds);
     intptr_t index = (object_id - kMaxPredefinedObjectIds);
     ASSERT(index >= max_vm_isolate_object_id_);
@@ -1629,6 +1627,7 @@
 
 
 VmIsolateSnapshotReader::VmIsolateSnapshotReader(
+    Snapshot::Kind kind,
     const uint8_t* buffer,
     intptr_t size,
     const uint8_t* instructions_buffer,
@@ -1638,10 +1637,11 @@
                        size,
                        instructions_buffer,
                        data_buffer,
-                       Snapshot::kFull,
+                       kind,
                        new ZoneGrowableArray<BackRefNode>(
                            kNumVmIsolateSnapshotReferences),
                        thread) {
+  ASSERT(Snapshot::IsFull(kind));
 }
 
 
@@ -1660,7 +1660,7 @@
 
 
 RawApiError* VmIsolateSnapshotReader::ReadVmIsolateSnapshot() {
-  ASSERT(kind() == Snapshot::kFull);
+  ASSERT(Snapshot::IsFull(kind()));
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   ASSERT(isolate != NULL);
@@ -1690,7 +1690,7 @@
     // only memory.
     *(ArrayHandle()) ^= ReadObject();
 
-    if (snapshot_code()) {
+    if (Snapshot::IncludesCode(kind())) {
       StubCode::ReadFrom(this);
     }
 
@@ -1704,7 +1704,8 @@
 }
 
 
-IsolateSnapshotReader::IsolateSnapshotReader(const uint8_t* buffer,
+IsolateSnapshotReader::IsolateSnapshotReader(Snapshot::Kind kind,
+                                             const uint8_t* buffer,
                                              intptr_t size,
                                              const uint8_t* instructions_buffer,
                                              const uint8_t* data_buffer,
@@ -1713,11 +1714,12 @@
                      size,
                      instructions_buffer,
                      data_buffer,
-                     Snapshot::kFull,
+                     kind,
                      new ZoneGrowableArray<BackRefNode>(
                          kNumInitialReferencesInFullSnapshot),
                      thread) {
   isolate()->set_compilation_allowed(instructions_buffer_ == NULL);
+  ASSERT(Snapshot::IsFull(kind));
 }
 
 
@@ -1762,19 +1764,18 @@
 }
 
 
-SnapshotWriter::SnapshotWriter(Snapshot::Kind kind,
-                               Thread* thread,
+SnapshotWriter::SnapshotWriter(Thread* thread,
+                               Snapshot::Kind kind,
                                uint8_t** buffer,
                                ReAlloc alloc,
                                intptr_t initial_size,
                                ForwardList* forward_list,
                                InstructionsWriter* instructions_writer,
                                bool can_send_any_object,
-                               bool snapshot_code,
                                bool vm_isolate_is_symbolic)
     : BaseWriter(buffer, alloc, initial_size),
-      kind_(kind),
       thread_(thread),
+      kind_(kind),
       object_store_(isolate()->object_store()),
       class_table_(isolate()->class_table()),
       forward_list_(forward_list),
@@ -1783,7 +1784,6 @@
       exception_msg_(NULL),
       unmarked_objects_(false),
       can_send_any_object_(can_send_any_object),
-      snapshot_code_(snapshot_code),
       vm_isolate_is_symbolic_(vm_isolate_is_symbolic) {
   ASSERT(forward_list_ != NULL);
 }
@@ -1876,7 +1876,7 @@
     }
   }
 
-  if (kind() == Snapshot::kFull) {
+  if (Snapshot::IsFull(kind())) {
     // Check it is a predefined symbol in the VM isolate.
     id = Symbols::LookupVMSymbol(rawobj);
     if (id != kInvalidIndex) {
@@ -1961,13 +1961,14 @@
 };
 
 
-FullSnapshotWriter::FullSnapshotWriter(uint8_t** vm_isolate_snapshot_buffer,
+FullSnapshotWriter::FullSnapshotWriter(Snapshot::Kind kind,
+                                       uint8_t** vm_isolate_snapshot_buffer,
                                        uint8_t** isolate_snapshot_buffer,
                                        ReAlloc alloc,
                                        InstructionsWriter* instructions_writer,
-                                       bool snapshot_code,
                                        bool vm_isolate_is_symbolic)
     : thread_(Thread::Current()),
+      kind_(kind),
       vm_isolate_snapshot_buffer_(vm_isolate_snapshot_buffer),
       isolate_snapshot_buffer_(isolate_snapshot_buffer),
       alloc_(alloc),
@@ -1977,7 +1978,6 @@
       instructions_writer_(instructions_writer),
       scripts_(Array::Handle(zone())),
       symbol_table_(Array::Handle(zone())),
-      snapshot_code_(snapshot_code),
       vm_isolate_is_symbolic_(vm_isolate_is_symbolic) {
   ASSERT(isolate_snapshot_buffer_ != NULL);
   ASSERT(alloc_ != NULL);
@@ -2029,15 +2029,14 @@
 
 void FullSnapshotWriter::WriteVmIsolateSnapshot() {
   ASSERT(vm_isolate_snapshot_buffer_ != NULL);
-  SnapshotWriter writer(Snapshot::kFull,
-                        thread(),
+  SnapshotWriter writer(thread(),
+                        kind_,
                         vm_isolate_snapshot_buffer_,
                         alloc_,
                         kInitialSize,
                         forward_list_,
                         instructions_writer_,
                         true, /* can_send_any_object */
-                        snapshot_code_,
                         vm_isolate_is_symbolic_);
   // Write full snapshot for the VM isolate.
   // Setup for long jump in case there is an exception while writing
@@ -2064,7 +2063,7 @@
     // read only memory.
     writer.WriteObject(scripts_.raw());
 
-    if (snapshot_code_) {
+    if (Snapshot::IncludesCode(kind_)) {
       ASSERT(!vm_isolate_is_symbolic_);
       StubCode::WriteTo(&writer);
     }
@@ -2080,15 +2079,14 @@
 
 
 void FullSnapshotWriter::WriteIsolateFullSnapshot() {
-  SnapshotWriter writer(Snapshot::kFull,
-                        thread(),
+  SnapshotWriter writer(thread(),
+                        kind_,
                         isolate_snapshot_buffer_,
                         alloc_,
                         kInitialSize,
                         forward_list_,
                         instructions_writer_,
                         true, /* can_send_any_object */
-                        snapshot_code_,
                         true /* vm_isolate_is_symbolic */);
   ObjectStore* object_store = isolate()->object_store();
   ASSERT(object_store != NULL);
@@ -2110,8 +2108,7 @@
     // is the root set for all dart allocated objects at this point.
     SnapshotWriterVisitor visitor(&writer, false);
     visitor.VisitPointers(object_store->from(),
-                          snapshot_code_ ? object_store->to()
-                                         : object_store->to_snapshot());
+                          object_store->to_snapshot(kind_));
 
     // Write out all forwarded objects.
     writer.WriteForwardedObjects();
@@ -2130,7 +2127,7 @@
     WriteVmIsolateSnapshot();
   }
   WriteIsolateFullSnapshot();
-  if (snapshot_code_) {
+  if (Snapshot::IncludesCode(kind_)) {
     instructions_writer_->Write();
 
     OS::Print("VMIsolate(CodeSize): %" Pd "\n", VmIsolateSnapshotSize());
@@ -2150,11 +2147,11 @@
     uint8_t** isolate_snapshot_buffer,
     ReAlloc alloc,
     InstructionsWriter* instructions_writer)
-  : FullSnapshotWriter(vm_isolate_snapshot_buffer,
+  : FullSnapshotWriter(Snapshot::kAppNoJIT,
+                       vm_isolate_snapshot_buffer,
                        isolate_snapshot_buffer,
                        alloc,
                        instructions_writer,
-                       true, /* snapshot_code */
                        false /* vm_isolate_is_symbolic */) {
 }
 
@@ -2240,14 +2237,14 @@
 
   // Check if it is a code object in that case just write a Null object
   // as we do not want code objects in the snapshot.
-  if (cid == kCodeCid && !snapshot_code()) {
+  if (cid == kCodeCid && !Snapshot::IncludesCode(kind_)) {
     WriteVMIsolateObject(kNullObject);
     return true;
   }
 
   // Check if classes are not being serialized and it is preinitialized type
   // or a predefined internal VM class in the object store.
-  if (kind_ != Snapshot::kFull) {
+  if (!Snapshot::IsFull(kind_)) {
     // Check if it is an internal VM class which is in the object store.
     if (cid == kClassCid) {
       RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj);
@@ -2402,7 +2399,7 @@
 
 
 void SnapshotWriter::WriteClassId(RawClass* cls) {
-  ASSERT(kind_ != Snapshot::kFull);
+  ASSERT(!Snapshot::IsFull(kind_));
   int class_id = cls->ptr()->id_;
   ASSERT(!IsSingletonClassId(class_id) && !IsObjectStoreClassId(class_id));
 
@@ -2662,15 +2659,14 @@
 
 ScriptSnapshotWriter::ScriptSnapshotWriter(uint8_t** buffer,
                                            ReAlloc alloc)
-    : SnapshotWriter(Snapshot::kScript,
-                     Thread::Current(),
+    : SnapshotWriter(Thread::Current(),
+                     Snapshot::kScript,
                      buffer,
                      alloc,
                      kInitialSize,
                      &forward_list_,
                      NULL, /* instructions_writer */
                      true, /* can_send_any_object */
-                     false, /* snapshot_code */
                      true /* vm_isolate_is_symbolic */),
       forward_list_(thread(), kMaxPredefinedObjectIds) {
   ASSERT(buffer != NULL);
@@ -2719,15 +2715,14 @@
 MessageWriter::MessageWriter(uint8_t** buffer,
                              ReAlloc alloc,
                              bool can_send_any_object)
-    : SnapshotWriter(Snapshot::kMessage,
-                     Thread::Current(),
+    : SnapshotWriter(Thread::Current(),
+                     Snapshot::kMessage,
                      buffer,
                      alloc,
                      kInitialSize,
                      &forward_list_,
                      NULL, /* instructions_writer */
                      can_send_any_object,
-                     false, /* snapshot_code */
                      true /* vm_isolate_is_symbolic */),
       forward_list_(thread(), kMaxPredefinedObjectIds) {
   ASSERT(buffer != NULL);
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index f9822b8..3dc6aae 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -151,9 +151,16 @@
 class Snapshot {
  public:
   enum Kind {
-    kFull = 0,  // Full snapshot of the current dart heap.
-    kScript,    // A partial snapshot of only the application script.
-    kMessage,   // A partial snapshot used only for isolate messaging.
+    kCore = 0,    // Full snapshot of core libraries. No root library, no code.
+    kAppWithJIT,  // Full snapshot of core libraries and application. Has some
+                  // code, but may compile in the future because we haven't
+                  // necessarily included code for every function or to
+                  // (de)optimize.
+    kAppNoJIT,    // Full snapshot of core libraries and application. Has
+                  // complete code for the application that never deopts. Will
+                  // not compile in the future.
+    kScript,      // A partial snapshot of only the application script.
+    kMessage,     // A partial snapshot used only for isolate messaging.
   };
 
   static const int kHeaderSize = 2 * sizeof(int64_t);
@@ -171,9 +178,18 @@
     return static_cast<Kind>(ReadUnaligned(&unaligned_kind_));
   }
 
+  static bool IsFull(Kind kind) {
+    return (kind == kCore) || (kind == kAppWithJIT) || (kind == kAppNoJIT);
+  }
+  static bool IncludesCode(Kind kind) {
+    return (kind == kAppWithJIT) || (kind == kAppNoJIT);
+  }
+
   bool IsMessageSnapshot() const { return kind() == kMessage; }
   bool IsScriptSnapshot() const { return kind() == kScript; }
-  bool IsFullSnapshot() const { return kind() == kFull; }
+  bool IsCoreSnapshot() const { return kind() == kCore; }
+  bool IsAppSnapshotWithJIT() const { return kind() == kAppWithJIT; }
+  bool IsAppSnapshotNoJIT() const { return kind() == kAppNoJIT; }
   uint8_t* Addr() { return reinterpret_cast<uint8_t*>(this); }
 
   static intptr_t length_offset() {
@@ -403,7 +419,6 @@
   Function* FunctionHandle() { return &function_; }
   MegamorphicCache* MegamorphicCacheHandle() { return &megamorphic_cache_; }
   Snapshot::Kind kind() const { return kind_; }
-  bool snapshot_code() const { return snapshot_code_; }
 
   // Reads an object.
   RawObject* ReadObject();
@@ -567,7 +582,6 @@
   bool is_vm_isolate() const;
 
   Snapshot::Kind kind_;  // Indicates type of snapshot(full, script, message).
-  bool snapshot_code_;
   Thread* thread_;  // Current thread.
   Zone* zone_;  // Zone for allocations while reading snapshot.
   Heap* heap_;  // Heap of the current isolate.
@@ -641,7 +655,8 @@
 
 class VmIsolateSnapshotReader : public SnapshotReader {
  public:
-  VmIsolateSnapshotReader(const uint8_t* buffer,
+  VmIsolateSnapshotReader(Snapshot::Kind kind,
+                          const uint8_t* buffer,
                           intptr_t size,
                           const uint8_t* instructions_buffer,
                           const uint8_t* data_buffer,
@@ -657,7 +672,8 @@
 
 class IsolateSnapshotReader : public SnapshotReader {
  public:
-  IsolateSnapshotReader(const uint8_t* buffer,
+  IsolateSnapshotReader(Snapshot::Kind kind,
+                        const uint8_t* buffer,
                         intptr_t size,
                         const uint8_t* instructions_buffer,
                         const uint8_t* data_buffer,
@@ -962,15 +978,14 @@
 
 class SnapshotWriter : public BaseWriter {
  protected:
-  SnapshotWriter(Snapshot::Kind kind,
-                 Thread* thread,
+  SnapshotWriter(Thread* thread,
+                 Snapshot::Kind kind,
                  uint8_t** buffer,
                  ReAlloc alloc,
                  intptr_t initial_size,
                  ForwardList* forward_list,
                  InstructionsWriter* instructions_writer,
                  bool can_send_any_object,
-                 bool snapshot_code,
                  bool vm_isolate_is_symbolic);
 
  public:
@@ -997,7 +1012,6 @@
     exception_msg_ = msg;
   }
   bool can_send_any_object() const { return can_send_any_object_; }
-  bool snapshot_code() const { return snapshot_code_; }
   bool vm_isolate_is_symbolic() const { return vm_isolate_is_symbolic_; }
   void ThrowException(Exceptions::ExceptionType type, const char* msg);
 
@@ -1063,8 +1077,8 @@
   ObjectStore* object_store() const { return object_store_; }
 
  private:
-  Snapshot::Kind kind_;
   Thread* thread_;
+  Snapshot::Kind kind_;
   ObjectStore* object_store_;  // Object store for common classes.
   ClassTable* class_table_;  // Class table for the class index to class lookup.
   ForwardList* forward_list_;
@@ -1073,7 +1087,6 @@
   const char* exception_msg_;  // Message associated with exception.
   bool unmarked_objects_;  // True if marked objects have been unmarked.
   bool can_send_any_object_;  // True if any Dart instance can be sent.
-  bool snapshot_code_;
   bool vm_isolate_is_symbolic_;
 
   friend class FullSnapshotWriter;
@@ -1111,11 +1124,11 @@
 class FullSnapshotWriter {
  public:
   static const intptr_t kInitialSize = 64 * KB;
-  FullSnapshotWriter(uint8_t** vm_isolate_snapshot_buffer,
+  FullSnapshotWriter(Snapshot::Kind kind,
+                     uint8_t** vm_isolate_snapshot_buffer,
                      uint8_t** isolate_snapshot_buffer,
                      ReAlloc alloc,
                      InstructionsWriter* instructions_writer,
-                     bool snapshot_code,
                      bool vm_isolate_is_symbolic);
   ~FullSnapshotWriter();
 
@@ -1150,6 +1163,7 @@
   void WriteIsolateFullSnapshot();
 
   Thread* thread_;
+  Snapshot::Kind kind_;
   uint8_t** vm_isolate_snapshot_buffer_;
   uint8_t** isolate_snapshot_buffer_;
   ReAlloc alloc_;
@@ -1159,7 +1173,6 @@
   InstructionsWriter* instructions_writer_;
   Array& scripts_;
   Array& symbol_table_;
-  bool snapshot_code_;
   bool vm_isolate_is_symbolic_;
 
   DISALLOW_COPY_AND_ASSIGN(FullSnapshotWriter);
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index bf15a61..ef7a10c 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -828,15 +828,14 @@
  public:
   static const intptr_t kInitialSize = 64 * KB;
   TestSnapshotWriter(uint8_t** buffer, ReAlloc alloc)
-      : SnapshotWriter(Snapshot::kScript,
-                       Thread::Current(),
+      : SnapshotWriter(Thread::Current(),
+                       Snapshot::kScript,
                        buffer,
                        alloc,
                        kInitialSize,
                        &forward_list_,
                        NULL, /* test_writer */
                        true, /* can_send_any_object */
-                       false, /* snapshot_code */
                        true /* vm_isolate_is_symbolic */),
         forward_list_(thread(), kMaxPredefinedObjectIds) {
     ASSERT(buffer != NULL);
@@ -1184,11 +1183,11 @@
 
     // Write snapshot with object content.
     {
-      FullSnapshotWriter writer(NULL,
+      FullSnapshotWriter writer(Snapshot::kCore,
+                                NULL,
                                 &isolate_snapshot_buffer,
                                 &malloc_allocator,
                                 NULL, /* instructions_writer */
-                                false, /* snapshot_code */
                                 true);
       writer.WriteFullSnapshot();
     }
@@ -1245,11 +1244,11 @@
 
     // Write snapshot with object content.
     {
-      FullSnapshotWriter writer(NULL,
+      FullSnapshotWriter writer(Snapshot::kCore,
+                                NULL,
                                 &isolate_snapshot_buffer,
                                 &malloc_allocator,
                                 NULL, /* instructions_writer */
-                                false, /* snapshot_code */
                                 true /* vm_isolate_is_symbolic */);
       writer.WriteFullSnapshot();
     }
diff --git a/samples/samples.status b/samples/samples.status
index ac35013..1073481 100644
--- a/samples/samples.status
+++ b/samples/samples.status
@@ -29,4 +29,4 @@
 *: Skip
 
 [ $noopt || $runtime == dart_precompiled || $runtime == dart_product ]
-sample_extension: RuntimeError # Platform.executable
+sample_extension: Skip # Platform.executable
diff --git a/sdk/lib/collection/collection.dart b/sdk/lib/collection/collection.dart
index 4e93785..5a2a906 100644
--- a/sdk/lib/collection/collection.dart
+++ b/sdk/lib/collection/collection.dart
@@ -4,6 +4,10 @@
 
 /**
  * Classes and utilities that supplement the collection support in dart:core.
+ * 
+ * To use this library in your code:
+ *
+ *     import 'dart:collection';
  */
 library dart.collection;
 
diff --git a/sdk/lib/convert/convert.dart b/sdk/lib/convert/convert.dart
index da0c87c..83bbfd6 100644
--- a/sdk/lib/convert/convert.dart
+++ b/sdk/lib/convert/convert.dart
@@ -11,8 +11,7 @@
  * provides support for implementing converters in a way which makes them easy to
  * chain and to use with streams.
  *
- * The `dart:convert` library works in both web apps and command-line apps.
- * To use it:
+ * To use this library in your code:
  *
  *     import 'dart:convert';
  *
diff --git a/sdk/lib/developer/developer.dart b/sdk/lib/developer/developer.dart
index 435c50d..e66e13a 100644
--- a/sdk/lib/developer/developer.dart
+++ b/sdk/lib/developer/developer.dart
@@ -8,6 +8,10 @@
 /// as a result of developer feedback. This library is platform dependent and
 /// therefore it has implementations for both dart2js and the Dart VM. Both are
 /// under development and may not support all operations yet.
+/// 
+/// To use this library in your code:
+/// 
+///     import 'dart:developer';
 ///
 library dart.developer;
 
diff --git a/sdk/lib/isolate/isolate.dart b/sdk/lib/isolate/isolate.dart
index a0bfa67..8caccdb 100644
--- a/sdk/lib/isolate/isolate.dart
+++ b/sdk/lib/isolate/isolate.dart
@@ -7,6 +7,10 @@
  * independent workers that are similar to threads
  * but don't share memory,
  * communicating only via messages.
+ * 
+ * To use this library in your code:
+ * 
+ *     import 'dart:isolate';
  */
 library dart.isolate;
 
diff --git a/sdk/lib/math/math.dart b/sdk/lib/math/math.dart
index 7073e4d..73768c9 100644
--- a/sdk/lib/math/math.dart
+++ b/sdk/lib/math/math.dart
@@ -4,6 +4,10 @@
 
 /**
  * Mathematical constants and functions, plus a random number generator.
+ * 
+ * To use this library in your code:
+ * 
+ *     import 'dart:math';
  */
 library dart.math;
 
diff --git a/sdk/lib/typed_data/typed_data.dart b/sdk/lib/typed_data/typed_data.dart
index d972b62..54d7b49 100644
--- a/sdk/lib/typed_data/typed_data.dart
+++ b/sdk/lib/typed_data/typed_data.dart
@@ -4,6 +4,10 @@
 
 /// Lists that efficiently handle fixed sized data
 /// (for example, unsigned 8 byte integers) and SIMD numeric types.
+/// 
+/// To use this library in your code:
+/// 
+///     import 'dart:typed_data';
 library dart.typed_data;
 
 import 'dart:collection';
diff --git a/tests/compiler/dart2js/const_exp_test.dart b/tests/compiler/dart2js/const_exp_test.dart
index 3117c2d..f45794c 100644
--- a/tests/compiler/dart2js/const_exp_test.dart
+++ b/tests/compiler/dart2js/const_exp_test.dart
@@ -30,14 +30,14 @@
 """, expectNoWarningsOrErrors: true).then((env) {
      var element = env.getElement('constant');
      Expect.isNotNull(element, "Element 'constant' not found.");
-     var constant = env.compiler.constants.getConstantForVariable(element);
+     var constant = element.constant;
      var value = env.compiler.constants.getConstantValue(constant);
      Expect.isNotNull(constant,
                       "No constant computed for '$element'.");
-     Expect.equals(expectedOutput, constant.getText(),
-         "Unexpected to string '${constant.getText()}' for constant "
+     Expect.equals(expectedOutput, constant.toDartText(),
+         "Unexpected to string '${constant.toDartText()}' for constant "
          "'$constantInitializer' of value "
-         "${value.toStructuredString()}");
+         "${value.toStructuredText()}");
    });
 }
 
diff --git a/tests/compiler/dart2js/constant_expression_evaluate_test.dart b/tests/compiler/dart2js/constant_expression_evaluate_test.dart
index 5fa34cc..60563f8 100644
--- a/tests/compiler/dart2js/constant_expression_evaluate_test.dart
+++ b/tests/compiler/dart2js/constant_expression_evaluate_test.dart
@@ -227,10 +227,10 @@
       Environment environment = new MemoryEnvironment(compiler, env);
       ConstantValue value =
           constant.evaluate(environment, DART_CONSTANT_SYSTEM);
-      String valueText = value.toStructuredString();
+      String valueText = value.toStructuredText();
       Expect.equals(expectedText, valueText,
           "Unexpected value '${valueText}' for contant "
-          "`${constant.getText()}`, expected '${expectedText}'.");
+          "`${constant.toDartText()}`, expected '${expectedText}'.");
     });
   });
 }
diff --git a/tests/compiler/dart2js/constant_expression_test.dart b/tests/compiler/dart2js/constant_expression_test.dart
index e028ac6..c24868f 100644
--- a/tests/compiler/dart2js/constant_expression_test.dart
+++ b/tests/compiler/dart2js/constant_expression_test.dart
@@ -218,28 +218,28 @@
     var constant = field.constant;
     Expect.equals(data.kind, constant.kind,
         "Unexpected kind '${constant.kind}' for contant "
-        "`${constant.getText()}`, expected '${data.kind}'.");
-    Expect.equals(data.text, constant.getText(),
-        "Unexpected text '${constant.getText()}' for contant, "
+        "`${constant.toDartText()}`, expected '${data.kind}'.");
+    Expect.equals(data.text, constant.toDartText(),
+        "Unexpected text '${constant.toDartText()}' for contant, "
         "expected '${data.text}'.");
     if (data.type != null) {
       String instanceType = constant.computeInstanceType().toString();
       Expect.equals(data.type, instanceType,
           "Unexpected type '$instanceType' for contant "
-          "`${constant.getText()}`, expected '${data.type}'.");
+          "`${constant.toDartText()}`, expected '${data.type}'.");
     }
     if (data.fields != null) {
       Map instanceFields = constant.computeInstanceFields();
       Expect.equals(data.fields.length, instanceFields.length,
           "Unexpected field count ${instanceFields.length} for contant "
-          "`${constant.getText()}`, expected '${data.fields.length}'.");
+          "`${constant.toDartText()}`, expected '${data.fields.length}'.");
       instanceFields.forEach((field, expression) {
         String name = '$field';
-        String expression = instanceFields[field].getText();
+        String expression = instanceFields[field].toDartText();
         String expected = data.fields[name];
         Expect.equals(expected, expression,
             "Unexpected field expression ${expression} for field '$name' in "
-            "contant `${constant.getText()}`, expected '${expected}'.");
+            "contant `${constant.toDartText()}`, expected '${expected}'.");
       });
     }
   });
diff --git a/tests/compiler/dart2js/mirrors_used_test.dart b/tests/compiler/dart2js/mirrors_used_test.dart
index 0844273..a96cf2a 100644
--- a/tests/compiler/dart2js/mirrors_used_test.dart
+++ b/tests/compiler/dart2js/mirrors_used_test.dart
@@ -137,7 +137,7 @@
     for (var dependency in backend.metadataConstants) {
       ConstantValue constant = dependency.constant;
       Expect.isFalse(compiledConstants.contains(constant),
-                     constant.toStructuredString());
+                     constant.toStructuredText());
     }
 
     // The type literal 'Foo' is both used as metadata, and as a plain value in
diff --git a/tests/compiler/dart2js/resolver_test.dart b/tests/compiler/dart2js/resolver_test.dart
index f8fb479..6067a6c 100644
--- a/tests/compiler/dart2js/resolver_test.dart
+++ b/tests/compiler/dart2js/resolver_test.dart
@@ -1069,12 +1069,12 @@
       Expect.equals(0, collector.errors.length);
       List<ConstantExpression> constants = elements.constants;
       String constantsText =
-          '[${constants.map((c) => c.getText()).join(', ')}]';
+          '[${constants.map((c) => c.toDartText()).join(', ')}]';
       Expect.equals(expectedConstants.length, constants.length,
           "Expected ${expectedConstants.length} constants for `${constant}` "
           "found $constantsText.");
       for (int index = 0; index < expectedConstants.length; index++) {
-        Expect.equals(expectedConstants[index], constants[index].getText(),
+        Expect.equals(expectedConstants[index], constants[index].toDartText(),
             "Expected ${expectedConstants} for `$constant`, "
             "found $constantsText.");
       }
diff --git a/tests/compiler/dart2js/semantic_visitor_test_decl_visitor.dart b/tests/compiler/dart2js/semantic_visitor_test_decl_visitor.dart
index 5382a29..a5e4e20 100644
--- a/tests/compiler/dart2js/semantic_visitor_test_decl_visitor.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test_decl_visitor.dart
@@ -236,7 +236,7 @@
       arg) {
     visits.add(new Visit(VisitKind.VISIT_OPTIONAL_PARAMETER_DECL,
         element: parameter,
-        constant: defaultValue != null ? defaultValue.getText() : null,
+        constant: defaultValue != null ? defaultValue.toDartText() : null,
         index: index));
   }
 
@@ -284,7 +284,7 @@
       ConstantExpression constant,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_LOCAL_CONSTANT_DECL,
-        element: variable, constant: constant.getText()));
+        element: variable, constant: constant.toDartText()));
   }
 
   @override
@@ -296,7 +296,7 @@
       arg) {
     visits.add(new Visit(VisitKind.VISIT_NAMED_INITIALIZING_FORMAL_DECL,
         element: initializingFormal,
-        constant: defaultValue != null ? defaultValue.getText() : null));
+        constant: defaultValue != null ? defaultValue.toDartText() : null));
   }
 
   @override
@@ -308,7 +308,7 @@
       arg) {
     visits.add(new Visit(VisitKind.VISIT_NAMED_PARAMETER_DECL,
         element: parameter,
-        constant: defaultValue != null ? defaultValue.getText() : null));
+        constant: defaultValue != null ? defaultValue.toDartText() : null));
   }
 
   @override
@@ -321,7 +321,7 @@
       arg) {
     visits.add(new Visit(VisitKind.VISIT_OPTIONAL_INITIALIZING_FORMAL_DECL,
         element: initializingFormal,
-        constant: defaultValue != null ? defaultValue.getText() : null,
+        constant: defaultValue != null ? defaultValue.toDartText() : null,
         index: index));
   }
 
@@ -347,7 +347,7 @@
       ConstantExpression constant,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_STATIC_CONSTANT_DECL,
-        element: field, constant: constant.getText()));
+        element: field, constant: constant.toDartText()));
   }
 
   @override
@@ -372,7 +372,7 @@
       ConstantExpression constant,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_CONSTANT_DECL,
-        element: field, constant: constant.getText()));
+        element: field, constant: constant.toDartText()));
   }
 
   @override
diff --git a/tests/compiler/dart2js/semantic_visitor_test_send_visitor.dart b/tests/compiler/dart2js/semantic_visitor_test_send_visitor.dart
index 2187ba8..9ded3ea 100644
--- a/tests/compiler/dart2js/semantic_visitor_test_send_visitor.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test_send_visitor.dart
@@ -244,7 +244,7 @@
       ConstantExpression constant,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_GET,
-        constant: constant.getText()));
+        constant: constant.toDartText()));
   }
 
   @override
@@ -255,7 +255,7 @@
       CallStructure callStructure,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_INVOKE,
-        constant: constant.getText(), arguments: arguments));
+        constant: constant.toDartText(), arguments: arguments));
     apply(arguments, arg);
   }
 
@@ -266,7 +266,7 @@
       Node rhs,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_SET,
-        constant: constant.getText(), rhs: rhs));
+        constant: constant.toDartText(), rhs: rhs));
     super.visitClassTypeLiteralSet(node, constant, rhs, arg);
   }
 
@@ -347,7 +347,7 @@
       ConstantExpression constant,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_GET,
-        constant: constant.getText()));
+        constant: constant.toDartText()));
   }
 
   @override
@@ -358,7 +358,7 @@
       CallStructure callStructure,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_INVOKE,
-        constant: constant.getText(), arguments: arguments));
+        constant: constant.toDartText(), arguments: arguments));
   }
 
   @override
@@ -368,7 +368,7 @@
       Node rhs,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_SET,
-        constant: constant.getText(), rhs: rhs));
+        constant: constant.toDartText(), rhs: rhs));
     super.visitDynamicTypeLiteralSet(node, constant, rhs, arg);
   }
 
@@ -1009,7 +1009,7 @@
       ConstantExpression constant,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_GET,
-        constant: constant.getText()));
+        constant: constant.toDartText()));
   }
 
   @override
@@ -1020,7 +1020,7 @@
       CallStructure callStructure,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_INVOKE,
-        constant: constant.getText(), arguments: arguments));
+        constant: constant.toDartText(), arguments: arguments));
     apply(arguments, arg);
   }
 
@@ -1031,7 +1031,7 @@
       Node rhs,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_SET,
-        constant: constant.getText(), rhs: rhs));
+        constant: constant.toDartText(), rhs: rhs));
     super.visitTypedefTypeLiteralSet(node, constant, rhs, arg);
   }
 
@@ -1767,7 +1767,7 @@
       Node rhs,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_COMPOUND,
-        constant: constant.getText(), operator: operator, rhs: rhs));
+        constant: constant.toDartText(), operator: operator, rhs: rhs));
     apply(rhs, arg);
   }
 
@@ -1779,7 +1779,7 @@
       Node rhs,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_COMPOUND,
-        constant: constant.getText(), operator: operator, rhs: rhs));
+        constant: constant.toDartText(), operator: operator, rhs: rhs));
     apply(rhs, arg);
   }
 
@@ -1803,7 +1803,7 @@
       Node rhs,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_COMPOUND,
-        constant: constant.getText(), operator: operator, rhs: rhs));
+        constant: constant.toDartText(), operator: operator, rhs: rhs));
     apply(rhs, arg);
   }
 
@@ -1824,7 +1824,7 @@
       IncDecOperator operator,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_PREFIX,
-        constant: constant.getText(), operator: operator));
+        constant: constant.toDartText(), operator: operator));
   }
 
   @override
@@ -1834,7 +1834,7 @@
       IncDecOperator operator,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_PREFIX,
-        constant: constant.getText(), operator: operator));
+        constant: constant.toDartText(), operator: operator));
   }
 
   @override
@@ -2037,7 +2037,7 @@
       IncDecOperator operator,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_PREFIX,
-        constant: constant.getText(), operator: operator));
+        constant: constant.toDartText(), operator: operator));
   }
 
   @override
@@ -2057,7 +2057,7 @@
       IncDecOperator operator,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_POSTFIX,
-        constant: constant.getText(), operator: operator));
+        constant: constant.toDartText(), operator: operator));
   }
 
   @override
@@ -2067,7 +2067,7 @@
       IncDecOperator operator,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_POSTFIX,
-        constant: constant.getText(), operator: operator));
+        constant: constant.toDartText(), operator: operator));
   }
 
   @override
@@ -2257,7 +2257,7 @@
       IncDecOperator operator,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_POSTFIX,
-        constant: constant.getText(), operator: operator));
+        constant: constant.toDartText(), operator: operator));
   }
 
   @override
@@ -2549,7 +2549,7 @@
       ConstructedConstantExpression constant,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_CONST_CONSTRUCTOR_INVOKE,
-                         constant: constant.getText()));
+                         constant: constant.toDartText()));
     super.visitConstConstructorInvoke(node, constant, arg);
   }
 
@@ -2560,7 +2560,7 @@
       arg) {
     visits.add(new Visit(
         VisitKind.VISIT_BOOL_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
-        constant: constant.getText()));
+        constant: constant.toDartText()));
     super.visitBoolFromEnvironmentConstructorInvoke(node, constant, arg);
   }
 
@@ -2571,7 +2571,7 @@
       arg) {
     visits.add(new Visit(
         VisitKind.VISIT_INT_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
-        constant: constant.getText()));
+        constant: constant.toDartText()));
     super.visitIntFromEnvironmentConstructorInvoke(node, constant, arg);
   }
 
@@ -2582,7 +2582,7 @@
       arg) {
     visits.add(new Visit(
         VisitKind.VISIT_STRING_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
-        constant: constant.getText()));
+        constant: constant.toDartText()));
     super.visitStringFromEnvironmentConstructorInvoke(node, constant, arg);
   }
 
@@ -3086,7 +3086,7 @@
       ConstantExpression constant,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_CONSTANT_GET,
-        constant: constant.getText()));
+        constant: constant.toDartText()));
     super.visitConstantGet(node, constant, arg);
   }
 
@@ -3098,7 +3098,7 @@
       CallStructure callStructure,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_CONSTANT_INVOKE,
-        constant: constant.getText()));
+        constant: constant.toDartText()));
     super.visitConstantInvoke(node, constant, arguments, callStructure, arg);
   }
 
@@ -3117,7 +3117,7 @@
       Node rhs,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_SET_IF_NULL,
-        constant: constant.getText(), rhs: rhs));
+        constant: constant.toDartText(), rhs: rhs));
     super.visitClassTypeLiteralSetIfNull(node, constant, rhs, arg);
   }
 
@@ -3140,7 +3140,7 @@
       Node rhs,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_SET_IF_NULL,
-        constant: constant.getText(), rhs: rhs));
+        constant: constant.toDartText(), rhs: rhs));
     super.visitDynamicTypeLiteralSetIfNull(node, constant, rhs, arg);
   }
 
@@ -3450,7 +3450,7 @@
       Node rhs,
       arg) {
     visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_SET_IF_NULL,
-        constant: constant.getText(), rhs: rhs));
+        constant: constant.toDartText(), rhs: rhs));
     super.visitTypedefTypeLiteralSetIfNull(node, constant, rhs, arg);
   }
 
diff --git a/tests/compiler/dart2js/serialization_test.dart b/tests/compiler/dart2js/serialization_test.dart
index 9d15022..7edeb4c 100644
--- a/tests/compiler/dart2js/serialization_test.dart
+++ b/tests/compiler/dart2js/serialization_test.dart
@@ -440,11 +440,9 @@
           element1.isConst, element2.isConst);
     check(element1, element2, 'isFinal',
           element1.isFinal, element2.isFinal);
-    if (element1.isConst) {
-      checkConstants(
-          element1, element2, 'constant',
-          element1.constant, element2.constant);
-    }
+    checkConstants(
+        element1, element2, 'constant',
+        element1.constant, element2.constant);
     check(element1, element2, 'isTopLevel',
           element1.isTopLevel, element2.isTopLevel);
     check(element1, element2, 'isStatic',
diff --git a/tests/compiler/dart2js/serialization_test_helper.dart b/tests/compiler/dart2js/serialization_test_helper.dart
index 4ee842d..0c871a8 100644
--- a/tests/compiler/dart2js/serialization_test_helper.dart
+++ b/tests/compiler/dart2js/serialization_test_helper.dart
@@ -105,8 +105,12 @@
            [bool equivalence(a, b) = equality]) {
   if (!equivalence(value1, value2)) {
     throw "property='$property'\n "
-          "object1=$object1 (${object1.runtimeType})\n value='${value1}' <>\n "
-          "object2=$object2 (${object2.runtimeType})\n value='${value2}'";
+          "object1=$object1 (${object1.runtimeType})\n "
+          "value=${value1 == null ? "null" : "'$value1'"} "
+          "(${value1.runtimeType}) <>\n "
+          "object2=$object2 (${object2.runtimeType})\n "
+          "value=${value2 == null ? "null" : "'$value2'"} "
+          "(${value2.runtimeType})";
   }
   return true;
 }
diff --git a/tests/compiler/dart2js_extra/26243_test.dart b/tests/compiler/dart2js_extra/26243_test.dart
new file mode 100644
index 0000000..156f54d
--- /dev/null
+++ b/tests/compiler/dart2js_extra/26243_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+var trace = [];
+void write(String s, int a, int b) {
+  trace.add("$s $a $b");
+}
+
+void foo() {
+  var i = 0;
+  write("foo", i, i += 1);
+}
+
+void bar() {
+  var i = 0;
+  try {
+    write("bar", i, i += 1);
+  } catch (_) {}
+}
+
+void baz() {
+  var i = 0;
+  write("baz-notry", i, i += 1);
+
+  i = 0;
+  try {
+    write("baz-try", i, i += 1);
+  } catch (_) {}
+}
+
+void main() {
+  foo();
+  bar();
+  baz();
+  Expect.listEquals(['foo 0 1', 'bar 0 1', 'baz-notry 0 1', 'baz-try 0 1'],
+      trace);
+}
diff --git a/tools/VERSION b/tools/VERSION
index 24fcc60..57ab3a2 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 1
 MINOR 17
 PATCH 0
-PRERELEASE 0
+PRERELEASE 1
 PRERELEASE_PATCH 0
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index 2eb609e..f4ddd0c 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -8,7 +8,7 @@
 # Now we need to override some settings and add some new ones.
 
 vars.update({
-  "dartium_chromium_commit": "c2d1ddba7a86ce11a8dcb77a4ac101872d6110bd",
+  "dartium_chromium_commit": "18554681ff1dfb53a553375c1b0c641fb3d63a1a",
   "dartium_webkit_commit": "1ebe477439d73297f0e6090b474fd9b761407434",
   "chromium_base_revision": "338390",