Version 1.22.1

Cherry-pick 339d16fbc5d611fbbcf46235c290c615589ecc87 to stable
Cherry-pick 67a93da99eb11ada7d8267243c6824d5c67de91c to stable
Cherry-pick 031af9e89990d39ca73cfe8726ab018c038e8b7e to stable
Cherry-pick bbd687197bc96b4d7a0555d3f0cd0e1e64c2b672 to stable
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a831e65..45a5ce4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 1.22.1 - 2017-02-22
+
+Patch release, resolves two issues:
+* Dart VM crash: [Issue 28072](https://github.com/dart-lang/sdk/issues/28757)
+
+* Dart VM bug combining types, await, and deferred loading: [Issue 28678](https://github.com/dart-lang/sdk/issues/28678)
+
+
 ## 1.22.0 - 2017-02-14
 
 ### Language
diff --git a/runtime/vm/ast.h b/runtime/vm/ast.h
index ca75856..c99b6cb 100644
--- a/runtime/vm/ast.h
+++ b/runtime/vm/ast.h
@@ -443,8 +443,12 @@
 
 class TypeNode : public AstNode {
  public:
-  TypeNode(TokenPosition token_pos, const AbstractType& type)
-      : AstNode(token_pos), type_(type) {
+  TypeNode(TokenPosition token_pos,
+           const AbstractType& type,
+           bool is_deferred_reference = false)
+      : AstNode(token_pos),
+        type_(type),
+        is_deferred_reference_(is_deferred_reference) {
     ASSERT(type_.IsZoneHandle());
     ASSERT(!type_.IsNull());
     ASSERT(type_.IsFinalized());
@@ -466,10 +470,14 @@
 
   virtual void VisitChildren(AstNodeVisitor* visitor) const {}
 
+  bool is_deferred_reference() const { return is_deferred_reference_; }
+  void set_is_deferred_reference(bool value) { is_deferred_reference_ = value; }
+
   DECLARE_COMMON_NODE_FUNCTIONS(TypeNode);
 
  private:
   const AbstractType& type_;
+  bool is_deferred_reference_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(TypeNode);
 };
diff --git a/runtime/vm/ast_transformer.cc b/runtime/vm/ast_transformer.cc
index fa1028d..af1331c 100644
--- a/runtime/vm/ast_transformer.cc
+++ b/runtime/vm/ast_transformer.cc
@@ -119,7 +119,14 @@
 
 
 void AwaitTransformer::VisitTypeNode(TypeNode* node) {
-  result_ = new (Z) TypeNode(node->token_pos(), node->type());
+  if (node->is_deferred_reference()) {
+    // Deferred references must use a temporary even after loading
+    // happened, so that the number of await temps is the same as
+    // before the loading.
+    result_ = MakeName(node);
+  } else {
+    result_ = node;
+  }
 }
 
 
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index e75d86d..9f918e0 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -11638,7 +11638,8 @@
                                                ClassFinalizer::kCanonicalize);
           // Type may be malbounded, but not malformed.
           ASSERT(!type.IsMalformed());
-          array = new (Z) TypeNode(primary_pos, type);
+          array = new (Z) TypeNode(primary_pos, type,
+                                   primary_node->is_deferred_reference());
         } else if (primary_node->primary().IsTypeParameter()) {
           array = LoadTypeParameter(primary_node);
         } else {
@@ -11733,7 +11734,8 @@
                                                ClassFinalizer::kCanonicalize);
           // Type may be malbounded, but not malformed.
           ASSERT(!type.IsMalformed());
-          selector = new (Z) TypeNode(primary_pos, type);
+          selector = new (Z) TypeNode(primary_pos, type,
+                                      primary_node->is_deferred_reference());
         } else {
           UNREACHABLE();  // Internal parser error.
         }
@@ -11760,7 +11762,8 @@
                                               ClassFinalizer::kCanonicalize);
           // Type may be malbounded, but not malformed.
           ASSERT(!type.IsMalformed());
-          left = new (Z) TypeNode(primary_pos, type);
+          left = new (Z) TypeNode(primary_pos, type,
+                                  primary_node->is_deferred_reference());
         } else if (primary_node->primary().IsTypeParameter()) {
           left = LoadTypeParameter(primary_node);
         } else if (primary_node->IsSuper()) {
@@ -12652,7 +12655,8 @@
       if ((resolved == NULL) || (resolved_func_level < type_param_func_level)) {
         // The identifier is a function type parameter, possibly shadowing
         // 'resolved'.
-        if (type_param_func_level < FunctionLevel()) {
+        if ((FunctionLevel() > 0) &&
+            (type_param_func_level < FunctionLevel())) {
           // Make sure that the function instantiator is captured.
           CaptureFunctionInstantiator();
         }
@@ -12719,7 +12723,8 @@
                                            ClassFinalizer::kCanonicalize);
       // Type may be malbounded, but not malformed.
       ASSERT(!type.IsMalformed());
-      resolved = new (Z) TypeNode(primary_pos, type);
+      resolved =
+          new (Z) TypeNode(primary_pos, type, primary->is_deferred_reference());
     }
   }
   return resolved;
@@ -14007,7 +14012,8 @@
               (primary_func_level < type_param_func_level)) {
             // The identifier is a function type parameter, possibly shadowing
             // already resolved 'primary'.
-            if (type_param_func_level < FunctionLevel()) {
+            if ((FunctionLevel() > 0) &&
+                (type_param_func_level < FunctionLevel())) {
               // Make sure that the function instantiator is captured.
               CaptureFunctionInstantiator();
             }
diff --git a/tests/language/deferred_regression_28678_lib.dart b/tests/language/deferred_regression_28678_lib.dart
new file mode 100644
index 0000000..f36c206
--- /dev/null
+++ b/tests/language/deferred_regression_28678_lib.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+var v;
+
+class Clazz { }
diff --git a/tests/language/deferred_regression_28678_test.dart b/tests/language/deferred_regression_28678_test.dart
new file mode 100644
index 0000000..5051e72
--- /dev/null
+++ b/tests/language/deferred_regression_28678_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that await after deferred loading works as expected.
+
+import 'dart:async';
+import "package:expect/expect.dart";
+import 'deferred_regression_28678_lib.dart' deferred as lib;
+
+class A {
+  m() => "here";
+}
+
+f(a, b) => new Future.microtask(() {});
+
+class R {
+  Future test_deferred() async {
+    var a = new A();
+    await lib.loadLibrary();
+    await f(lib.Clazz, lib.v);
+    Expect.equals("here", a.m());
+  }
+}
+
+main() async {
+  await new R().test_deferred();
+}
diff --git a/tests/language/language.status b/tests/language/language.status
index 717b3d4..5c7703f 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -272,6 +272,7 @@
 deferred_optimized_test: Crash # Requires deferred libraries
 deferred_redirecting_factory_test: Crash # Requires deferred libraries
 deferred_regression_22995_test: Crash # Requires deferred libraries
+deferred_regression_28678_test: Crash # Requires deferred libraries
 deferred_shadow_load_library_test: Crash # Requires deferred libraries
 deferred_shared_and_unshared_classes_test: Crash # Requires deferred libraries
 deferred_static_seperate_test: Crash # Requires deferred libraries
diff --git a/tests/language/language_kernel.status b/tests/language/language_kernel.status
index c53b287..fc6bb7c 100644
--- a/tests/language/language_kernel.status
+++ b/tests/language/language_kernel.status
@@ -222,7 +222,7 @@
 
 # dartk: precompilation failures
 [ $compiler == dartkp && $runtime == dart_precompiled ]
-if_null_assignment_static_test/35: Crash  # Dartk Issue 28302
+deferred_regression_28678_test: RuntimeError # Issue 28335
 
 # dartk: precompilation failures (debug)
 [ $compiler == dartkp && $runtime == dart_precompiled && $mode == debug ]
diff --git a/tools/VERSION b/tools/VERSION
index 9b5dcb4..fceaa52 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -26,6 +26,6 @@
 CHANNEL stable
 MAJOR 1
 MINOR 22
-PATCH 0
+PATCH 1
 PRERELEASE 0
 PRERELEASE_PATCH 0