diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index a8fa140..5f3d560 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -46,6 +46,12 @@
   UInt length;
   T[length] items;
 }
+
+// Untagged pairs.
+type Pair<T0, T1> {
+  T0 first;
+  T1 second;
+}
 ```
 
 A string table consists of an array of end offsets and a payload array of
@@ -346,6 +352,7 @@
 type VariableGet extends Expression {
   Byte tag = 20;
   FileOffset fileOffset;
+  UInt variableDeclarationPosition; // Byte offset in the binary for the variable declaration.
   VariableReference variable;
 }
 
@@ -353,11 +360,13 @@
   Byte tag = 128 + N; // Where 0 <= N < 8.
   // Equivalent to a VariableGet with index N.
   FileOffset fileOffset;
+  UInt variableDeclarationPosition; // Byte offset in the binary for the variable declaration.
 }
 
 type VariableSet extends Expression {
   Byte tag = 21;
   FileOffset fileOffset;
+  UInt variableDeclarationPosition; // Byte offset in the binary for the variable declaration.
   VariableReference variable;
   Expression value;
 }
@@ -365,6 +374,7 @@
 type SpecializedVariableSet extends Expression {
   Byte tag = 136 + N; // Where 0 <= N < 8.
   FileOffset fileOffset;
+  UInt variableDeclarationPosition; // Byte offset in the binary for the variable declaration.
   Expression value;
   // Equivalent to VariableSet with index N.
 }
@@ -429,6 +439,7 @@
 
 type Arguments {
   // Note: there is no tag on Arguments.
+  UInt numArguments; // equals positional.length + named.length
   List<DartType> types;
   List<Expression> positional;
   List<NamedExpression> named;
@@ -782,8 +793,7 @@
 
 type SwitchCase {
   // Note: there is no tag on SwitchCase
-  List<Expression> expressions;
-  FileOffset[expressions.length] expressionOffsets; // 1-to-1 with expressions.
+  List<Pair<FileOffset, Expression>> expressions;
   Byte isDefault; // 1 if default, 0 is not default.
   Statement body;
 }
@@ -819,6 +829,7 @@
 type TryCatch extends Statement {
   Byte tag = 75;
   Statement body;
+  Byte anyCatchNeedsStackTrace; // 1 if any catch needs a stacktrace (have a stacktrace variable).
   List<Catch> catches;
 }
 
@@ -910,6 +921,7 @@
   Byte tag = 94;
   List<TypeParameter> typeParameters;
   UInt requiredParameterCount;
+  UInt totalParameterCount; // positionalParameters.length + namedParameters.length
   List<DartType> positionalParameters;
   List<NamedDartType> namedParameters;
   DartType returnType;
@@ -949,7 +961,10 @@
   // the class type parameters in a constructor refer to those declared on the
   // class.
   UInt index;
-  
+
+  // Byte offset in the binary for the type declaration.
+  // Note: This can also be 0, which is a 'forward reference' and is not to be used.
+  UInt typeParameterPosition;
   Option<DartType> bound;
 }
 
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 59fc9ed..c1b6670 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -3586,6 +3586,9 @@
   int flags = 0;
   DartType type; // Not null, defaults to dynamic.
 
+  /// Offset of the declaration, set and used when writing the binary.
+  int binaryOffset = -1;
+
   /// For locals, this is the initial value.
   /// For parameters, this is the default value.
   ///
@@ -4169,6 +4172,9 @@
   /// be set to the root class for type parameters without an explicit bound.
   DartType bound;
 
+  /// Offset of the declaration, set and used when writing the binary.
+  int binaryOffset = 0;
+
   TypeParameter([this.name, this.bound]);
 
   accept(TreeVisitor v) => v.visitTypeParameter(this);
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index e5af2a3..db11ce4 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -665,19 +665,23 @@
         return new InvalidExpression();
       case Tag.VariableGet:
         int offset = readOffset();
+        readUInt(); // offset of the variable declaration in the binary.
         return new VariableGet(readVariableReference(), readDartTypeOption())
           ..fileOffset = offset;
       case Tag.SpecializedVariableGet:
         int index = tagByte & Tag.SpecializedPayloadMask;
         int offset = readOffset();
+        readUInt(); // offset of the variable declaration in the binary.
         return new VariableGet(variableStack[index])..fileOffset = offset;
       case Tag.VariableSet:
         int offset = readOffset();
+        readUInt(); // offset of the variable declaration in the binary.
         return new VariableSet(readVariableReference(), readExpression())
           ..fileOffset = offset;
       case Tag.SpecializedVariableSet:
         int index = tagByte & Tag.SpecializedPayloadMask;
         int offset = readOffset();
+        readUInt(); // offset of the variable declaration in the binary.
         return new VariableSet(variableStack[index], readExpression())
           ..fileOffset = offset;
       case Tag.PropertyGet:
@@ -949,10 +953,12 @@
         switchCaseStack.addAll(cases);
         for (int i = 0; i < cases.length; ++i) {
           var caseNode = cases[i];
-          _fillTreeNodeList(caseNode.expressions, readExpression, caseNode);
-          caseNode.expressionOffsets.length = caseNode.expressions.length;
-          for (int i = 0; i < caseNode.expressionOffsets.length; ++i) {
+          int length = readUInt();
+          caseNode.expressions.length = length;
+          caseNode.expressionOffsets.length = length;
+          for (int i = 0; i < length; ++i) {
             caseNode.expressionOffsets[i] = readOffset();
+            caseNode.expressions[i] = readExpression()..parent = caseNode;
           }
           caseNode.isDefault = readByte() == 1;
           caseNode.body = readStatement()..parent = caseNode;
@@ -969,7 +975,9 @@
         int offset = readOffset();
         return new ReturnStatement(readExpressionOption())..fileOffset = offset;
       case Tag.TryCatch:
-        return new TryCatch(readStatement(), readCatchList());
+        Statement body = readStatement();
+        readByte(); // whether any catch needs a stacktrace.
+        return new TryCatch(body, readCatchList());
       case Tag.TryFinally:
         return new TryFinally(readStatement(), readStatement());
       case Tag.YieldStatement:
@@ -1070,8 +1078,10 @@
         int typeParameterStackHeight = typeParameterStack.length;
         var typeParameters = readAndPushTypeParameterList();
         var requiredParameterCount = readUInt();
+        var totalParameterCount = readUInt();
         var positional = readDartTypeList();
         var named = readNamedTypeList();
+        assert(positional.length + named.length == totalParameterCount);
         var returnType = readDartType();
         typeParameterStack.length = typeParameterStackHeight;
         return new FunctionType(positional, returnType,
@@ -1084,6 +1094,7 @@
         return new FunctionType(positional, returnType);
       case Tag.TypeParameterType:
         int index = readUInt();
+        readUInt(); // offset of the TypeParameter declaration in the binary.
         var bound = readDartTypeOption();
         return new TypeParameterType(typeParameterStack[index], bound);
       default:
@@ -1117,9 +1128,11 @@
   }
 
   Arguments readArguments() {
+    var numArguments = readUInt();
     var typeArguments = readDartTypeList();
     var positional = readExpressionList();
     var named = readNamedExpressionList();
+    assert(numArguments == positional.length + named.length);
     return new Arguments(positional, types: typeArguments, named: named);
   }
 
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index cdc92ea..0edfdd8 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -404,7 +404,7 @@
 
   visitLocalInitializer(LocalInitializer node) {
     writeByte(Tag.LocalInitializer);
-    writeVariableDeclaration(node.variable);
+    writeVariableDeclaration(node.variable, false);
   }
 
   visitFunctionNode(FunctionNode node) {
@@ -444,9 +444,11 @@
         node.promotedType == null) {
       writeByte(Tag.SpecializedVariableGet + index);
       writeOffset(node.fileOffset);
+      writeUInt30(node.variable.binaryOffset);
     } else {
       writeByte(Tag.VariableGet);
       writeOffset(node.fileOffset);
+      writeUInt30(node.variable.binaryOffset);
       writeUInt30(_variableIndexer[node.variable]);
       writeOptionalNode(node.promotedType);
     }
@@ -458,10 +460,12 @@
     if (index & Tag.SpecializedPayloadMask == index) {
       writeByte(Tag.SpecializedVariableSet + index);
       writeOffset(node.fileOffset);
+      writeUInt30(node.variable.binaryOffset);
       writeNode(node.value);
     } else {
       writeByte(Tag.VariableSet);
       writeOffset(node.fileOffset);
+      writeUInt30(node.variable.binaryOffset);
       writeUInt30(_variableIndexer[node.variable]);
       writeNode(node.value);
     }
@@ -566,6 +570,7 @@
   }
 
   visitArguments(Arguments node) {
+    writeUInt30(node.positional.length + node.named.length);
     writeNodeList(node.types);
     writeNodeList(node.positional);
     writeNodeList(node.named);
@@ -724,7 +729,7 @@
 
   visitLet(Let node) {
     writeByte(Tag.Let);
-    writeVariableDeclaration(node.variable);
+    writeVariableDeclaration(node.variable, false);
     writeNode(node.body);
     --_variableIndexer.stackHeight;
   }
@@ -842,7 +847,7 @@
     _variableIndexer.pushScope();
     writeByte(node.isAsync ? Tag.AsyncForInStatement : Tag.ForInStatement);
     writeOffset(node.fileOffset);
-    writeVariableDeclaration(node.variable);
+    writeVariableDeclaration(node.variable, false);
     writeNode(node.iterable);
     writeNode(node.body);
     _variableIndexer.popScope();
@@ -858,8 +863,12 @@
 
   visitSwitchCase(SwitchCase node) {
     // Note: there is no tag on SwitchCase.
-    writeNodeList(node.expressions);
-    node.expressionOffsets.forEach(writeOffset);
+    int length = node.expressions.length;
+    writeUInt30(length);
+    for (int i = 0; i < length; ++i) {
+      writeOffset(node.expressionOffsets[i]);
+      writeNode(node.expressions[i]);
+    }
     writeByte(node.isDefault ? 1 : 0);
     writeNode(node.body);
   }
@@ -885,6 +894,13 @@
   visitTryCatch(TryCatch node) {
     writeByte(Tag.TryCatch);
     writeNode(node.body);
+    if (node.catches.any((Catch c) => c.stackTrace != null)) {
+      // at least one catch needs the stack trace.
+      writeByte(1);
+    } else {
+      // no catch needs the stack trace.
+      writeByte(0);
+    }
     writeNodeList(node.catches);
   }
 
@@ -912,11 +928,13 @@
   }
 
   visitVariableDeclaration(VariableDeclaration node) {
-    writeByte(Tag.VariableDeclaration);
-    writeVariableDeclaration(node);
+    writeVariableDeclaration(node, true);
   }
 
-  void writeVariableDeclaration(VariableDeclaration node) {
+  void writeVariableDeclaration(VariableDeclaration node,
+      [bool hasTag = false]) {
+    node.binaryOffset = _sink.flushedLength + _sink.length;
+    if (hasTag) writeByte(Tag.VariableDeclaration);
     writeOffset(node.fileOffset);
     writeOffset(node.fileEqualsOffset);
     writeByte(node.flags);
@@ -937,14 +955,14 @@
       writeByte(Tag.Nothing);
     } else {
       writeByte(Tag.Something);
-      writeVariableDeclaration(node);
+      writeVariableDeclaration(node, false);
     }
   }
 
   visitFunctionDeclaration(FunctionDeclaration node) {
     writeByte(Tag.FunctionDeclaration);
     writeOffset(node.fileOffset);
-    writeVariableDeclaration(node.variable);
+    writeVariableDeclaration(node.variable, false);
     writeNode(node.function);
   }
 
@@ -998,6 +1016,8 @@
       _typeParameterIndexer.enter(node.typeParameters);
       writeNodeList(node.typeParameters);
       writeUInt30(node.requiredParameterCount);
+      writeUInt30(
+          node.positionalParameters.length + node.namedParameters.length);
       writeNodeList(node.positionalParameters);
       writeNodeList(node.namedParameters);
       writeNode(node.returnType);
@@ -1013,6 +1033,7 @@
   visitTypeParameterType(TypeParameterType node) {
     writeByte(Tag.TypeParameterType);
     writeUInt30(_typeParameterIndexer[node.parameter]);
+    writeUInt30(node.parameter.binaryOffset);
     writeOptionalNode(node.bound);
   }
 
@@ -1027,6 +1048,7 @@
   }
 
   visitTypeParameter(TypeParameter node) {
+    node.binaryOffset = _sink.flushedLength + _sink.length;
     writeStringReference(node.name ?? '');
     writeNode(node.bound);
   }
@@ -1307,6 +1329,7 @@
   final Sink<List<int>> _sink;
   Uint8List _buffer = new Uint8List(SIZE);
   int length = 0;
+  int flushedLength = 0;
 
   BufferedSink(this._sink);
 
@@ -1316,6 +1339,7 @@
       _sink.add(_buffer);
       _buffer = new Uint8List(SIZE);
       length = 0;
+      flushedLength += SIZE;
     }
   }
 
@@ -1326,6 +1350,7 @@
         (bytes.length < SMALL || length < SMALL)) {
       if (length == 0) {
         _sink.add(bytes);
+        flushedLength += bytes.length;
       } else {
         _buffer.setRange(length, length + bytes.length, bytes);
         length += bytes.length;
@@ -1341,10 +1366,13 @@
       _buffer = new Uint8List(SIZE);
       _buffer.setRange(0, remainder, bytes, alreadyEmitted);
       length = remainder;
+      flushedLength += SIZE;
     } else {
       _sink.add(_buffer.sublist(0, length));
       _sink.add(bytes);
       _buffer = new Uint8List(SIZE);
+      flushedLength += length;
+      flushedLength += bytes.length;
       length = 0;
     }
   }
@@ -1352,6 +1380,7 @@
   void flush() {
     _sink.add(_buffer.sublist(0, length));
     _buffer = new Uint8List(SIZE);
+    flushedLength += length;
     length = 0;
   }
 
diff --git a/runtime/vm/kernel.h b/runtime/vm/kernel.h
index 5125d44..54c794a 100644
--- a/runtime/vm/kernel.h
+++ b/runtime/vm/kernel.h
@@ -230,6 +230,13 @@
 
   T** raw_array() { return array_; }
 
+  bool CanStream() {
+    for (intptr_t i = 0; i < length_; ++i) {
+      if (!array_[i]->can_stream()) return false;
+    }
+    return true;
+  }
+
  private:
   T** array_;
   int length_;
@@ -387,14 +394,17 @@
   virtual void AcceptVisitor(Visitor* visitor);
   virtual void AcceptTreeVisitor(TreeVisitor* visitor) = 0;
   intptr_t kernel_offset() const { return kernel_offset_; }
+  bool can_stream() { return can_stream_; }
 
  protected:
-  TreeNode() : kernel_offset_(-1) {}
+  TreeNode() : kernel_offset_(-1), can_stream_(true) {}
 
   // Offset for this node in the kernel-binary. If this node has a tag the
   // offset includes the tag. Can be -1 to indicate "unknown" or invalid offset.
   intptr_t kernel_offset_;
 
+  bool can_stream_;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(TreeNode);
 };
@@ -1018,6 +1028,7 @@
   VariableGet() {}
 
   Ref<VariableDeclaration> variable_;
+  intptr_t variable_kernel_offset_;
 
   DISALLOW_COPY_AND_ASSIGN(VariableGet);
 };
@@ -1042,6 +1053,7 @@
   VariableSet() {}
 
   Ref<VariableDeclaration> variable_;
+  intptr_t variable_kernel_offset_;
   Child<Expression> expression_;
 
   DISALLOW_COPY_AND_ASSIGN(VariableSet);
@@ -1152,7 +1164,9 @@
 
 class StaticGet : public Expression {
  public:
-  explicit StaticGet(NameIndex target) : target_reference_(target) {}
+  StaticGet(NameIndex target, bool can_stream) : target_reference_(target) {
+    can_stream_ = can_stream;
+  }
 
   static StaticGet* ReadFrom(Reader* reader);
 
@@ -2174,12 +2188,12 @@
   virtual void AcceptStatementVisitor(StatementVisitor* visitor);
   virtual void VisitChildren(Visitor* visitor);
 
-  LabeledStatement* target() { return target_; }
+  intptr_t target_index() { return target_index_; }
 
  private:
   BreakStatement() {}
 
-  Ref<LabeledStatement> target_;
+  intptr_t target_index_;
 
   DISALLOW_COPY_AND_ASSIGN(BreakStatement);
 };
@@ -2365,12 +2379,12 @@
   virtual void AcceptStatementVisitor(StatementVisitor* visitor);
   virtual void VisitChildren(Visitor* visitor);
 
-  SwitchCase* target() { return target_; }
+  intptr_t target_index() { return target_index_; }
 
  private:
   ContinueSwitchStatement() {}
 
-  Ref<SwitchCase> target_;
+  intptr_t target_index_;
 
   DISALLOW_COPY_AND_ASSIGN(ContinueSwitchStatement);
 };
@@ -2404,7 +2418,10 @@
 
 class ReturnStatement : public Statement {
  public:
-  explicit ReturnStatement(Expression* expression) : expression_(expression) {}
+  ReturnStatement(Expression* expression, bool can_stream)
+      : expression_(expression) {
+    can_stream_ = can_stream;
+  }
 
   static ReturnStatement* ReadFrom(Reader* reader);
 
diff --git a/runtime/vm/kernel_binary.cc b/runtime/vm/kernel_binary.cc
index 55cee46..220355d 100644
--- a/runtime/vm/kernel_binary.cc
+++ b/runtime/vm/kernel_binary.cc
@@ -201,6 +201,10 @@
 
   fields().ReadFrom<Field>(reader, this);
   procedures().ReadFrom<Procedure>(reader, this);
+
+  can_stream_ =
+      classes().CanStream() && fields().CanStream() && procedures().CanStream();
+
   return this;
 }
 
@@ -231,6 +235,8 @@
   reader->record_token_position(position_);
   annotations_.ReadFromStatic<Expression>(reader);
 
+  can_stream_ = annotations_.CanStream();
+
   return this;
 }
 
@@ -251,6 +257,9 @@
   constructors_.ReadFrom<Constructor>(reader, this);
   procedures_.ReadFrom<Procedure>(reader, this);
 
+  can_stream_ = can_stream_ && fields_.CanStream() &&
+                constructors_.CanStream() && procedures_.CanStream();
+
   return this;
 }
 
@@ -266,6 +275,9 @@
   implemented_classes_.ReadFromStatic<DowncastReader<DartType, InterfaceType> >(
       reader);
   constructors_.ReadFrom<Constructor>(reader, this);
+
+  can_stream_ = constructors_.CanStream();
+
   return this;
 }
 
@@ -318,6 +330,10 @@
   annotations_.ReadFromStatic<Expression>(reader);
   type_ = DartType::ReadFrom(reader);
   initializer_ = reader->ReadOptional<Expression>();
+
+  can_stream_ = (initializer_ == NULL || initializer_->can_stream()) &&
+                annotations_.CanStream();
+
   return this;
 }
 
@@ -336,6 +352,10 @@
   annotations_.ReadFromStatic<Expression>(reader);
   function_ = FunctionNode::ReadFrom(reader);
   initializers_.ReadFromStatic<Initializer>(reader);
+
+  can_stream_ = annotations_.CanStream() && function_->can_stream() &&
+                initializers_.CanStream();
+
   return this;
 }
 
@@ -358,6 +378,10 @@
   reader->record_token_position(end_position_);
   annotations_.ReadFromStatic<Expression>(reader);
   function_ = reader->ReadOptional<FunctionNode>();
+
+  can_stream_ = annotations_.CanStream() &&
+                (function_ == NULL || function_->can_stream());
+
   return this;
 }
 
@@ -394,6 +418,9 @@
   FieldInitializer* initializer = new FieldInitializer();
   initializer->field_reference_ = Reference::ReadMemberFrom(reader);
   initializer->value_ = Expression::ReadFrom(reader);
+
+  initializer->can_stream_ = initializer->value_->can_stream();
+
   return initializer;
 }
 
@@ -403,6 +430,9 @@
   SuperInitializer* init = new SuperInitializer();
   init->target_reference_ = Reference::ReadMemberFrom(reader);
   init->arguments_ = Arguments::ReadFrom(reader);
+
+  init->can_stream_ = init->arguments_->can_stream();
+
   return init;
 }
 
@@ -412,6 +442,9 @@
   RedirectingInitializer* init = new RedirectingInitializer();
   init->target_reference_ = Reference::ReadMemberFrom(reader);
   init->arguments_ = Arguments::ReadFrom(reader);
+
+  init->can_stream_ = init->arguments_->can_stream();
+
   return init;
 }
 
@@ -420,6 +453,9 @@
   TRACE_READ_OFFSET();
   LocalInitializer* init = new LocalInitializer();
   init->variable_ = VariableDeclaration::ReadFromImpl(reader, false);
+
+  init->can_stream_ = init->variable_->can_stream();
+
   return init;
 }
 
@@ -548,7 +584,9 @@
   VariableGet* get = new VariableGet();
   get->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
   get->position_ = reader->ReadPosition();
+  get->variable_kernel_offset_ = reader->ReadUInt();
   get->variable_ = reader->helper()->variables().Lookup(reader->ReadUInt());
+  ASSERT(get->variable_->kernel_offset() == get->variable_kernel_offset_);
   reader->ReadOptional<DartType>();  // Unused promoted type.
   return get;
 }
@@ -559,7 +597,9 @@
   VariableGet* get = new VariableGet();
   get->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
   get->position_ = reader->ReadPosition();
+  get->variable_kernel_offset_ = reader->ReadUInt();
   get->variable_ = reader->helper()->variables().Lookup(payload);
+  ASSERT(get->variable_->kernel_offset() == get->variable_kernel_offset_);
   return get;
 }
 
@@ -569,8 +609,13 @@
   VariableSet* set = new VariableSet();
   set->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
   set->position_ = reader->ReadPosition();
+  set->variable_kernel_offset_ = reader->ReadUInt();
   set->variable_ = reader->helper()->variables().Lookup(reader->ReadUInt());
+  ASSERT(set->variable_->kernel_offset() == set->variable_kernel_offset_);
   set->expression_ = Expression::ReadFrom(reader);
+
+  set->can_stream_ = set->expression_->can_stream();
+
   return set;
 }
 
@@ -581,7 +626,12 @@
   set->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
   set->variable_ = reader->helper()->variables().Lookup(payload);
   set->position_ = reader->ReadPosition();
+  set->variable_kernel_offset_ = reader->ReadUInt();
+  ASSERT(set->variable_->kernel_offset() == set->variable_kernel_offset_);
   set->expression_ = Expression::ReadFrom(reader);
+
+  set->can_stream_ = set->expression_->can_stream();
+
   return set;
 }
 
@@ -594,6 +644,9 @@
   get->receiver_ = Expression::ReadFrom(reader);
   get->name_ = Name::ReadFrom(reader);
   get->interface_target_reference_ = Reference::ReadMemberFrom(reader, true);
+
+  get->can_stream_ = get->receiver_->can_stream();
+
   return get;
 }
 
@@ -607,6 +660,9 @@
   set->name_ = Name::ReadFrom(reader);
   set->value_ = Expression::ReadFrom(reader);
   set->interface_target_reference_ = Reference::ReadMemberFrom(reader, true);
+
+  set->can_stream_ = set->receiver_->can_stream() && set->value_->can_stream();
+
   return set;
 }
 
@@ -618,6 +674,9 @@
   get->position_ = reader->ReadPosition();
   get->receiver_ = Expression::ReadFrom(reader);
   get->target_reference_ = Reference::ReadMemberFrom(reader);
+
+  get->can_stream_ = get->receiver_->can_stream();
+
   return get;
 }
 
@@ -630,6 +689,9 @@
   set->receiver_ = Expression::ReadFrom(reader);
   set->target_reference_ = Reference::ReadMemberFrom(reader);
   set->value_ = Expression::ReadFrom(reader);
+
+  set->can_stream_ = set->receiver_->can_stream() && set->value_->can_stream();
+
   return set;
 }
 
@@ -651,6 +713,9 @@
   set->position_ = reader->ReadPosition();
   set->target_reference_ = Reference::ReadMemberFrom(reader);
   set->expression_ = Expression::ReadFrom(reader);
+
+  set->can_stream_ = set->expression_->can_stream();
+
   return set;
 }
 
@@ -658,9 +723,15 @@
 Arguments* Arguments::ReadFrom(Reader* reader) {
   TRACE_READ_OFFSET();
   Arguments* arguments = new Arguments();
+  intptr_t num_arguments = reader->ReadUInt();
   arguments->types().ReadFromStatic<DartType>(reader);
   arguments->positional().ReadFromStatic<Expression>(reader);
   arguments->named().ReadFromStatic<NamedExpression>(reader);
+  ASSERT(arguments->count() == num_arguments);
+
+  arguments->can_stream_ =
+      arguments->positional().CanStream() && arguments->named().CanStream();
+
   return arguments;
 }
 
@@ -669,7 +740,11 @@
   TRACE_READ_OFFSET();
   StringIndex name_index(reader->ReadUInt());
   Expression* expression = Expression::ReadFrom(reader);
-  return new NamedExpression(name_index, expression);
+  NamedExpression* named = new NamedExpression(name_index, expression);
+
+  named->can_stream_ = expression->can_stream();
+
+  return named;
 }
 
 
@@ -683,6 +758,10 @@
   invocation->arguments_ = Arguments::ReadFrom(reader);
   invocation->interface_target_reference_ =
       Reference::ReadMemberFrom(reader, true);
+
+  invocation->can_stream_ = invocation->receiver_->can_stream() &&
+                            invocation->arguments_->can_stream();
+
   return invocation;
 }
 
@@ -694,6 +773,10 @@
   invocation->receiver_ = Expression::ReadFrom(reader);
   invocation->target_reference_ = Reference::ReadMemberFrom(reader);
   invocation->arguments_ = Arguments::ReadFrom(reader);
+
+  invocation->can_stream_ = invocation->receiver_->can_stream() &&
+                            invocation->arguments_->can_stream();
+
   return invocation;
 }
 
@@ -706,6 +789,9 @@
   invocation->position_ = reader->ReadPosition();
   invocation->procedure_reference_ = Reference::ReadMemberFrom(reader);
   invocation->arguments_ = Arguments::ReadFrom(reader);
+
+  invocation->can_stream_ = invocation->arguments_->can_stream();
+
   return invocation;
 }
 
@@ -719,6 +805,9 @@
   invocation->position_ = reader->ReadPosition();
   invocation->target_reference_ = Reference::ReadMemberFrom(reader);
   invocation->arguments_ = Arguments::ReadFrom(reader);
+
+  invocation->can_stream_ = invocation->arguments_->can_stream();
+
   return invocation;
 }
 
@@ -728,6 +817,9 @@
   Not* n = new Not();
   n->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
   n->expression_ = Expression::ReadFrom(reader);
+
+  n->can_stream_ = n->expression_->can_stream();
+
   return n;
 }
 
@@ -739,6 +831,9 @@
   expr->left_ = Expression::ReadFrom(reader);
   expr->operator_ = static_cast<Operator>(reader->ReadByte());
   expr->right_ = Expression::ReadFrom(reader);
+
+  expr->can_stream_ = expr->left_->can_stream() && expr->right_->can_stream();
+
   return expr;
 }
 
@@ -751,6 +846,11 @@
   expr->then_ = Expression::ReadFrom(reader);
   expr->otherwise_ = Expression::ReadFrom(reader);
   reader->ReadOptional<DartType>();  // Unused static type.
+
+  expr->can_stream_ = expr->condition_->can_stream() &&
+                      expr->then_->can_stream() &&
+                      expr->otherwise_->can_stream();
+
   return expr;
 }
 
@@ -761,6 +861,9 @@
   concat->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
   concat->position_ = reader->ReadPosition();
   concat->expressions_.ReadFromStatic<Expression>(reader);
+
+  concat->can_stream_ = concat->expressions_.CanStream();
+
   return concat;
 }
 
@@ -772,6 +875,9 @@
   expr->position_ = reader->ReadPosition();
   expr->operand_ = Expression::ReadFrom(reader);
   expr->type_ = DartType::ReadFrom(reader);
+
+  expr->can_stream_ = expr->operand_->can_stream();
+
   return expr;
 }
 
@@ -783,6 +889,9 @@
   expr->position_ = reader->ReadPosition();
   expr->operand_ = Expression::ReadFrom(reader);
   expr->type_ = DartType::ReadFrom(reader);
+
+  expr->can_stream_ = expr->operand_->can_stream();
+
   return expr;
 }
 
@@ -891,6 +1000,9 @@
   t->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
   t->position_ = reader->ReadPosition();
   t->expression_ = Expression::ReadFrom(reader);
+
+  t->can_stream_ = t->expression_->can_stream();
+
   return t;
 }
 
@@ -903,6 +1015,9 @@
   literal->position_ = reader->ReadPosition();
   literal->type_ = DartType::ReadFrom(reader);
   literal->expressions_.ReadFromStatic<Expression>(reader);
+
+  literal->can_stream_ = literal->expressions_.CanStream();
+
   return literal;
 }
 
@@ -916,6 +1031,9 @@
   literal->key_type_ = DartType::ReadFrom(reader);
   literal->value_type_ = DartType::ReadFrom(reader);
   literal->entries_.ReadFromStatic<MapEntry>(reader);
+
+  literal->can_stream_ = literal->entries_.CanStream();
+
   return literal;
 }
 
@@ -924,6 +1042,9 @@
   MapEntry* entry = new MapEntry();
   entry->key_ = Expression::ReadFrom(reader);
   entry->value_ = Expression::ReadFrom(reader);
+
+  entry->can_stream_ = entry->key_->can_stream() && entry->value_->can_stream();
+
   return entry;
 }
 
@@ -933,6 +1054,9 @@
   AwaitExpression* await = new AwaitExpression();
   await->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
   await->operand_ = Expression::ReadFrom(reader);
+
+  await->can_stream_ = await->operand_->can_stream();
+
   return await;
 }
 
@@ -943,6 +1067,9 @@
   FunctionExpression* expr = new FunctionExpression();
   expr->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
   expr->function_ = FunctionNode::ReadFrom(reader);
+
+  expr->can_stream_ = false;
+
   return expr;
 }
 
@@ -959,6 +1086,8 @@
   let->position_ = reader->min_position();
   let->end_position_ = reader->max_position();
 
+  let->can_stream_ = let->variable_->can_stream() && let->body_->can_stream();
+
   return let;
 }
 
@@ -983,6 +1112,8 @@
   vector_get->vector_expression_ = Expression::ReadFrom(reader);
   vector_get->index_ = reader->ReadUInt();
 
+  vector_get->can_stream_ = false;
+
   return vector_get;
 }
 
@@ -996,6 +1127,8 @@
   vector_set->index_ = reader->ReadUInt();
   vector_set->value_ = Expression::ReadFrom(reader);
 
+  vector_set->can_stream_ = false;
+
   return vector_set;
 }
 
@@ -1008,6 +1141,8 @@
       reader->offset() - 1;  // -1 to include tag byte.
   vector_copy->vector_expression_ = Expression::ReadFrom(reader);
 
+  vector_copy->can_stream_ = false;
+
   return vector_copy;
 }
 
@@ -1024,6 +1159,8 @@
   closure_creation->function_type_ =
       FunctionType::Cast(DartType::ReadFrom(reader));
 
+  closure_creation->can_stream_ = false;
+
   return closure_creation;
 }
 
@@ -1083,13 +1220,22 @@
 
 InvalidStatement* InvalidStatement::ReadFrom(Reader* reader) {
   TRACE_READ_OFFSET();
-  return new InvalidStatement();
+  InvalidStatement* stmt = new InvalidStatement();
+  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
+  return stmt;
 }
 
 
 ExpressionStatement* ExpressionStatement::ReadFrom(Reader* reader) {
   TRACE_READ_OFFSET();
-  return new ExpressionStatement(Expression::ReadFrom(reader));
+  intptr_t offset = reader->offset() - 1;  // -1 to include tag byte.
+  ExpressionStatement* stmt =
+      new ExpressionStatement(Expression::ReadFrom(reader));
+  stmt->kernel_offset_ = offset;
+
+  stmt->can_stream_ = stmt->expression_->can_stream();
+
+  return stmt;
 }
 
 
@@ -1104,21 +1250,30 @@
   block->position_ = reader->min_position();
   block->end_position_ = reader->max_position();
 
+  block->can_stream_ = block->statements().CanStream();
+
   return block;
 }
 
 
 EmptyStatement* EmptyStatement::ReadFrom(Reader* reader) {
   TRACE_READ_OFFSET();
-  return new EmptyStatement();
+  EmptyStatement* stmt = new EmptyStatement();
+  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
+  return stmt;
 }
 
 
 AssertStatement* AssertStatement::ReadFrom(Reader* reader) {
   TRACE_READ_OFFSET();
   AssertStatement* stmt = new AssertStatement();
+  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
   stmt->condition_ = Expression::ReadFrom(reader);
   stmt->message_ = reader->ReadOptional<Expression>();
+
+  stmt->can_stream_ = stmt->condition_->can_stream() &&
+                      (stmt->message_ == NULL || stmt->message_->can_stream());
+
   return stmt;
 }
 
@@ -1126,9 +1281,14 @@
 LabeledStatement* LabeledStatement::ReadFrom(Reader* reader) {
   TRACE_READ_OFFSET();
   LabeledStatement* stmt = new LabeledStatement();
+  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
+
   reader->helper()->labels()->Push(stmt);
   stmt->body_ = Statement::ReadFrom(reader);
   reader->helper()->labels()->Pop(stmt);
+
+  stmt->can_stream_ = stmt->body_->can_stream();
+
   return stmt;
 }
 
@@ -1136,8 +1296,9 @@
 BreakStatement* BreakStatement::ReadFrom(Reader* reader) {
   TRACE_READ_OFFSET();
   BreakStatement* stmt = new BreakStatement();
+  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
   stmt->position_ = reader->ReadPosition();
-  stmt->target_ = reader->helper()->labels()->Lookup(reader->ReadUInt());
+  stmt->target_index_ = reader->ReadUInt();
   return stmt;
 }
 
@@ -1145,8 +1306,13 @@
 WhileStatement* WhileStatement::ReadFrom(Reader* reader) {
   TRACE_READ_OFFSET();
   WhileStatement* stmt = new WhileStatement();
+  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
   stmt->condition_ = Expression::ReadFrom(reader);
   stmt->body_ = Statement::ReadFrom(reader);
+
+  stmt->can_stream_ =
+      stmt->condition_->can_stream() && stmt->body_->can_stream();
+
   return stmt;
 }
 
@@ -1154,8 +1320,13 @@
 DoStatement* DoStatement::ReadFrom(Reader* reader) {
   TRACE_READ_OFFSET();
   DoStatement* dostmt = new DoStatement();
+  dostmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
   dostmt->body_ = Statement::ReadFrom(reader);
   dostmt->condition_ = Expression::ReadFrom(reader);
+
+  dostmt->can_stream_ =
+      dostmt->body_->can_stream() && dostmt->condition_->can_stream();
+
   return dostmt;
 }
 
@@ -1174,6 +1345,11 @@
   forstmt->end_position_ = reader->max_position();
   forstmt->position_ = reader->min_position();
 
+  forstmt->can_stream_ =
+      forstmt->body_->can_stream() &&
+      (forstmt->condition_ == NULL || forstmt->condition_->can_stream()) &&
+      forstmt->variables_.CanStream() && forstmt->updates_.CanStream();
+
   return forstmt;
 }
 
@@ -1196,39 +1372,49 @@
   }
   forinstmt->variable_->set_end_position(forinstmt->position_);
 
+  forinstmt->can_stream_ = forinstmt->variable_->can_stream() &&
+                           forinstmt->iterable_->can_stream() &&
+                           forinstmt->body_->can_stream();
+
   return forinstmt;
 }
 
 
 SwitchStatement* SwitchStatement::ReadFrom(Reader* reader) {
   TRACE_READ_OFFSET();
-  SwitchCaseScope<ReaderHelper> scope(reader->helper());
   SwitchStatement* stmt = new SwitchStatement();
+  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
   stmt->condition_ = Expression::ReadFrom(reader);
-  // We need to explicitly create empty [SwitchCase]s first in order to add them
-  // to the [SwitchCaseScope]. This is necessary since a [Statement] in a switch
-  // case can refer to one defined later on.
   int count = reader->ReadUInt();
+  stmt->cases_.EnsureInitialized(count);
   for (intptr_t i = 0; i < count; i++) {
     SwitchCase* sc = stmt->cases_.GetOrCreate<SwitchCase>(i);
-    reader->helper()->switch_cases().Push(sc);
-  }
-  for (intptr_t i = 0; i < count; i++) {
-    SwitchCase* sc = stmt->cases_[i];
     sc->ReadFrom(reader);
   }
+
+  stmt->can_stream_ =
+      stmt->condition_->can_stream() && stmt->cases_.CanStream();
+
   return stmt;
 }
 
 
 SwitchCase* SwitchCase::ReadFrom(Reader* reader) {
   TRACE_READ_OFFSET();
-  expressions_.ReadFromStatic<Expression>(reader);
-  for (intptr_t i = 0; i < expressions_.length(); ++i) {
-    expressions_[i]->set_position(reader->ReadPosition());
+  int length = reader->ReadListLength();
+  expressions_.EnsureInitialized(length);
+
+  for (intptr_t i = 0; i < length; i++) {
+    ASSERT(expressions_[i] == NULL);
+    TokenPosition position = reader->ReadPosition();
+    expressions_[i] = Expression::ReadFrom(reader);
+    expressions_[i]->set_position(position);
   }
   is_default_ = reader->ReadBool();
   body_ = Statement::ReadFrom(reader);
+
+  can_stream_ = expressions_.CanStream() && body_->can_stream();
+
   return this;
 }
 
@@ -1236,7 +1422,9 @@
 ContinueSwitchStatement* ContinueSwitchStatement::ReadFrom(Reader* reader) {
   TRACE_READ_OFFSET();
   ContinueSwitchStatement* stmt = new ContinueSwitchStatement();
-  stmt->target_ = reader->helper()->switch_cases().Lookup(reader->ReadUInt());
+  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
+  stmt->target_index_ = reader->ReadUInt();
+
   return stmt;
 }
 
@@ -1244,9 +1432,15 @@
 IfStatement* IfStatement::ReadFrom(Reader* reader) {
   TRACE_READ_OFFSET();
   IfStatement* ifstmt = new IfStatement();
+  ifstmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
   ifstmt->condition_ = Expression::ReadFrom(reader);
   ifstmt->then_ = Statement::ReadFrom(reader);
   ifstmt->otherwise_ = Statement::ReadFrom(reader);
+
+  ifstmt->can_stream_ = ifstmt->condition_->can_stream() &&
+                        ifstmt->then_->can_stream() &&
+                        ifstmt->otherwise_->can_stream();
+
   return ifstmt;
 }
 
@@ -1254,8 +1448,13 @@
 ReturnStatement* ReturnStatement::ReadFrom(Reader* reader) {
   TRACE_READ_OFFSET();
   ReturnStatement* ret = new ReturnStatement();
+  ret->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
   ret->position_ = reader->ReadPosition();
   ret->expression_ = reader->ReadOptional<Expression>();
+
+  ret->can_stream_ =
+      (ret->expression_ == NULL || ret->expression_->can_stream());
+
   return ret;
 }
 
@@ -1265,10 +1464,14 @@
   PositionScope scope(reader);
 
   TryCatch* tc = new TryCatch();
+  tc->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
   tc->body_ = Statement::ReadFrom(reader);
+  reader->ReadBool();  // whether any catch needs a stacktrace.
   tc->catches_.ReadFromStatic<Catch>(reader);
   tc->position_ = reader->min_position();
 
+  tc->can_stream_ = tc->body_->can_stream() && tc->catches_.CanStream();
+
   return tc;
 }
 
@@ -1289,6 +1492,8 @@
   c->end_position_ = reader->max_position();
   c->position_ = reader->min_position();
 
+  c->can_stream_ = c->body_->can_stream();
+
   return c;
 }
 
@@ -1296,8 +1501,12 @@
 TryFinally* TryFinally::ReadFrom(Reader* reader) {
   TRACE_READ_OFFSET();
   TryFinally* tf = new TryFinally();
+  tf->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
   tf->body_ = Statement::ReadFrom(reader);
   tf->finalizer_ = Statement::ReadFrom(reader);
+
+  tf->can_stream_ = tf->body_->can_stream() && tf->finalizer_->can_stream();
+
   return tf;
 }
 
@@ -1305,10 +1514,14 @@
 YieldStatement* YieldStatement::ReadFrom(Reader* reader) {
   TRACE_READ_OFFSET();
   YieldStatement* stmt = new YieldStatement();
+  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
   stmt->position_ = reader->ReadPosition();
   reader->record_yield_token_position(stmt->position_);
   stmt->flags_ = reader->ReadByte();
   stmt->expression_ = Expression::ReadFrom(reader);
+
+  stmt->can_stream_ = stmt->expression_->can_stream();
+
   return stmt;
 }
 
@@ -1343,6 +1556,9 @@
   decl->end_position_ = position;
   reader->helper()->variables().Push(decl);
 
+  decl->can_stream_ =
+      (decl->initializer_ == NULL || decl->initializer_->can_stream());
+
   return decl;
 }
 
@@ -1355,6 +1571,9 @@
   decl->variable_ = VariableDeclaration::ReadFromImpl(reader, false);
   VariableScope<ReaderHelper> parameters(reader->helper());
   decl->function_ = FunctionNode::ReadFrom(reader);
+
+  decl->can_stream_ = false;
+
   return decl;
 }
 
@@ -1463,8 +1682,12 @@
   TypeParameterScope<ReaderHelper> scope(reader->helper());
   type->type_parameters().ReadFrom(reader);
   type->required_parameter_count_ = reader->ReadUInt();
+  intptr_t total_parameter_count = reader->ReadUInt();
   type->positional_parameters().ReadFromStatic<DartType>(reader);
   type->named_parameters().ReadFromStatic<NamedParameter>(reader);
+  ASSERT(type->positional_parameters().length() +
+             type->named_parameters().length() ==
+         total_parameter_count);
   type->return_type_ = DartType::ReadFrom(reader);
   return type;
 }
@@ -1486,6 +1709,7 @@
   TypeParameterType* type = new TypeParameterType();
   type->parameter_ =
       reader->helper()->type_parameters().Lookup(reader->ReadUInt());
+  reader->ReadUInt();  // binary offset of parameter
   // There is an optional promoted bound, currently ignored.
   delete reader->ReadOptional<DartType>();
   return type;
@@ -1546,6 +1770,8 @@
   program->main_method_reference_ =
       Reference::ReadMemberFrom(reader, /*allow_null=*/true);
 
+  program->can_stream_ = false;
+
   return program;
 }
 
@@ -1573,12 +1799,19 @@
       reader->helper());
   VariableScope<ReaderHelper> vars(reader->helper());
   function->body_ = reader->ReadOptional<Statement>();
+
+  function->can_stream_ =
+      function->positional_parameters_.CanStream() &&
+      function->named_parameters_.CanStream() &&
+      (function->body_ == NULL || function->body_->can_stream());
+
   return function;
 }
 
 
 TypeParameter* TypeParameter::ReadFrom(Reader* reader) {
   TRACE_READ_OFFSET();
+  kernel_offset_ = reader->offset();
   name_index_ = StringIndex(reader->ReadUInt());
   bound_ = DartType::ReadFrom(reader);
   return this;
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index b8ae51c..0e6459f 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -268,19 +268,6 @@
 };
 
 
-template <typename T>
-class SwitchCaseScope {
- public:
-  explicit SwitchCaseScope(T* builder) : builder_(builder) {
-    builder_->switch_cases().EnterScope();
-  }
-  ~SwitchCaseScope() { builder_->switch_cases().LeaveScope(); }
-
- private:
-  T* builder_;
-};
-
-
 // Unlike other scopes, labels from enclosing functions are not visible in
 // nested functions.  The LabelScope class is used to hide outer labels.
 template <typename Builder, typename Block>
@@ -308,7 +295,6 @@
 
   BlockStack<VariableDeclaration>& variables() { return scope_; }
   BlockStack<TypeParameter>& type_parameters() { return type_parameters_; }
-  BlockStack<SwitchCase>& switch_cases() { return switch_cases_; }
 
   BlockStack<LabeledStatement>* labels() { return labels_; }
   void set_labels(BlockStack<LabeledStatement>* labels) { labels_ = labels; }
@@ -317,7 +303,6 @@
   Program* program_;
   BlockStack<VariableDeclaration> scope_;
   BlockStack<TypeParameter> type_parameters_;
-  BlockStack<SwitchCase> switch_cases_;
   BlockStack<LabeledStatement>* labels_;
 };
 
@@ -422,6 +407,8 @@
 
   uint8_t ReadByte() { return buffer_[offset_++]; }
 
+  uint8_t PeekByte() { return buffer_[offset_]; }
+
   bool ReadBool() { return (ReadByte() & 1) == 1; }
 
   word ReadFlags() { return ReadByte(); }
@@ -439,6 +426,19 @@
     }
   }
 
+  Tag PeekTag(uint8_t* payload = NULL) {
+    uint8_t byte = PeekByte();
+    bool has_payload = (byte & kSpecializedTagHighBit) != 0;
+    if (has_payload) {
+      if (payload != NULL) {
+        *payload = byte & kSpecializedPayloadMask;
+      }
+      return static_cast<Tag>(byte & kSpecializedTagMask);
+    } else {
+      return static_cast<Tag>(byte);
+    }
+  }
+
   const uint8_t* Consume(int count) {
     ASSERT(offset_ + count <= size_);
     const uint8_t* old = buffer_ + offset_;
diff --git a/runtime/vm/kernel_binary_flowgraph.cc b/runtime/vm/kernel_binary_flowgraph.cc
index ca31817..dec055d 100644
--- a/runtime/vm/kernel_binary_flowgraph.cc
+++ b/runtime/vm/kernel_binary_flowgraph.cc
@@ -4,6 +4,7 @@
 
 #include "vm/kernel_binary_flowgraph.h"
 
+#include "vm/longjump.h"
 #include "vm/object_store.h"
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -13,54 +14,599 @@
 
 #define Z (zone_)
 #define H (translation_helper_)
+#define T (type_translator_)
 #define I Isolate::Current()
 
-StreamingConstantEvaluator::StreamingConstantEvaluator(
+
+StreamingDartTypeTranslator::StreamingDartTypeTranslator(
     StreamingFlowGraphBuilder* builder,
-    Zone* zone,
-    TranslationHelper* h,
-    DartTypeTranslator* type_translator)
+    bool finalize)
+    : builder_(builder),
+      translation_helper_(builder->translation_helper_),
+      active_class_(builder->active_class()),
+      type_parameter_scope_(NULL),
+      zone_(translation_helper_.zone()),
+      result_(AbstractType::Handle(translation_helper_.zone())),
+      finalize_(finalize) {}
+
+
+AbstractType& StreamingDartTypeTranslator::BuildType() {
+  BuildTypeInternal();
+
+  // We return a new `ZoneHandle` here on purpose: The intermediate language
+  // instructions do not make a copy of the handle, so we do it.
+  return dart::AbstractType::ZoneHandle(Z, result_.raw());
+}
+
+void StreamingDartTypeTranslator::BuildTypeInternal() {
+  Tag tag = builder_->ReadTag();
+  switch (tag) {
+    case kInvalidType:
+      result_ = ClassFinalizer::NewFinalizedMalformedType(
+          Error::Handle(Z),  // No previous error.
+          dart::Script::Handle(Z, dart::Script::null()),
+          TokenPosition::kNoSource, "[InvalidType] in Kernel IR.");
+      break;
+    case kDynamicType:
+      result_ = Object::dynamic_type().raw();
+      break;
+    case kVoidType:
+      result_ = Object::void_type().raw();
+      break;
+    case kBottomType:
+      result_ = dart::Class::Handle(Z, I->object_store()->null_class())
+                    .CanonicalType();
+      break;
+    case kInterfaceType:
+      BuildInterfaceType(false);
+      break;
+    case kSimpleInterfaceType:
+      BuildInterfaceType(true);
+      break;
+    case kFunctionType:
+      BuildFunctionType(false);
+      break;
+    case kSimpleFunctionType:
+      BuildFunctionType(true);
+      break;
+    case kTypeParameterType:
+      BuildTypeParameterType();
+      break;
+    default:
+      UNREACHABLE();
+  }
+}
+
+void StreamingDartTypeTranslator::BuildInterfaceType(bool simple) {
+  // NOTE: That an interface type like `T<A, B>` is considered to be
+  // malformed iff `T` is malformed.
+  //   => We therefore ignore errors in `A` or `B`.
+
+  NameIndex klass_name =
+      builder_->ReadCanonicalNameReference();  // read klass_name.
+
+  intptr_t length;
+  if (simple) {
+    length = 0;
+  } else {
+    length = builder_->ReadListLength();  // read type_arguments list length.
+  }
+  const TypeArguments& type_arguments =
+      BuildTypeArguments(length);  // read type arguments.
+
+  dart::Object& klass =
+      dart::Object::Handle(Z, H.LookupClassByKernelClass(klass_name));
+  result_ = Type::New(klass, type_arguments, TokenPosition::kNoSource);
+  if (finalize_) {
+    ASSERT(active_class_->klass != NULL);
+    result_ = ClassFinalizer::FinalizeType(*active_class_->klass, result_);
+  }
+}
+
+void StreamingDartTypeTranslator::BuildFunctionType(bool simple) {
+  intptr_t list_length = 0;
+  intptr_t* type_parameters = NULL;
+  if (!simple) {
+    list_length =
+        builder_->ReadListLength();  // read type_parameters list length
+    type_parameters = new intptr_t[list_length];
+    for (int i = 0; i < list_length; ++i) {
+      type_parameters[i] = builder_->ReaderOffset();
+      builder_->SkipStringReference();  // read string index (name).
+      builder_->SkipDartType();         // read dart type.
+    }
+  }
+
+  // The spec describes in section "19.1 Static Types":
+  //
+  //     Any use of a malformed type gives rise to a static warning. A
+  //     malformed type is then interpreted as dynamic by the static type
+  //     checker and the runtime unless explicitly specified otherwise.
+  //
+  // So we convert malformed return/parameter types to `dynamic`.
+  TypeParameterScope scope(this, type_parameters, list_length);
+
+  Function& signature_function = Function::ZoneHandle(
+      Z, Function::NewSignatureFunction(*active_class_->klass,
+                                        TokenPosition::kNoSource));
+
+  intptr_t required_count;
+  intptr_t all_count;
+  intptr_t positional_count;
+  if (!simple) {
+    required_count = builder_->ReadUInt();  // read required parameter count.
+    all_count = builder_->ReadUInt();       // read total parameter count.
+    positional_count =
+        builder_->ReadListLength();  // read positional_parameters list length.
+  } else {
+    positional_count =
+        builder_->ReadListLength();  // read positional_parameters list length.
+    required_count = positional_count;
+    all_count = positional_count;
+  }
+
+  const Array& parameter_types =
+      Array::Handle(Z, Array::New(1 + all_count, Heap::kOld));
+  signature_function.set_parameter_types(parameter_types);
+  const Array& parameter_names =
+      Array::Handle(Z, Array::New(1 + all_count, Heap::kOld));
+  signature_function.set_parameter_names(parameter_names);
+
+  intptr_t pos = 0;
+  parameter_types.SetAt(pos, AbstractType::dynamic_type());
+  parameter_names.SetAt(pos, H.DartSymbol("_receiver_"));
+  ++pos;
+  for (intptr_t i = 0; i < positional_count; ++i, ++pos) {
+    BuildTypeInternal();  // read ith positional parameter.
+    if (result_.IsMalformed()) {
+      result_ = AbstractType::dynamic_type().raw();
+    }
+    parameter_types.SetAt(pos, result_);
+    parameter_names.SetAt(pos, H.DartSymbol("noname"));
+  }
+
+  // The additional first parameter is the receiver type (set to dynamic).
+  signature_function.set_num_fixed_parameters(1 + required_count);
+  signature_function.SetNumOptionalParameters(
+      all_count - required_count, positional_count > required_count);
+
+  if (!simple) {
+    const intptr_t named_count =
+        builder_->ReadListLength();  // read named_parameters list length.
+    for (intptr_t i = 0; i < named_count; ++i, ++pos) {
+      // read string reference (i.e. named_parameters[i].name).
+      dart::String& name = H.DartSymbol(builder_->ReadStringReference());
+      BuildTypeInternal();  // read named_parameters[i].type.
+      if (result_.IsMalformed()) {
+        result_ = AbstractType::dynamic_type().raw();
+      }
+      parameter_types.SetAt(pos, result_);
+      parameter_names.SetAt(pos, name);
+    }
+  }
+
+  BuildTypeInternal();  // read return type.
+  if (result_.IsMalformed()) {
+    result_ = AbstractType::dynamic_type().raw();
+  }
+  signature_function.set_result_type(result_);
+
+  Type& signature_type =
+      Type::ZoneHandle(Z, signature_function.SignatureType());
+
+  if (finalize_) {
+    signature_type ^=
+        ClassFinalizer::FinalizeType(*active_class_->klass, signature_type);
+    // Do not refer to signature_function anymore, since it may have been
+    // replaced during canonicalization.
+    signature_function = Function::null();
+  }
+
+  result_ = signature_type.raw();
+}
+
+static intptr_t FindTypeParameterIndex(intptr_t* parameters,
+                                       intptr_t parameters_count,
+                                       intptr_t look_for) {
+  for (intptr_t i = 0; i < parameters_count; ++i) {
+    if (look_for == parameters[i]) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+static intptr_t FindTypeParameterIndex(List<TypeParameter>* parameters,
+                                       intptr_t look_for) {
+  for (intptr_t i = 0; i < parameters->length(); ++i) {
+    if (look_for == (*parameters)[i]->kernel_offset()) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+void StreamingDartTypeTranslator::BuildTypeParameterType() {
+  builder_->ReadUInt();                           // read parameter index.
+  intptr_t binary_offset = builder_->ReadUInt();  // read binary offset.
+  builder_->SkipOptionalDartType();               // read bound.
+
+  if (binary_offset == 0) {
+    // TODO(jensj): This doesn't appear to actually happen.
+    UNIMPLEMENTED();
+    return;
+  }
+
+  for (TypeParameterScope* scope = type_parameter_scope_; scope != NULL;
+       scope = scope->outer()) {
+    const intptr_t index = FindTypeParameterIndex(
+        scope->parameters(), scope->parameters_count(), binary_offset);
+    if (index >= 0) {
+      result_ ^= dart::Type::DynamicType();
+      return;
+    }
+  }
+
+  if ((active_class_->member != NULL) && active_class_->member->IsProcedure()) {
+    Procedure* procedure = Procedure::Cast(active_class_->member);
+    if ((procedure->function() != NULL) &&
+        (procedure->function()->type_parameters().length() > 0)) {
+      //
+      // WARNING: This is a little hackish:
+      //
+      // We have a static factory constructor. The kernel IR gives the factory
+      // constructor function it's own type parameters (which are equal in name
+      // and number to the ones of the enclosing class).
+      // I.e.,
+      //
+      //   class A<T> {
+      //     factory A.x() { return new B<T>(); }
+      //   }
+      //
+      //  is basically translated to this:
+      //
+      //   class A<T> {
+      //     static A.x<T'>() { return new B<T'>(); }
+      //   }
+      //
+      const intptr_t index = FindTypeParameterIndex(
+          &procedure->function()->type_parameters(), binary_offset);
+      if (index >= 0) {
+        if (procedure->kind() == Procedure::kFactory) {
+          // The index of the type parameter in [parameters] is
+          // the same index into the `klass->type_parameters()` array.
+          result_ ^= dart::TypeArguments::Handle(
+                         Z, active_class_->klass->type_parameters())
+                         .TypeAt(index);
+        } else {
+          result_ ^= dart::Type::DynamicType();
+        }
+        return;
+      }
+    }
+  }
+
+  ASSERT(active_class_->kernel_class != NULL);
+  List<TypeParameter>* parameters =
+      &active_class_->kernel_class->type_parameters();
+  const intptr_t index = FindTypeParameterIndex(parameters, binary_offset);
+  if (index >= 0) {
+    // The index of the type parameter in [parameters] is
+    // the same index into the `klass->type_parameters()` array.
+    result_ ^=
+        dart::TypeArguments::Handle(Z, active_class_->klass->type_parameters())
+            .TypeAt(index);
+    return;
+  }
+
+  UNREACHABLE();
+}
+
+const TypeArguments& StreamingDartTypeTranslator::BuildTypeArguments(
+    intptr_t length) {
+  bool only_dynamic = true;
+  intptr_t offset = builder_->ReaderOffset();
+  for (intptr_t i = 0; i < length; ++i) {
+    if (builder_->ReadTag() != kDynamicType) {  // read ith type's tag.
+      only_dynamic = false;
+      builder_->SetOffset(offset);
+      break;
+    }
+  }
+  TypeArguments& type_arguments = TypeArguments::ZoneHandle(Z);
+  if (!only_dynamic) {
+    type_arguments = TypeArguments::New(length);
+    for (intptr_t i = 0; i < length; ++i) {
+      BuildTypeInternal();  // read ith type.
+      if (!result_.IsDynamicType()) {
+        only_dynamic = false;
+      }
+      if (result_.IsMalformed()) {
+        type_arguments = TypeArguments::null();
+        return type_arguments;
+      }
+      type_arguments.SetTypeAt(i, result_);
+    }
+
+    if (finalize_) {
+      type_arguments = type_arguments.Canonicalize();
+    }
+  }
+  return type_arguments;
+}
+
+const TypeArguments&
+StreamingDartTypeTranslator::BuildInstantiatedTypeArguments(
+    const dart::Class& receiver_class,
+    intptr_t length) {
+  const TypeArguments& type_arguments = BuildTypeArguments(length);
+  if (type_arguments.IsNull()) return type_arguments;
+
+  // We make a temporary [Type] object and use `ClassFinalizer::FinalizeType` to
+  // finalize the argument types.
+  // (This can for example make the [type_arguments] vector larger)
+  Type& type = Type::Handle(
+      Z, Type::New(receiver_class, type_arguments, TokenPosition::kNoSource));
+  if (finalize_) {
+    type ^=
+        ClassFinalizer::FinalizeType(*builder_->active_class()->klass, type);
+  }
+
+  const TypeArguments& instantiated_type_arguments =
+      TypeArguments::ZoneHandle(Z, type.arguments());
+  return instantiated_type_arguments;
+}
+
+
+const Type& StreamingDartTypeTranslator::ReceiverType(
+    const dart::Class& klass) {
+  ASSERT(!klass.IsNull());
+  ASSERT(!klass.IsTypedefClass());
+  // Note that if klass is _Closure, the returned type will be _Closure,
+  // and not the signature type.
+  Type& type = Type::ZoneHandle(Z, klass.CanonicalType());
+  if (!type.IsNull()) {
+    return type;
+  }
+  type = Type::New(klass, TypeArguments::Handle(Z, klass.type_parameters()),
+                   klass.token_pos());
+  if (klass.is_type_finalized()) {
+    type ^= ClassFinalizer::FinalizeType(klass, type);
+    klass.SetCanonicalType(type);
+  }
+  return type;
+}
+
+
+StreamingConstantEvaluator::StreamingConstantEvaluator(
+    StreamingFlowGraphBuilder* builder)
     : builder_(builder),
       isolate_(Isolate::Current()),
-      zone_(zone),
-      translation_helper_(*h),
-      // type_translator_(*type_translator),
+      zone_(builder_->zone_),
+      translation_helper_(builder_->translation_helper_),
+      type_translator_(builder_->type_translator_),
       script_(Script::Handle(
-          zone,
+          zone_,
           builder == NULL ? Script::null()
                           : builder_->parsed_function()->function().script())),
-      result_(Instance::Handle(zone)) {}
+      result_(Instance::Handle(zone_)) {}
 
 
-Instance& StreamingConstantEvaluator::EvaluateExpression() {
-  intptr_t offset = builder_->ReaderOffset();
+Instance& StreamingConstantEvaluator::EvaluateExpression(intptr_t offset,
+                                                         bool reset_position) {
   if (!GetCachedConstant(offset, &result_)) {
+    intptr_t original_offset = builder_->ReaderOffset();
+    builder_->SetOffset(offset);
     uint8_t payload = 0;
-    Tag tag = builder_->ReadTag(&payload);
+    Tag tag = builder_->ReadTag(&payload);  // read tag.
     switch (tag) {
+      case kVariableGet:
+        EvaluateVariableGet();
+        break;
+      case kSpecializedVariableGet:
+        EvaluateVariableGet(payload);
+        break;
+      case kPropertyGet:
+        EvaluatePropertyGet();
+        break;
       case kStaticGet:
         EvaluateStaticGet();
         break;
+      case kMethodInvocation:
+        EvaluateMethodInvocation();
+        break;
+      case kStaticInvocation:
+      case kConstStaticInvocation:
+        EvaluateStaticInvocation();
+        break;
+      case kConstructorInvocation:
+      case kConstConstructorInvocation:
+        EvaluateConstructorInvocationInternal();
+        break;
+      case kNot:
+        EvaluateNot();
+        break;
+      case kLogicalExpression:
+        EvaluateLogicalExpression();
+        break;
+      case kConditionalExpression:
+        EvaluateConditionalExpression();
+        break;
+      case kStringConcatenation:
+        EvaluateStringConcatenation();
+        break;
       case kSymbolLiteral:
         EvaluateSymbolLiteral();
         break;
+      case kTypeLiteral:
+        EvaluateTypeLiteral();
+        break;
+      case kListLiteral:
+      case kConstListLiteral:
+        EvaluateListLiteralInternal();
+        break;
+      case kMapLiteral:
+      case kConstMapLiteral:
+        EvaluateMapLiteralInternal();
+        break;
+      case kLet:
+        EvaluateLet();
+        break;
+      case kBigIntLiteral:
+        EvaluateBigIntLiteral();
+        break;
+      case kStringLiteral:
+        EvaluateStringLiteral();
+        break;
+      case kSpecialIntLiteral:
+        EvaluateIntLiteral(payload);
+        break;
+      case kNegativeIntLiteral:
+        EvaluateIntLiteral(true);
+        break;
+      case kPositiveIntLiteral:
+        EvaluateIntLiteral(false);
+        break;
       case kDoubleLiteral:
         EvaluateDoubleLiteral();
         break;
+      case kTrueLiteral:
+        EvaluateBoolLiteral(true);
+        break;
+      case kFalseLiteral:
+        EvaluateBoolLiteral(false);
+        break;
+      case kNullLiteral:
+        EvaluateNullLiteral();
+        break;
       default:
         UNREACHABLE();
     }
 
     CacheConstantValue(offset, result_);
+    if (reset_position) builder_->SetOffset(original_offset);
   }
   // We return a new `ZoneHandle` here on purpose: The intermediate language
   // instructions do not make a copy of the handle, so we do it.
-  return dart::Instance::ZoneHandle(Z, result_.raw());
+  return Instance::ZoneHandle(Z, result_.raw());
+}
+
+Instance& StreamingConstantEvaluator::EvaluateListLiteral(intptr_t offset,
+                                                          bool reset_position) {
+  if (!GetCachedConstant(offset, &result_)) {
+    intptr_t original_offset = builder_->ReaderOffset();
+    builder_->SetOffset(offset);
+    builder_->ReadTag();  // skip tag.
+    EvaluateListLiteralInternal();
+
+    CacheConstantValue(offset, result_);
+    if (reset_position) builder_->SetOffset(original_offset);
+  }
+  // We return a new `ZoneHandle` here on purpose: The intermediate language
+  // instructions do not make a copy of the handle, so we do it.
+  return Instance::ZoneHandle(Z, result_.raw());
+}
+
+Instance& StreamingConstantEvaluator::EvaluateMapLiteral(intptr_t offset,
+                                                         bool reset_position) {
+  if (!GetCachedConstant(offset, &result_)) {
+    intptr_t original_offset = builder_->ReaderOffset();
+    builder_->SetOffset(offset);
+    builder_->ReadTag();  // skip tag.
+    EvaluateMapLiteralInternal();
+
+    CacheConstantValue(offset, result_);
+    if (reset_position) builder_->SetOffset(original_offset);
+  }
+  // We return a new `ZoneHandle` here on purpose: The intermediate language
+  // instructions do not make a copy of the handle, so we do it.
+  return Instance::ZoneHandle(Z, result_.raw());
+}
+
+Instance& StreamingConstantEvaluator::EvaluateConstructorInvocation(
+    intptr_t offset,
+    bool reset_position) {
+  if (!GetCachedConstant(offset, &result_)) {
+    intptr_t original_offset = builder_->ReaderOffset();
+    builder_->SetOffset(offset);
+    builder_->ReadTag();  // skip tag.
+    EvaluateConstructorInvocationInternal();
+
+    CacheConstantValue(offset, result_);
+    if (reset_position) builder_->SetOffset(original_offset);
+  }
+  // We return a new `ZoneHandle` here on purpose: The intermediate language
+  // instructions do not make a copy of the handle, so we do it.
+  return Instance::ZoneHandle(Z, result_.raw());
+}
+
+Object& StreamingConstantEvaluator::EvaluateExpressionSafe(intptr_t offset) {
+  LongJumpScope jump;
+  if (setjmp(*jump.Set()) == 0) {
+    return EvaluateExpression(offset);
+  } else {
+    Thread* thread = H.thread();
+    Error& error = Error::Handle(Z);
+    error = thread->sticky_error();
+    thread->clear_sticky_error();
+    return error;
+  }
+}
+
+void StreamingConstantEvaluator::EvaluateVariableGet() {
+  // When we see a [VariableGet] the corresponding [VariableDeclaration] must've
+  // been executed already. It therefore must have a constant object associated
+  // with it.
+  builder_->ReadPosition();  // read position.
+  intptr_t variable_kernel_position =
+      builder_->ReadUInt();          // read kernel position.
+  builder_->ReadUInt();              // read relative variable index.
+  builder_->SkipOptionalDartType();  // read promoted type.
+  LocalVariable* variable = builder_->LookupVariable(variable_kernel_position);
+  ASSERT(variable->IsConst());
+  result_ = variable->ConstValue()->raw();
+}
+
+void StreamingConstantEvaluator::EvaluateVariableGet(uint8_t payload) {
+  // When we see a [VariableGet] the corresponding [VariableDeclaration] must've
+  // been executed already. It therefore must have a constant object associated
+  // with it.
+  builder_->ReadPosition();  // read position.
+  intptr_t variable_kernel_position =
+      builder_->ReadUInt();  // read kernel position.
+  LocalVariable* variable = builder_->LookupVariable(variable_kernel_position);
+  ASSERT(variable->IsConst());
+  result_ = variable->ConstValue()->raw();
+}
+
+void StreamingConstantEvaluator::EvaluatePropertyGet() {
+  builder_->ReadPosition();  // read position.
+  intptr_t expression_offset = builder_->ReaderOffset();
+  builder_->SkipExpression();                            // read receiver.
+  StringIndex name = builder_->ReadNameAsStringIndex();  // read name.
+  // Read unused "interface_target_reference".
+  builder_->SkipCanonicalNameReference();
+
+  if (H.StringEquals(name, "length")) {
+    EvaluateExpression(expression_offset);
+    if (result_.IsString()) {
+      const dart::String& str =
+          dart::String::Handle(Z, dart::String::RawCast(result_.raw()));
+      result_ = Integer::New(str.Length());
+    } else {
+      H.ReportError(
+          "Constant expressions can only call "
+          "'length' on string constants.");
+    }
+  } else {
+    UNREACHABLE();
+  }
 }
 
 void StreamingConstantEvaluator::EvaluateStaticGet() {
-  builder_->ReadPosition();
-  NameIndex target = builder_->ReadCanonicalNameReference();
+  builder_->ReadPosition();  // read position.
+  NameIndex target =
+      builder_->ReadCanonicalNameReference();  // read target_reference.
 
   if (H.IsField(target)) {
     const dart::Field& field =
@@ -92,10 +638,183 @@
   }
 }
 
+void StreamingConstantEvaluator::EvaluateMethodInvocation() {
+  builder_->ReadPosition();  // read position.
+  // This method call wasn't cached, so receiver et al. isn't cached either.
+  const dart::Instance& receiver =
+      EvaluateExpression(builder_->ReaderOffset(), false);  // read receiver.
+  dart::Class& klass = dart::Class::Handle(
+      Z, isolate_->class_table()->At(receiver.GetClassId()));
+  ASSERT(!klass.IsNull());
+
+  // Search the superclass chain for the selector.
+  dart::Function& function = dart::Function::Handle(Z);
+  const dart::String& method_name =
+      builder_->ReadNameAsMethodName();  // read name.
+  while (!klass.IsNull()) {
+    function = klass.LookupDynamicFunctionAllowPrivate(method_name);
+    if (!function.IsNull()) break;
+    klass = klass.SuperClass();
+  }
+
+  // The frontend should guarantee that [MethodInvocation]s inside constant
+  // expressions are always valid.
+  ASSERT(!function.IsNull());
+
+  // Read first parts of arguments: count and list of types.
+  intptr_t argument_count = builder_->PeekArgumentsCount();
+  // Dart does not support generic methods yet.
+  ASSERT(builder_->PeekArgumentsTypeCount() == 0);
+  builder_->SkipArgumentsBeforeActualArguments();
+
+  // Run the method and canonicalize the result.
+  const Object& result = RunFunction(function, argument_count, &receiver, NULL);
+  result_ ^= result.raw();
+  result_ = H.Canonicalize(result_);
+
+  builder_->SkipCanonicalNameReference();  // read "interface_target_reference"
+}
+
+void StreamingConstantEvaluator::EvaluateStaticInvocation() {
+  builder_->ReadPosition();  // read position.
+  NameIndex procedue_reference =
+      builder_->ReadCanonicalNameReference();  // read procedure reference.
+
+  const Function& function = Function::ZoneHandle(
+      Z, H.LookupStaticMethodByKernelProcedure(procedue_reference));
+  dart::Class& klass = dart::Class::Handle(Z, function.Owner());
+
+  intptr_t argument_count =
+      builder_->ReadUInt();  // read arguments part #1: arguments count.
+
+  // Build the type arguments vector (if necessary).
+  const TypeArguments* type_arguments =
+      TranslateTypeArguments(function, &klass);  // read argument types.
+
+  // read positional and named parameters.
+  const Object& result =
+      RunFunction(function, argument_count, NULL, type_arguments);
+  result_ ^= result.raw();
+  result_ = H.Canonicalize(result_);
+}
+
+void StreamingConstantEvaluator::EvaluateConstructorInvocationInternal() {
+  builder_->ReadPosition();  // read position.
+
+  NameIndex target = builder_->ReadCanonicalNameReference();  // read target.
+  const Function& constructor =
+      Function::Handle(Z, H.LookupConstructorByKernelConstructor(target));
+  dart::Class& klass = dart::Class::Handle(Z, constructor.Owner());
+
+  intptr_t argument_count =
+      builder_->ReadUInt();  // read arguments part #1: arguments count.
+
+  // Build the type arguments vector (if necessary).
+  const TypeArguments* type_arguments =
+      TranslateTypeArguments(constructor, &klass);  // read argument types.
+
+  // Prepare either the instance or the type argument vector for the constructor
+  // call.
+  Instance* receiver = NULL;
+  const TypeArguments* type_arguments_argument = NULL;
+  if (!constructor.IsFactory()) {
+    receiver = &Instance::ZoneHandle(Z, Instance::New(klass, Heap::kOld));
+    if (type_arguments != NULL) {
+      receiver->SetTypeArguments(*type_arguments);
+    }
+  } else {
+    type_arguments_argument = type_arguments;
+  }
+
+  // read positional and named parameters.
+  const Object& result = RunFunction(constructor, argument_count, receiver,
+                                     type_arguments_argument);
+
+  if (constructor.IsFactory()) {
+    // Factories return the new object.
+    result_ ^= result.raw();
+    result_ = H.Canonicalize(result_);
+  } else {
+    ASSERT(!receiver->IsNull());
+    result_ = H.Canonicalize(*receiver);
+  }
+}
+
+void StreamingConstantEvaluator::EvaluateNot() {
+  result_ ^= Bool::Get(!EvaluateBooleanExpressionHere()).raw();
+}
+
+void StreamingConstantEvaluator::EvaluateLogicalExpression() {
+  bool left = EvaluateBooleanExpressionHere();  // read left.
+  LogicalExpression::Operator op = static_cast<LogicalExpression::Operator>(
+      builder_->ReadByte());  // read operator.
+  if (op == LogicalExpression::kAnd) {
+    if (left) {
+      EvaluateBooleanExpressionHere();  // read right.
+    } else {
+      builder_->SkipExpression();  // read right.
+    }
+  } else {
+    ASSERT(op == LogicalExpression::kOr);
+    if (!left) {
+      EvaluateBooleanExpressionHere();  // read right.
+    } else {
+      builder_->SkipExpression();  // read right.
+    }
+  }
+}
+
+void StreamingConstantEvaluator::EvaluateConditionalExpression() {
+  bool condition = EvaluateBooleanExpressionHere();
+  if (condition) {
+    EvaluateExpression(builder_->ReaderOffset(), false);  // read then.
+    builder_->SkipExpression();                           // read otherwise.
+  } else {
+    builder_->SkipExpression();                           // read then.
+    EvaluateExpression(builder_->ReaderOffset(), false);  // read otherwise.
+  }
+  builder_->SkipOptionalDartType();  // read unused static type.
+}
+
+void StreamingConstantEvaluator::EvaluateStringConcatenation() {
+  builder_->ReadPosition();                      // read position.
+  intptr_t length = builder_->ReadListLength();  // read list length.
+
+  bool all_string = true;
+  const Array& strings = Array::Handle(Z, Array::New(length));
+  for (intptr_t i = 0; i < length; ++i) {
+    EvaluateExpression(builder_->ReaderOffset(),
+                       false);  // read ith expression.
+    strings.SetAt(i, result_);
+    all_string = all_string && result_.IsString();
+  }
+  if (all_string) {
+    result_ = dart::String::ConcatAll(strings, Heap::kOld);
+    result_ = H.Canonicalize(result_);
+  } else {
+    // Get string interpolation function.
+    const dart::Class& cls = dart::Class::Handle(
+        Z, dart::Library::LookupCoreClass(Symbols::StringBase()));
+    ASSERT(!cls.IsNull());
+    const Function& func = Function::Handle(
+        Z, cls.LookupStaticFunction(
+               dart::Library::PrivateCoreLibName(Symbols::Interpolate())));
+    ASSERT(!func.IsNull());
+
+    // Build argument array to pass to the interpolation function.
+    const Array& interpolate_arg = Array::Handle(Z, Array::New(1, Heap::kOld));
+    interpolate_arg.SetAt(0, strings);
+
+    // Run and canonicalize.
+    const Object& result =
+        RunFunction(func, interpolate_arg, Array::null_array());
+    result_ = H.Canonicalize(dart::String::Cast(result));
+  }
+}
 
 void StreamingConstantEvaluator::EvaluateSymbolLiteral() {
-  StringIndex str_index(builder_->ReadUInt());
-  const dart::String& symbol_value = H.DartSymbol(str_index);
+  const dart::String& symbol_value = H.DartSymbol(
+      builder_->ReadStringReference());  // read index into string table.
 
   const dart::Class& symbol_class =
       dart::Class::ZoneHandle(Z, I->object_store()->symbol_class());
@@ -107,13 +826,184 @@
       symbol_class, TypeArguments::Handle(Z), symbol_constructor, symbol_value);
 }
 
+void StreamingConstantEvaluator::EvaluateTypeLiteral() {
+  const AbstractType& type = T.BuildType();
+  if (type.IsMalformed()) {
+    H.ReportError("Malformed type literal in constant expression.");
+  }
+  result_ = type.raw();
+}
 
-void StreamingConstantEvaluator::EvaluateDoubleLiteral() {
-  StringIndex str_index(builder_->ReadUInt());
-  result_ = dart::Double::New(H.DartString(str_index), Heap::kOld);
+void StreamingConstantEvaluator::EvaluateListLiteralInternal() {
+  builder_->ReadPosition();  // read position.
+  const TypeArguments& type_arguments = T.BuildTypeArguments(1);  // read type.
+  intptr_t length = builder_->ReadListLength();  // read list length.
+  const Array& const_list =
+      Array::ZoneHandle(Z, Array::New(length, Heap::kOld));
+  const_list.SetTypeArguments(type_arguments);
+  for (intptr_t i = 0; i < length; ++i) {
+    const Instance& expression = EvaluateExpression(
+        builder_->ReaderOffset(), false);  // read ith expression.
+    const_list.SetAt(i, expression);
+  }
+  const_list.MakeImmutable();
+  result_ = H.Canonicalize(const_list);
+}
+
+void StreamingConstantEvaluator::EvaluateMapLiteralInternal() {
+  builder_->ReadPosition();  // read position.
+  const TypeArguments& type_arguments =
+      T.BuildTypeArguments(2);  // read key type and value type.
+
+  intptr_t length = builder_->ReadListLength();  // read length of entries.
+
+  // This MapLiteral wasn't cached, so content isn't cached either.
+  Array& const_kv_array =
+      Array::ZoneHandle(Z, Array::New(2 * length, Heap::kOld));
+  for (intptr_t i = 0; i < length; ++i) {
+    const_kv_array.SetAt(2 * i + 0, EvaluateExpression(builder_->ReaderOffset(),
+                                                       false));  // read key.
+    const_kv_array.SetAt(2 * i + 1, EvaluateExpression(builder_->ReaderOffset(),
+                                                       false));  // read value.
+  }
+
+  const_kv_array.MakeImmutable();
+  const_kv_array ^= H.Canonicalize(const_kv_array);
+
+  const dart::Class& map_class = dart::Class::Handle(
+      Z, dart::Library::LookupCoreClass(Symbols::ImmutableMap()));
+  ASSERT(!map_class.IsNull());
+  ASSERT(map_class.NumTypeArguments() == 2);
+
+  const dart::Field& field = dart::Field::Handle(
+      Z, map_class.LookupInstanceFieldAllowPrivate(H.DartSymbol("_kvPairs")));
+  ASSERT(!field.IsNull());
+
+  // NOTE: This needs to be kept in sync with `runtime/lib/immutable_map.dart`!
+  result_ = Instance::New(map_class, Heap::kOld);
+  ASSERT(!result_.IsNull());
+  result_.SetTypeArguments(type_arguments);
+  result_.SetField(field, const_kv_array);
   result_ = H.Canonicalize(result_);
 }
 
+void StreamingConstantEvaluator::EvaluateLet() {
+  intptr_t kernel_position = builder_->ReaderOffset();
+  LocalVariable* local = builder_->LookupVariable(kernel_position);
+
+  // read variable declaration.
+  builder_->ReadPosition();         // read position.
+  builder_->ReadPosition();         // read equals position.
+  builder_->ReadFlags();            // read flags.
+  builder_->SkipStringReference();  // read name index.
+  builder_->SkipDartType();         // read type.
+  Tag tag = builder_->ReadTag();    // read (first part of) initializer.
+  if (tag == kNothing) {
+    local->SetConstValue(Instance::ZoneHandle(Z, dart::Instance::null()));
+  } else {
+    local->SetConstValue(EvaluateExpression(
+        builder_->ReaderOffset(), false));  // read rest of initializer.
+  }
+
+  EvaluateExpression(builder_->ReaderOffset(), false);  // read body
+}
+
+void StreamingConstantEvaluator::EvaluateBigIntLiteral() {
+  const dart::String& value =
+      H.DartString(builder_->ReadStringReference());  // read string reference.
+  result_ = Integer::New(value, Heap::kOld);
+  result_ = H.Canonicalize(result_);
+}
+
+void StreamingConstantEvaluator::EvaluateStringLiteral() {
+  result_ = H.DartSymbol(builder_->ReadStringReference())
+                .raw();  // read string reference.
+}
+
+void StreamingConstantEvaluator::EvaluateIntLiteral(uint8_t payload) {
+  int64_t value = static_cast<int32_t>(payload) - SpecializedIntLiteralBias;
+  result_ = dart::Integer::New(value, Heap::kOld);
+  result_ = H.Canonicalize(result_);
+}
+
+void StreamingConstantEvaluator::EvaluateIntLiteral(bool is_negative) {
+  int64_t value = is_negative ? -static_cast<int64_t>(builder_->ReadUInt())
+                              : builder_->ReadUInt();  // read value.
+  result_ = dart::Integer::New(value, Heap::kOld);
+  result_ = H.Canonicalize(result_);
+}
+
+void StreamingConstantEvaluator::EvaluateDoubleLiteral() {
+  result_ = Double::New(H.DartString(builder_->ReadStringReference()),
+                        Heap::kOld);  // read string reference.
+  result_ = H.Canonicalize(result_);
+}
+
+void StreamingConstantEvaluator::EvaluateBoolLiteral(bool value) {
+  result_ = dart::Bool::Get(value).raw();
+}
+
+void StreamingConstantEvaluator::EvaluateNullLiteral() {
+  result_ = dart::Instance::null();
+}
+
+// This depends on being about to read the list of positionals on arguments.
+const Object& StreamingConstantEvaluator::RunFunction(
+    const Function& function,
+    intptr_t argument_count,
+    const Instance* receiver,
+    const TypeArguments* type_args) {
+  // We do not support generic methods yet.
+  ASSERT((receiver == NULL) || (type_args == NULL));
+  intptr_t extra_arguments =
+      (receiver != NULL ? 1 : 0) + (type_args != NULL ? 1 : 0);
+
+  // Build up arguments.
+  const Array& arguments =
+      Array::ZoneHandle(Z, Array::New(extra_arguments + argument_count));
+  intptr_t pos = 0;
+  if (receiver != NULL) {
+    arguments.SetAt(pos++, *receiver);
+  }
+  if (type_args != NULL) {
+    arguments.SetAt(pos++, *type_args);
+  }
+
+  // List of positional.
+  intptr_t list_length = builder_->ReadListLength();  // read list length.
+  for (intptr_t i = 0; i < list_length; ++i) {
+    EvaluateExpression(builder_->ReaderOffset(),
+                       false);  // read ith expression.
+    arguments.SetAt(pos++, result_);
+  }
+
+  // List of named.
+  list_length = builder_->ReadListLength();  // read list length.
+  const Array& names = Array::ZoneHandle(Z, Array::New(list_length));
+  for (intptr_t i = 0; i < list_length; ++i) {
+    dart::String& name =
+        H.DartSymbol(builder_->ReadStringReference());  // read ith name index.
+    names.SetAt(i, name);
+    EvaluateExpression(builder_->ReaderOffset(),
+                       false);  // read ith expression.
+    arguments.SetAt(pos++, result_);
+  }
+
+  return RunFunction(function, arguments, names);
+}
+
+const Object& StreamingConstantEvaluator::RunFunction(const Function& function,
+                                                      const Array& arguments,
+                                                      const Array& names) {
+  const Array& args_descriptor =
+      Array::Handle(Z, ArgumentsDescriptor::New(arguments.Length(), names));
+  const Object& result = Object::Handle(
+      Z, DartEntry::InvokeFunction(function, arguments, args_descriptor));
+  if (result.IsError()) {
+    H.ReportError(Error::Cast(result), "error evaluating constant constructor");
+  }
+  return result;
+}
 
 RawObject* StreamingConstantEvaluator::EvaluateConstConstructorCall(
     const dart::Class& type_class,
@@ -154,6 +1044,33 @@
   return H.Canonicalize(instance);
 }
 
+const TypeArguments* StreamingConstantEvaluator::TranslateTypeArguments(
+    const Function& target,
+    dart::Class* target_klass) {
+  intptr_t types_count = builder_->ReadListLength();  // read types count.
+
+  const TypeArguments* type_arguments = NULL;
+  if (types_count > 0) {
+    type_arguments = &T.BuildInstantiatedTypeArguments(
+        *target_klass, types_count);  // read types.
+
+    if (!(type_arguments->IsNull() || type_arguments->IsInstantiated())) {
+      H.ReportError("Type must be constant in const constructor.");
+    }
+  } else if (target.IsFactory() && type_arguments == NULL) {
+    // All factories take a type arguments vector as first argument (independent
+    // of whether the class is generic or not).
+    type_arguments = &TypeArguments::ZoneHandle(Z, TypeArguments::null());
+  }
+  return type_arguments;
+}
+
+bool StreamingConstantEvaluator::EvaluateBooleanExpressionHere() {
+  EvaluateExpression(builder_->ReaderOffset(), false);
+  AssertBoolInCheckedMode();
+  return result_.raw() == Bool::True().raw();
+}
+
 bool StreamingConstantEvaluator::GetCachedConstant(intptr_t kernel_offset,
                                                    Instance* value) {
   if (builder_ == NULL) return false;
@@ -177,7 +1094,7 @@
   // do not assert that 'compile_time_constants' has not changed.
   constants.Release();
   if (FLAG_compiler_stats && is_present) {
-    H.thread()->compiler_stats()->num_const_cache_hits++;
+    ++H.thread()->compiler_stats()->num_const_cache_hits;
   }
   return is_present;
 }
@@ -208,100 +1125,108 @@
 }
 
 
-Fragment StreamingFlowGraphBuilder::BuildAt(intptr_t kernel_offset) {
+Fragment StreamingFlowGraphBuilder::BuildExpressionAt(intptr_t kernel_offset) {
   SetOffset(kernel_offset);
+  return BuildExpression();  // read expression.
+}
 
+Fragment StreamingFlowGraphBuilder::BuildStatementAt(intptr_t kernel_offset) {
+  SetOffset(kernel_offset);
+  return BuildStatement();  // read statement.
+}
+
+Fragment StreamingFlowGraphBuilder::BuildExpression(TokenPosition* position) {
   uint8_t payload = 0;
-  Tag tag = ReadTag(&payload);
+  Tag tag = ReadTag(&payload);  // read tag.
   switch (tag) {
     case kInvalidExpression:
-      return BuildInvalidExpression();
-    //    case kVariableGet:
-    //      return VariableGet::ReadFrom(reader_);
-    //    case kSpecializedVariableGet:
-    //      return VariableGet::ReadFrom(reader_, payload);
-    //    case kVariableSet:
-    //      return VariableSet::ReadFrom(reader_);
-    //    case kSpecializedVariableSet:
-    //      return VariableSet::ReadFrom(reader_, payload);
-    //    case kPropertyGet:
-    //      return PropertyGet::ReadFrom(reader_);
-    //    case kPropertySet:
-    //      return PropertySet::ReadFrom(reader_);
-    //    case kDirectPropertyGet:
-    //      return DirectPropertyGet::ReadFrom(reader_);
-    //    case kDirectPropertySet:
-    //      return DirectPropertySet::ReadFrom(reader_);
+      return BuildInvalidExpression(position);
+    case kVariableGet:
+      return BuildVariableGet(position);
+    case kSpecializedVariableGet:
+      return BuildVariableGet(payload, position);
+    case kVariableSet:
+      return BuildVariableSet(position);
+    case kSpecializedVariableSet:
+      return BuildVariableSet(payload, position);
+    case kPropertyGet:
+      return BuildPropertyGet(position);
+    case kPropertySet:
+      return BuildPropertySet(position);
+    case kDirectPropertyGet:
+      return BuildDirectPropertyGet(position);
+    case kDirectPropertySet:
+      return BuildDirectPropertySet(position);
     case kStaticGet:
-      return BuildStaticGet();
-    //    case kStaticSet:
-    //      return StaticSet::ReadFrom(reader_);
-    //    case kMethodInvocation:
-    //      return MethodInvocation::ReadFrom(reader_);
-    //    case kDirectMethodInvocation:
-    //      return DirectMethodInvocation::ReadFrom(reader_);
-    //    case kStaticInvocation:
-    //      return StaticInvocation::ReadFrom(reader_, false);
-    //    case kConstStaticInvocation:
-    //      return StaticInvocation::ReadFrom(reader_, true);
-    //    case kConstructorInvocation:
-    //      return ConstructorInvocation::ReadFrom(reader_, false);
-    //    case kConstConstructorInvocation:
-    //      return ConstructorInvocation::ReadFrom(reader_, true);
-    //    case kNot:
-    //      return Not::ReadFrom(reader_);
-    //    case kLogicalExpression:
-    //      return LogicalExpression::ReadFrom(reader_);
-    //    case kConditionalExpression:
-    //      return ConditionalExpression::ReadFrom(reader_);
-    //    case kStringConcatenation:
-    //      return StringConcatenation::ReadFrom(reader_);
-    //    case kIsExpression:
-    //      return IsExpression::ReadFrom(reader_);
-    //    case kAsExpression:
-    //      return AsExpression::ReadFrom(reader_);
+      return BuildStaticGet(position);
+    case kStaticSet:
+      return BuildStaticSet(position);
+    case kMethodInvocation:
+      return BuildMethodInvocation(position);
+    case kDirectMethodInvocation:
+      return BuildDirectMethodInvocation(position);
+    case kStaticInvocation:
+      return BuildStaticInvocation(false, position);
+    case kConstStaticInvocation:
+      return BuildStaticInvocation(true, position);
+    case kConstructorInvocation:
+      return BuildConstructorInvocation(false, position);
+    case kConstConstructorInvocation:
+      return BuildConstructorInvocation(true, position);
+    case kNot:
+      return BuildNot(position);
+    case kLogicalExpression:
+      return BuildLogicalExpression(position);
+    case kConditionalExpression:
+      return BuildConditionalExpression(position);
+    case kStringConcatenation:
+      return BuildStringConcatenation(position);
+    case kIsExpression:
+      return BuildIsExpression(position);
+    case kAsExpression:
+      return BuildAsExpression(position);
     case kSymbolLiteral:
-      return BuildSymbolLiteral();
-    //    case kTypeLiteral:
-    //      return TypeLiteral::ReadFrom(reader_);
+      return BuildSymbolLiteral(position);
+    case kTypeLiteral:
+      return BuildTypeLiteral(position);
     case kThisExpression:
-      return BuildThisExpression();
+      return BuildThisExpression(position);
     case kRethrow:
-      return BuildRethrow();
-    //    case kThrow:
-    //      return Throw::ReadFrom(reader_);
-    //    case kListLiteral:
-    //      return ListLiteral::ReadFrom(reader_, false);
-    //    case kConstListLiteral:
-    //      return ListLiteral::ReadFrom(reader_, true);
-    //    case kMapLiteral:
-    //      return MapLiteral::ReadFrom(reader_, false);
-    //    case kConstMapLiteral:
-    //      return MapLiteral::ReadFrom(reader_, true);
-    //    case kAwaitExpression:
-    //      return AwaitExpression::ReadFrom(reader_);
-    //    case kFunctionExpression:
-    //      return FunctionExpression::ReadFrom(reader_);
-    //    case kLet:
-    //      return Let::ReadFrom(reader_);
+      return BuildRethrow(position);
+    case kThrow:
+      return BuildThrow(position);
+    case kListLiteral:
+      return BuildListLiteral(false, position);
+    case kConstListLiteral:
+      return BuildListLiteral(true, position);
+    case kMapLiteral:
+      return BuildMapLiteral(false, position);
+    case kConstMapLiteral:
+      return BuildMapLiteral(true, position);
+    case kFunctionExpression:
+      // TODO(jensj)
+      UNIMPLEMENTED();
+      return Fragment();
+    case kLet:
+      return BuildLet(position);
     case kBigIntLiteral:
-      return BuildBigIntLiteral();
+      return BuildBigIntLiteral(position);
     case kStringLiteral:
-      return BuildStringLiteral();
+      return BuildStringLiteral(position);
     case kSpecialIntLiteral:
-      return BuildIntLiteral(payload);
+      return BuildIntLiteral(payload, position);
     case kNegativeIntLiteral:
-      return BuildIntLiteral(true);
+      return BuildIntLiteral(true, position);
     case kPositiveIntLiteral:
-      return BuildIntLiteral(false);
+      return BuildIntLiteral(false, position);
     case kDoubleLiteral:
-      return BuildDoubleLiteral();
+      return BuildDoubleLiteral(position);
     case kTrueLiteral:
-      return BuildBoolLiteral(true);
+      return BuildBoolLiteral(true, position);
     case kFalseLiteral:
-      return BuildBoolLiteral(false);
+      return BuildBoolLiteral(false, position);
     case kNullLiteral:
-      return BuildNullLiteral();
+      return BuildNullLiteral(position);
     default:
       UNREACHABLE();
   }
@@ -309,129 +1234,1287 @@
   return Fragment();
 }
 
+Fragment StreamingFlowGraphBuilder::BuildStatement() {
+  Tag tag = ReadTag();  // read tag.
+  switch (tag) {
+    case kInvalidStatement:
+      return BuildInvalidStatement();
+    case kExpressionStatement:
+      return BuildExpressionStatement();
+    case kBlock:
+      return BuildBlock();
+    case kEmptyStatement:
+      return BuildEmptyStatement();
+    case kAssertStatement:
+      return BuildAssertStatement();
+    case kLabeledStatement:
+      return BuildLabeledStatement();
+    case kBreakStatement:
+      return BuildBreakStatement();
+    case kWhileStatement:
+      return BuildWhileStatement();
+    case kDoStatement:
+      return BuildDoStatement();
+    case kForStatement:
+      return BuildForStatement();
+    case kForInStatement:
+      return BuildForInStatement(false);
+    case kAsyncForInStatement:
+      return BuildForInStatement(true);
+    case kSwitchStatement:
+      return BuildSwitchStatement();
+    case kContinueSwitchStatement:
+      return BuildContinueSwitchStatement();
+    case kIfStatement:
+      return BuildIfStatement();
+    case kReturnStatement:
+      return BuildReturnStatement();
+    case kTryCatch:
+      return BuildTryCatch();
+    case kTryFinally:
+      return BuildTryFinally();
+    case kYieldStatement:
+      return BuildYieldStatement();
+    case kVariableDeclaration:
+      return BuildVariableDeclaration(true);
+    case kFunctionDeclaration:
+      // TODO(jensj)
+      UNIMPLEMENTED();
+      return Fragment();
+    default:
+      UNREACHABLE();
+  }
+  return Fragment();
+}
 
 intptr_t StreamingFlowGraphBuilder::ReaderOffset() {
   return reader_->offset();
 }
 
-
 void StreamingFlowGraphBuilder::SetOffset(intptr_t offset) {
   reader_->set_offset(offset);
 }
 
-
 void StreamingFlowGraphBuilder::SkipBytes(intptr_t bytes) {
   reader_->set_offset(ReaderOffset() + bytes);
 }
 
+bool StreamingFlowGraphBuilder::ReadBool() {
+  return reader_->ReadBool();
+}
+
+uint8_t StreamingFlowGraphBuilder::ReadByte() {
+  return reader_->ReadByte();
+}
 
 uint32_t StreamingFlowGraphBuilder::ReadUInt() {
   return reader_->ReadUInt();
 }
 
+uint32_t StreamingFlowGraphBuilder::PeekUInt() {
+  intptr_t offset = ReaderOffset();
+  uint32_t result = reader_->ReadUInt();
+  SetOffset(offset);
+  return result;
+}
 
 intptr_t StreamingFlowGraphBuilder::ReadListLength() {
   return reader_->ReadListLength();
 }
 
+StringIndex StreamingFlowGraphBuilder::ReadStringReference() {
+  return StringIndex(ReadUInt());
+}
 
 NameIndex StreamingFlowGraphBuilder::ReadCanonicalNameReference() {
   return reader_->ReadCanonicalNameReference();
 }
 
+StringIndex StreamingFlowGraphBuilder::ReadNameAsStringIndex() {
+  StringIndex name_index = ReadStringReference();  // read name index.
+  if ((H.StringSize(name_index) >= 1) && H.CharacterAt(name_index, 0) == '_') {
+    ReadUInt();  // read library index.
+  }
+  return name_index;
+}
+
+const dart::String& StreamingFlowGraphBuilder::ReadNameAsMethodName() {
+  StringIndex name_index = ReadStringReference();  // read name index.
+  if ((H.StringSize(name_index) >= 1) && H.CharacterAt(name_index, 0) == '_') {
+    NameIndex library_reference =
+        ReadCanonicalNameReference();  // read library index.
+    return H.DartMethodName(library_reference, name_index);
+  } else {
+    return H.DartMethodName(NameIndex(NULL), name_index);
+  }
+}
+
+const dart::String& StreamingFlowGraphBuilder::ReadNameAsSetterName() {
+  StringIndex name_index = ReadStringReference();  // read name index.
+  if ((H.StringSize(name_index) >= 1) && H.CharacterAt(name_index, 0) == '_') {
+    NameIndex library_reference =
+        ReadCanonicalNameReference();  // read library index.
+    return H.DartSetterName(library_reference, name_index);
+  } else {
+    return H.DartSetterName(NameIndex(NULL), name_index);
+  }
+}
+
+const dart::String& StreamingFlowGraphBuilder::ReadNameAsGetterName() {
+  StringIndex name_index = ReadStringReference();  // read name index.
+  if ((H.StringSize(name_index) >= 1) && H.CharacterAt(name_index, 0) == '_') {
+    NameIndex library_reference =
+        ReadCanonicalNameReference();  // read library index.
+    return H.DartGetterName(library_reference, name_index);
+  } else {
+    return H.DartGetterName(NameIndex(NULL), name_index);
+  }
+}
+
+void StreamingFlowGraphBuilder::SkipStringReference() {
+  ReadUInt();
+}
+
+void StreamingFlowGraphBuilder::SkipCanonicalNameReference() {
+  ReadUInt();
+}
+
+void StreamingFlowGraphBuilder::SkipDartType() {
+  Tag tag = ReadTag();
+  switch (tag) {
+    case kInvalidType:
+    case kDynamicType:
+    case kVoidType:
+    case kBottomType:
+      // those contain nothing.
+      return;
+    case kInterfaceType:
+      SkipInterfaceType(false);
+      return;
+    case kSimpleInterfaceType:
+      SkipInterfaceType(true);
+      return;
+    case kFunctionType:
+      SkipFunctionType(false);
+      return;
+    case kSimpleFunctionType:
+      SkipFunctionType(true);
+      return;
+    case kTypeParameterType:
+      ReadUInt();              // read index for parameter.
+      ReadUInt();              // read binary offset.
+      SkipOptionalDartType();  // read bound bound.
+      return;
+    default:
+      UNREACHABLE();
+  }
+}
+
+void StreamingFlowGraphBuilder::SkipOptionalDartType() {
+  Tag tag = ReadTag();  // read tag.
+  if (tag == kNothing) {
+    return;
+  }
+  ASSERT(tag == kSomething);
+
+  SkipDartType();  // read type.
+}
+
+void StreamingFlowGraphBuilder::SkipInterfaceType(bool simple) {
+  ReadUInt();  // read klass_name.
+  if (!simple) {
+    intptr_t length = ReadListLength();  // read number of types.
+    for (intptr_t i = 0; i < length; ++i) {
+      SkipDartType();  // skip the ith type.
+    }
+  }
+}
+
+void StreamingFlowGraphBuilder::SkipFunctionType(bool simple) {
+  if (!simple) {
+    intptr_t list_length =
+        ReadListLength();  // read type_parameters list length.
+    for (int i = 0; i < list_length; ++i) {
+      SkipStringReference();  // read string index (name).
+      SkipDartType();         // read dart type.
+    }
+    ReadUInt();  // read required parameter count.
+    ReadUInt();  // read total parameter count.
+  }
+
+  const intptr_t positional_count =
+      ReadListLength();  // read positional_parameters list length.
+  for (intptr_t i = 0; i < positional_count; ++i) {
+    SkipDartType();  // read ith positional parameter.
+  }
+
+  if (!simple) {
+    const intptr_t named_count =
+        ReadListLength();  // read named_parameters list length.
+    for (intptr_t i = 0; i < named_count; ++i) {
+      // read string reference (i.e. named_parameters[i].name).
+      SkipStringReference();
+      SkipDartType();  // read named_parameters[i].type.
+    }
+  }
+
+  SkipDartType();  // read return type.
+}
+
+void StreamingFlowGraphBuilder::SkipExpression() {
+  uint8_t payload = 0;
+  Tag tag = ReadTag(&payload);
+  switch (tag) {
+    case kInvalidExpression:
+      return;
+    case kVariableGet:
+      ReadPosition();          // read position.
+      ReadUInt();              // read kernel position.
+      ReadUInt();              // read relative variable index.
+      SkipOptionalDartType();  // read promoted type.
+      return;
+    case kSpecializedVariableGet:
+      ReadPosition();  // read position.
+      ReadUInt();      // read kernel position.
+      return;
+    case kVariableSet:
+      ReadPosition();    // read position.
+      ReadUInt();        // read kernel position.
+      ReadUInt();        // read relative variable index.
+      SkipExpression();  // read expression.
+      return;
+    case kSpecializedVariableSet:
+      ReadPosition();    // read position.
+      ReadUInt();        // read kernel position.
+      SkipExpression();  // read expression.
+      return;
+    case kPropertyGet:
+      ReadPosition();    // read position.
+      SkipExpression();  // read receiver.
+      SkipName();        // read name.
+      // Read unused "interface_target_reference".
+      SkipCanonicalNameReference();
+      return;
+    case kPropertySet:
+      ReadPosition();    // read position.
+      SkipExpression();  // read receiver.
+      SkipName();        // read name.
+      SkipExpression();  // read value.
+      // read unused "interface_target_reference".
+      SkipCanonicalNameReference();
+      return;
+    case kDirectPropertyGet:
+      ReadPosition();                // read position.
+      SkipExpression();              // read receiver.
+      SkipCanonicalNameReference();  // read target_reference.
+      return;
+    case kDirectPropertySet:
+      ReadPosition();                // read position.
+      SkipExpression();              // read receiver.
+      SkipCanonicalNameReference();  // read target_reference.
+      SkipExpression();              // read value·
+      return;
+    case kStaticGet:
+      ReadPosition();                // read position.
+      SkipCanonicalNameReference();  // read target_reference.
+      return;
+    case kStaticSet:
+      ReadPosition();                // read position.
+      SkipCanonicalNameReference();  // read target_reference.
+      SkipExpression();              // read expression.
+      return;
+    case kMethodInvocation:
+      ReadPosition();    // read position.
+      SkipExpression();  // read receiver.
+      SkipName();        // read name.
+      SkipArguments();   // read arguments.
+      // read unused "interface_target_reference".
+      SkipCanonicalNameReference();
+      return;
+    case kDirectMethodInvocation:
+      SkipExpression();              // read receiver.
+      SkipCanonicalNameReference();  // read target_reference.
+      SkipArguments();               // read arguments.
+      return;
+    case kStaticInvocation:
+    case kConstStaticInvocation:
+      ReadPosition();                // read position.
+      SkipCanonicalNameReference();  // read procedure_reference.
+      SkipArguments();               // read arguments.
+      return;
+    case kConstructorInvocation:
+    case kConstConstructorInvocation:
+      ReadPosition();                // read position.
+      SkipCanonicalNameReference();  // read target_reference.
+      SkipArguments();               // read arguments.
+      return;
+    case kNot:
+      SkipExpression();  // read expression.
+      return;
+    case kLogicalExpression:
+      SkipExpression();  // read left.
+      SkipBytes(1);      // read operator.
+      SkipExpression();  // read right.
+      return;
+    case kConditionalExpression:
+      SkipExpression();        // read condition.
+      SkipExpression();        // read then.
+      SkipExpression();        // read otherwise.
+      SkipOptionalDartType();  // read unused static type.
+      return;
+    case kStringConcatenation: {
+      ReadPosition();                           // read position.
+      intptr_t list_length = ReadListLength();  // read list length.
+      for (intptr_t i = 0; i < list_length; ++i) {
+        SkipExpression();  // read ith expression.
+      }
+      return;
+    }
+    case kIsExpression:
+      ReadPosition();    // read position.
+      SkipExpression();  // read operand.
+      SkipDartType();    // read type.
+      return;
+    case kAsExpression:
+      ReadPosition();    // read position.
+      SkipExpression();  // read operand.
+      SkipDartType();    // read type.
+      return;
+    case kSymbolLiteral:
+      SkipStringReference();  // read index into string table.
+      return;
+    case kTypeLiteral:
+      SkipDartType();  // read type.
+      return;
+    case kThisExpression:
+      return;
+    case kRethrow:
+      ReadPosition();  // read position.
+      return;
+    case kThrow:
+      ReadPosition();    // read position.
+      SkipExpression();  // read expression.
+      return;
+    case kListLiteral:
+    case kConstListLiteral: {
+      ReadPosition();                           // read position.
+      SkipDartType();                           // read type.
+      intptr_t list_length = ReadListLength();  // read list length.
+      for (intptr_t i = 0; i < list_length; ++i) {
+        SkipExpression();  // read ith expression.
+      }
+      return;
+    }
+    case kMapLiteral:
+    case kConstMapLiteral: {
+      ReadPosition();                           // read position.
+      SkipDartType();                           // read key type.
+      SkipDartType();                           // read value type.
+      intptr_t list_length = ReadListLength();  // read list length.
+      for (intptr_t i = 0; i < list_length; ++i) {
+        SkipExpression();  // read ith key.
+        SkipExpression();  // read ith value.
+      }
+      return;
+    }
+    case kFunctionExpression:
+      // TODO(jensj)
+      UNIMPLEMENTED();
+      return;
+    case kLet:
+      SkipVariableDeclaration();  // read variable declaration.
+      SkipExpression();           // read expression.
+      return;
+    case kBigIntLiteral:
+      SkipStringReference();  // read string reference.
+      return;
+    case kStringLiteral:
+      SkipStringReference();  // read string reference.
+      return;
+    case kSpecialIntLiteral:
+      return;
+    case kNegativeIntLiteral:
+      ReadUInt();  // read value.
+      return;
+    case kPositiveIntLiteral:
+      ReadUInt();  // read value.
+      return;
+    case kDoubleLiteral:
+      SkipStringReference();  // read index into string table.
+      return;
+    case kTrueLiteral:
+      return;
+    case kFalseLiteral:
+      return;
+    case kNullLiteral:
+      return;
+    default:
+      UNREACHABLE();
+  }
+}
+
+void StreamingFlowGraphBuilder::SkipStatement() {
+  Tag tag = ReadTag();  // read tag.
+  switch (tag) {
+    case kInvalidStatement:
+      return;
+    case kExpressionStatement:
+      SkipExpression();  // read expression.
+      return;
+    case kBlock: {
+      intptr_t list_length = ReadListLength();  // read number of statements.
+      for (intptr_t i = 0; i < list_length; ++i) {
+        SkipStatement();  // read ith statement.
+      }
+      return;
+    }
+    case kEmptyStatement:
+      return;
+    case kAssertStatement: {
+      SkipExpression();     // Read condition.
+      Tag tag = ReadTag();  // read (first part of) message.
+      if (tag == kSomething) {
+        SkipExpression();  // read (rest of) message.
+      }
+      return;
+    }
+    case kLabeledStatement:
+      SkipStatement();  // read body.
+      return;
+    case kBreakStatement:
+      ReadPosition();  // read position.
+      ReadUInt();      // read target_index.
+      return;
+    case kWhileStatement:
+      SkipExpression();  // read condition.
+      SkipStatement();   // read body.
+      return;
+    case kDoStatement:
+      SkipStatement();   // read body.
+      SkipExpression();  // read condition.
+      return;
+    case kForStatement: {
+      intptr_t list_length = ReadListLength();  // read number of variables.
+      for (intptr_t i = 0; i < list_length; ++i) {
+        SkipVariableDeclaration();  // read ith variable.
+      }
+      Tag tag = ReadTag();  // Read first part of condition.
+      if (tag == kSomething) {
+        SkipExpression();  // read rest of condition.
+      }
+      list_length = ReadListLength();  // read number of updates.
+      for (intptr_t i = 0; i < list_length; ++i) {
+        SkipExpression();  // read ith update.
+      }
+      SkipStatement();  // read body.
+      return;
+    }
+    case kForInStatement:
+    case kAsyncForInStatement:
+      ReadPosition();             // read position.
+      SkipVariableDeclaration();  // read variable.
+      SkipExpression();           // read iterable.
+      SkipStatement();            // read body.
+      return;
+    case kSwitchStatement: {
+      SkipExpression();                  // read condition.
+      int num_cases = ReadListLength();  // read number of cases.
+      for (intptr_t i = 0; i < num_cases; ++i) {
+        int num_expressions = ReadListLength();  // read number of expressions.
+        for (intptr_t j = 0; j < num_expressions; ++j) {
+          ReadPosition();    // read jth position.
+          SkipExpression();  // read jth expression.
+        }
+        ReadBool();       // read is_default.
+        SkipStatement();  // read body.
+      }
+      return;
+    }
+    case kContinueSwitchStatement:
+      ReadUInt();  // read target_index.
+      return;
+    case kIfStatement:
+      SkipExpression();  // read condition.
+      SkipStatement();   // read then.
+      SkipStatement();   // read otherwise.
+      return;
+    case kReturnStatement: {
+      ReadPosition();       // read position
+      Tag tag = ReadTag();  // read (first part of) expression.
+      if (tag == kSomething) {
+        SkipExpression();  // read (rest of) expression.
+      }
+      return;
+    }
+    case kTryCatch: {
+      SkipStatement();  // read body.
+      ReadBool();       // read any_catch_needs_stack_trace.
+      intptr_t num_matches = ReadListLength();  // read number of catches.
+      for (intptr_t i = 0; i < num_matches; ++i) {
+        SkipDartType();   // read guard.
+        tag = ReadTag();  // read first part of exception.
+        if (tag == kSomething) {
+          SkipVariableDeclaration();  // read exception.
+        }
+        tag = ReadTag();  // read first part of stack trace.
+        if (tag == kSomething) {
+          SkipVariableDeclaration();  // read stack trace.
+        }
+        SkipStatement();  // read body.
+      }
+      return;
+    }
+    case kTryFinally:
+      SkipStatement();  // read body.
+      SkipStatement();  // read finalizer.
+      return;
+    case kYieldStatement:
+      ReadPosition();    // read position.
+      ReadByte();        // read flags.
+      SkipExpression();  // read expression.
+      return;
+    case kVariableDeclaration:
+      SkipVariableDeclaration();
+      return;
+    case kFunctionDeclaration:
+      // TODO(jensj)
+      UNIMPLEMENTED();
+      return;
+    default:
+      UNREACHABLE();
+  }
+}
+
+void StreamingFlowGraphBuilder::SkipName() {
+  StringIndex name_index = ReadStringReference();  // read name index.
+  if ((H.StringSize(name_index) >= 1) && H.CharacterAt(name_index, 0) == '_') {
+    SkipCanonicalNameReference();  // read library index.
+  }
+}
+
+void StreamingFlowGraphBuilder::SkipArguments() {
+  ReadUInt();  // read argument count.
+
+  // List of types.
+  intptr_t list_length = ReadListLength();  // read list length.
+  for (intptr_t i = 0; i < list_length; ++i) {
+    SkipDartType();  // read ith type.
+  }
+
+  // List of positional.
+  list_length = ReadListLength();  // read list length.
+  for (intptr_t i = 0; i < list_length; ++i) {
+    SkipExpression();  // read ith expression.
+  }
+
+  // List of named.
+  list_length = ReadListLength();  // read list length.
+  for (intptr_t i = 0; i < list_length; ++i) {
+    SkipStringReference();  // read ith name index.
+    SkipExpression();       // read ith expression.
+  }
+}
+
+void StreamingFlowGraphBuilder::SkipVariableDeclaration() {
+  ReadPosition();         // read position.
+  ReadPosition();         // read equals position.
+  ReadFlags();            // read flags.
+  SkipStringReference();  // read name index.
+  SkipDartType();         // read type.
+  Tag tag = ReadTag();    // read (first part of) initializer.
+  if (tag == kSomething) {
+    SkipExpression();  // read (actual) initializer.
+  }
+}
 
 TokenPosition StreamingFlowGraphBuilder::ReadPosition(bool record) {
   return reader_->ReadPosition(record);
 }
 
-
 Tag StreamingFlowGraphBuilder::ReadTag(uint8_t* payload) {
   return reader_->ReadTag(payload);
 }
 
+Tag StreamingFlowGraphBuilder::PeekTag(uint8_t* payload) {
+  return reader_->PeekTag(payload);
+}
+
+word StreamingFlowGraphBuilder::ReadFlags() {
+  return reader_->ReadFlags();
+}
+
+void StreamingFlowGraphBuilder::loop_depth_inc() {
+  ++flow_graph_builder_->loop_depth_;
+}
+
+void StreamingFlowGraphBuilder::loop_depth_dec() {
+  --flow_graph_builder_->loop_depth_;
+}
+
+intptr_t StreamingFlowGraphBuilder::for_in_depth() {
+  return flow_graph_builder_->for_in_depth_;
+}
+
+void StreamingFlowGraphBuilder::for_in_depth_inc() {
+  ++flow_graph_builder_->for_in_depth_;
+}
+
+void StreamingFlowGraphBuilder::for_in_depth_dec() {
+  --flow_graph_builder_->for_in_depth_;
+}
+
+void StreamingFlowGraphBuilder::catch_depth_inc() {
+  ++flow_graph_builder_->catch_depth_;
+}
+
+void StreamingFlowGraphBuilder::catch_depth_dec() {
+  --flow_graph_builder_->catch_depth_;
+}
+
+void StreamingFlowGraphBuilder::try_depth_inc() {
+  ++flow_graph_builder_->try_depth_;
+}
+
+void StreamingFlowGraphBuilder::try_depth_dec() {
+  --flow_graph_builder_->try_depth_;
+}
+
+intptr_t StreamingFlowGraphBuilder::CurrentTryIndex() {
+  return flow_graph_builder_->CurrentTryIndex();
+}
+
+intptr_t StreamingFlowGraphBuilder::AllocateTryIndex() {
+  return flow_graph_builder_->AllocateTryIndex();
+}
+
+LocalVariable* StreamingFlowGraphBuilder::CurrentException() {
+  return flow_graph_builder_->CurrentException();
+}
+
+LocalVariable* StreamingFlowGraphBuilder::CurrentStackTrace() {
+  return flow_graph_builder_->CurrentStackTrace();
+}
 
 CatchBlock* StreamingFlowGraphBuilder::catch_block() {
   return flow_graph_builder_->catch_block_;
 }
 
+ActiveClass* StreamingFlowGraphBuilder::active_class() {
+  return &flow_graph_builder_->active_class_;
+}
 
 ScopeBuildingResult* StreamingFlowGraphBuilder::scopes() {
   return flow_graph_builder_->scopes_;
 }
 
-
 ParsedFunction* StreamingFlowGraphBuilder::parsed_function() {
   return flow_graph_builder_->parsed_function_;
 }
 
+TryFinallyBlock* StreamingFlowGraphBuilder::try_finally_block() {
+  return flow_graph_builder_->try_finally_block_;
+}
+
+SwitchBlock* StreamingFlowGraphBuilder::switch_block() {
+  return flow_graph_builder_->switch_block_;
+}
+
+BreakableBlock* StreamingFlowGraphBuilder::breakable_block() {
+  return flow_graph_builder_->breakable_block_;
+}
+
+GrowableArray<YieldContinuation>&
+StreamingFlowGraphBuilder::yield_continuations() {
+  return flow_graph_builder_->yield_continuations_;
+}
+
+Value* StreamingFlowGraphBuilder::stack() {
+  return flow_graph_builder_->stack_;
+}
+
+Value* StreamingFlowGraphBuilder::Pop() {
+  return flow_graph_builder_->Pop();
+}
+
+Tag StreamingFlowGraphBuilder::PeekArgumentsFirstPositionalTag() {
+  // read parts of arguments, then go back to before doing so.
+  intptr_t offset = ReaderOffset();
+  ReadUInt();  // read number of arguments.
+
+  // List of types.
+  intptr_t list_length = ReadListLength();  // read list length.
+  for (intptr_t i = 0; i < list_length; ++i) {
+    SkipDartType();  // read ith type.
+  }
+
+  // List of positional.
+  list_length = ReadListLength();  // read list length.
+  for (intptr_t i = 0; i < list_length; ++i) {
+    Tag tag = ReadTag();  // read first tag.
+    SetOffset(offset);    // reset offset.
+    return tag;
+  }
+
+  UNREACHABLE();
+  return kNothing;
+}
+
+const TypeArguments& StreamingFlowGraphBuilder::PeekArgumentsInstantiatedType(
+    const dart::Class& klass) {
+  // read parts of arguments, then go back to before doing so.
+  intptr_t offset = ReaderOffset();
+  ReadUInt();                               // read argument count.
+  intptr_t list_length = ReadListLength();  // read types list length.
+  const TypeArguments& type_arguments =
+      T.BuildInstantiatedTypeArguments(klass, list_length);  // read types.
+  SetOffset(offset);
+  return type_arguments;
+}
+
+intptr_t StreamingFlowGraphBuilder::PeekArgumentsCount() {
+  return PeekUInt();
+}
+
+intptr_t StreamingFlowGraphBuilder::PeekArgumentsTypeCount() {
+  intptr_t offset = ReaderOffset();
+  ReadUInt();                               // read arguments count.
+  intptr_t types_count = ReadListLength();  // read length of types list.
+  SetOffset(offset);
+  return types_count;
+}
+
+void StreamingFlowGraphBuilder::SkipArgumentsBeforeActualArguments() {
+  ReadUInt();  // read arguments count.
+  intptr_t types_count = ReadListLength();
+  for (intptr_t i = 0; i < types_count; ++i) {
+    SkipDartType();  // read ith type.
+  }
+}
+
+LocalVariable* StreamingFlowGraphBuilder::LookupVariable(
+    intptr_t kernel_offset) {
+  return flow_graph_builder_->LookupVariable(kernel_offset);
+}
+
+LocalVariable* StreamingFlowGraphBuilder::MakeTemporary() {
+  return flow_graph_builder_->MakeTemporary();
+}
+
+Token::Kind StreamingFlowGraphBuilder::MethodKind(const dart::String& name) {
+  return flow_graph_builder_->MethodKind(name);
+}
+
+dart::RawFunction* StreamingFlowGraphBuilder::LookupMethodByMember(
+    NameIndex target,
+    const dart::String& method_name) {
+  return flow_graph_builder_->LookupMethodByMember(target, method_name);
+}
+
+bool StreamingFlowGraphBuilder::NeedsDebugStepCheck(const Function& function,
+                                                    TokenPosition position) {
+  return flow_graph_builder_->NeedsDebugStepCheck(function, position);
+}
+
+bool StreamingFlowGraphBuilder::NeedsDebugStepCheck(Value* value,
+                                                    TokenPosition position) {
+  return flow_graph_builder_->NeedsDebugStepCheck(value, position);
+}
+
+void StreamingFlowGraphBuilder::InlineBailout(const char* reason) {
+  flow_graph_builder_->InlineBailout(reason);
+}
 
 Fragment StreamingFlowGraphBuilder::DebugStepCheck(TokenPosition position) {
   return flow_graph_builder_->DebugStepCheck(position);
 }
 
-
 Fragment StreamingFlowGraphBuilder::LoadLocal(LocalVariable* variable) {
   return flow_graph_builder_->LoadLocal(variable);
 }
 
+Fragment StreamingFlowGraphBuilder::Return(TokenPosition position) {
+  return flow_graph_builder_->Return(position);
+}
 
 Fragment StreamingFlowGraphBuilder::PushArgument() {
   return flow_graph_builder_->PushArgument();
 }
 
+Fragment StreamingFlowGraphBuilder::EvaluateAssertion() {
+  return flow_graph_builder_->EvaluateAssertion();
+}
 
 Fragment StreamingFlowGraphBuilder::RethrowException(TokenPosition position,
                                                      int catch_try_index) {
   return flow_graph_builder_->RethrowException(position, catch_try_index);
 }
 
-
 Fragment StreamingFlowGraphBuilder::ThrowNoSuchMethodError() {
   return flow_graph_builder_->ThrowNoSuchMethodError();
 }
 
-
 Fragment StreamingFlowGraphBuilder::Constant(const Object& value) {
   return flow_graph_builder_->Constant(value);
 }
 
-
 Fragment StreamingFlowGraphBuilder::IntConstant(int64_t value) {
   return flow_graph_builder_->IntConstant(value);
 }
 
-
 Fragment StreamingFlowGraphBuilder::LoadStaticField() {
   return flow_graph_builder_->LoadStaticField();
 }
 
-
 Fragment StreamingFlowGraphBuilder::StaticCall(TokenPosition position,
                                                const Function& target,
                                                intptr_t argument_count) {
   return flow_graph_builder_->StaticCall(position, target, argument_count);
 }
 
+Fragment StreamingFlowGraphBuilder::StaticCall(TokenPosition position,
+                                               const Function& target,
+                                               intptr_t argument_count,
+                                               const Array& argument_names) {
+  return flow_graph_builder_->StaticCall(position, target, argument_count,
+                                         argument_names);
+}
 
-Fragment StreamingFlowGraphBuilder::BuildInvalidExpression() {
+Fragment StreamingFlowGraphBuilder::InstanceCall(TokenPosition position,
+                                                 const dart::String& name,
+                                                 Token::Kind kind,
+                                                 intptr_t argument_count,
+                                                 intptr_t num_args_checked) {
+  return flow_graph_builder_->InstanceCall(position, name, kind, argument_count,
+                                           num_args_checked);
+}
+
+Fragment StreamingFlowGraphBuilder::ThrowException(TokenPosition position) {
+  return flow_graph_builder_->ThrowException(position);
+}
+
+Fragment StreamingFlowGraphBuilder::BooleanNegate() {
+  return flow_graph_builder_->BooleanNegate();
+}
+
+Fragment StreamingFlowGraphBuilder::TranslateInstantiatedTypeArguments(
+    const TypeArguments& type_arguments) {
+  return flow_graph_builder_->TranslateInstantiatedTypeArguments(
+      type_arguments);
+}
+
+Fragment StreamingFlowGraphBuilder::StrictCompare(Token::Kind kind,
+                                                  bool number_check) {
+  return flow_graph_builder_->StrictCompare(kind, number_check);
+}
+
+Fragment StreamingFlowGraphBuilder::AllocateObject(const dart::Class& klass,
+                                                   intptr_t argument_count) {
+  return flow_graph_builder_->AllocateObject(klass, argument_count);
+}
+
+Fragment StreamingFlowGraphBuilder::InstanceCall(TokenPosition position,
+                                                 const dart::String& name,
+                                                 Token::Kind kind,
+                                                 intptr_t argument_count,
+                                                 const Array& argument_names,
+                                                 intptr_t num_args_checked) {
+  return flow_graph_builder_->InstanceCall(position, name, kind, argument_count,
+                                           argument_names, num_args_checked);
+}
+
+Fragment StreamingFlowGraphBuilder::StoreLocal(TokenPosition position,
+                                               LocalVariable* variable) {
+  return flow_graph_builder_->StoreLocal(position, variable);
+}
+
+Fragment StreamingFlowGraphBuilder::StoreStaticField(TokenPosition position,
+                                                     const dart::Field& field) {
+  return flow_graph_builder_->StoreStaticField(position, field);
+}
+
+Fragment StreamingFlowGraphBuilder::StringInterpolate(TokenPosition position) {
+  return flow_graph_builder_->StringInterpolate(position);
+}
+
+Fragment StreamingFlowGraphBuilder::StringInterpolateSingle(
+    TokenPosition position) {
+  return flow_graph_builder_->StringInterpolateSingle(position);
+}
+
+Fragment StreamingFlowGraphBuilder::ThrowTypeError() {
+  return flow_graph_builder_->ThrowTypeError();
+}
+
+Fragment StreamingFlowGraphBuilder::LoadInstantiatorTypeArguments() {
+  return flow_graph_builder_->LoadInstantiatorTypeArguments();
+}
+
+Fragment StreamingFlowGraphBuilder::LoadFunctionTypeArguments() {
+  return flow_graph_builder_->LoadFunctionTypeArguments();
+}
+
+Fragment StreamingFlowGraphBuilder::InstantiateType(const AbstractType& type) {
+  return flow_graph_builder_->InstantiateType(type);
+}
+
+Fragment StreamingFlowGraphBuilder::CreateArray() {
+  return flow_graph_builder_->CreateArray();
+}
+
+Fragment StreamingFlowGraphBuilder::StoreIndexed(intptr_t class_id) {
+  return flow_graph_builder_->StoreIndexed(class_id);
+}
+
+Fragment StreamingFlowGraphBuilder::CheckStackOverflow() {
+  return flow_graph_builder_->CheckStackOverflow();
+}
+
+Fragment StreamingFlowGraphBuilder::CloneContext() {
+  return flow_graph_builder_->CloneContext();
+}
+
+Fragment StreamingFlowGraphBuilder::TranslateFinallyFinalizers(
+    TryFinallyBlock* outer_finally,
+    intptr_t target_context_depth) {
+  // TranslateFinallyFinalizers can move the readers offset.
+  // Save the current position and restore it afterwards.
+  intptr_t offset = ReaderOffset();
+  Fragment result = flow_graph_builder_->TranslateFinallyFinalizers(
+      outer_finally, target_context_depth);
+  SetOffset(offset);
+  return result;
+}
+
+Fragment StreamingFlowGraphBuilder::BranchIfTrue(
+    TargetEntryInstr** then_entry,
+    TargetEntryInstr** otherwise_entry,
+    bool negate) {
+  return flow_graph_builder_->BranchIfTrue(then_entry, otherwise_entry, negate);
+}
+
+Fragment StreamingFlowGraphBuilder::BranchIfEqual(
+    TargetEntryInstr** then_entry,
+    TargetEntryInstr** otherwise_entry,
+    bool negate) {
+  return flow_graph_builder_->BranchIfEqual(then_entry, otherwise_entry,
+                                            negate);
+}
+
+Fragment StreamingFlowGraphBuilder::BranchIfNull(
+    TargetEntryInstr** then_entry,
+    TargetEntryInstr** otherwise_entry,
+    bool negate) {
+  return flow_graph_builder_->BranchIfNull(then_entry, otherwise_entry, negate);
+}
+
+Fragment StreamingFlowGraphBuilder::CatchBlockEntry(const Array& handler_types,
+                                                    intptr_t handler_index,
+                                                    bool needs_stacktrace) {
+  return flow_graph_builder_->CatchBlockEntry(handler_types, handler_index,
+                                              needs_stacktrace);
+}
+
+Fragment StreamingFlowGraphBuilder::TryCatch(int try_handler_index) {
+  return flow_graph_builder_->TryCatch(try_handler_index);
+}
+
+Fragment StreamingFlowGraphBuilder::Drop() {
+  return flow_graph_builder_->Drop();
+}
+
+Fragment StreamingFlowGraphBuilder::NullConstant() {
+  return flow_graph_builder_->NullConstant();
+}
+
+JoinEntryInstr* StreamingFlowGraphBuilder::BuildJoinEntry() {
+  return flow_graph_builder_->BuildJoinEntry();
+}
+
+JoinEntryInstr* StreamingFlowGraphBuilder::BuildJoinEntry(intptr_t try_index) {
+  return flow_graph_builder_->BuildJoinEntry(try_index);
+}
+
+Fragment StreamingFlowGraphBuilder::Goto(JoinEntryInstr* destination) {
+  return flow_graph_builder_->Goto(destination);
+}
+
+Fragment StreamingFlowGraphBuilder::BuildImplicitClosureCreation(
+    const Function& target) {
+  return flow_graph_builder_->BuildImplicitClosureCreation(target);
+}
+
+Fragment StreamingFlowGraphBuilder::CheckBooleanInCheckedMode() {
+  return flow_graph_builder_->CheckBooleanInCheckedMode();
+}
+
+Fragment StreamingFlowGraphBuilder::CheckAssignableInCheckedMode(
+    const dart::AbstractType& dst_type,
+    const dart::String& dst_name) {
+  return flow_graph_builder_->CheckAssignableInCheckedMode(dst_type, dst_name);
+}
+
+Fragment StreamingFlowGraphBuilder::CheckVariableTypeInCheckedMode(
+    intptr_t variable_kernel_position) {
+  if (I->type_checks()) {
+    LocalVariable* variable = LookupVariable(variable_kernel_position);
+    return flow_graph_builder_->CheckVariableTypeInCheckedMode(
+        variable->type(), variable->name());
+  }
+  return Fragment();
+}
+
+Fragment StreamingFlowGraphBuilder::CheckVariableTypeInCheckedMode(
+    const AbstractType& dst_type,
+    const dart::String& name_symbol) {
+  return flow_graph_builder_->CheckVariableTypeInCheckedMode(dst_type,
+                                                             name_symbol);
+}
+
+Fragment StreamingFlowGraphBuilder::EnterScope(intptr_t kernel_offset,
+                                               bool* new_context) {
+  return flow_graph_builder_->EnterScope(kernel_offset, new_context);
+}
+
+Fragment StreamingFlowGraphBuilder::ExitScope(intptr_t kernel_offset) {
+  return flow_graph_builder_->ExitScope(kernel_offset);
+}
+
+Fragment StreamingFlowGraphBuilder::TranslateCondition(bool* negate) {
+  *negate = PeekTag() == kNot;
+  if (*negate) {
+    SkipBytes(1);  // Skip Not tag, thus go directly to the inner expression.
+  }
+  Fragment instructions = BuildExpression();  // read expression.
+  instructions += CheckBooleanInCheckedMode();
+  return instructions;
+}
+
+const TypeArguments& StreamingFlowGraphBuilder::BuildTypeArguments() {
+  ReadUInt();                                // read arguments count.
+  intptr_t types_count = ReadListLength();   // read type count.
+  return T.BuildTypeArguments(types_count);  // read types.
+}
+
+Fragment StreamingFlowGraphBuilder::BuildArguments(Array* argument_names,
+                                                   intptr_t* argument_count,
+                                                   bool skip_push_arguments,
+                                                   bool do_drop) {
+  intptr_t dummy;
+  if (argument_count == NULL) argument_count = &dummy;
+  *argument_count = ReadUInt();  // read arguments count.
+
+  // List of types.
+  intptr_t list_length = ReadListLength();  // read type count.
+  for (intptr_t i = 0; i < list_length; ++i) {
+    SkipDartType();  // read ith type.
+  }
+
+  return BuildArgumentsFromActualArguments(argument_names, skip_push_arguments,
+                                           do_drop);
+}
+
+Fragment StreamingFlowGraphBuilder::BuildArgumentsFromActualArguments(
+    Array* argument_names,
+    bool skip_push_arguments,
+    bool do_drop) {
+  Fragment instructions;
+
+  // List of positional.
+  intptr_t list_length = ReadListLength();  // read list length.
+  for (intptr_t i = 0; i < list_length; ++i) {
+    instructions += BuildExpression();  // read ith expression.
+    if (!skip_push_arguments) instructions += PushArgument();
+    if (do_drop) instructions += Drop();
+  }
+
+  // List of named.
+  list_length = ReadListLength();  // read list length.
+  if (argument_names != NULL && list_length > 0) {
+    *argument_names ^= Array::New(list_length, Heap::kOld);
+  }
+  for (intptr_t i = 0; i < list_length; ++i) {
+    dart::String& name =
+        H.DartSymbol(ReadStringReference());  // read ith name index.
+    instructions += BuildExpression();        // read ith expression.
+    if (!skip_push_arguments) instructions += PushArgument();
+    if (do_drop) instructions += Drop();
+    if (argument_names != NULL) {
+      argument_names->SetAt(i, name);
+    }
+  }
+
+  return instructions;
+}
+
+Fragment StreamingFlowGraphBuilder::BuildInvalidExpression(
+    TokenPosition* position) {
+  if (position != NULL) *position = TokenPosition::kNoSource;
+
   // The frontend will take care of emitting normal errors (like
   // [NoSuchMethodError]s) and only emit [InvalidExpression]s in very special
   // situations (e.g. an invalid annotation).
   return ThrowNoSuchMethodError();
 }
 
+Fragment StreamingFlowGraphBuilder::BuildVariableGet(TokenPosition* position) {
+  (position != NULL) ? * position = ReadPosition()
+                     : ReadPosition();             // read position.
+  intptr_t variable_kernel_position = ReadUInt();  // read kernel position.
+  ReadUInt();              // read relative variable index.
+  SkipOptionalDartType();  // read promoted type.
 
-Fragment StreamingFlowGraphBuilder::BuildStaticGet() {
-  intptr_t saved_offset = ReaderOffset() - 1;  // Include the tag.
-  TokenPosition position = ReadPosition();
-  NameIndex target = ReadCanonicalNameReference();
+  return LoadLocal(LookupVariable(variable_kernel_position));
+}
+
+Fragment StreamingFlowGraphBuilder::BuildVariableGet(uint8_t payload,
+                                                     TokenPosition* position) {
+  (position != NULL) ? * position = ReadPosition()
+                     : ReadPosition();             // read position.
+  intptr_t variable_kernel_position = ReadUInt();  // read kernel position.
+  return LoadLocal(LookupVariable(variable_kernel_position));
+}
+
+Fragment StreamingFlowGraphBuilder::BuildVariableSet(TokenPosition* p) {
+  TokenPosition position = ReadPosition();  // read position.
+  if (p != NULL) *p = position;
+
+  intptr_t variable_kernel_position = ReadUInt();  // read kernel position.
+  ReadUInt();                                 // read relative variable index.
+  Fragment instructions = BuildExpression();  // read expression.
+
+  if (NeedsDebugStepCheck(stack(), position)) {
+    instructions = DebugStepCheck(position) + instructions;
+  }
+  instructions += CheckVariableTypeInCheckedMode(variable_kernel_position);
+  instructions +=
+      StoreLocal(position, LookupVariable(variable_kernel_position));
+  return instructions;
+}
+
+Fragment StreamingFlowGraphBuilder::BuildVariableSet(uint8_t payload,
+                                                     TokenPosition* p) {
+  TokenPosition position = ReadPosition();  // read position.
+  if (p != NULL) *p = position;
+
+  intptr_t variable_kernel_position = ReadUInt();  // read kernel position.
+  Fragment instructions = BuildExpression();       // read expression.
+
+  if (NeedsDebugStepCheck(stack(), position)) {
+    instructions = DebugStepCheck(position) + instructions;
+  }
+  instructions += CheckVariableTypeInCheckedMode(variable_kernel_position);
+  instructions +=
+      StoreLocal(position, LookupVariable(variable_kernel_position));
+
+  return instructions;
+}
+
+Fragment StreamingFlowGraphBuilder::BuildPropertyGet(TokenPosition* p) {
+  TokenPosition position = ReadPosition();  // read position.
+  if (p != NULL) *p = position;
+
+  Fragment instructions = BuildExpression();  // read receiver.
+  instructions += PushArgument();
+
+  const dart::String& getter_name = ReadNameAsGetterName();  // read name.
+  SkipCanonicalNameReference();  // Read unused "interface_target_reference".
+
+  return instructions + InstanceCall(position, getter_name, Token::kGET, 1);
+}
+
+Fragment StreamingFlowGraphBuilder::BuildPropertySet(TokenPosition* p) {
+  Fragment instructions(NullConstant());
+  LocalVariable* variable = MakeTemporary();
+
+  TokenPosition position = ReadPosition();  // read position.
+  if (p != NULL) *p = position;
+
+  instructions += BuildExpression();  // read receiver.
+  instructions += PushArgument();
+
+  const dart::String& setter_name = ReadNameAsSetterName();  // read name.
+
+  instructions += BuildExpression();  // read value.
+  instructions += StoreLocal(TokenPosition::kNoSource, variable);
+  instructions += PushArgument();
+
+  SkipCanonicalNameReference();  // read unused "interface_target_reference".
+
+  instructions += InstanceCall(position, setter_name, Token::kSET, 2);
+  return instructions + Drop();
+}
+
+Fragment StreamingFlowGraphBuilder::BuildDirectPropertyGet(TokenPosition* p) {
+  TokenPosition position = ReadPosition();  // read position.
+  if (p != NULL) *p = position;
+
+  Fragment instructions = BuildExpression();  // read receiver.
+  NameIndex kernel_name =
+      ReadCanonicalNameReference();  // read target_reference.
+
+  Function& target = Function::ZoneHandle(Z);
+  if (H.IsProcedure(kernel_name)) {
+    if (H.IsGetter(kernel_name)) {
+      target = LookupMethodByMember(kernel_name, H.DartGetterName(kernel_name));
+    } else {
+      // Undo stack change for the BuildExpression.
+      Pop();
+
+      target = LookupMethodByMember(kernel_name, H.DartMethodName(kernel_name));
+      target = target.ImplicitClosureFunction();
+      ASSERT(!target.IsNull());
+      return BuildImplicitClosureCreation(target);
+    }
+  } else {
+    ASSERT(H.IsField(kernel_name));
+    const dart::String& getter_name = H.DartGetterName(kernel_name);
+    target = LookupMethodByMember(kernel_name, getter_name);
+    ASSERT(target.IsGetterFunction() || target.IsImplicitGetterFunction());
+  }
+
+  instructions += PushArgument();
+  return instructions + StaticCall(position, target, 1);
+}
+
+Fragment StreamingFlowGraphBuilder::BuildDirectPropertySet(TokenPosition* p) {
+  TokenPosition position = ReadPosition();  // read position.
+  if (p != NULL) *p = position;
+
+  Fragment instructions(NullConstant());
+  LocalVariable* value = MakeTemporary();
+
+  instructions += BuildExpression();  // read receiver.
+  instructions += PushArgument();
+
+  NameIndex target_reference =
+      ReadCanonicalNameReference();  // read target_reference.
+  const dart::String& method_name = H.DartSetterName(target_reference);
+  const Function& target = Function::ZoneHandle(
+      Z, LookupMethodByMember(target_reference, method_name));
+  ASSERT(target.IsSetterFunction() || target.IsImplicitSetterFunction());
+
+  instructions += BuildExpression();  // read value.
+  instructions += StoreLocal(TokenPosition::kNoSource, value);
+  instructions += PushArgument();
+
+  instructions += StaticCall(position, target, 2);
+
+  return instructions + Drop();
+}
+
+Fragment StreamingFlowGraphBuilder::BuildStaticGet(TokenPosition* p) {
+  intptr_t offset = ReaderOffset() - 1;  // Include the tag.
+
+  TokenPosition position = ReadPosition();  // read position.
+  if (p != NULL) *p = position;
+
+  NameIndex target = ReadCanonicalNameReference();  // read target_reference.
 
   if (H.IsField(target)) {
     const dart::Field& field =
         dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(target));
     if (field.is_const()) {
-      SetOffset(saved_offset);  // EvaluateExpression needs the tag.
-      return Constant(constant_evaluator_.EvaluateExpression());
+      return Constant(constant_evaluator_.EvaluateExpression(offset));
     } else {
       const dart::Class& owner = dart::Class::Handle(Z, field.Owner());
       const dart::String& getter_name = H.DartGetterName(target);
@@ -451,8 +2534,7 @@
     if (H.IsGetter(target)) {
       return StaticCall(position, function, 0);
     } else if (H.IsMethod(target)) {
-      SetOffset(saved_offset);  // EvaluateExpression needs the tag.
-      return Constant(constant_evaluator_.EvaluateExpression());
+      return Constant(constant_evaluator_.EvaluateExpression(offset));
     } else {
       UNIMPLEMENTED();
     }
@@ -461,20 +2543,632 @@
   return Fragment();
 }
 
+Fragment StreamingFlowGraphBuilder::BuildStaticSet(TokenPosition* p) {
+  TokenPosition position = ReadPosition();  // read position.
+  if (p != NULL) *p = position;
 
-Fragment StreamingFlowGraphBuilder::BuildSymbolLiteral() {
-  SkipBytes(-1);  // EvaluateExpression needs the tag.
-  return Constant(constant_evaluator_.EvaluateExpression());
+  NameIndex target = ReadCanonicalNameReference();  // read target_reference.
+
+  if (H.IsField(target)) {
+    const dart::Field& field =
+        dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(target));
+    const AbstractType& dst_type = AbstractType::ZoneHandle(Z, field.type());
+    Fragment instructions = BuildExpression();  // read expression.
+    if (NeedsDebugStepCheck(stack(), position)) {
+      instructions = DebugStepCheck(position) + instructions;
+    }
+    instructions += CheckAssignableInCheckedMode(
+        dst_type, dart::String::ZoneHandle(Z, field.name()));
+    LocalVariable* variable = MakeTemporary();
+    instructions += LoadLocal(variable);
+    return instructions + StoreStaticField(position, field);
+  } else {
+    ASSERT(H.IsProcedure(target));
+
+    // Evaluate the expression on the right hand side.
+    Fragment instructions = BuildExpression();  // read expression.
+    LocalVariable* variable = MakeTemporary();
+
+    // Prepare argument.
+    instructions += LoadLocal(variable);
+    instructions += PushArgument();
+
+    // Invoke the setter function.
+    const Function& function =
+        Function::ZoneHandle(Z, H.LookupStaticMethodByKernelProcedure(target));
+    instructions += StaticCall(position, function, 1);
+
+    // Drop the unused result & leave the stored value on the stack.
+    return instructions + Drop();
+  }
 }
 
+static bool IsNumberLiteral(Tag tag) {
+  return tag == kNegativeIntLiteral || tag == kPositiveIntLiteral ||
+         tag == kSpecialIntLiteral || tag == kDoubleLiteral;
+}
 
-Fragment StreamingFlowGraphBuilder::BuildThisExpression() {
+Fragment StreamingFlowGraphBuilder::BuildMethodInvocation(TokenPosition* p) {
+  intptr_t offset = ReaderOffset() - 1;     // Include the tag.
+  TokenPosition position = ReadPosition();  // read position.
+  if (p != NULL) *p = position;
+
+  Tag receiver_tag = PeekTag();  // peek tag for receiver.
+  if (IsNumberLiteral(receiver_tag)) {
+    intptr_t before_branch_offset = ReaderOffset();
+
+    SkipExpression();  // read receiver (it's just a number literal).
+
+    const dart::String& name = ReadNameAsMethodName();  // read name.
+    const Token::Kind token_kind = MethodKind(name);
+    intptr_t argument_count = PeekArgumentsCount() + 1;
+
+    if ((argument_count == 1) && (token_kind == Token::kNEGATE)) {
+      const Object& result = constant_evaluator_.EvaluateExpressionSafe(offset);
+      if (!result.IsError()) {
+        SkipArguments();  // read arguments,
+        // read unused "interface_target_reference".
+        SkipCanonicalNameReference();
+        return Constant(result);
+      }
+    } else if ((argument_count == 2) &&
+               Token::IsBinaryArithmeticOperator(token_kind) &&
+               IsNumberLiteral(PeekArgumentsFirstPositionalTag())) {
+      const Object& result = constant_evaluator_.EvaluateExpressionSafe(offset);
+      if (!result.IsError()) {
+        SkipArguments();
+        // read unused "interface_target_reference".
+        SkipCanonicalNameReference();
+        return Constant(result);
+      }
+    }
+
+    SetOffset(before_branch_offset);
+  }
+
+  Fragment instructions = BuildExpression();  // read receiver.
+
+  const dart::String& name = ReadNameAsMethodName();  // read name.
+  const Token::Kind token_kind = MethodKind(name);
+
+  // Detect comparison with null.
+  if ((token_kind == Token::kEQ || token_kind == Token::kNE) &&
+      PeekArgumentsCount() == 1 &&
+      (receiver_tag == kNullLiteral ||
+       PeekArgumentsFirstPositionalTag() == kNullLiteral)) {
+    // "==" or "!=" with null on either side.
+    instructions += BuildArguments(NULL, NULL, true);  // read arguments.
+    SkipCanonicalNameReference();  // read unused "interface_target_reference".
+    Token::Kind strict_cmp_kind =
+        token_kind == Token::kEQ ? Token::kEQ_STRICT : Token::kNE_STRICT;
+    return instructions +
+           StrictCompare(strict_cmp_kind, /*number_check = */ true);
+  }
+
+  instructions += PushArgument();  // push receiver as argument.
+
+  // TODO(28109) Support generic methods in the VM or reify them away.
+  Array& argument_names = Array::ZoneHandle(Z);
+  intptr_t argument_count;
+  instructions +=
+      BuildArguments(&argument_names, &argument_count);  // read arguments.
+  ++argument_count;
+
+  intptr_t num_args_checked = 1;
+  // If we have a special operation (e.g. +/-/==) we mark both arguments as
+  // to be checked.
+  if (token_kind != Token::kILLEGAL) {
+    ASSERT(argument_count <= 2);
+    num_args_checked = argument_count;
+  }
+
+  instructions += InstanceCall(position, name, token_kind, argument_count,
+                               argument_names, num_args_checked);
+  // Later optimization passes assume that result of a x.[]=(...) call is not
+  // used. We must guarantee this invariant because violation will lead to an
+  // illegal IL once we replace x.[]=(...) with a sequence that does not
+  // actually produce any value. See http://dartbug.com/29135 for more details.
+  if (name.raw() == Symbols::AssignIndexToken().raw()) {
+    instructions += Drop();
+    instructions += NullConstant();
+  }
+
+  SkipCanonicalNameReference();  // read unused "interface_target_reference".
+
+  return instructions;
+}
+
+Fragment StreamingFlowGraphBuilder::BuildDirectMethodInvocation(
+    TokenPosition* position) {
+  if (position != NULL) *position = TokenPosition::kNoSource;
+
+  // TODO(28109) Support generic methods in the VM or reify them away.
+  Tag receiver_tag = PeekTag();               // peek tag for receiver.
+  Fragment instructions = BuildExpression();  // read receiver.
+
+  NameIndex kernel_name =
+      ReadCanonicalNameReference();  // read target_reference.
+  const dart::String& method_name = H.DartProcedureName(kernel_name);
+  const Token::Kind token_kind = MethodKind(method_name);
+
+  // Detect comparison with null.
+  if ((token_kind == Token::kEQ || token_kind == Token::kNE) &&
+      PeekArgumentsCount() == 1 &&
+      (receiver_tag == kNullLiteral ||
+       PeekArgumentsFirstPositionalTag() == kNullLiteral)) {
+    // "==" or "!=" with null on either side.
+    instructions += BuildArguments(NULL, NULL, true);  // read arguments.
+    Token::Kind strict_cmp_kind =
+        token_kind == Token::kEQ ? Token::kEQ_STRICT : Token::kNE_STRICT;
+    return instructions +
+           StrictCompare(strict_cmp_kind, /*number_check = */ true);
+  }
+
+  instructions += PushArgument();  // push receiver as argument.
+
+  const Function& target =
+      Function::ZoneHandle(Z, LookupMethodByMember(kernel_name, method_name));
+
+  Array& argument_names = Array::ZoneHandle(Z);
+  intptr_t argument_count;
+  instructions +=
+      BuildArguments(&argument_names, &argument_count);  // read arguments.
+  ++argument_count;
+  return instructions + StaticCall(TokenPosition::kNoSource, target,
+                                   argument_count, argument_names);
+}
+
+Fragment StreamingFlowGraphBuilder::BuildStaticInvocation(bool is_const,
+                                                          TokenPosition* p) {
+  TokenPosition position = ReadPosition();  // read position.
+  if (p != NULL) *p = position;
+
+  NameIndex procedue_reference =
+      ReadCanonicalNameReference();  // read procedure reference.
+  intptr_t argument_count = PeekArgumentsCount();
+  const Function& target = Function::ZoneHandle(
+      Z, H.LookupStaticMethodByKernelProcedure(procedue_reference));
+  const dart::Class& klass = dart::Class::ZoneHandle(Z, target.Owner());
+  if (target.IsGenerativeConstructor() || target.IsFactory()) {
+    // The VM requires a TypeArguments object as first parameter for
+    // every factory constructor.
+    ++argument_count;
+  }
+
+  Fragment instructions;
+  LocalVariable* instance_variable = NULL;
+
+  // If we cross the Kernel -> VM core library boundary, a [StaticInvocation]
+  // can appear, but the thing we're calling is not a static method, but a
+  // factory constructor.
+  // The `H.LookupStaticmethodByKernelProcedure` will potentially resolve to the
+  // forwarded constructor.
+  // In that case we'll make an instance and pass it as first argument.
+  //
+  // TODO(27590): Get rid of this after we're using core libraries compiled
+  // into Kernel.
+  if (target.IsGenerativeConstructor()) {
+    if (klass.NumTypeArguments() > 0) {
+      const TypeArguments& type_arguments =
+          PeekArgumentsInstantiatedType(klass);
+      instructions += TranslateInstantiatedTypeArguments(type_arguments);
+      instructions += PushArgument();
+      instructions += AllocateObject(klass, 1);
+    } else {
+      instructions += AllocateObject(klass, 0);
+    }
+
+    instance_variable = MakeTemporary();
+
+    instructions += LoadLocal(instance_variable);
+    instructions += PushArgument();
+  } else if (target.IsFactory()) {
+    // The VM requires currently a TypeArguments object as first parameter for
+    // every factory constructor :-/ !
+    //
+    // TODO(27590): Get rid of this after we're using core libraries compiled
+    // into Kernel.
+    const TypeArguments& type_arguments = PeekArgumentsInstantiatedType(klass);
+    instructions += TranslateInstantiatedTypeArguments(type_arguments);
+    instructions += PushArgument();
+  } else {
+    // TODO(28109) Support generic methods in the VM or reify them away.
+  }
+
+  bool special_case_identical =
+      klass.IsTopLevel() && (klass.library() == dart::Library::CoreLibrary()) &&
+      (target.name() == Symbols::Identical().raw());
+
+  Array& argument_names = Array::ZoneHandle(Z);
+  instructions += BuildArguments(&argument_names, NULL,
+                                 special_case_identical);  // read arguments.
+  ASSERT(target.AreValidArguments(argument_count, argument_names, NULL));
+
+  // Special case identical(x, y) call.
+  // TODO(27590) consider moving this into the inliner and force inline it
+  // there.
+  if (special_case_identical) {
+    ASSERT(argument_count == 2);
+    instructions += StrictCompare(Token::kEQ_STRICT, /*number_check=*/true);
+  } else {
+    instructions +=
+        StaticCall(position, target, argument_count, argument_names);
+    if (target.IsGenerativeConstructor()) {
+      // Drop the result of the constructor call and leave [instance_variable]
+      // on top-of-stack.
+      instructions += Drop();
+    }
+  }
+
+  return instructions;
+}
+
+Fragment StreamingFlowGraphBuilder::BuildConstructorInvocation(
+    bool is_const,
+    TokenPosition* p) {
+  if (is_const) {
+    intptr_t offset = ReaderOffset() - 1;                 // Include the tag.
+    (p != NULL) ? * p = ReadPosition() : ReadPosition();  // read position.
+
+    SetOffset(offset);
+    SkipExpression();  // read past this ConstructorInvocation.
+    return Constant(constant_evaluator_.EvaluateConstructorInvocation(offset));
+  }
+
+  TokenPosition position = ReadPosition();  // read position.
+  if (p != NULL) *p = position;
+
+  NameIndex kernel_name =
+      ReadCanonicalNameReference();  // read target_reference.
+
+  dart::Class& klass = dart::Class::ZoneHandle(
+      Z, H.LookupClassByKernelClass(H.EnclosingName(kernel_name)));
+
+  Fragment instructions;
+
+  // Check for malbounded-ness of type.
+  if (I->type_checks()) {
+    intptr_t offset = ReaderOffset();
+
+    const TypeArguments& type_arguments = BuildTypeArguments();
+
+    AbstractType& type = AbstractType::Handle(
+        Z, Type::New(klass, type_arguments, TokenPosition::kNoSource));
+    type = ClassFinalizer::FinalizeType(klass, type);
+
+    if (type.IsMalbounded()) {
+      // Evaluate expressions for correctness.
+      instructions +=
+          BuildArgumentsFromActualArguments(NULL, false, /*do_drop*/ true);
+
+      // Throw an error & keep the [Value] on the stack.
+      instructions += ThrowTypeError();
+
+      // Bail out early.
+      return instructions;
+    }
+
+    SetOffset(offset);
+  }
+
+  if (klass.NumTypeArguments() > 0) {
+    const TypeArguments& type_arguments = PeekArgumentsInstantiatedType(klass);
+    if (!klass.IsGeneric()) {
+      Type& type = Type::ZoneHandle(Z, T.ReceiverType(klass).raw());
+
+      // TODO(27590): Can we move this code into [ReceiverType]?
+      type ^= ClassFinalizer::FinalizeType(*active_class()->klass, type,
+                                           ClassFinalizer::kFinalize);
+      ASSERT(!type.IsMalformedOrMalbounded());
+
+      TypeArguments& canonicalized_type_arguments =
+          TypeArguments::ZoneHandle(Z, type.arguments());
+      canonicalized_type_arguments =
+          canonicalized_type_arguments.Canonicalize();
+      instructions += Constant(canonicalized_type_arguments);
+    } else {
+      instructions += TranslateInstantiatedTypeArguments(type_arguments);
+    }
+
+    instructions += PushArgument();
+    instructions += AllocateObject(klass, 1);
+  } else {
+    instructions += AllocateObject(klass, 0);
+  }
+  LocalVariable* variable = MakeTemporary();
+
+  instructions += LoadLocal(variable);
+  instructions += PushArgument();
+
+  Array& argument_names = Array::ZoneHandle(Z);
+  intptr_t argument_count;
+  instructions +=
+      BuildArguments(&argument_names, &argument_count);  // read arguments.
+
+  const Function& target = Function::ZoneHandle(
+      Z, H.LookupConstructorByKernelConstructor(klass, kernel_name));
+  ++argument_count;
+  instructions += StaticCall(position, target, argument_count, argument_names);
+  return instructions + Drop();
+}
+
+Fragment StreamingFlowGraphBuilder::BuildNot(TokenPosition* position) {
+  if (position != NULL) *position = TokenPosition::kNoSource;
+
+  Fragment instructions = BuildExpression();  // read expression.
+  instructions += CheckBooleanInCheckedMode();
+  instructions += BooleanNegate();
+  return instructions;
+}
+
+Fragment StreamingFlowGraphBuilder::BuildLogicalExpression(
+    TokenPosition* position) {
+  if (position != NULL) *position = TokenPosition::kNoSource;
+
+  bool negate;
+  Fragment instructions = TranslateCondition(&negate);  // read left.
+
+  TargetEntryInstr* right_entry;
+  TargetEntryInstr* constant_entry;
+  LogicalExpression::Operator op =
+      static_cast<LogicalExpression::Operator>(ReadByte());
+
+  if (op == LogicalExpression::kAnd) {
+    instructions += BranchIfTrue(&right_entry, &constant_entry, negate);
+  } else {
+    instructions += BranchIfTrue(&constant_entry, &right_entry, negate);
+  }
+
+  Value* top = stack();
+  Fragment right_fragment(right_entry);
+  right_fragment += TranslateCondition(&negate);  // read right.
+
+  right_fragment += Constant(Bool::True());
+  right_fragment +=
+      StrictCompare(negate ? Token::kNE_STRICT : Token::kEQ_STRICT);
+  right_fragment += StoreLocal(TokenPosition::kNoSource,
+                               parsed_function()->expression_temp_var());
+  right_fragment += Drop();
+
+  ASSERT(top == stack());
+  Fragment constant_fragment(constant_entry);
+  constant_fragment += Constant(Bool::Get(op == LogicalExpression::kOr));
+  constant_fragment += StoreLocal(TokenPosition::kNoSource,
+                                  parsed_function()->expression_temp_var());
+  constant_fragment += Drop();
+
+  JoinEntryInstr* join = BuildJoinEntry();
+  right_fragment += Goto(join);
+  constant_fragment += Goto(join);
+
+  return Fragment(instructions.entry, join) +
+         LoadLocal(parsed_function()->expression_temp_var());
+}
+
+Fragment StreamingFlowGraphBuilder::BuildConditionalExpression(
+    TokenPosition* position) {
+  if (position != NULL) *position = TokenPosition::kNoSource;
+
+  bool negate;
+  Fragment instructions = TranslateCondition(&negate);  // read condition.
+
+  TargetEntryInstr* then_entry;
+  TargetEntryInstr* otherwise_entry;
+  instructions += BranchIfTrue(&then_entry, &otherwise_entry, negate);
+
+  Value* top = stack();
+  Fragment then_fragment(then_entry);
+  then_fragment += BuildExpression();  // read then.
+  then_fragment += StoreLocal(TokenPosition::kNoSource,
+                              parsed_function()->expression_temp_var());
+  then_fragment += Drop();
+  ASSERT(stack() == top);
+
+  Fragment otherwise_fragment(otherwise_entry);
+  otherwise_fragment += BuildExpression();  // read otherwise.
+  otherwise_fragment += StoreLocal(TokenPosition::kNoSource,
+                                   parsed_function()->expression_temp_var());
+  otherwise_fragment += Drop();
+  ASSERT(stack() == top);
+
+  JoinEntryInstr* join = BuildJoinEntry();
+  then_fragment += Goto(join);
+  otherwise_fragment += Goto(join);
+
+  SkipOptionalDartType();  // read unused static type.
+
+  return Fragment(instructions.entry, join) +
+         LoadLocal(parsed_function()->expression_temp_var());
+}
+
+Fragment StreamingFlowGraphBuilder::BuildStringConcatenation(TokenPosition* p) {
+  TokenPosition position = ReadPosition();  // read position.
+  if (p != NULL) *p = position;
+
+  intptr_t length = ReadListLength();  // read list length.
+  // Note: there will be "length" expressions.
+
+  Fragment instructions;
+  if (length == 1) {
+    instructions += BuildExpression();  // read expression.
+    instructions += StringInterpolateSingle(position);
+  } else {
+    // The type arguments for CreateArray.
+    instructions += Constant(TypeArguments::ZoneHandle(Z));
+    instructions += IntConstant(length);
+    instructions += CreateArray();
+    LocalVariable* array = MakeTemporary();
+
+    for (intptr_t i = 0; i < length; ++i) {
+      instructions += LoadLocal(array);
+      instructions += IntConstant(i);
+      instructions += BuildExpression();  // read ith expression.
+      instructions += StoreIndexed(kArrayCid);
+      instructions += Drop();
+    }
+
+    instructions += StringInterpolate(position);
+  }
+
+  return instructions;
+}
+
+Fragment StreamingFlowGraphBuilder::BuildIsExpression(TokenPosition* p) {
+  TokenPosition position = ReadPosition();  // read position.
+  if (p != NULL) *p = position;
+
+  Fragment instructions = BuildExpression();  // read operand.
+
+  const AbstractType& type = T.BuildType();  // read type.
+
+  // The VM does not like an instanceOf call with a dynamic type. We need to
+  // special case this situation.
+  const Type& object_type = Type::Handle(Z, Type::ObjectType());
+
+  if (type.IsMalformed()) {
+    instructions += Drop();
+    instructions += ThrowTypeError();
+    return instructions;
+  }
+
+  if (type.IsInstantiated() &&
+      object_type.IsSubtypeOf(type, NULL, NULL, Heap::kOld)) {
+    // Evaluate the expression on the left but ignore it's result.
+    instructions += Drop();
+
+    // Let condition be always true.
+    instructions += Constant(Bool::True());
+  } else {
+    instructions += PushArgument();
+
+    // See if simple instanceOf is applicable.
+    if (dart::FlowGraphBuilder::SimpleInstanceOfType(type)) {
+      instructions += Constant(type);
+      instructions += PushArgument();  // Type.
+      instructions += InstanceCall(position, dart::Library::PrivateCoreLibName(
+                                                 Symbols::_simpleInstanceOf()),
+                                   Token::kIS, 2, 2);  // 2 checked arguments.
+      return instructions;
+    }
+
+    if (!type.IsInstantiated(kCurrentClass)) {
+      instructions += LoadInstantiatorTypeArguments();
+    } else {
+      instructions += NullConstant();
+    }
+    instructions += PushArgument();  // Instantiator type arguments.
+
+    if (!type.IsInstantiated(kFunctions)) {
+      instructions += LoadFunctionTypeArguments();
+    } else {
+      instructions += NullConstant();
+    }
+    instructions += PushArgument();  // Function type arguments.
+
+    instructions += Constant(type);
+    instructions += PushArgument();  // Type.
+
+    instructions += InstanceCall(
+        position, dart::Library::PrivateCoreLibName(Symbols::_instanceOf()),
+        Token::kIS, 4);
+  }
+  return instructions;
+}
+
+Fragment StreamingFlowGraphBuilder::BuildAsExpression(TokenPosition* p) {
+  TokenPosition position = ReadPosition();  // read position.
+  if (p != NULL) *p = position;
+
+  Fragment instructions = BuildExpression();  // read operand.
+
+  const AbstractType& type = T.BuildType();  // read type.
+
+  // The VM does not like an Object_as call with a dynamic type. We need to
+  // special case this situation.
+  const Type& object_type = Type::Handle(Z, Type::ObjectType());
+
+  if (type.IsMalformed()) {
+    instructions += Drop();
+    instructions += ThrowTypeError();
+    return instructions;
+  }
+
+  if (type.IsInstantiated() &&
+      object_type.IsSubtypeOf(type, NULL, NULL, Heap::kOld)) {
+    // We already evaluated the operand on the left and just leave it there as
+    // the result of the `obj as dynamic` expression.
+  } else {
+    instructions += PushArgument();
+
+    if (!type.IsInstantiated(kCurrentClass)) {
+      instructions += LoadInstantiatorTypeArguments();
+    } else {
+      instructions += NullConstant();
+    }
+    instructions += PushArgument();  // Instantiator type arguments.
+
+    if (!type.IsInstantiated(kFunctions)) {
+      instructions += LoadFunctionTypeArguments();
+    } else {
+      instructions += NullConstant();
+    }
+    instructions += PushArgument();  // Function type arguments.
+
+    instructions += Constant(type);
+    instructions += PushArgument();  // Type.
+
+    instructions += InstanceCall(
+        position, dart::Library::PrivateCoreLibName(Symbols::_as()), Token::kAS,
+        4);
+  }
+  return instructions;
+}
+
+Fragment StreamingFlowGraphBuilder::BuildSymbolLiteral(
+    TokenPosition* position) {
+  if (position != NULL) *position = TokenPosition::kNoSource;
+
+  intptr_t offset = ReaderOffset() - 1;  // EvaluateExpression needs the tag.
+  SkipStringReference();                 // read index into string table.
+  return Constant(constant_evaluator_.EvaluateExpression(offset));
+}
+
+Fragment StreamingFlowGraphBuilder::BuildTypeLiteral(TokenPosition* position) {
+  if (position != NULL) *position = TokenPosition::kNoSource;
+
+  const AbstractType& type = T.BuildType();  // read type.
+  if (type.IsMalformed()) H.ReportError("Malformed type literal");
+
+  Fragment instructions;
+  if (type.IsInstantiated()) {
+    instructions += Constant(type);
+  } else {
+    if (!type.IsInstantiated(kCurrentClass)) {
+      instructions += LoadInstantiatorTypeArguments();
+    } else {
+      instructions += NullConstant();
+    }
+    if (!type.IsInstantiated(kFunctions)) {
+      instructions += LoadFunctionTypeArguments();
+    } else {
+      instructions += NullConstant();
+    }
+    instructions += InstantiateType(type);
+  }
+  return instructions;
+}
+
+Fragment StreamingFlowGraphBuilder::BuildThisExpression(
+    TokenPosition* position) {
+  if (position != NULL) *position = TokenPosition::kNoSource;
+
   return LoadLocal(scopes()->this_variable);
 }
 
+Fragment StreamingFlowGraphBuilder::BuildRethrow(TokenPosition* p) {
+  TokenPosition position = ReadPosition();  // read position.
+  if (p != NULL) *p = position;
 
-Fragment StreamingFlowGraphBuilder::BuildRethrow() {
-  TokenPosition position = ReadPosition();
   Fragment instructions = DebugStepCheck(position);
   instructions += LoadLocal(catch_block()->exception_var());
   instructions += PushArgument();
@@ -485,46 +3179,1140 @@
   return instructions;
 }
 
+Fragment StreamingFlowGraphBuilder::BuildThrow(TokenPosition* p) {
+  TokenPosition position = ReadPosition();  // read position.
+  if (p != NULL) *p = position;
 
-Fragment StreamingFlowGraphBuilder::BuildBigIntLiteral() {
-  const dart::String& value = H.DartString(StringIndex(ReadUInt()));
+  Fragment instructions;
+
+  instructions += BuildExpression();  // read expression.
+
+  if (NeedsDebugStepCheck(stack(), position)) {
+    instructions = DebugStepCheck(position) + instructions;
+  }
+  instructions += PushArgument();
+  instructions += ThrowException(position);
+  ASSERT(instructions.is_closed());
+
+  return instructions;
+}
+
+Fragment StreamingFlowGraphBuilder::BuildListLiteral(bool is_const,
+                                                     TokenPosition* p) {
+  if (is_const) {
+    intptr_t offset = ReaderOffset() - 1;                 // Include the tag.
+    (p != NULL) ? * p = ReadPosition() : ReadPosition();  // read position.
+
+    SetOffset(offset);
+    SkipExpression();  // read past the ListLiteral.
+    return Constant(constant_evaluator_.EvaluateListLiteral(offset));
+  }
+
+  TokenPosition position = ReadPosition();  // read position.
+  if (p != NULL) *p = position;
+
+  const TypeArguments& type_arguments = T.BuildTypeArguments(1);  // read type.
+  intptr_t length = ReadListLength();  // read list length.
+  // Note: there will be "length" expressions.
+
+  // The type argument for the factory call.
+  Fragment instructions = TranslateInstantiatedTypeArguments(type_arguments);
+  instructions += PushArgument();
+  if (length == 0) {
+    instructions += Constant(Object::empty_array());
+  } else {
+    // The type arguments for CreateArray.
+    instructions += Constant(TypeArguments::ZoneHandle(Z));
+    instructions += IntConstant(length);
+    instructions += CreateArray();
+
+    LocalVariable* array = MakeTemporary();
+    for (intptr_t i = 0; i < length; ++i) {
+      instructions += LoadLocal(array);
+      instructions += IntConstant(i);
+      instructions += BuildExpression();  // read ith expression.
+      instructions += StoreIndexed(kArrayCid);
+      instructions += Drop();
+    }
+  }
+  instructions += PushArgument();  // The array.
+
+  const dart::Class& factory_class =
+      dart::Class::Handle(Z, dart::Library::LookupCoreClass(Symbols::List()));
+  const Function& factory_method = Function::ZoneHandle(
+      Z, factory_class.LookupFactory(
+             dart::Library::PrivateCoreLibName(Symbols::ListLiteralFactory())));
+
+  return instructions + StaticCall(position, factory_method, 2);
+}
+
+Fragment StreamingFlowGraphBuilder::BuildMapLiteral(bool is_const,
+                                                    TokenPosition* p) {
+  if (is_const) {
+    intptr_t offset = ReaderOffset() - 1;  // Include the tag.
+    (p != NULL) ? * p = ReadPosition() : ReadPosition();
+
+    SetOffset(offset);
+    SkipExpression();  // Read past the MapLiteral.
+    return Constant(constant_evaluator_.EvaluateMapLiteral(offset));
+  }
+
+  TokenPosition position = ReadPosition();  // read position.
+  if (p != NULL) *p = position;
+
+  const TypeArguments& type_arguments =
+      T.BuildTypeArguments(2);  // read key_type and value_type.
+
+  // The type argument for the factory call `new Map<K, V>._fromLiteral(List)`.
+  Fragment instructions = TranslateInstantiatedTypeArguments(type_arguments);
+  instructions += PushArgument();
+
+  intptr_t length = ReadListLength();  // read list length.
+  // Note: there will be "length" map entries (i.e. key and value expressions).
+
+  if (length == 0) {
+    instructions += Constant(Object::empty_array());
+  } else {
+    // The type arguments for `new List<X>(int len)`.
+    instructions += Constant(TypeArguments::ZoneHandle(Z));
+
+    // We generate a list of tuples, i.e. [key1, value1, ..., keyN, valueN].
+    instructions += IntConstant(2 * length);
+    instructions += CreateArray();
+
+    LocalVariable* array = MakeTemporary();
+    for (intptr_t i = 0; i < length; ++i) {
+      instructions += LoadLocal(array);
+      instructions += IntConstant(2 * i);
+      instructions += BuildExpression();  // read ith key.
+      instructions += StoreIndexed(kArrayCid);
+      instructions += Drop();
+
+      instructions += LoadLocal(array);
+      instructions += IntConstant(2 * i + 1);
+      instructions += BuildExpression();  // read ith value.
+      instructions += StoreIndexed(kArrayCid);
+      instructions += Drop();
+    }
+  }
+  instructions += PushArgument();  // The array.
+
+
+  const dart::Class& map_class =
+      dart::Class::Handle(Z, dart::Library::LookupCoreClass(Symbols::Map()));
+  const Function& factory_method = Function::ZoneHandle(
+      Z, map_class.LookupFactory(
+             dart::Library::PrivateCoreLibName(Symbols::MapLiteralFactory())));
+
+  return instructions + StaticCall(position, factory_method, 2);
+}
+
+Fragment StreamingFlowGraphBuilder::BuildLet(TokenPosition* position) {
+  if (position != NULL) *position = TokenPosition::kNoSource;
+
+  Fragment instructions = BuildVariableDeclaration(false);  // read variable.
+  instructions += BuildExpression();                        // read body.
+  return instructions;
+}
+
+
+Fragment StreamingFlowGraphBuilder::BuildBigIntLiteral(
+    TokenPosition* position) {
+  if (position != NULL) *position = TokenPosition::kNoSource;
+
+  const dart::String& value =
+      H.DartString(ReadStringReference());  // read index into string table.
   return Constant(Integer::ZoneHandle(Z, Integer::New(value, Heap::kOld)));
 }
 
+Fragment StreamingFlowGraphBuilder::BuildStringLiteral(
+    TokenPosition* position) {
+  if (position != NULL) *position = TokenPosition::kNoSource;
 
-Fragment StreamingFlowGraphBuilder::BuildStringLiteral() {
-  StringIndex str_index(ReadUInt());
-  return Constant(H.DartSymbol(str_index));
+  return Constant(
+      H.DartSymbol(ReadStringReference()));  // read index into string table.
 }
 
+Fragment StreamingFlowGraphBuilder::BuildIntLiteral(uint8_t payload,
+                                                    TokenPosition* position) {
+  if (position != NULL) *position = TokenPosition::kNoSource;
 
-Fragment StreamingFlowGraphBuilder::BuildIntLiteral(uint8_t payload) {
   int64_t value = static_cast<int32_t>(payload) - SpecializedIntLiteralBias;
   return IntConstant(value);
 }
 
+Fragment StreamingFlowGraphBuilder::BuildIntLiteral(bool is_negative,
+                                                    TokenPosition* position) {
+  if (position != NULL) *position = TokenPosition::kNoSource;
 
-Fragment StreamingFlowGraphBuilder::BuildIntLiteral(bool is_negative) {
-  int64_t value = is_negative ? -static_cast<int64_t>(ReadUInt()) : ReadUInt();
+  int64_t value = is_negative ? -static_cast<int64_t>(ReadUInt())
+                              : ReadUInt();  // read value.
   return IntConstant(value);
 }
 
+Fragment StreamingFlowGraphBuilder::BuildDoubleLiteral(
+    TokenPosition* position) {
+  if (position != NULL) *position = TokenPosition::kNoSource;
 
-Fragment StreamingFlowGraphBuilder::BuildDoubleLiteral() {
-  SkipBytes(-1);  // EvaluateExpression needs the tag.
-  return Constant(constant_evaluator_.EvaluateExpression());
+  intptr_t offset = ReaderOffset() - 1;  // EvaluateExpression needs the tag.
+  SkipStringReference();                 // read index into string table.
+  return Constant(constant_evaluator_.EvaluateExpression(offset));
 }
 
+Fragment StreamingFlowGraphBuilder::BuildBoolLiteral(bool value,
+                                                     TokenPosition* position) {
+  if (position != NULL) *position = TokenPosition::kNoSource;
 
-Fragment StreamingFlowGraphBuilder::BuildBoolLiteral(bool value) {
   return Constant(Bool::Get(value));
 }
 
+Fragment StreamingFlowGraphBuilder::BuildNullLiteral(TokenPosition* position) {
+  if (position != NULL) *position = TokenPosition::kNoSource;
 
-Fragment StreamingFlowGraphBuilder::BuildNullLiteral() {
   return Constant(Instance::ZoneHandle(Z, Instance::null()));
 }
 
+Fragment StreamingFlowGraphBuilder::BuildInvalidStatement() {
+  H.ReportError("Invalid statements not implemented yet!");
+  return Fragment();
+}
+
+Fragment StreamingFlowGraphBuilder::BuildExpressionStatement() {
+  Fragment instructions = BuildExpression();  // read expression.
+  instructions += Drop();
+  return instructions;
+}
+
+Fragment StreamingFlowGraphBuilder::BuildBlock() {
+  intptr_t offset = ReaderOffset() - 1;  // Include the tag.
+
+  Fragment instructions;
+
+  instructions += EnterScope(offset);
+  intptr_t list_length = ReadListLength();  // read number of statements.
+  for (intptr_t i = 0; i < list_length; ++i) {
+    if (instructions.is_open()) {
+      instructions += BuildStatement();  // read ith statement.
+    } else {
+      SkipStatement();  // read ith statement.
+    }
+  }
+  instructions += ExitScope(offset);
+
+  return instructions;
+}
+
+Fragment StreamingFlowGraphBuilder::BuildEmptyStatement() {
+  return Fragment();
+}
+
+Fragment StreamingFlowGraphBuilder::BuildAssertStatement() {
+  if (!I->asserts()) {
+    intptr_t offset = ReaderOffset() - 1;  // Include the tag.
+    SetOffset(offset);
+    SkipStatement();  // read this statement.
+    return Fragment();
+  }
+
+  TargetEntryInstr* then;
+  TargetEntryInstr* otherwise;
+
+  Fragment instructions;
+  // Asserts can be of the following two kinds:
+  //
+  //    * `assert(expr)`
+  //    * `assert(() { ... })`
+  //
+  // The call to `_AssertionError._evaluateAssertion()` will take care of both
+  // and returns a boolean.
+  instructions += BuildExpression();  // read condition.
+  instructions += PushArgument();
+  instructions += EvaluateAssertion();
+  instructions += CheckBooleanInCheckedMode();
+  instructions += Constant(Bool::True());
+  instructions += BranchIfEqual(&then, &otherwise, false);
+
+  const dart::Class& klass = dart::Class::ZoneHandle(
+      Z, dart::Library::LookupCoreClass(Symbols::AssertionError()));
+  ASSERT(!klass.IsNull());
+  const dart::Function& constructor = dart::Function::ZoneHandle(
+      Z, klass.LookupConstructorAllowPrivate(
+             H.DartSymbol("_AssertionError._create")));
+  ASSERT(!constructor.IsNull());
+
+  const dart::String& url = H.DartString(
+      parsed_function()->function().ToLibNamePrefixedQualifiedCString(),
+      Heap::kOld);
+
+  // Create instance of _AssertionError
+  Fragment otherwise_fragment(otherwise);
+  otherwise_fragment += AllocateObject(klass, 0);
+  LocalVariable* instance = MakeTemporary();
+
+  // Call _AssertionError._create constructor.
+  otherwise_fragment += LoadLocal(instance);
+  otherwise_fragment += PushArgument();  // this
+
+  otherwise_fragment += Constant(H.DartString("<no message>", Heap::kOld));
+  otherwise_fragment += PushArgument();  // failedAssertion
+
+  otherwise_fragment += Constant(url);
+  otherwise_fragment += PushArgument();  // url
+
+  otherwise_fragment += IntConstant(0);
+  otherwise_fragment += PushArgument();  // line
+
+  otherwise_fragment += IntConstant(0);
+  otherwise_fragment += PushArgument();  // column
+
+  Tag tag = ReadTag();  // read (first part of) message.
+  if (tag == kSomething) {
+    otherwise_fragment += BuildExpression();  // read (rest of) message.
+  } else {
+    otherwise_fragment += Constant(H.DartString("<no message>", Heap::kOld));
+  }
+  otherwise_fragment += PushArgument();  // message
+
+  otherwise_fragment += StaticCall(TokenPosition::kNoSource, constructor, 6);
+  otherwise_fragment += Drop();
+
+  // Throw _AssertionError exception.
+  otherwise_fragment += PushArgument();
+  otherwise_fragment += ThrowException(TokenPosition::kNoSource);
+  otherwise_fragment += Drop();
+
+  return Fragment(instructions.entry, then);
+}
+
+Fragment StreamingFlowGraphBuilder::BuildLabeledStatement() {
+  // There can be serveral cases:
+  //
+  //   * the body contains a break
+  //   * the body doesn't contain a break
+  //
+  //   * translating the body results in a closed fragment
+  //   * translating the body results in a open fragment
+  //
+  // => We will only know which case we are in after the body has been
+  //    traversed.
+
+  BreakableBlock block(flow_graph_builder_);
+  Fragment instructions = BuildStatement();  // read body.
+  if (block.HadJumper()) {
+    if (instructions.is_open()) {
+      instructions += Goto(block.destination());
+    }
+    return Fragment(instructions.entry, block.destination());
+  } else {
+    return instructions;
+  }
+}
+
+Fragment StreamingFlowGraphBuilder::BuildBreakStatement() {
+  TokenPosition position = ReadPosition();  // read position.
+  intptr_t target_index = ReadUInt();       // read target index.
+
+  TryFinallyBlock* outer_finally = NULL;
+  intptr_t target_context_depth = -1;
+  JoinEntryInstr* destination = breakable_block()->BreakDestination(
+      target_index, &outer_finally, &target_context_depth);
+
+  Fragment instructions;
+  instructions +=
+      TranslateFinallyFinalizers(outer_finally, target_context_depth);
+  if (instructions.is_open()) {
+    if (NeedsDebugStepCheck(parsed_function()->function(), position)) {
+      instructions += DebugStepCheck(position);
+    }
+    instructions += Goto(destination);
+  }
+  return instructions;
+}
+
+Fragment StreamingFlowGraphBuilder::BuildWhileStatement() {
+  loop_depth_inc();
+  bool negate;
+  Fragment condition = TranslateCondition(&negate);  // read condition.
+  TargetEntryInstr* body_entry;
+  TargetEntryInstr* loop_exit;
+  condition += BranchIfTrue(&body_entry, &loop_exit, negate);
+
+  Fragment body(body_entry);
+  body += BuildStatement();  // read body.
+
+  Instruction* entry;
+  if (body.is_open()) {
+    JoinEntryInstr* join = BuildJoinEntry();
+    body += Goto(join);
+
+    Fragment loop(join);
+    loop += CheckStackOverflow();
+    loop += condition;
+    entry = new (Z) GotoInstr(join);
+  } else {
+    entry = condition.entry;
+  }
+
+
+  loop_depth_dec();
+  return Fragment(entry, loop_exit);
+}
+
+Fragment StreamingFlowGraphBuilder::BuildDoStatement() {
+  loop_depth_inc();
+  Fragment body = BuildStatement();  // read body.
+
+  if (body.is_closed()) {
+    SkipExpression();  // read condition.
+    loop_depth_dec();
+    return body;
+  }
+
+  bool negate;
+  JoinEntryInstr* join = BuildJoinEntry();
+  Fragment loop(join);
+  loop += CheckStackOverflow();
+  loop += body;
+  loop += TranslateCondition(&negate);  // read condition.
+  TargetEntryInstr* loop_repeat;
+  TargetEntryInstr* loop_exit;
+  loop += BranchIfTrue(&loop_repeat, &loop_exit, negate);
+
+  Fragment repeat(loop_repeat);
+  repeat += Goto(join);
+
+  loop_depth_dec();
+  return Fragment(new (Z) GotoInstr(join), loop_exit);
+}
+
+Fragment StreamingFlowGraphBuilder::BuildForStatement() {
+  intptr_t offset = ReaderOffset() - 1;  // Include the tag.
+
+  Fragment declarations;
+
+  bool new_context = false;
+  declarations += EnterScope(offset, &new_context);
+
+  intptr_t list_length = ReadListLength();  // read number of variables.
+  for (intptr_t i = 0; i < list_length; ++i) {
+    declarations += BuildVariableDeclaration(false);  // read ith variable.
+  }
+
+  loop_depth_inc();
+  bool negate = false;
+  Tag tag = ReadTag();  // Read first part of condition.
+  Fragment condition =
+      tag == kNothing ? Constant(Bool::True())
+                      : TranslateCondition(&negate);  // read rest of condition.
+  TargetEntryInstr* body_entry;
+  TargetEntryInstr* loop_exit;
+  condition += BranchIfTrue(&body_entry, &loop_exit, negate);
+
+  Fragment updates;
+  list_length = ReadListLength();  // read number of updates.
+  for (intptr_t i = 0; i < list_length; ++i) {
+    updates += BuildExpression();  // read ith update.
+    updates += Drop();
+  }
+
+  Fragment body(body_entry);
+  body += BuildStatement();  // read body.
+
+  if (body.is_open()) {
+    // We allocated a fresh context before the loop which contains captured
+    // [ForStatement] variables.  Before jumping back to the loop entry we clone
+    // the context object (at same depth) which ensures the next iteration of
+    // the body gets a fresh set of [ForStatement] variables (with the old
+    // (possibly updated) values).
+    if (new_context) body += CloneContext();
+
+    body += updates;
+    JoinEntryInstr* join = BuildJoinEntry();
+    declarations += Goto(join);
+    body += Goto(join);
+
+    Fragment loop(join);
+    loop += CheckStackOverflow();
+    loop += condition;
+  } else {
+    declarations += condition;
+  }
+
+  Fragment loop(declarations.entry, loop_exit);
+  loop_depth_dec();
+
+  loop += ExitScope(offset);
+
+  return loop;
+}
+
+Fragment StreamingFlowGraphBuilder::BuildForInStatement(bool async) {
+  intptr_t offset = ReaderOffset() - 1;  // Include the tag.
+
+  TokenPosition position = ReadPosition();  // read position.
+  intptr_t variable_kernel_position = ReaderOffset();
+  SkipVariableDeclaration();  // read variable.
+
+  TokenPosition iterable_position = TokenPosition::kNoSource;
+  Fragment instructions =
+      BuildExpression(&iterable_position);  // read iterable.
+  instructions += PushArgument();
+
+  const dart::String& iterator_getter = dart::String::ZoneHandle(
+      Z, dart::Field::GetterSymbol(Symbols::Iterator()));
+  instructions +=
+      InstanceCall(iterable_position, iterator_getter, Token::kGET, 1);
+  LocalVariable* iterator = scopes()->iterator_variables[for_in_depth()];
+  instructions += StoreLocal(TokenPosition::kNoSource, iterator);
+  instructions += Drop();
+
+  for_in_depth_inc();
+  loop_depth_inc();
+  Fragment condition = LoadLocal(iterator);
+  condition += PushArgument();
+  condition +=
+      InstanceCall(iterable_position, Symbols::MoveNext(), Token::kILLEGAL, 1);
+  TargetEntryInstr* body_entry;
+  TargetEntryInstr* loop_exit;
+  condition += BranchIfTrue(&body_entry, &loop_exit, false);
+
+  Fragment body(body_entry);
+  body += EnterScope(offset);
+  body += LoadLocal(iterator);
+  body += PushArgument();
+  const dart::String& current_getter = dart::String::ZoneHandle(
+      Z, dart::Field::GetterSymbol(Symbols::Current()));
+  body += InstanceCall(position, current_getter, Token::kGET, 1);
+  body += StoreLocal(TokenPosition::kNoSource,
+                     LookupVariable(variable_kernel_position));
+  body += Drop();
+  body += BuildStatement();  // read body.
+  body += ExitScope(offset);
+
+  if (body.is_open()) {
+    JoinEntryInstr* join = BuildJoinEntry();
+    instructions += Goto(join);
+    body += Goto(join);
+
+    Fragment loop(join);
+    loop += CheckStackOverflow();
+    loop += condition;
+  } else {
+    instructions += condition;
+  }
+
+  loop_depth_dec();
+  for_in_depth_dec();
+  return Fragment(instructions.entry, loop_exit);
+}
+
+Fragment StreamingFlowGraphBuilder::BuildSwitchStatement() {
+  // We need the number of cases. So start by getting that, then go back.
+  intptr_t offset = ReaderOffset();
+  SkipExpression();                  // temporarily skip condition
+  int num_cases = ReadListLength();  // read number of cases.
+  SetOffset(offset);
+
+  SwitchBlock block(flow_graph_builder_, num_cases);
+
+  // Instead of using a variable we should reuse the expression on the stack,
+  // since it won't be assigned again, we don't need phi nodes.
+  Fragment head_instructions = BuildExpression();  // read condition.
+  head_instructions +=
+      StoreLocal(TokenPosition::kNoSource, scopes()->switch_variable);
+  head_instructions += Drop();
+
+  num_cases = ReadListLength();  // read number of cases.
+
+  // Phase 1: Generate bodies and try to find out whether a body will be target
+  // of a jump due to:
+  //   * `continue case_label`
+  //   * `case e1: case e2: body`
+  Fragment* body_fragments = new Fragment[num_cases];
+  intptr_t* case_expression_offsets = new intptr_t[num_cases];
+  bool* case_is_default = new bool[num_cases];
+
+  for (intptr_t i = 0; i < num_cases; ++i) {
+    case_expression_offsets[i] = ReaderOffset();
+    int num_expressions = ReadListLength();  // read number of expressions.
+    for (intptr_t j = 0; j < num_expressions; ++j) {
+      ReadPosition();    // read jth position.
+      SkipExpression();  // read jth expression.
+    }
+    bool is_default = ReadBool();  // read is_default.
+    case_is_default[i] = is_default;
+    Fragment& body_fragment = body_fragments[i] =
+        BuildStatement();  // read body.
+
+    if (body_fragment.entry == NULL) {
+      // Make a NOP in order to ensure linking works properly.
+      body_fragment = NullConstant();
+      body_fragment += Drop();
+    }
+
+    // The Dart language specification mandates fall-throughs in [SwitchCase]es
+    // to be runtime errors.
+    if (!is_default && body_fragment.is_open() && (i < (num_cases - 1))) {
+      const dart::Class& klass = dart::Class::ZoneHandle(
+          Z, dart::Library::LookupCoreClass(Symbols::FallThroughError()));
+      ASSERT(!klass.IsNull());
+      const dart::Function& constructor = dart::Function::ZoneHandle(
+          Z, klass.LookupConstructorAllowPrivate(
+                 H.DartSymbol("FallThroughError._create")));
+      ASSERT(!constructor.IsNull());
+      const dart::String& url = H.DartString(
+          parsed_function()->function().ToLibNamePrefixedQualifiedCString(),
+          Heap::kOld);
+
+      // Create instance of _FallThroughError
+      body_fragment += AllocateObject(klass, 0);
+      LocalVariable* instance = MakeTemporary();
+
+      // Call _FallThroughError._create constructor.
+      body_fragment += LoadLocal(instance);
+      body_fragment += PushArgument();  // this
+
+      body_fragment += Constant(url);
+      body_fragment += PushArgument();  // url
+
+      body_fragment += NullConstant();
+      body_fragment += PushArgument();  // line
+
+      body_fragment += StaticCall(TokenPosition::kNoSource, constructor, 3);
+      body_fragment += Drop();
+
+      // Throw the exception
+      body_fragment += PushArgument();
+      body_fragment += ThrowException(TokenPosition::kNoSource);
+      body_fragment += Drop();
+    }
+
+    // If there is an implicit fall-through we have one [SwitchCase] and
+    // multiple expressions, e.g.
+    //
+    //    switch(expr) {
+    //      case a:
+    //      case b:
+    //        <stmt-body>
+    //    }
+    //
+    // This means that the <stmt-body> will have more than 1 incoming edge (one
+    // from `a == expr` and one from `a != expr && b == expr`). The
+    // `block.Destination()` records the additional jump.
+    if (num_expressions > 1) {
+      block.DestinationDirect(i);
+    }
+  }
+
+  intptr_t end_offset = ReaderOffset();
+
+  // Phase 2: Generate everything except the real bodies:
+  //   * jump directly to a body (if there is no jumper)
+  //   * jump to a wrapper block which jumps to the body (if there is a jumper)
+  Fragment current_instructions = head_instructions;
+  for (intptr_t i = 0; i < num_cases; ++i) {
+    SetOffset(case_expression_offsets[i]);
+    int num_expressions = ReadListLength();  // read length of expressions.
+
+    if (case_is_default[i]) {
+      ASSERT(i == (num_cases - 1));
+
+      // Evaluate the conditions for the default [SwitchCase] just for the
+      // purpose of potentially triggering a compile-time error.
+
+      for (intptr_t j = 0; j < num_expressions; ++j) {
+        ReadPosition();  // read jth position.
+        // this reads the expression, but doesn't skip past it.
+        constant_evaluator_.EvaluateExpression(ReaderOffset());
+        SkipExpression();  // read jth expression.
+      }
+
+      if (block.HadJumper(i)) {
+        // There are several branches to the body, so we will make a goto to
+        // the join block (and prepend a join instruction to the real body).
+        JoinEntryInstr* join = block.DestinationDirect(i);
+        current_instructions += Goto(join);
+
+        current_instructions = Fragment(current_instructions.entry, join);
+        current_instructions += body_fragments[i];
+      } else {
+        current_instructions += body_fragments[i];
+      }
+    } else {
+      JoinEntryInstr* body_join = NULL;
+      if (block.HadJumper(i)) {
+        body_join = block.DestinationDirect(i);
+        body_fragments[i] = Fragment(body_join) + body_fragments[i];
+      }
+
+      for (intptr_t j = 0; j < num_expressions; ++j) {
+        TargetEntryInstr* then;
+        TargetEntryInstr* otherwise;
+
+        TokenPosition position = ReadPosition();  // read jth position.
+        current_instructions +=
+            Constant(constant_evaluator_.EvaluateExpression(ReaderOffset()));
+        SkipExpression();  // read jth expression.
+        current_instructions += PushArgument();
+        current_instructions += LoadLocal(scopes()->switch_variable);
+        current_instructions += PushArgument();
+        current_instructions +=
+            InstanceCall(position, Symbols::EqualOperator(), Token::kEQ,
+                         /*argument_count=*/2,
+                         /*num_args_checked=*/2);
+        current_instructions += BranchIfTrue(&then, &otherwise, false);
+
+        Fragment then_fragment(then);
+
+        if (body_join != NULL) {
+          // There are several branches to the body, so we will make a goto to
+          // the join block (the real body has already been prepended with a
+          // join instruction).
+          then_fragment += Goto(body_join);
+        } else {
+          // There is only a signle branch to the body, so we will just append
+          // the body fragment.
+          then_fragment += body_fragments[i];
+        }
+
+        current_instructions = Fragment(otherwise);
+      }
+    }
+  }
+
+  bool has_no_default = num_cases > 0 && !case_is_default[num_cases - 1];
+  if (has_no_default) {
+    // There is no default, which means we have an open [current_instructions]
+    // (which is a [TargetEntryInstruction] for the last "otherwise" branch).
+    //
+    // Furthermore the last [SwitchCase] can be open as well.  If so, we need
+    // to join these two.
+    Fragment& last_body = body_fragments[num_cases - 1];
+    if (last_body.is_open()) {
+      ASSERT(current_instructions.is_open());
+      ASSERT(current_instructions.current->IsTargetEntry());
+
+      // Join the last "otherwise" branch and the last [SwitchCase] fragment.
+      JoinEntryInstr* join = BuildJoinEntry();
+      current_instructions += Goto(join);
+      last_body += Goto(join);
+
+      current_instructions = Fragment(join);
+    }
+  } else {
+    // All non-default cases will be closed (i.e. break/continue/throw/return)
+    // So it is fine to just let more statements after the switch append to the
+    // default case.
+  }
+
+  delete[] body_fragments;
+
+  SetOffset(end_offset);
+  return Fragment(head_instructions.entry, current_instructions.current);
+}
+
+Fragment StreamingFlowGraphBuilder::BuildContinueSwitchStatement() {
+  intptr_t target_index = ReadUInt();  // read target index.
+
+  TryFinallyBlock* outer_finally = NULL;
+  intptr_t target_context_depth = -1;
+  JoinEntryInstr* entry = switch_block()->Destination(
+      target_index, &outer_finally, &target_context_depth);
+
+  Fragment instructions;
+  instructions +=
+      TranslateFinallyFinalizers(outer_finally, target_context_depth);
+  if (instructions.is_open()) {
+    instructions += Goto(entry);
+  }
+  return instructions;
+}
+
+Fragment StreamingFlowGraphBuilder::BuildIfStatement() {
+  bool negate;
+  Fragment instructions = TranslateCondition(&negate);  // read condition.
+  TargetEntryInstr* then_entry;
+  TargetEntryInstr* otherwise_entry;
+  instructions += BranchIfTrue(&then_entry, &otherwise_entry, negate);
+
+  Fragment then_fragment(then_entry);
+  then_fragment += BuildStatement();  // read then.
+
+  Fragment otherwise_fragment(otherwise_entry);
+  otherwise_fragment += BuildStatement();  // read otherwise.
+
+  if (then_fragment.is_open()) {
+    if (otherwise_fragment.is_open()) {
+      JoinEntryInstr* join = BuildJoinEntry();
+      then_fragment += Goto(join);
+      otherwise_fragment += Goto(join);
+      return Fragment(instructions.entry, join);
+    } else {
+      return Fragment(instructions.entry, then_fragment.current);
+    }
+  } else if (otherwise_fragment.is_open()) {
+    return Fragment(instructions.entry, otherwise_fragment.current);
+  } else {
+    return instructions.closed();
+  }
+}
+
+Fragment StreamingFlowGraphBuilder::BuildReturnStatement() {
+  TokenPosition position = ReadPosition();  // read position.
+  Tag tag = ReadTag();                      // read first part of expression.
+
+  bool inside_try_finally = try_finally_block() != NULL;
+
+  Fragment instructions = tag == kNothing
+                              ? NullConstant()
+                              : BuildExpression();  // read rest of expression.
+
+  if (instructions.is_open()) {
+    if (inside_try_finally) {
+      ASSERT(scopes()->finally_return_variable != NULL);
+      const Function& function = parsed_function()->function();
+      if (NeedsDebugStepCheck(function, position)) {
+        instructions += DebugStepCheck(position);
+      }
+      instructions += StoreLocal(position, scopes()->finally_return_variable);
+      instructions += Drop();
+      instructions += TranslateFinallyFinalizers(NULL, -1);
+      if (instructions.is_open()) {
+        instructions += LoadLocal(scopes()->finally_return_variable);
+        instructions += Return(TokenPosition::kNoSource);
+      }
+    } else {
+      instructions += Return(position);
+    }
+  } else {
+    Pop();
+  }
+
+  return instructions;
+}
+
+Fragment StreamingFlowGraphBuilder::BuildTryCatch() {
+  InlineBailout("kernel::FlowgraphBuilder::VisitTryCatch");
+
+  intptr_t try_handler_index = AllocateTryIndex();
+  Fragment try_body = TryCatch(try_handler_index);
+  JoinEntryInstr* after_try = BuildJoinEntry();
+
+  // Fill in the body of the try.
+  try_depth_inc();
+  {
+    TryCatchBlock block(flow_graph_builder_, try_handler_index);
+    try_body += BuildStatement();  // read body.
+    try_body += Goto(after_try);
+  }
+  try_depth_dec();
+
+  bool needs_stacktrace = ReadBool();  // read any_catch_needs_stack_trace
+
+  catch_depth_inc();
+  intptr_t num_matches = ReadListLength();  // read number of catches.
+  const Array& handler_types =
+      Array::ZoneHandle(Z, Array::New(num_matches, Heap::kOld));
+  Fragment catch_body =
+      CatchBlockEntry(handler_types, try_handler_index, needs_stacktrace);
+  // Fill in the body of the catch.
+  for (intptr_t i = 0; i < num_matches; ++i) {
+    intptr_t catch_offset = ReaderOffset();  // Catch has no tag.
+    Tag tag = PeekTag();                     // peek guard type.
+    AbstractType* type_guard = NULL;
+    if (tag != kDynamicType) {
+      type_guard = &T.BuildType();  // read guard.
+      handler_types.SetAt(i, *type_guard);
+    } else {
+      SkipDartType();  // read guard.
+      handler_types.SetAt(i, Object::dynamic_type());
+    }
+
+    Fragment catch_handler_body = EnterScope(catch_offset);
+
+    tag = ReadTag();  // read first part of exception.
+    if (tag == kSomething) {
+      catch_handler_body += LoadLocal(CurrentException());
+      catch_handler_body +=
+          StoreLocal(TokenPosition::kNoSource, LookupVariable(ReaderOffset()));
+      catch_handler_body += Drop();
+      SkipVariableDeclaration();  // read exception.
+    }
+
+    tag = ReadTag();  // read first part of stack trace.
+    if (tag == kSomething) {
+      catch_handler_body += LoadLocal(CurrentStackTrace());
+      catch_handler_body +=
+          StoreLocal(TokenPosition::kNoSource, LookupVariable(ReaderOffset()));
+      catch_handler_body += Drop();
+      SkipVariableDeclaration();  // read stack trace.
+    }
+
+    {
+      CatchBlock block(flow_graph_builder_, CurrentException(),
+                       CurrentStackTrace(), try_handler_index);
+
+      catch_handler_body += BuildStatement();  // read body.
+
+      // Note: ExitScope adjusts context_depth_ so even if catch_handler_body
+      // is closed we still need to execute ExitScope for its side effect.
+      catch_handler_body += ExitScope(catch_offset);
+      if (catch_handler_body.is_open()) {
+        catch_handler_body += Goto(after_try);
+      }
+    }
+
+    if (type_guard != NULL) {
+      if (type_guard->IsMalformed()) {
+        catch_body += ThrowTypeError();
+        catch_body += Drop();
+      } else {
+        catch_body += LoadLocal(CurrentException());
+        catch_body += PushArgument();  // exception
+        catch_body += NullConstant();
+        catch_body += PushArgument();  // instantiator type arguments
+        catch_body += NullConstant();
+        catch_body += PushArgument();  // function type arguments
+        catch_body += Constant(*type_guard);
+        catch_body += PushArgument();  // guard type
+        catch_body += InstanceCall(
+            TokenPosition::kNoSource,
+            dart::Library::PrivateCoreLibName(Symbols::_instanceOf()),
+            Token::kIS, 4);
+
+        TargetEntryInstr* catch_entry;
+        TargetEntryInstr* next_catch_entry;
+        catch_body += BranchIfTrue(&catch_entry, &next_catch_entry, false);
+
+        Fragment(catch_entry) + catch_handler_body;
+        catch_body = Fragment(next_catch_entry);
+      }
+    } else {
+      catch_body += catch_handler_body;
+    }
+  }
+
+  // In case the last catch body was not handling the exception and branching to
+  // after the try block, we will rethrow the exception (i.e. no default catch
+  // handler).
+  if (catch_body.is_open()) {
+    catch_body += LoadLocal(CurrentException());
+    catch_body += PushArgument();
+    catch_body += LoadLocal(CurrentStackTrace());
+    catch_body += PushArgument();
+    catch_body += RethrowException(TokenPosition::kNoSource, try_handler_index);
+    Drop();
+  }
+  catch_depth_dec();
+
+  return Fragment(try_body.entry, after_try);
+}
+
+Fragment StreamingFlowGraphBuilder::BuildTryFinally() {
+  // Note on streaming:
+  // We only stream this TryFinally if we can stream everything inside it,
+  // so creating a "TryFinallyBlock" with a kernel binary offset instead of an
+  // AST node isn't a problem.
+
+
+  InlineBailout("kernel::FlowgraphBuilder::VisitTryFinally");
+
+  // There are 5 different cases where we need to execute the finally block:
+  //
+  //  a) 1/2/3th case: Special control flow going out of `node->body()`:
+  //
+  //   * [BreakStatement] transfers control to a [LabledStatement]
+  //   * [ContinueSwitchStatement] transfers control to a [SwitchCase]
+  //   * [ReturnStatement] returns a value
+  //
+  //   => All three cases will automatically append all finally blocks
+  //      between the branching point and the destination (so we don't need to
+  //      do anything here).
+  //
+  //  b) 4th case: Translating the body resulted in an open fragment (i.e. body
+  //               executes without any control flow out of it)
+  //
+  //   => We are responsible for jumping out of the body to a new block (with
+  //      different try index) and execute the finalizer.
+  //
+  //  c) 5th case: An exception occurred inside the body.
+  //
+  //   => We are responsible for catching it, executing the finally block and
+  //      rethrowing the exception.
+  intptr_t try_handler_index = AllocateTryIndex();
+  Fragment try_body = TryCatch(try_handler_index);
+  JoinEntryInstr* after_try = BuildJoinEntry();
+
+  intptr_t offset = ReaderOffset();
+  SkipStatement();  // temporarily read body.
+  intptr_t finalizer_offset = ReaderOffset();
+  SetOffset(offset);
+
+  // Fill in the body of the try.
+  try_depth_inc();
+  {
+    TryFinallyBlock tfb(flow_graph_builder_, NULL, finalizer_offset);
+    TryCatchBlock tcb(flow_graph_builder_, try_handler_index);
+    try_body += BuildStatement();  // read body.
+  }
+  try_depth_dec();
+
+  if (try_body.is_open()) {
+    // Please note: The try index will be on level out of this block,
+    // thereby ensuring if there's an exception in the finally block we
+    // won't run it twice.
+    JoinEntryInstr* finally_entry = BuildJoinEntry();
+
+    try_body += Goto(finally_entry);
+
+    Fragment finally_body(finally_entry);
+    finally_body += BuildStatement();  // read finalizer.
+    finally_body += Goto(after_try);
+  }
+
+  // Fill in the body of the catch.
+  catch_depth_inc();
+  const Array& handler_types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld));
+  handler_types.SetAt(0, Object::dynamic_type());
+  // Note: rethrow will actually force mark the handler as needing a stacktrace.
+  Fragment finally_body = CatchBlockEntry(handler_types, try_handler_index,
+                                          /* needs_stacktrace = */ false);
+  SetOffset(finalizer_offset);
+  finally_body += BuildStatement();  // read finalizer
+  if (finally_body.is_open()) {
+    finally_body += LoadLocal(CurrentException());
+    finally_body += PushArgument();
+    finally_body += LoadLocal(CurrentStackTrace());
+    finally_body += PushArgument();
+    finally_body +=
+        RethrowException(TokenPosition::kNoSource, try_handler_index);
+    Drop();
+  }
+  catch_depth_dec();
+
+  return Fragment(try_body.entry, after_try);
+}
+
+Fragment StreamingFlowGraphBuilder::BuildYieldStatement() {
+  TokenPosition position = ReadPosition();  // read position.
+  uint8_t flags = ReadByte();               // read flags.
+
+  ASSERT((flags & YieldStatement::kFlagNative) ==
+         YieldStatement::kFlagNative);  // Must have been desugared.
+
+  // Setup yield/continue point:
+  //
+  //   ...
+  //   :await_jump_var = index;
+  //   :await_ctx_var = :current_context_var
+  //   return <expr>
+  //
+  // Continuation<index>:
+  //   Drop(1)
+  //   ...
+  //
+  // BuildGraphOfFunction will create a dispatch that jumps to
+  // Continuation<:await_jump_var> upon entry to the function.
+  //
+  Fragment instructions = IntConstant(yield_continuations().length() + 1);
+  instructions +=
+      StoreLocal(TokenPosition::kNoSource, scopes()->yield_jump_variable);
+  instructions += Drop();
+  instructions += LoadLocal(parsed_function()->current_context_var());
+  instructions +=
+      StoreLocal(TokenPosition::kNoSource, scopes()->yield_context_variable);
+  instructions += Drop();
+  instructions += BuildExpression();  // read expression.
+  instructions += Return(TokenPosition::kNoSource);
+
+  // Note: DropTempsInstr serves as an anchor instruction. It will not
+  // be linked into the resulting graph.
+  DropTempsInstr* anchor = new (Z) DropTempsInstr(0, NULL);
+  yield_continuations().Add(YieldContinuation(anchor, CurrentTryIndex()));
+
+  Fragment continuation(instructions.entry, anchor);
+
+  if (parsed_function()->function().IsAsyncClosure() ||
+      parsed_function()->function().IsAsyncGenClosure()) {
+    // If function is async closure or async gen closure it takes three
+    // parameters where the second and the third are exception and stack_trace.
+    // Check if exception is non-null and rethrow it.
+    //
+    //   :async_op([:result, :exception, :stack_trace]) {
+    //     ...
+    //     Continuation<index>:
+    //       if (:exception != null) rethrow(:exception, :stack_trace);
+    //     ...
+    //   }
+    //
+    LocalScope* scope = parsed_function()->node_sequence()->scope();
+    LocalVariable* exception_var = scope->VariableAt(2);
+    LocalVariable* stack_trace_var = scope->VariableAt(3);
+    ASSERT(exception_var->name().raw() == Symbols::ExceptionParameter().raw());
+    ASSERT(stack_trace_var->name().raw() ==
+           Symbols::StackTraceParameter().raw());
+
+    TargetEntryInstr* no_error;
+    TargetEntryInstr* error;
+
+    continuation += LoadLocal(exception_var);
+    continuation += BranchIfNull(&no_error, &error);
+
+    Fragment rethrow(error);
+    rethrow += LoadLocal(exception_var);
+    rethrow += PushArgument();
+    rethrow += LoadLocal(stack_trace_var);
+    rethrow += PushArgument();
+    rethrow += RethrowException(position, CatchClauseNode::kInvalidTryIndex);
+    Drop();
+
+
+    continuation = Fragment(continuation.entry, no_error);
+  }
+
+  return continuation;
+}
+
+Fragment StreamingFlowGraphBuilder::BuildVariableDeclaration(bool has_tag) {
+  intptr_t kernel_position = ReaderOffset() - (has_tag ? 1 : 0);
+  LocalVariable* variable = LookupVariable(kernel_position);
+
+  TokenPosition position = ReadPosition();         // read position.
+  TokenPosition equals_position = ReadPosition();  // read equals position.
+  word flags = ReadFlags();                        // read flags.
+  dart::String& name = H.DartSymbol(ReadStringReference());  // read name index.
+  AbstractType& type = T.BuildType();                        // read type.
+  Tag tag = ReadTag();  // read (first part of) initializer.
+
+  Fragment instructions;
+  if (tag == kNothing) {
+    instructions += NullConstant();
+  } else {
+    if ((flags & VariableDeclaration::kFlagConst) ==
+        VariableDeclaration::kFlagConst) {
+      // Const!
+      const Instance& constant_value = constant_evaluator_.EvaluateExpression(
+          ReaderOffset());  // read initializer form current position.
+      variable->SetConstValue(constant_value);
+      instructions += Constant(constant_value);
+      SkipExpression();  // skip initializer.
+    } else {
+      // Initializer
+      instructions += BuildExpression();  // read (actual) initializer.
+      instructions += CheckVariableTypeInCheckedMode(type, name);
+    }
+  }
+
+  // Use position of equal sign if it exists. If the equal sign does not exist
+  // use the position of the identifier.
+  TokenPosition debug_position = Utils::Maximum(position, equals_position);
+  if (NeedsDebugStepCheck(stack(), debug_position)) {
+    instructions = DebugStepCheck(debug_position) + instructions;
+  }
+  instructions += StoreLocal(position, variable);
+  instructions += Drop();
+  return instructions;
+}
 
 }  // namespace kernel
 }  // namespace dart
diff --git a/runtime/vm/kernel_binary_flowgraph.h b/runtime/vm/kernel_binary_flowgraph.h
index 124987a..3e741db 100644
--- a/runtime/vm/kernel_binary_flowgraph.h
+++ b/runtime/vm/kernel_binary_flowgraph.h
@@ -17,27 +17,132 @@
 namespace dart {
 namespace kernel {
 
+class StreamingDartTypeTranslator {
+ public:
+  StreamingDartTypeTranslator(StreamingFlowGraphBuilder* builder,
+                              bool finalize = false);
+
+  // Can return a malformed type.
+  AbstractType& BuildType();
+  // Will return `TypeArguments::null()` in case any of the arguments are
+  // malformed.
+  const TypeArguments& BuildTypeArguments(intptr_t length);
+
+  // Will return `TypeArguments::null()` in case any of the arguments are
+  // malformed.
+  const TypeArguments& BuildInstantiatedTypeArguments(
+      const dart::Class& receiver_class,
+      intptr_t length);
+
+  const Type& ReceiverType(const dart::Class& klass);
+
+ private:
+  // Can build a malformed type.
+  void BuildTypeInternal();
+  void BuildInterfaceType(bool simple);
+  void BuildFunctionType(bool simple);
+  void BuildTypeParameterType();
+
+  class TypeParameterScope {
+   public:
+    TypeParameterScope(StreamingDartTypeTranslator* translator,
+                       intptr_t* parameters,
+                       intptr_t parameters_count)
+        : parameters_(parameters),
+          parameters_count_(parameters_count),
+          outer_(translator->type_parameter_scope_),
+          translator_(translator) {
+      translator_->type_parameter_scope_ = this;
+    }
+    ~TypeParameterScope() {
+      delete[] parameters_;
+      translator_->type_parameter_scope_ = outer_;
+    }
+
+    TypeParameterScope* outer() const { return outer_; }
+    intptr_t* parameters() const { return parameters_; }
+    intptr_t parameters_count() const { return parameters_count_; }
+
+   private:
+    intptr_t* parameters_;
+    intptr_t parameters_count_;
+    TypeParameterScope* outer_;
+    StreamingDartTypeTranslator* translator_;
+  };
+
+  StreamingFlowGraphBuilder* builder_;
+  TranslationHelper& translation_helper_;
+  ActiveClass* active_class_;
+  TypeParameterScope* type_parameter_scope_;
+  Zone* zone_;
+  AbstractType& result_;
+  bool finalize_;
+};
+
+
 class StreamingConstantEvaluator {
  public:
-  StreamingConstantEvaluator(StreamingFlowGraphBuilder* builder,
-                             Zone* zone,
-                             TranslationHelper* h,
-                             DartTypeTranslator* type_translator);
+  explicit StreamingConstantEvaluator(StreamingFlowGraphBuilder* builder);
 
   virtual ~StreamingConstantEvaluator() {}
 
-  Instance& EvaluateExpression();
-
-  void EvaluateStaticGet();
-  void EvaluateSymbolLiteral();
-  void EvaluateDoubleLiteral();
+  Instance& EvaluateExpression(intptr_t offset, bool reset_position = true);
+  Instance& EvaluateListLiteral(intptr_t offset, bool reset_position = true);
+  Instance& EvaluateMapLiteral(intptr_t offset, bool reset_position = true);
+  Instance& EvaluateConstructorInvocation(intptr_t offset,
+                                          bool reset_position = true);
+  Object& EvaluateExpressionSafe(intptr_t offset);
 
  private:
+  void EvaluateVariableGet();
+  void EvaluateVariableGet(uint8_t payload);
+  void EvaluatePropertyGet();
+  void EvaluateStaticGet();
+  void EvaluateMethodInvocation();
+  void EvaluateStaticInvocation();
+  void EvaluateConstructorInvocationInternal();
+  void EvaluateNot();
+  void EvaluateLogicalExpression();
+  void EvaluateConditionalExpression();
+  void EvaluateStringConcatenation();
+  void EvaluateSymbolLiteral();
+  void EvaluateTypeLiteral();
+  void EvaluateListLiteralInternal();
+  void EvaluateMapLiteralInternal();
+  void EvaluateLet();
+  void EvaluateBigIntLiteral();
+  void EvaluateStringLiteral();
+  void EvaluateIntLiteral(uint8_t payload);
+  void EvaluateIntLiteral(bool is_negative);
+  void EvaluateDoubleLiteral();
+  void EvaluateBoolLiteral(bool value);
+  void EvaluateNullLiteral();
+
+  const Object& RunFunction(const Function& function,
+                            intptr_t argument_count,
+                            const Instance* receiver,
+                            const TypeArguments* type_args);
+
+  const Object& RunFunction(const Function& function,
+                            const Array& arguments,
+                            const Array& names);
+
   RawObject* EvaluateConstConstructorCall(const dart::Class& type_class,
                                           const TypeArguments& type_arguments,
                                           const Function& constructor,
                                           const Object& argument);
 
+  const TypeArguments* TranslateTypeArguments(const Function& target,
+                                              dart::Class* target_klass);
+
+  void AssertBoolInCheckedMode() {
+    if (isolate_->type_checks() && !result_.IsBool()) {
+      translation_helper_.ReportError("Expected boolean expression.");
+    }
+  }
+
+  bool EvaluateBooleanExpressionHere();
+
   bool GetCachedConstant(intptr_t kernel_offset, Instance* value);
   void CacheConstantValue(intptr_t kernel_offset, const Instance& value);
 
@@ -45,7 +150,7 @@
   Isolate* isolate_;
   Zone* zone_;
   TranslationHelper& translation_helper_;
-  //  DartTypeTranslator& type_translator_;
+  StreamingDartTypeTranslator& type_translator_;
 
   Script& script_;
   Instance& result_;
@@ -61,32 +166,91 @@
         translation_helper_(flow_graph_builder->translation_helper_),
         zone_(flow_graph_builder->zone_),
         reader_(new Reader(buffer, buffer_length)),
-        constant_evaluator_(this,
-                            flow_graph_builder->zone_,
-                            &flow_graph_builder->translation_helper_,
-                            &flow_graph_builder->type_translator_) {}
+        constant_evaluator_(this),
+        type_translator_(this, /* finalize= */ true) {}
 
-  virtual ~StreamingFlowGraphBuilder() {}
-
-  Fragment BuildAt(intptr_t kernel_offset);
+  Fragment BuildExpressionAt(intptr_t kernel_offset);
+  Fragment BuildStatementAt(intptr_t kernel_offset);
 
  private:
+  Fragment BuildExpression(TokenPosition* position = NULL);
+  Fragment BuildStatement();
+
   intptr_t ReaderOffset();
   void SetOffset(intptr_t offset);
   void SkipBytes(intptr_t skip);
+  bool ReadBool();
+  uint8_t ReadByte();
   uint32_t ReadUInt();
+  uint32_t PeekUInt();
   intptr_t ReadListLength();
+  StringIndex ReadStringReference();
   NameIndex ReadCanonicalNameReference();
+  StringIndex ReadNameAsStringIndex();
+  const dart::String& ReadNameAsMethodName();
+  const dart::String& ReadNameAsGetterName();
+  const dart::String& ReadNameAsSetterName();
+  void SkipStringReference();
+  void SkipCanonicalNameReference();
+  void SkipDartType();
+  void SkipOptionalDartType();
+  void SkipInterfaceType(bool simple);
+  void SkipFunctionType(bool simple);
+  void SkipExpression();
+  void SkipStatement();
+  void SkipName();
+  void SkipArguments();
+  void SkipVariableDeclaration();
   TokenPosition ReadPosition(bool record = true);
   Tag ReadTag(uint8_t* payload = NULL);
+  Tag PeekTag(uint8_t* payload = NULL);
+  word ReadFlags();
 
+  void loop_depth_inc();
+  void loop_depth_dec();
+  intptr_t for_in_depth();
+  void for_in_depth_inc();
+  void for_in_depth_dec();
+  void catch_depth_inc();
+  void catch_depth_dec();
+  void try_depth_inc();
+  void try_depth_dec();
+  intptr_t CurrentTryIndex();
+  intptr_t AllocateTryIndex();
+  LocalVariable* CurrentException();
+  LocalVariable* CurrentStackTrace();
   CatchBlock* catch_block();
+  ActiveClass* active_class();
   ScopeBuildingResult* scopes();
   ParsedFunction* parsed_function();
+  TryFinallyBlock* try_finally_block();
+  SwitchBlock* switch_block();
+  BreakableBlock* breakable_block();
+  GrowableArray<YieldContinuation>& yield_continuations();
+  Value* stack();
+  Value* Pop();
 
+  Tag PeekArgumentsFirstPositionalTag();
+  const TypeArguments& PeekArgumentsInstantiatedType(const dart::Class& klass);
+  intptr_t PeekArgumentsCount();
+  intptr_t PeekArgumentsTypeCount();
+  void SkipArgumentsBeforeActualArguments();
+
+  LocalVariable* LookupVariable(intptr_t kernel_offset);
+  LocalVariable* MakeTemporary();
+  Token::Kind MethodKind(const dart::String& name);
+  dart::RawFunction* LookupMethodByMember(NameIndex target,
+                                          const dart::String& method_name);
+
+  bool NeedsDebugStepCheck(const Function& function, TokenPosition position);
+  bool NeedsDebugStepCheck(Value* value, TokenPosition position);
+
+  void InlineBailout(const char* reason);
   Fragment DebugStepCheck(TokenPosition position);
   Fragment LoadLocal(LocalVariable* variable);
+  Fragment Return(TokenPosition position);
   Fragment PushArgument();
+  Fragment EvaluateAssertion();
   Fragment RethrowException(TokenPosition position, int catch_try_index);
   Fragment ThrowNoSuchMethodError();
   Fragment Constant(const Object& value);
@@ -95,27 +259,145 @@
   Fragment StaticCall(TokenPosition position,
                       const Function& target,
                       intptr_t argument_count);
+  Fragment StaticCall(TokenPosition position,
+                      const Function& target,
+                      intptr_t argument_count,
+                      const Array& argument_names);
+  Fragment InstanceCall(TokenPosition position,
+                        const dart::String& name,
+                        Token::Kind kind,
+                        intptr_t argument_count,
+                        intptr_t num_args_checked = 1);
+  Fragment InstanceCall(TokenPosition position,
+                        const dart::String& name,
+                        Token::Kind kind,
+                        intptr_t argument_count,
+                        const Array& argument_names,
+                        intptr_t num_args_checked);
+  Fragment ThrowException(TokenPosition position);
+  Fragment BooleanNegate();
+  Fragment TranslateInstantiatedTypeArguments(
+      const TypeArguments& type_arguments);
+  Fragment StrictCompare(Token::Kind kind, bool number_check = false);
+  Fragment AllocateObject(const dart::Class& klass, intptr_t argument_count);
+  Fragment StoreLocal(TokenPosition position, LocalVariable* variable);
+  Fragment StoreStaticField(TokenPosition position, const dart::Field& field);
+  Fragment StringInterpolate(TokenPosition position);
+  Fragment StringInterpolateSingle(TokenPosition position);
+  Fragment ThrowTypeError();
+  Fragment LoadInstantiatorTypeArguments();
+  Fragment LoadFunctionTypeArguments();
+  Fragment InstantiateType(const AbstractType& type);
+  Fragment CreateArray();
+  Fragment StoreIndexed(intptr_t class_id);
+  Fragment CheckStackOverflow();
+  Fragment CloneContext();
+  Fragment TranslateFinallyFinalizers(TryFinallyBlock* outer_finally,
+                                      intptr_t target_context_depth);
+  Fragment BranchIfTrue(TargetEntryInstr** then_entry,
+                        TargetEntryInstr** otherwise_entry,
+                        bool negate);
+  Fragment BranchIfEqual(TargetEntryInstr** then_entry,
+                         TargetEntryInstr** otherwise_entry,
+                         bool negate);
+  Fragment BranchIfNull(TargetEntryInstr** then_entry,
+                        TargetEntryInstr** otherwise_entry,
+                        bool negate = false);
+  Fragment CatchBlockEntry(const Array& handler_types,
+                           intptr_t handler_index,
+                           bool needs_stacktrace);
+  Fragment TryCatch(int try_handler_index);
+  Fragment Drop();
+  Fragment NullConstant();
+  JoinEntryInstr* BuildJoinEntry();
+  JoinEntryInstr* BuildJoinEntry(intptr_t try_index);
+  Fragment Goto(JoinEntryInstr* destination);
+  Fragment BuildImplicitClosureCreation(const Function& target);
+  Fragment CheckBooleanInCheckedMode();
+  Fragment CheckAssignableInCheckedMode(const dart::AbstractType& dst_type,
+                                        const dart::String& dst_name);
+  Fragment CheckVariableTypeInCheckedMode(intptr_t variable_kernel_position);
+  Fragment CheckVariableTypeInCheckedMode(const AbstractType& dst_type,
+                                          const dart::String& name_symbol);
+  Fragment EnterScope(intptr_t kernel_offset, bool* new_context = NULL);
+  Fragment ExitScope(intptr_t kernel_offset);
 
-  Fragment BuildInvalidExpression();
-  Fragment BuildStaticGet();
-  Fragment BuildSymbolLiteral();
-  Fragment BuildThisExpression();
-  Fragment BuildRethrow();
-  Fragment BuildBigIntLiteral();
-  Fragment BuildStringLiteral();
-  Fragment BuildIntLiteral(uint8_t payload);
-  Fragment BuildIntLiteral(bool is_negative);
-  Fragment BuildDoubleLiteral();
-  Fragment BuildBoolLiteral(bool value);
-  Fragment BuildNullLiteral();
+  Fragment TranslateCondition(bool* negate);
+  const TypeArguments& BuildTypeArguments();
+  Fragment BuildArguments(Array* argument_names,
+                          intptr_t* argument_count,
+                          bool skip_push_arguments = false,
+                          bool do_drop = false);
+  Fragment BuildArgumentsFromActualArguments(Array* argument_names,
+                                             bool skip_push_arguments = false,
+                                             bool do_drop = false);
+
+  Fragment BuildInvalidExpression(TokenPosition* position);
+  Fragment BuildVariableGet(TokenPosition* position);
+  Fragment BuildVariableGet(uint8_t payload, TokenPosition* position);
+  Fragment BuildVariableSet(TokenPosition* position);
+  Fragment BuildVariableSet(uint8_t payload, TokenPosition* position);
+  Fragment BuildPropertyGet(TokenPosition* position);
+  Fragment BuildPropertySet(TokenPosition* position);
+  Fragment BuildDirectPropertyGet(TokenPosition* position);
+  Fragment BuildDirectPropertySet(TokenPosition* position);
+  Fragment BuildStaticGet(TokenPosition* position);
+  Fragment BuildStaticSet(TokenPosition* position);
+  Fragment BuildMethodInvocation(TokenPosition* position);
+  Fragment BuildDirectMethodInvocation(TokenPosition* position);
+  Fragment BuildStaticInvocation(bool is_const, TokenPosition* position);
+  Fragment BuildConstructorInvocation(bool is_const, TokenPosition* position);
+  Fragment BuildNot(TokenPosition* position);
+  Fragment BuildLogicalExpression(TokenPosition* position);
+  Fragment BuildConditionalExpression(TokenPosition* position);
+  Fragment BuildStringConcatenation(TokenPosition* position);
+  Fragment BuildIsExpression(TokenPosition* position);
+  Fragment BuildAsExpression(TokenPosition* position);
+  Fragment BuildSymbolLiteral(TokenPosition* position);
+  Fragment BuildTypeLiteral(TokenPosition* position);
+  Fragment BuildThisExpression(TokenPosition* position);
+  Fragment BuildRethrow(TokenPosition* position);
+  Fragment BuildThrow(TokenPosition* position);
+  Fragment BuildListLiteral(bool is_const, TokenPosition* position);
+  Fragment BuildMapLiteral(bool is_const, TokenPosition* position);
+  Fragment BuildLet(TokenPosition* position);
+  Fragment BuildBigIntLiteral(TokenPosition* position);
+  Fragment BuildStringLiteral(TokenPosition* position);
+  Fragment BuildIntLiteral(uint8_t payload, TokenPosition* position);
+  Fragment BuildIntLiteral(bool is_negative, TokenPosition* position);
+  Fragment BuildDoubleLiteral(TokenPosition* position);
+  Fragment BuildBoolLiteral(bool value, TokenPosition* position);
+  Fragment BuildNullLiteral(TokenPosition* position);
+
+  Fragment BuildInvalidStatement();
+  Fragment BuildExpressionStatement();
+  Fragment BuildBlock();
+  Fragment BuildEmptyStatement();
+  Fragment BuildAssertStatement();
+  Fragment BuildLabeledStatement();
+  Fragment BuildBreakStatement();
+  Fragment BuildWhileStatement();
+  Fragment BuildDoStatement();
+  Fragment BuildForStatement();
+  Fragment BuildForInStatement(bool async);
+  Fragment BuildSwitchStatement();
+  Fragment BuildContinueSwitchStatement();
+  Fragment BuildIfStatement();
+  Fragment BuildReturnStatement();
+  Fragment BuildTryCatch();
+  Fragment BuildTryFinally();
+  Fragment BuildYieldStatement();
+  Fragment BuildVariableDeclaration(bool has_tag);
 
   FlowGraphBuilder* flow_graph_builder_;
   TranslationHelper& translation_helper_;
   Zone* zone_;
   Reader* reader_;
   StreamingConstantEvaluator constant_evaluator_;
+  StreamingDartTypeTranslator type_translator_;
 
   friend class StreamingConstantEvaluator;
+  friend class StreamingDartTypeTranslator;
 };
 
 
diff --git a/runtime/vm/kernel_reader.cc b/runtime/vm/kernel_reader.cc
index 458ad1b..1ddd641 100644
--- a/runtime/vm/kernel_reader.cc
+++ b/runtime/vm/kernel_reader.cc
@@ -212,11 +212,13 @@
       // to be patched.
       if (procedure != NULL) {
         // We will handle the StaticGet specially and will not use the name.
+        // Note that we pass "true" in cannot_stream to avoid trying to stream
+        // a non-existing part of the binary.
         //
         // TODO(kmillikin): we are leaking the new function body.  Find a way to
         // deallocate it.
         procedure->function()->ReplaceBody(
-            new ReturnStatement(new StaticGet(NameIndex())));
+            new ReturnStatement(new StaticGet(NameIndex(), false), false));
       }
       return library;
     }
diff --git a/runtime/vm/kernel_to_il.cc b/runtime/vm/kernel_to_il.cc
index f5c2b83..1130320 100644
--- a/runtime/vm/kernel_to_il.cc
+++ b/runtime/vm/kernel_to_il.cc
@@ -816,186 +816,6 @@
 }
 
 
-class BreakableBlock {
- public:
-  BreakableBlock(FlowGraphBuilder* builder, LabeledStatement* statement)
-      : builder_(builder),
-        labeled_statement_(statement),
-        outer_(builder->breakable_block_),
-        destination_(NULL),
-        outer_finally_(builder->try_finally_block_),
-        context_depth_(builder->context_depth_),
-        try_index_(builder->CurrentTryIndex()) {
-    builder_->breakable_block_ = this;
-  }
-  ~BreakableBlock() { builder_->breakable_block_ = outer_; }
-
-  bool HadJumper() { return destination_ != NULL; }
-
-  JoinEntryInstr* destination() { return destination_; }
-
-  JoinEntryInstr* BreakDestination(LabeledStatement* label,
-                                   TryFinallyBlock** outer_finally,
-                                   intptr_t* context_depth) {
-    BreakableBlock* block = builder_->breakable_block_;
-    while (block->labeled_statement_ != label) {
-      block = block->outer_;
-    }
-    ASSERT(block != NULL);
-    *outer_finally = block->outer_finally_;
-    *context_depth = block->context_depth_;
-    return block->EnsureDestination();
-  }
-
- private:
-  JoinEntryInstr* EnsureDestination() {
-    if (destination_ == NULL) {
-      destination_ = builder_->BuildJoinEntry(try_index_);
-    }
-    return destination_;
-  }
-
-  FlowGraphBuilder* builder_;
-  LabeledStatement* labeled_statement_;
-  BreakableBlock* outer_;
-  JoinEntryInstr* destination_;
-  TryFinallyBlock* outer_finally_;
-  intptr_t context_depth_;
-  intptr_t try_index_;
-};
-
-
-class SwitchBlock {
- public:
-  SwitchBlock(FlowGraphBuilder* builder, SwitchStatement* switch_stmt)
-      : builder_(builder),
-        outer_(builder->switch_block_),
-        outer_finally_(builder->try_finally_block_),
-        switch_statement_(switch_stmt),
-        context_depth_(builder->context_depth_),
-        try_index_(builder->CurrentTryIndex()) {
-    builder_->switch_block_ = this;
-  }
-  ~SwitchBlock() { builder_->switch_block_ = outer_; }
-
-  bool HadJumper(SwitchCase* switch_case) {
-    return destinations_.Lookup(switch_case) != NULL;
-  }
-
-  JoinEntryInstr* Destination(SwitchCase* label,
-                              TryFinallyBlock** outer_finally = NULL,
-                              intptr_t* context_depth = NULL) {
-    // Find corresponding [SwitchStatement].
-    SwitchBlock* block = this;
-    while (true) {
-      block->EnsureSwitchCaseMapping();
-      if (block->Contains(label)) break;
-      block = block->outer_;
-    }
-
-    // Set the outer finally block.
-    if (outer_finally != NULL) {
-      *outer_finally = block->outer_finally_;
-      *context_depth = block->context_depth_;
-    }
-
-    // Ensure there's [JoinEntryInstr] for that [SwitchCase].
-    return block->EnsureDestination(label);
-  }
-
- private:
-  typedef std::set<SwitchCase*> DestinationSwitches;
-
-  JoinEntryInstr* EnsureDestination(SwitchCase* switch_case) {
-    JoinEntryInstr* cached_inst = destinations_.Lookup(switch_case);
-    if (cached_inst == NULL) {
-      JoinEntryInstr* inst = builder_->BuildJoinEntry(try_index_);
-      destinations_.Insert(switch_case, inst);
-      return inst;
-    }
-    return cached_inst;
-  }
-
-  void EnsureSwitchCaseMapping() {
-    if (destination_switches_.begin() == destination_switches_.end()) {
-      List<SwitchCase>& cases = switch_statement_->cases();
-      for (intptr_t i = 0; i < cases.length(); i++) {
-        destination_switches_.insert(cases[i]);
-      }
-    }
-  }
-
-  bool Contains(SwitchCase* sc) {
-    return destination_switches_.find(sc) != destination_switches_.end();
-  }
-
-  FlowGraphBuilder* builder_;
-  SwitchBlock* outer_;
-
-  Map<SwitchCase, JoinEntryInstr*> destinations_;
-  DestinationSwitches destination_switches_;
-
-  TryFinallyBlock* outer_finally_;
-  SwitchStatement* switch_statement_;
-  intptr_t context_depth_;
-  intptr_t try_index_;
-};
-
-
-class TryFinallyBlock {
- public:
-  TryFinallyBlock(FlowGraphBuilder* builder, Statement* finalizer)
-      : builder_(builder),
-        outer_(builder->try_finally_block_),
-        finalizer_(finalizer),
-        context_depth_(builder->context_depth_),
-        // Finalizers are executed outside of the try block hence
-        // try depth of finalizers are one less than current try
-        // depth.
-        try_depth_(builder->try_depth_ - 1),
-        try_index_(builder_->CurrentTryIndex()) {
-    builder_->try_finally_block_ = this;
-  }
-  ~TryFinallyBlock() { builder_->try_finally_block_ = outer_; }
-
-  Statement* finalizer() const { return finalizer_; }
-  intptr_t context_depth() const { return context_depth_; }
-  intptr_t try_depth() const { return try_depth_; }
-  intptr_t try_index() const { return try_index_; }
-  TryFinallyBlock* outer() const { return outer_; }
-
- private:
-  FlowGraphBuilder* const builder_;
-  TryFinallyBlock* const outer_;
-  Statement* const finalizer_;
-  const intptr_t context_depth_;
-  const intptr_t try_depth_;
-  const intptr_t try_index_;
-};
-
-
-class TryCatchBlock {
- public:
-  explicit TryCatchBlock(FlowGraphBuilder* builder,
-                         intptr_t try_handler_index = -1)
-      : builder_(builder),
-        outer_(builder->try_catch_block_),
-        try_index_(try_handler_index) {
-    if (try_index_ == -1) try_index_ = builder->AllocateTryIndex();
-    builder->try_catch_block_ = this;
-  }
-  ~TryCatchBlock() { builder_->try_catch_block_ = outer_; }
-
-  intptr_t try_index() { return try_index_; }
-  TryCatchBlock* outer() const { return outer_; }
-
- private:
-  FlowGraphBuilder* builder_;
-  TryCatchBlock* outer_;
-  intptr_t try_index_;
-};
-
-
 Fragment& Fragment::operator+=(const Fragment& other) {
   if (entry == NULL) {
     entry = other.entry;
@@ -2271,11 +2091,17 @@
     }
 
     Statement* finalizer = try_finally_block_->finalizer();
+    intptr_t finalizer_kernel_offset =
+        try_finally_block_->finalizer_kernel_offset();
     try_finally_block_ = try_finally_block_->outer();
-
-    // This will potentially have exceptional cases as described in
-    // [VisitTryFinally] and will handle them.
-    instructions += TranslateStatement(finalizer);
+    if (finalizer != NULL) {
+      // This will potentially have exceptional cases as described in
+      // [VisitTryFinally] and will handle them.
+      instructions += TranslateStatement(finalizer);
+    } else {
+      instructions += streaming_flow_graph_builder_->BuildStatementAt(
+          finalizer_kernel_offset);
+    }
 
     // We only need to make sure that if the finalizer ended normally, we
     // continue towards the next outer try-finally.
@@ -2299,9 +2125,15 @@
 
 
 Fragment FlowGraphBuilder::EnterScope(TreeNode* node, bool* new_context) {
+  return EnterScope(node->kernel_offset(), new_context);
+}
+
+
+Fragment FlowGraphBuilder::EnterScope(intptr_t kernel_offset,
+                                      bool* new_context) {
   Fragment instructions;
   const intptr_t context_size =
-      scopes_->scopes.Lookup(node->kernel_offset())->num_context_variables();
+      scopes_->scopes.Lookup(kernel_offset)->num_context_variables();
   if (context_size > 0) {
     instructions += PushContext(context_size);
     instructions += Drop();
@@ -2314,9 +2146,14 @@
 
 
 Fragment FlowGraphBuilder::ExitScope(TreeNode* node) {
+  return ExitScope(node->kernel_offset());
+}
+
+
+Fragment FlowGraphBuilder::ExitScope(intptr_t kernel_offset) {
   Fragment instructions;
   const intptr_t context_size =
-      scopes_->scopes.Lookup(node->kernel_offset())->num_context_variables();
+      scopes_->scopes.Lookup(kernel_offset)->num_context_variables();
   if (context_size > 0) {
     instructions += PopContext();
   }
@@ -3193,6 +3030,13 @@
 }
 
 
+dart::LocalVariable* FlowGraphBuilder::LookupVariable(intptr_t kernel_offset) {
+  LocalVariable* local = scopes_->locals.Lookup(kernel_offset);
+  ASSERT(local != NULL);
+  return local;
+}
+
+
 void FlowGraphBuilder::SetTempIndex(Definition* definition) {
   definition->set_temp_index(
       stack_ == NULL ? 0 : stack_->definition()->temp_index() + 1);
@@ -3988,6 +3832,18 @@
   return Fragment();
 }
 
+Fragment FlowGraphBuilder::CheckVariableTypeInCheckedMode(
+    const AbstractType& dst_type,
+    const dart::String& name_symbol) {
+  if (I->type_checks()) {
+    if (dst_type.IsMalformed()) {
+      return ThrowTypeError();
+    }
+    return CheckAssignableInCheckedMode(dst_type, name_symbol);
+  }
+  return Fragment();
+}
+
 
 bool FlowGraphBuilder::NeedsDebugStepCheck(const Function& function,
                                            TokenPosition position) {
@@ -4541,7 +4397,15 @@
 #ifdef DEBUG
   intptr_t original_context_depth = context_depth_;
 #endif
-  statement->AcceptStatementVisitor(this);
+
+  // TODO(jensj): VariableDeclaration doesn't necessarily have a tag.
+  if (statement->can_stream() &&
+      statement->Type() != Node::kTypeVariableDeclaration) {
+    fragment_ = streaming_flow_graph_builder_->BuildStatementAt(
+        statement->kernel_offset());
+  } else {
+    statement->AcceptStatementVisitor(this);
+  }
   DEBUG_ASSERT(context_depth_ == original_context_depth);
   return fragment_;
 }
@@ -4562,7 +4426,12 @@
 
 
 Fragment FlowGraphBuilder::TranslateExpression(Expression* expression) {
-  expression->AcceptExpressionVisitor(this);
+  if (expression->can_stream()) {
+    fragment_ = streaming_flow_graph_builder_->BuildExpressionAt(
+        expression->kernel_offset());
+  } else {
+    expression->AcceptExpressionVisitor(this);
+  }
   return fragment_;
 }
 
@@ -4583,43 +4452,59 @@
 }
 
 
+#define STREAM_EXPRESSION_IF_POSSIBLE(node)                                    \
+  if (node->can_stream()) {                                                    \
+    fragment_ = streaming_flow_graph_builder_->BuildExpressionAt(              \
+        node->kernel_offset());                                                \
+    return;                                                                    \
+  }
+
+
 void FlowGraphBuilder::VisitInvalidExpression(InvalidExpression* node) {
-  fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset());
+  fragment_ =
+      streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset());
 }
 
 
 void FlowGraphBuilder::VisitNullLiteral(NullLiteral* node) {
-  fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset());
+  fragment_ =
+      streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset());
 }
 
 
 void FlowGraphBuilder::VisitBoolLiteral(BoolLiteral* node) {
-  fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset());
+  fragment_ =
+      streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset());
 }
 
 
 void FlowGraphBuilder::VisitIntLiteral(IntLiteral* node) {
-  fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset());
+  fragment_ =
+      streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset());
 }
 
 
 void FlowGraphBuilder::VisitBigintLiteral(BigintLiteral* node) {
-  fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset());
+  fragment_ =
+      streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset());
 }
 
 
 void FlowGraphBuilder::VisitDoubleLiteral(DoubleLiteral* node) {
-  fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset());
+  fragment_ =
+      streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset());
 }
 
 
 void FlowGraphBuilder::VisitStringLiteral(StringLiteral* node) {
-  fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset());
+  fragment_ =
+      streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset());
 }
 
 
 void FlowGraphBuilder::VisitSymbolLiteral(SymbolLiteral* node) {
-  fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset());
+  fragment_ =
+      streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset());
 }
 
 
@@ -4922,8 +4807,9 @@
   return type;
 }
 
-
 void FlowGraphBuilder::VisitTypeLiteral(TypeLiteral* node) {
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   const AbstractType& type = T.TranslateType(node->type());
   if (type.IsMalformed()) H.ReportError("Malformed type literal");
 
@@ -4948,11 +4834,14 @@
 
 
 void FlowGraphBuilder::VisitVariableGet(VariableGet* node) {
-  fragment_ = LoadLocal(LookupVariable(node->variable()));
+  fragment_ =
+      streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset());
 }
 
 
 void FlowGraphBuilder::VisitVariableSet(VariableSet* node) {
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   Fragment instructions = TranslateExpression(node->expression());
   if (NeedsDebugStepCheck(stack_, node->position())) {
     instructions = DebugStepCheck(node->position()) + instructions;
@@ -4965,10 +4854,8 @@
 
 
 void FlowGraphBuilder::VisitStaticGet(StaticGet* node) {
-  if (node->kernel_offset() != -1) {
-    fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset());
-    return;
-  }
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   // A StaticGet will always have a kernel_offset, except for the StaticGet that
   // was manually created for _getMainClosure in dart:_builtin.  Compile that
   // one specially here.
@@ -4998,6 +4885,8 @@
 
 
 void FlowGraphBuilder::VisitStaticSet(StaticSet* node) {
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   NameIndex target = node->target();
   if (H.IsField(target)) {
     const dart::Field& field =
@@ -5035,6 +4924,8 @@
 
 
 void FlowGraphBuilder::VisitPropertyGet(PropertyGet* node) {
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   Fragment instructions = TranslateExpression(node->receiver());
   instructions += PushArgument();
   const dart::String& getter_name = H.DartGetterName(node->name());
@@ -5044,6 +4935,8 @@
 
 
 void FlowGraphBuilder::VisitPropertySet(PropertySet* node) {
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   Fragment instructions(NullConstant());
   LocalVariable* variable = MakeTemporary();
   instructions += TranslateExpression(node->receiver());
@@ -5059,6 +4952,8 @@
 
 
 void FlowGraphBuilder::VisitDirectPropertyGet(DirectPropertyGet* node) {
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   Function& target = Function::ZoneHandle(Z);
   NameIndex kernel_name = node->target();
   if (H.IsProcedure(kernel_name)) {
@@ -5085,6 +4980,8 @@
 
 
 void FlowGraphBuilder::VisitDirectPropertySet(DirectPropertySet* node) {
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   const dart::String& method_name = H.DartSetterName(node->target());
   const Function& target = Function::ZoneHandle(
       Z, LookupMethodByMember(node->target(), method_name));
@@ -5104,6 +5001,8 @@
 
 
 void FlowGraphBuilder::VisitStaticInvocation(StaticInvocation* node) {
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   const Function& target = Function::ZoneHandle(
       Z, H.LookupStaticMethodByKernelProcedure(node->procedure()));
   const dart::Class& klass = dart::Class::ZoneHandle(Z, target.Owner());
@@ -5223,6 +5122,8 @@
 
 
 void FlowGraphBuilder::VisitMethodInvocation(MethodInvocation* node) {
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   const dart::String& name = H.DartMethodName(node->name());
   const intptr_t argument_count = node->arguments()->count() + 1;
   const Token::Kind token_kind = MethodKind(name);
@@ -5277,6 +5178,8 @@
 
 void FlowGraphBuilder::VisitDirectMethodInvocation(
     DirectMethodInvocation* node) {
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   const dart::String& method_name = H.DartProcedureName(node->target());
   const Token::Kind token_kind = MethodKind(method_name);
 
@@ -5298,6 +5201,8 @@
 
 
 void FlowGraphBuilder::VisitConstructorInvocation(ConstructorInvocation* node) {
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   if (node->is_const()) {
     fragment_ =
         Constant(constant_evaluator_.EvaluateConstructorInvocation(node));
@@ -5386,6 +5291,8 @@
 
 
 void FlowGraphBuilder::VisitIsExpression(IsExpression* node) {
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   Fragment instructions = TranslateExpression(node->operand());
 
   // The VM does not like an instanceOf call with a dynamic type. We need to
@@ -5449,6 +5356,8 @@
 
 
 void FlowGraphBuilder::VisitAsExpression(AsExpression* node) {
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   Fragment instructions = TranslateExpression(node->operand());
 
   // The VM does not like an Object_as call with a dynamic type. We need to
@@ -5496,6 +5405,8 @@
 
 
 void FlowGraphBuilder::VisitConditionalExpression(ConditionalExpression* node) {
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   bool negate;
   Fragment instructions = TranslateCondition(node->condition(), &negate);
 
@@ -5528,6 +5439,8 @@
 
 
 void FlowGraphBuilder::VisitLogicalExpression(LogicalExpression* node) {
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   bool negate;
   Fragment instructions = TranslateCondition(node->left(), &negate);
   TargetEntryInstr* right_entry;
@@ -5567,6 +5480,8 @@
 
 
 void FlowGraphBuilder::VisitNot(Not* node) {
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   Fragment instructions = TranslateExpression(node->expression());
   instructions += CheckBooleanInCheckedMode();
   instructions += BooleanNegate();
@@ -5575,11 +5490,14 @@
 
 
 void FlowGraphBuilder::VisitThisExpression(ThisExpression* node) {
-  fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset());
+  fragment_ =
+      streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset());
 }
 
 
 void FlowGraphBuilder::VisitStringConcatenation(StringConcatenation* node) {
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   List<Expression>& expressions = node->expressions();
 
   Fragment instructions;
@@ -5609,6 +5527,8 @@
 
 
 void FlowGraphBuilder::VisitListLiteral(ListLiteral* node) {
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   if (node->is_const()) {
     fragment_ = Constant(constant_evaluator_.EvaluateListLiteral(node));
     return;
@@ -5650,6 +5570,8 @@
 
 
 void FlowGraphBuilder::VisitMapLiteral(MapLiteral* node) {
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   if (node->is_const()) {
     fragment_ = Constant(constant_evaluator_.EvaluateMapLiteral(node));
     return;
@@ -5706,6 +5628,8 @@
 
 
 void FlowGraphBuilder::VisitLet(Let* node) {
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   Fragment instructions = TranslateStatement(node->variable());
   instructions += TranslateExpression(node->body());
   fragment_ = instructions;
@@ -5713,6 +5637,8 @@
 
 
 void FlowGraphBuilder::VisitThrow(Throw* node) {
+  STREAM_EXPRESSION_IF_POSSIBLE(node);
+
   Fragment instructions;
 
   instructions += TranslateExpression(node->expression());
@@ -5728,7 +5654,8 @@
 
 
 void FlowGraphBuilder::VisitRethrow(Rethrow* node) {
-  fragment_ = streaming_flow_graph_builder_->BuildAt(node->kernel_offset());
+  fragment_ =
+      streaming_flow_graph_builder_->BuildExpressionAt(node->kernel_offset());
 }
 
 
@@ -5754,18 +5681,29 @@
   return instructions;
 }
 
+#define STREAM_STATEMENT_IF_POSSIBLE(node)                                     \
+  if (node->can_stream()) {                                                    \
+    fragment_ = streaming_flow_graph_builder_->BuildStatementAt(               \
+        node->kernel_offset());                                                \
+    return;                                                                    \
+  }
+
 
 void FlowGraphBuilder::VisitInvalidStatement(InvalidStatement* node) {
-  H.ReportError("Invalid statements not implemented yet!");
+  fragment_ =
+      streaming_flow_graph_builder_->BuildStatementAt(node->kernel_offset());
 }
 
 
 void FlowGraphBuilder::VisitEmptyStatement(EmptyStatement* node) {
-  fragment_ = Fragment();
+  fragment_ =
+      streaming_flow_graph_builder_->BuildStatementAt(node->kernel_offset());
 }
 
 
 void FlowGraphBuilder::VisitBlock(Block* node) {
+  STREAM_STATEMENT_IF_POSSIBLE(node);
+
   Fragment instructions;
 
   instructions += EnterScope(node);
@@ -5781,6 +5719,8 @@
 
 
 void FlowGraphBuilder::VisitReturnStatement(ReturnStatement* node) {
+  STREAM_STATEMENT_IF_POSSIBLE(node);
+
   bool inside_try_finally = try_finally_block_ != NULL;
 
   Fragment instructions = node->expression() == NULL
@@ -5812,6 +5752,8 @@
 
 
 void FlowGraphBuilder::VisitExpressionStatement(ExpressionStatement* node) {
+  STREAM_STATEMENT_IF_POSSIBLE(node);
+
   Fragment instructions = TranslateExpression(node->expression());
   instructions += Drop();
   fragment_ = instructions;
@@ -5860,6 +5802,8 @@
 
 
 void FlowGraphBuilder::VisitIfStatement(IfStatement* node) {
+  STREAM_STATEMENT_IF_POSSIBLE(node);
+
   bool negate;
   Fragment instructions = TranslateCondition(node->condition(), &negate);
   TargetEntryInstr* then_entry;
@@ -5890,6 +5834,8 @@
 
 
 void FlowGraphBuilder::VisitWhileStatement(WhileStatement* node) {
+  STREAM_STATEMENT_IF_POSSIBLE(node);
+
   ++loop_depth_;
   bool negate;
   Fragment condition = TranslateCondition(node->condition(), &negate);
@@ -5920,6 +5866,8 @@
 
 
 void FlowGraphBuilder::VisitDoStatement(DoStatement* node) {
+  STREAM_STATEMENT_IF_POSSIBLE(node);
+
   ++loop_depth_;
   Fragment body = TranslateStatement(node->body());
 
@@ -5948,6 +5896,8 @@
 
 
 void FlowGraphBuilder::VisitForStatement(ForStatement* node) {
+  STREAM_STATEMENT_IF_POSSIBLE(node);
+
   Fragment declarations;
 
   bool new_context = false;
@@ -6004,6 +5954,8 @@
 
 
 void FlowGraphBuilder::VisitForInStatement(ForInStatement* node) {
+  STREAM_STATEMENT_IF_POSSIBLE(node);
+
   Fragment instructions = TranslateExpression(node->iterable());
   instructions += PushArgument();
 
@@ -6057,6 +6009,8 @@
 
 
 void FlowGraphBuilder::VisitLabeledStatement(LabeledStatement* node) {
+  STREAM_STATEMENT_IF_POSSIBLE(node);
+
   // There can be serveral cases:
   //
   //   * the body contains a break
@@ -6068,7 +6022,7 @@
   // => We will only know which case we are in after the body has been
   //    traversed.
 
-  BreakableBlock block(this, node);
+  BreakableBlock block(this);
   Fragment instructions = TranslateStatement(node->body());
   if (block.HadJumper()) {
     if (instructions.is_open()) {
@@ -6082,26 +6036,15 @@
 
 
 void FlowGraphBuilder::VisitBreakStatement(BreakStatement* node) {
-  TryFinallyBlock* outer_finally = NULL;
-  intptr_t target_context_depth = -1;
-  JoinEntryInstr* destination = breakable_block_->BreakDestination(
-      node->target(), &outer_finally, &target_context_depth);
-
-  Fragment instructions;
-  instructions +=
-      TranslateFinallyFinalizers(outer_finally, target_context_depth);
-  if (instructions.is_open()) {
-    if (NeedsDebugStepCheck(parsed_function_->function(), node->position())) {
-      instructions += DebugStepCheck(node->position());
-    }
-    instructions += Goto(destination);
-  }
-  fragment_ = instructions;
+  fragment_ =
+      streaming_flow_graph_builder_->BuildStatementAt(node->kernel_offset());
 }
 
 
 void FlowGraphBuilder::VisitSwitchStatement(SwitchStatement* node) {
-  SwitchBlock block(this, node);
+  STREAM_STATEMENT_IF_POSSIBLE(node);
+
+  SwitchBlock block(this, node->cases().length());
 
   // Instead of using a variable we should reuse the expression on the stack,
   // since it won't be assigned again, we don't need phi nodes.
@@ -6179,7 +6122,7 @@
     // from `a == expr` and one from `a != expr && b == expr`). The
     // `block.Destination()` records the additional jump.
     if (switch_case->expressions().length() > 1) {
-      block.Destination(switch_case);
+      block.DestinationDirect(i);
     }
   }
 
@@ -6199,10 +6142,10 @@
         constant_evaluator_.EvaluateExpression(switch_case->expressions()[k]);
       }
 
-      if (block.HadJumper(switch_case)) {
+      if (block.HadJumper(i)) {
         // There are several branches to the body, so we will make a goto to
         // the join block (and prepend a join instruction to the real body).
-        JoinEntryInstr* join = block.Destination(switch_case);
+        JoinEntryInstr* join = block.DestinationDirect(i);
         current_instructions += Goto(join);
 
         current_instructions = Fragment(current_instructions.entry, join);
@@ -6212,8 +6155,8 @@
       }
     } else {
       JoinEntryInstr* body_join = NULL;
-      if (block.HadJumper(switch_case)) {
-        body_join = block.Destination(switch_case);
+      if (block.HadJumper(i)) {
+        body_join = block.DestinationDirect(i);
         body_fragments[i] = Fragment(body_join) + body_fragments[i];
       }
 
@@ -6285,22 +6228,14 @@
 
 void FlowGraphBuilder::VisitContinueSwitchStatement(
     ContinueSwitchStatement* node) {
-  TryFinallyBlock* outer_finally = NULL;
-  intptr_t target_context_depth = -1;
-  JoinEntryInstr* entry = switch_block_->Destination(
-      node->target(), &outer_finally, &target_context_depth);
-
-  Fragment instructions;
-  instructions +=
-      TranslateFinallyFinalizers(outer_finally, target_context_depth);
-  if (instructions.is_open()) {
-    instructions += Goto(entry);
-  }
-  fragment_ = instructions;
+  fragment_ =
+      streaming_flow_graph_builder_->BuildStatementAt(node->kernel_offset());
 }
 
 
 void FlowGraphBuilder::VisitAssertStatement(AssertStatement* node) {
+  STREAM_STATEMENT_IF_POSSIBLE(node);
+
   if (!I->asserts()) {
     fragment_ = Fragment();
     return;
@@ -6376,6 +6311,8 @@
 
 
 void FlowGraphBuilder::VisitTryFinally(TryFinally* node) {
+  STREAM_STATEMENT_IF_POSSIBLE(node);
+
   InlineBailout("kernel::FlowgraphBuilder::VisitTryFinally");
 
   // There are 5 different cases where we need to execute the finally block:
@@ -6407,7 +6344,7 @@
   // Fill in the body of the try.
   ++try_depth_;
   {
-    TryFinallyBlock tfb(this, node->finalizer());
+    TryFinallyBlock tfb(this, node->finalizer(), -1);
     TryCatchBlock tcb(this, try_handler_index);
     try_body += TranslateStatement(node->body());
   }
@@ -6450,6 +6387,8 @@
 
 
 void FlowGraphBuilder::VisitTryCatch(class TryCatch* node) {
+  STREAM_STATEMENT_IF_POSSIBLE(node);
+
   InlineBailout("kernel::FlowgraphBuilder::VisitTryCatch");
 
   intptr_t try_handler_index = AllocateTryIndex();
@@ -6569,6 +6508,8 @@
 
 
 void FlowGraphBuilder::VisitYieldStatement(YieldStatement* node) {
+  STREAM_STATEMENT_IF_POSSIBLE(node);
+
   ASSERT(node->is_native());  // Must have been desugared.
   // Setup yield/continue point:
   //
diff --git a/runtime/vm/kernel_to_il.h b/runtime/vm/kernel_to_il.h
index 524a13a..ae0db18 100644
--- a/runtime/vm/kernel_to_il.h
+++ b/runtime/vm/kernel_to_il.h
@@ -347,9 +347,11 @@
 
   const dart::String& DartSetterName(NameIndex setter);
   const dart::String& DartSetterName(Name* setter_name);
+  const dart::String& DartSetterName(NameIndex parent, StringIndex setter);
 
   const dart::String& DartGetterName(NameIndex getter);
   const dart::String& DartGetterName(Name* getter_name);
+  const dart::String& DartGetterName(NameIndex parent, StringIndex getter);
 
   const dart::String& DartFieldName(Name* kernel_name);
 
@@ -357,6 +359,7 @@
 
   const dart::String& DartMethodName(NameIndex method);
   const dart::String& DartMethodName(Name* method_name);
+  const dart::String& DartMethodName(NameIndex parent, StringIndex method);
 
   const dart::String& DartFactoryName(NameIndex factory);
 
@@ -389,9 +392,6 @@
                                   dart::String* name_to_modify,
                                   bool symbolize = true);
 
-  const dart::String& DartSetterName(NameIndex parent, StringIndex setter);
-  const dart::String& DartGetterName(NameIndex parent, StringIndex getter);
-  const dart::String& DartMethodName(NameIndex parent, StringIndex method);
 
   Thread* thread_;
   Zone* zone_;
@@ -770,6 +770,17 @@
   bool needs_expr_temp_;
 };
 
+struct YieldContinuation {
+  Instruction* entry;
+  intptr_t try_index;
+
+  YieldContinuation(Instruction* entry, intptr_t try_index)
+      : entry(entry), try_index(try_index) {}
+
+  YieldContinuation()
+      : entry(NULL), try_index(CatchClauseNode::kInvalidTryIndex) {}
+};
+
 class FlowGraphBuilder : public ExpressionVisitor, public StatementVisitor {
  public:
   FlowGraphBuilder(TreeNode* node,
@@ -880,7 +891,9 @@
   Fragment TranslateFunctionNode(FunctionNode* node, TreeNode* parent);
 
   Fragment EnterScope(TreeNode* node, bool* new_context = NULL);
+  Fragment EnterScope(intptr_t kernel_offset, bool* new_context = NULL);
   Fragment ExitScope(TreeNode* node);
+  Fragment ExitScope(intptr_t kernel_offset);
 
   Fragment LoadContextAt(int depth);
   Fragment AdjustContextTo(int depth);
@@ -983,6 +996,8 @@
   Fragment EvaluateAssertion();
   Fragment CheckReturnTypeInCheckedMode();
   Fragment CheckVariableTypeInCheckedMode(VariableDeclaration* variable);
+  Fragment CheckVariableTypeInCheckedMode(const AbstractType& dst_type,
+                                          const dart::String& name_symbol);
   Fragment CheckBooleanInCheckedMode();
   Fragment CheckAssignableInCheckedMode(const dart::AbstractType& dst_type,
                                         const dart::String& dst_name);
@@ -1012,6 +1027,7 @@
                     LocalVariable* variable,
                     intptr_t pos);
   dart::LocalVariable* LookupVariable(VariableDeclaration* var);
+  dart::LocalVariable* LookupVariable(intptr_t kernel_offset);
 
   void SetTempIndex(Definition* definition);
 
@@ -1056,17 +1072,6 @@
 
   ScopeBuildingResult* scopes_;
 
-  struct YieldContinuation {
-    Instruction* entry;
-    intptr_t try_index;
-
-    YieldContinuation(Instruction* entry, intptr_t try_index)
-        : entry(entry), try_index(try_index) {}
-
-    YieldContinuation()
-        : entry(NULL), try_index(CatchClauseNode::kInvalidTryIndex) {}
-  };
-
   GrowableArray<YieldContinuation> yield_continuations_;
 
   LocalVariable* CurrentException() {
@@ -1119,6 +1124,199 @@
 };
 
 
+class SwitchBlock {
+ public:
+  SwitchBlock(FlowGraphBuilder* builder, intptr_t num_cases)
+      : builder_(builder),
+        outer_(builder->switch_block_),
+        outer_finally_(builder->try_finally_block_),
+        num_cases_(num_cases),
+        context_depth_(builder->context_depth_),
+        try_index_(builder->CurrentTryIndex()) {
+    builder_->switch_block_ = this;
+    if (outer_ != NULL) {
+      depth_ = outer_->depth_ + outer_->num_cases_;
+    } else {
+      depth_ = 0;
+    }
+  }
+  ~SwitchBlock() { builder_->switch_block_ = outer_; }
+
+  bool HadJumper(intptr_t case_num) {
+    return destinations_.Lookup(case_num) != NULL;
+  }
+
+  // Get destination via absolute target number (i.e. the correct destination
+  // is not not necessarily in this block.
+  JoinEntryInstr* Destination(intptr_t target_index,
+                              TryFinallyBlock** outer_finally = NULL,
+                              intptr_t* context_depth = NULL) {
+    // Find corresponding [SwitchStatement].
+    SwitchBlock* block = this;
+    while (block->depth_ > target_index) {
+      block = block->outer_;
+    }
+
+    // Set the outer finally block.
+    if (outer_finally != NULL) {
+      *outer_finally = block->outer_finally_;
+      *context_depth = block->context_depth_;
+    }
+
+    // Ensure there's [JoinEntryInstr] for that [SwitchCase].
+    return block->EnsureDestination(target_index - block->depth_);
+  }
+
+  // Get destination via relative target number (i.e. relative to this block,
+  // 0 is first case in this block etc).
+  JoinEntryInstr* DestinationDirect(intptr_t case_num,
+                                    TryFinallyBlock** outer_finally = NULL,
+                                    intptr_t* context_depth = NULL) {
+    // Set the outer finally block.
+    if (outer_finally != NULL) {
+      *outer_finally = outer_finally_;
+      *context_depth = context_depth_;
+    }
+
+    // Ensure there's [JoinEntryInstr] for that [SwitchCase].
+    return EnsureDestination(case_num);
+  }
+
+ private:
+  JoinEntryInstr* EnsureDestination(intptr_t case_num) {
+    JoinEntryInstr* cached_inst = destinations_.Lookup(case_num);
+    if (cached_inst == NULL) {
+      JoinEntryInstr* inst = builder_->BuildJoinEntry(try_index_);
+      destinations_.Insert(case_num, inst);
+      return inst;
+    }
+    return cached_inst;
+  }
+
+  FlowGraphBuilder* builder_;
+  SwitchBlock* outer_;
+
+  IntMap<JoinEntryInstr*> destinations_;
+
+  TryFinallyBlock* outer_finally_;
+  intptr_t num_cases_;
+  intptr_t depth_;
+  intptr_t context_depth_;
+  intptr_t try_index_;
+};
+
+
+class TryCatchBlock {
+ public:
+  explicit TryCatchBlock(FlowGraphBuilder* builder,
+                         intptr_t try_handler_index = -1)
+      : builder_(builder),
+        outer_(builder->try_catch_block_),
+        try_index_(try_handler_index) {
+    if (try_index_ == -1) try_index_ = builder->AllocateTryIndex();
+    builder->try_catch_block_ = this;
+  }
+  ~TryCatchBlock() { builder_->try_catch_block_ = outer_; }
+
+  intptr_t try_index() { return try_index_; }
+  TryCatchBlock* outer() const { return outer_; }
+
+ private:
+  FlowGraphBuilder* builder_;
+  TryCatchBlock* outer_;
+  intptr_t try_index_;
+};
+
+
+class TryFinallyBlock {
+ public:
+  TryFinallyBlock(FlowGraphBuilder* builder,
+                  Statement* finalizer,
+                  intptr_t finalizer_kernel_offset)
+      : builder_(builder),
+        outer_(builder->try_finally_block_),
+        finalizer_(finalizer),
+        finalizer_kernel_offset_(finalizer_kernel_offset),
+        context_depth_(builder->context_depth_),
+        // Finalizers are executed outside of the try block hence
+        // try depth of finalizers are one less than current try
+        // depth.
+        try_depth_(builder->try_depth_ - 1),
+        try_index_(builder_->CurrentTryIndex()) {
+    builder_->try_finally_block_ = this;
+  }
+  ~TryFinallyBlock() { builder_->try_finally_block_ = outer_; }
+
+  Statement* finalizer() const { return finalizer_; }
+  intptr_t finalizer_kernel_offset() const { return finalizer_kernel_offset_; }
+  intptr_t context_depth() const { return context_depth_; }
+  intptr_t try_depth() const { return try_depth_; }
+  intptr_t try_index() const { return try_index_; }
+  TryFinallyBlock* outer() const { return outer_; }
+
+ private:
+  FlowGraphBuilder* const builder_;
+  TryFinallyBlock* const outer_;
+  Statement* const finalizer_;
+  intptr_t finalizer_kernel_offset_;
+  const intptr_t context_depth_;
+  const intptr_t try_depth_;
+  const intptr_t try_index_;
+};
+
+
+class BreakableBlock {
+ public:
+  explicit BreakableBlock(FlowGraphBuilder* builder)
+      : builder_(builder),
+        outer_(builder->breakable_block_),
+        destination_(NULL),
+        outer_finally_(builder->try_finally_block_),
+        context_depth_(builder->context_depth_),
+        try_index_(builder->CurrentTryIndex()) {
+    if (builder_->breakable_block_ == NULL) {
+      index_ = 0;
+    } else {
+      index_ = builder_->breakable_block_->index_ + 1;
+    }
+    builder_->breakable_block_ = this;
+  }
+  ~BreakableBlock() { builder_->breakable_block_ = outer_; }
+
+  bool HadJumper() { return destination_ != NULL; }
+
+  JoinEntryInstr* destination() { return destination_; }
+
+  JoinEntryInstr* BreakDestination(intptr_t label_index,
+                                   TryFinallyBlock** outer_finally,
+                                   intptr_t* context_depth) {
+    BreakableBlock* block = builder_->breakable_block_;
+    while (block->index_ != label_index) {
+      block = block->outer_;
+    }
+    ASSERT(block != NULL);
+    *outer_finally = block->outer_finally_;
+    *context_depth = block->context_depth_;
+    return block->EnsureDestination();
+  }
+
+ private:
+  JoinEntryInstr* EnsureDestination() {
+    if (destination_ == NULL) {
+      destination_ = builder_->BuildJoinEntry(try_index_);
+    }
+    return destination_;
+  }
+
+  FlowGraphBuilder* builder_;
+  intptr_t index_;
+  BreakableBlock* outer_;
+  JoinEntryInstr* destination_;
+  TryFinallyBlock* outer_finally_;
+  intptr_t context_depth_;
+  intptr_t try_index_;
+};
+
 class CatchBlock {
  public:
   CatchBlock(FlowGraphBuilder* builder,
