Version 2.9.0-8.0.dev

Merge commit '9c94f0841078756ea0437a590b66ddfe24eabdaf' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 90551fb..4ccf379 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,18 @@
 
 ### Core libraries
 
+#### `dart:convert`
+
+*   **Breaking Change** [#41100][]: When encoding a string containing unpaired
+    surrogates as UTF-8, the unpaired surrogates will be encoded as replacement
+    characters (`U+FFFD`). When decoding UTF-8, encoded surrogates will be
+    treated as malformed input. When decoding UTF-8 with `allowMalformed: true`,
+    the number of replacement characters emitted for malformed input sequences
+    has been changed to match the [WHATWG encoding standard][].
+
+[#41100]: https://github.com/dart-lang/sdk/issues/41100
+[WHATWG encoding standard]: https://encoding.spec.whatwg.org/#utf-8-decoder
+
 #### `dart:html`
 
 *   **Breaking Change**: `CssClassSet.add()` previously returned `null` if the
diff --git a/DEPS b/DEPS
index 008541f..f29c6914 100644
--- a/DEPS
+++ b/DEPS
@@ -91,7 +91,7 @@
   "dart_style_tag": "1.3.6",  # Please see the note above before updating.
 
   "dartdoc_tag" : "v0.31.0",
-  "ffi_tag": "ea88d71b043ee14b268c3aedff14e9eb32e20959",
+  "ffi_tag": "4cc14129e81f8804e73321f0ccf5484397a5ddce",
   "fixnum_tag": "eb3748663dc979271ff6a3d014fbe522543b1d91",
   "glob_tag": "e9f4e6b7ae8abe5071461cf8f47191bb19cf7ef6",
   "html_tag": "083a36cd801a4b787ba156b7c6e4c8b2e2daed4a",
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 7548761..b5a49ba 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -538,6 +538,9 @@
 
   if (is_clang) {
     default_warning_flags += [ "-Wno-tautological-constant-compare" ]
+  } else {
+    default_warning_flags +=
+        [ "-Wno-ignored-qualifiers" ]  # Warnings in BoringSSL headers
   }
 
   if (is_mac) {
diff --git a/pkg/_fe_analyzer_shared/lib/src/testing/features.dart b/pkg/_fe_analyzer_shared/lib/src/testing/features.dart
index f42cd25..7725a34 100644
--- a/pkg/_fe_analyzer_shared/lib/src/testing/features.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/testing/features.dart
@@ -225,11 +225,13 @@
 }
 
 class FeaturesDataInterpreter implements DataInterpreter<Features> {
-  const FeaturesDataInterpreter();
+  final String wildcard;
+
+  const FeaturesDataInterpreter({this.wildcard: null});
 
   @override
   String isAsExpected(Features actualFeatures, String expectedData) {
-    if (expectedData == '*') {
+    if (wildcard != null && expectedData == wildcard) {
       return null;
     } else if (expectedData == '') {
       return actualFeatures.isNotEmpty ? "Expected empty data." : null;
@@ -255,7 +257,7 @@
           if (actualValue != '') {
             errorsFound.add('Non-empty data found for $key');
           }
-        } else if (expectedValue == '*') {
+        } else if (wildcard != null && expectedValue == wildcard) {
           return;
         } else if (expectedValue is List) {
           if (actualValue is List) {
@@ -263,10 +265,10 @@
             for (Object expectedObject in expectedValue) {
               String expectedText = '$expectedObject';
               bool matchFound = false;
-              if (expectedText.endsWith('*')) {
+              if (wildcard != null && expectedText.endsWith(wildcard)) {
                 // Wildcard matcher.
                 String prefix =
-                    expectedText.substring(0, expectedText.indexOf('*'));
+                    expectedText.substring(0, expectedText.indexOf(wildcard));
                 List matches = [];
                 for (Object actualObject in actualList) {
                   if ('$actualObject'.startsWith(prefix)) {
diff --git a/pkg/analysis_server/lib/src/server/crash_reporting.dart b/pkg/analysis_server/lib/src/server/crash_reporting.dart
index 879adbc..866b9ff 100644
--- a/pkg/analysis_server/lib/src/server/crash_reporting.dart
+++ b/pkg/analysis_server/lib/src/server/crash_reporting.dart
@@ -8,10 +8,20 @@
 import 'package:analyzer/instrumentation/service.dart';
 import 'package:telemetry/crash_reporting.dart';
 
-class CrashReportingInstrumentation extends NoopInstrumentationService {
-  final CrashReportSender reporter;
+const _angularPluginName = 'Angular Analysis Plugin';
 
-  CrashReportingInstrumentation(this.reporter);
+class CrashReportingInstrumentation extends NoopInstrumentationService {
+  // A staging reporter, that we are in the process of phasing out.
+  final CrashReportSender stagingReporter;
+
+  // A prod reporter, that we are in the process of phasing in.
+  final CrashReportSender prodReporter;
+
+  // The angular plugin crash reporter.
+  final CrashReportSender angularReporter;
+
+  CrashReportingInstrumentation(
+      this.stagingReporter, this.prodReporter, this.angularReporter);
 
   @override
   void logException(dynamic exception,
@@ -28,19 +38,11 @@
       // Get the root CaughtException, which matters most for debugging.
       var root = exception.rootCaughtException;
 
-      reporter
-          .sendReport(root.exception, root.stackTrace,
-              attachments: crashReportAttachments, comment: root.message)
-          .catchError((error) {
-        // We silently ignore errors sending crash reports (network issues, ...).
-      });
+      _sendServerReport(root.exception, root.stackTrace,
+          attachments: crashReportAttachments, comment: root.message);
     } else {
-      reporter
-          .sendReport(exception, stackTrace ?? StackTrace.current,
-              attachments: crashReportAttachments)
-          .catchError((error) {
-        // We silently ignore errors sending crash reports (network issues, ...).
-      });
+      _sendServerReport(exception, stackTrace ?? StackTrace.current,
+          attachments: crashReportAttachments);
     }
   }
 
@@ -50,15 +52,27 @@
     dynamic exception,
     StackTrace stackTrace,
   ) {
-    // TODO(devoncarew): Temporarily disabled; re-enable after deciding on a
-    // plan of action for the AngularDart analysis plugin.
-    const angularPluginName = 'Angular Analysis Plugin';
-    if (plugin.name == angularPluginName) {
-      return;
+    if (plugin.name == _angularPluginName) {
+      angularReporter.sendReport(exception, stackTrace).catchError((error) {
+        // We silently ignore errors sending crash reports (network issues, ...).
+      });
+    } else {
+      _sendServerReport(exception, stackTrace,
+          comment: 'plugin: ${plugin.name}');
     }
+  }
 
-    reporter
-        .sendReport(exception, stackTrace, comment: 'plugin: ${plugin.name}')
+  void _sendServerReport(Object exception, Object stackTrace,
+      {String comment, List<CrashReportAttachment> attachments}) {
+    stagingReporter
+        .sendReport(exception, stackTrace,
+            attachments: attachments, comment: comment)
+        .catchError((error) {
+      // We silently ignore errors sending crash reports (network issues, ...).
+    });
+    prodReporter
+        .sendReport(exception, stackTrace,
+            attachments: attachments, comment: comment)
         .catchError((error) {
       // We silently ignore errors sending crash reports (network issues, ...).
     });
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 91c6074..54245c7 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -403,8 +403,13 @@
 
     // Use sdkConfig to optionally override analytics settings.
     final crashProductId = sdkConfig.crashReportingId ?? 'Dart_analysis_server';
-    final crashReportSender =
-        CrashReportSender(crashProductId, shouldSendCallback);
+    final crashReportSenderStaging =
+        CrashReportSender.staging(crashProductId, shouldSendCallback);
+    final crashReportSenderProd =
+        CrashReportSender.prod(crashProductId, shouldSendCallback);
+    // TODO(mfairhurst): send these to prod or disable.
+    final crashReportSenderAngular = CrashReportSender.staging(
+        'Dart_angular_analysis_plugin', shouldSendCallback);
 
     if (telemetry.SHOW_ANALYTICS_UI) {
       if (results.wasParsed(ANALYTICS_FLAG)) {
@@ -455,8 +460,10 @@
     }
 
     var errorNotifier = ErrorNotifier();
-    allInstrumentationServices
-        .add(CrashReportingInstrumentation(crashReportSender));
+    allInstrumentationServices.add(CrashReportingInstrumentation(
+        crashReportSenderStaging,
+        crashReportSenderProd,
+        crashReportSenderAngular));
     instrumentationService =
         MulticastInstrumentationService(allInstrumentationServices);
 
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
index b970dab..c836fb5 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
@@ -7,13 +7,9 @@
 import 'package:analysis_server/src/protocol_server.dart'
     show CompletionSuggestion;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
-import 'package:analysis_server/src/services/completion/dart/feature_computer.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/dart/element/visitor.dart';
-import 'package:meta/meta.dart';
 
 /// A contributor that produces suggestions based on the static members of a
 /// given class, enum, or extension. More concretely, this class produces
@@ -23,134 +19,53 @@
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
       DartCompletionRequest request, SuggestionBuilder builder) async {
+    if (request.libraryElement == null) {
+      // Gracefully degrade if the library could not be determined, such as a
+      // detached part file or source change.
+      // TODO(brianwilkerson) Consider testing for this before invoking _any_ of
+      //  the contributors.
+      return const <CompletionSuggestion>[];
+    }
     var targetId = request.dotTarget;
     if (targetId is Identifier && !request.target.isCascade) {
-      var elem = targetId.staticElement;
-      if (elem is ClassElement || elem is ExtensionElement) {
-        if (request.libraryElement == null) {
-          // Gracefully degrade if the library could not be determined, such as
-          // a detached part file or source change.
-          return const <CompletionSuggestion>[];
+      var element = targetId.staticElement;
+      if (element is ClassElement) {
+        for (var accessor in element.accessors) {
+          if (accessor.isStatic) {
+            builder.suggestAccessor(accessor, inheritanceDistance: -1.0);
+          }
         }
-        var builder = _SuggestionBuilder(request);
-        elem.accept(builder);
-        return builder.suggestions;
+        for (var constructor in element.constructors) {
+          builder.suggestConstructor(constructor, hasClassName: true);
+        }
+        for (var field in element.fields) {
+          if (field.isStatic && (!field.isSynthetic || element.isEnum)) {
+            builder.suggestField(field, inheritanceDistance: -1.0);
+          }
+        }
+        for (var method in element.methods) {
+          if (method.isStatic) {
+            builder.suggestMethod(method, inheritanceDistance: -1.0);
+          }
+        }
+      } else if (element is ExtensionElement) {
+        for (var accessor in element.accessors) {
+          if (accessor.isStatic) {
+            builder.suggestAccessor(accessor, inheritanceDistance: -1.0);
+          }
+        }
+        for (var field in element.fields) {
+          if (field.isStatic) {
+            builder.suggestField(field, inheritanceDistance: -1.0);
+          }
+        }
+        for (var method in element.methods) {
+          if (method.isStatic) {
+            builder.suggestMethod(method, inheritanceDistance: -1.0);
+          }
+        }
       }
     }
     return const <CompletionSuggestion>[];
   }
 }
-
-/// This class visits elements in a class or extension and provides suggestions
-/// based on the visible static members in that class.
-class _SuggestionBuilder extends SimpleElementVisitor<void> {
-  /// Information about the completion being requested.
-  final DartCompletionRequest request;
-
-  /// A collection of completion suggestions.
-  final List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
-
-  /// Initialize a newly created suggestion builder.
-  _SuggestionBuilder(this.request);
-
-  @override
-  void visitClassElement(ClassElement element) {
-    element.visitChildren(this);
-  }
-
-  @override
-  void visitConstructorElement(ConstructorElement element) {
-    _addSuggestion(element, element.returnType);
-  }
-
-  @override
-  void visitExtensionElement(ExtensionElement element) {
-    element.visitChildren(this);
-  }
-
-  @override
-  void visitFieldElement(FieldElement element) {
-    if (element.isStatic) {
-      _addSuggestion(element, element.type);
-    }
-  }
-
-  @override
-  void visitMethodElement(MethodElement element) {
-    if (element.isStatic && !element.isOperator) {
-      _addSuggestion(element, element.returnType);
-    }
-  }
-
-  @override
-  void visitPropertyAccessorElement(PropertyAccessorElement element) {
-    if (element.isStatic) {
-      _addSuggestion(element, element.returnType);
-    }
-  }
-
-  /// Add a suggestion based on the given [element].
-  void _addSuggestion(Element element, DartType elementType) {
-    if (element.isPrivate) {
-      if (element.library != request.libraryElement) {
-        // Don't suggest private members for imported libraries.
-        return;
-      }
-    }
-    if (element.isSynthetic) {
-      if (element is PropertyAccessorElement ||
-          element is FieldElement && !_isSpecialEnumField(element)) {
-        return;
-      }
-    }
-    var completion = element.displayName;
-    if (completion == null || completion.isEmpty) {
-      return;
-    }
-    var relevance;
-    if (request.useNewRelevance) {
-      var contextType = request.featureComputer
-          .contextTypeFeature(request.contextType, elementType);
-      var elementKind = request.featureComputer
-          .elementKindFeature(element, request.opType.completionLocation);
-      var hasDeprecated = request.featureComputer.hasDeprecatedFeature(element);
-      relevance = _computeRelevance(
-          contextType: contextType,
-          elementKind: elementKind,
-          hasDeprecated: hasDeprecated);
-    } else {
-      relevance =
-          element.hasDeprecated ? DART_RELEVANCE_LOW : DART_RELEVANCE_DEFAULT;
-    }
-    var suggestion = createSuggestion(request, element,
-        completion: completion, relevance: relevance);
-    if (suggestion != null) {
-      suggestions.add(suggestion);
-    }
-  }
-
-  /// Compute a relevance value from the given feature scores:
-  /// - [contextType] is higher if the type of the element matches the context
-  ///   type,
-  /// - [elementKind] is higher if the kind of element occurs more frequently in
-  ///   the given location, and
-  /// - [hasDeprecated] is higher if the element is not deprecated.
-  int _computeRelevance(
-      {@required double contextType,
-      @required double elementKind,
-      @required double hasDeprecated}) {
-    var score = weightedAverage(
-        [contextType, elementKind, hasDeprecated], [1.0, 0.75, 0.5]);
-    return toRelevance(score, Relevance.member);
-  }
-
-  /// Determine whether the [element] is one of the synthetic enum accessors
-  /// for which we should generate a suggestion.
-  bool _isSpecialEnumField(FieldElement element) {
-    var parent = element.enclosingElement;
-    if (parent is ClassElement && parent.isEnum) {
-      return element.name == 'values';
-    }
-    return false;
-  }
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index cad2006..e8eb817 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -214,13 +214,11 @@
   /// Add a suggestion for the given [accessor].
   void addSuggestionForAccessor(
       {@required PropertyAccessorElement accessor,
-      String containingMethodName,
       @required double inheritanceDistance}) {
     if (accessor.isAccessibleIn(request.libraryElement)) {
       var member = accessor.isSynthetic ? accessor.variable : accessor;
       if (_shouldAddSuggestion(member)) {
         builder.suggestAccessor(accessor,
-            containingMemberName: containingMethodName,
             inheritanceDistance: inheritanceDistance);
       }
     }
@@ -229,15 +227,12 @@
   /// Add a suggestion for the given [method].
   void addSuggestionForMethod(
       {@required MethodElement method,
-      String containingMethodName,
       CompletionSuggestionKind kind,
       @required double inheritanceDistance}) {
     if (method.isAccessibleIn(request.libraryElement) &&
         _shouldAddSuggestion(method)) {
       builder.suggestMethod(method,
-          containingMemberName: containingMethodName,
-          kind: kind,
-          inheritanceDistance: inheritanceDistance);
+          kind: kind, inheritanceDistance: inheritanceDistance);
     }
   }
 
@@ -376,9 +371,7 @@
   /// distance feature computed for the accessor (or `-1.0` if the accessor is a
   /// static accessor).
   void suggestAccessor(PropertyAccessorElement accessor,
-      {String containingMemberName, @required double inheritanceDistance}) {
-    // TODO(brianwilkerson) Remove [containingMemberName].
-    containingMemberName ??= _containingMemberName;
+      {@required double inheritanceDistance}) {
     assert(accessor.enclosingElement is ClassElement ||
         accessor.enclosingElement is ExtensionElement);
     if (accessor.isSynthetic) {
@@ -388,9 +381,7 @@
       if (accessor.isGetter) {
         var variable = accessor.variable;
         if (variable is FieldElement) {
-          suggestField(variable,
-              containingMemberName: containingMemberName,
-              inheritanceDistance: inheritanceDistance);
+          suggestField(variable, inheritanceDistance: inheritanceDistance);
         }
       }
     } else {
@@ -407,7 +398,7 @@
         var startsWithDollar =
             featureComputer.startsWithDollarFeature(accessor.name);
         var superMatches = featureComputer.superMatchesFeature(
-            containingMemberName, accessor.name);
+            _containingMemberName, accessor.name);
         relevance = _computeMemberRelevance(
             contextType: contextType,
             elementKind: elementKind,
@@ -587,9 +578,7 @@
   /// value of the inheritance distance feature computed for the field (or
   /// `-1.0` if the field is a static field).
   void suggestField(FieldElement field,
-      {String containingMemberName, @required double inheritanceDistance}) {
-    // TODO(brianwilkerson) Remove [containingMemberName].
-    containingMemberName ??= _containingMemberName;
+      {@required double inheritanceDistance}) {
     int relevance;
     if (request.useNewRelevance) {
       var featureComputer = request.featureComputer;
@@ -600,8 +589,8 @@
       var hasDeprecated = featureComputer.hasDeprecatedFeature(field);
       var startsWithDollar =
           featureComputer.startsWithDollarFeature(field.name);
-      var superMatches =
-          featureComputer.superMatchesFeature(containingMemberName, field.name);
+      var superMatches = featureComputer.superMatchesFeature(
+          _containingMemberName, field.name);
       relevance = _computeMemberRelevance(
           contextType: contextType,
           elementKind: elementKind,
@@ -721,11 +710,7 @@
   /// used as the kind for the suggestion. The [inheritanceDistance] is the
   /// value of the inheritance distance feature computed for the method.
   void suggestMethod(MethodElement method,
-      {String containingMemberName,
-      CompletionSuggestionKind kind,
-      @required double inheritanceDistance}) {
-    // TODO(brianwilkerson) Remove [containingMemberName].
-    containingMemberName ??= _containingMemberName;
+      {CompletionSuggestionKind kind, @required double inheritanceDistance}) {
     // TODO(brianwilkerson) Refactor callers so that we're passing in the type
     //  of the target (assuming we don't already have that type available via
     //  the [request]) and compute the [inheritanceDistance] in this method.
@@ -740,7 +725,7 @@
       var startsWithDollar =
           featureComputer.startsWithDollarFeature(method.name);
       var superMatches = featureComputer.superMatchesFeature(
-          containingMemberName, method.name);
+          _containingMemberName, method.name);
       relevance = _computeMemberRelevance(
           contextType: contextType,
           elementKind: elementKind,
@@ -749,8 +734,7 @@
           startsWithDollar: startsWithDollar,
           superMatches: superMatches);
     } else {
-      relevance = _computeOldMemberRelevance(method,
-          containingMethodName: containingMemberName);
+      relevance = _computeOldMemberRelevance(method);
       if (request.opType.includeReturnValueSuggestions) {
         relevance = request.opType
             .returnValueSuggestionsFilter(method.returnType, relevance);
@@ -971,13 +955,10 @@
   }
 
   /// Compute the old relevance score for a member.
-  int _computeOldMemberRelevance(Element member,
-      {String containingMethodName}) {
-    // TODO(brianwilkerson) Remove [containingMethodName].
-    containingMethodName ??= _containingMemberName;
+  int _computeOldMemberRelevance(Element member) {
     if (member.hasOrInheritsDeprecated) {
       return DART_RELEVANCE_LOW;
-    } else if (member.name == containingMethodName) {
+    } else if (member.name == _containingMemberName) {
       // Boost the relevance of a super expression calling a method of the
       // same name as the containing method.
       return DART_RELEVANCE_HIGH;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
index 3fce378..1be5e6e 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
@@ -74,7 +74,6 @@
         }
       }
     }
-    String containingMethodName;
     List<InterfaceType> mixins;
     List<InterfaceType> superclassConstraints;
     if (expression is SuperExpression && type is InterfaceType) {
@@ -82,16 +81,6 @@
       mixins = (type as InterfaceType).mixins;
       superclassConstraints = (type as InterfaceType).superclassConstraints;
       type = (type as InterfaceType).superclass;
-      // Determine the name of the containing method because the most likely
-      // completion is a super expression with same name.
-      var containingMethod =
-          expression.thisOrAncestorOfType<MethodDeclaration>();
-      if (containingMethod != null) {
-        var id = containingMethod.name;
-        if (id != null) {
-          containingMethodName = id.name;
-        }
-      }
     }
     if (type == null || type.isDynamic) {
       // Suggest members from object if target is "dynamic".
@@ -101,7 +90,7 @@
     // Build the suggestions.
     if (type is InterfaceType) {
       var memberBuilder = _SuggestionBuilder(request, builder);
-      memberBuilder.buildSuggestions(type, containingMethodName,
+      memberBuilder.buildSuggestions(type,
           mixins: mixins, superclassConstraints: superclassConstraints);
     } else if (type is FunctionType) {
       builder.suggestFunctionCall();
@@ -240,7 +229,7 @@
   /// Return completion suggestions for 'dot' completions on the given [type].
   /// If the 'dot' completion is a super expression, then [containingMethodName]
   /// is the name of the method in which the completion is requested.
-  void buildSuggestions(InterfaceType type, String containingMethodName,
+  void buildSuggestions(InterfaceType type,
       {List<InterfaceType> mixins, List<InterfaceType> superclassConstraints}) {
     // Visit all of the types in the class hierarchy, collecting possible
     // completions.  If multiple elements are found that complete to the same
@@ -263,17 +252,13 @@
         // Exclude static methods when completion on an instance.
         if (!method.isStatic) {
           addSuggestionForMethod(
-              method: method,
-              containingMethodName: containingMethodName,
-              inheritanceDistance: inheritanceDistance);
+              method: method, inheritanceDistance: inheritanceDistance);
         }
       }
       for (var accessor in targetType.accessors) {
         if (!accessor.isStatic) {
           addSuggestionForAccessor(
-              accessor: accessor,
-              containingMethodName: containingMethodName,
-              inheritanceDistance: inheritanceDistance);
+              accessor: accessor, inheritanceDistance: inheritanceDistance);
         }
       }
       if (targetType.isDartCoreFunction) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart
index 292bee5..2451a7c 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart
@@ -208,4 +208,8 @@
     }
     return false;
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static AddDiagnosticPropertyReference newInstance() =>
+      AddDiagnosticPropertyReference();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_field_formal_parameters.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_field_formal_parameters.dart
index 2d5018e..133873f 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_field_formal_parameters.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_field_formal_parameters.dart
@@ -71,4 +71,7 @@
       }
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static AddFieldFormalParameters newInstance() => AddFieldFormalParameters();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_required_keyword.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_required_keyword.dart
index f844c86..ca26be2 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_required_keyword.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_required_keyword.dart
@@ -17,4 +17,7 @@
       builder.addSimpleInsertion(node.parent.offset, 'required ');
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static AddRequiredKeyword newInstance() => AddRequiredKeyword();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_return_type.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_return_type.dart
index c1f61c6..7ff6f15 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_return_type.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_return_type.dart
@@ -111,6 +111,9 @@
     }
     return baseType;
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static AddReturnType newInstance() => AddReturnType();
 }
 
 /// Copied from lib/src/services/refactoring/extract_method.dart", but
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart
index b8a8824..5361b82 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart
@@ -195,4 +195,7 @@
   DartChangeBuilder _temporaryBuilder(DartChangeBuilder builder) =>
       DartChangeBuilderImpl.forWorkspace(
           (builder as DartChangeBuilderImpl).workspace);
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static AddTypeAnnotation newInstance() => AddTypeAnnotation();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_add_all_to_spread.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_add_all_to_spread.dart
index f1099b6..a6fc1e4 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_add_all_to_spread.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_add_all_to_spread.dart
@@ -109,4 +109,7 @@
       builder.addDeletion(range.node(invocation));
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertAddAllToSpread newInstance() => ConvertAddAllToSpread();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_conditional_expression_to_if_element.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_conditional_expression_to_if_element.dart
index 1a2e32f..b545497 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_conditional_expression_to_if_element.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_conditional_expression_to_if_element.dart
@@ -49,4 +49,8 @@
       });
     }
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertConditionalExpressionToIfElement newInstance() =>
+      ConvertConditionalExpressionToIfElement();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_line.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_line.dart
index b87f9f6..3288b0c 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_line.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_line.dart
@@ -75,4 +75,8 @@
       });
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertDocumentationIntoLine newInstance() =>
+      ConvertDocumentationIntoLine();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart
index 5d3108b..522a60a 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart
@@ -169,6 +169,10 @@
       });
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertMapFromIterableToForLiteral newInstance() =>
+      ConvertMapFromIterableToForLiteral();
 }
 
 /// A visitor that can be used to find references to a parameter.
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_quotes.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_quotes.dart
index 2e661fd..52e7880 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_quotes.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_quotes.dart
@@ -76,6 +76,9 @@
 
   @override
   bool get fromDouble => false;
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToDoubleQuotes newInstance() => ConvertToDoubleQuotes();
 }
 
 class ConvertToSingleQuotes extends ConvertQuotes {
@@ -89,4 +92,7 @@
 
   @override
   bool get fromDouble => true;
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToSingleQuotes newInstance() => ConvertToSingleQuotes();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_contains.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_contains.dart
index f80ac75..8be4d1b 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_contains.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_contains.dart
@@ -138,6 +138,9 @@
     // so we should never reach this point.
     return NegationStyle.none;
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToContains newInstance() => ConvertToContains();
 }
 
 /// An indication of whether the `contains` test should be negated, not negated,
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_expression_function_body.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_expression_function_body.dart
index 771db27..0e4b2c9 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_expression_function_body.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_expression_function_body.dart
@@ -62,4 +62,8 @@
       });
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToExpressionFunctionBody newInstance() =>
+      ConvertToExpressionFunctionBody();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart
index bba054b..d62d9eb 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart
@@ -103,4 +103,8 @@
       builder.addSimpleReplacement(range.node(node), replacement);
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToGenericFunctionSyntax newInstance() =>
+      ConvertToGenericFunctionSyntax();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_int_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_int_literal.dart
index b4f967c..72d1338 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_int_literal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_int_literal.dart
@@ -41,4 +41,7 @@
       });
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToIntLiteral newInstance() => ConvertToIntLiteral();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_list_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_list_literal.dart
index 1c4dda0..c3ecab5 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_list_literal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_list_literal.dart
@@ -47,4 +47,7 @@
       });
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToListLiteral newInstance() => ConvertToListLiteral();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_map_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_map_literal.dart
index b8098ce..daccb53 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_map_literal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_map_literal.dart
@@ -57,4 +57,7 @@
       (element == typeProvider.mapElement ||
           (element.name == 'LinkedHashMap' &&
               element.library.name == 'dart.collection'));
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToMapLiteral newInstance() => ConvertToMapLiteral();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart
index adace32..18604d3 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart
@@ -102,4 +102,7 @@
       });
     }
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToNullAware newInstance() => ConvertToNullAware();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_on_type.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_on_type.dart
index 22876af..2df2ee0 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_on_type.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_on_type.dart
@@ -48,4 +48,7 @@
       }
     }
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToOnType newInstance() => ConvertToOnType();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart
index a055b5c..7856391 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart
@@ -55,4 +55,7 @@
       });
     }
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToPackageImport newInstance() => ConvertToPackageImport();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart
index 938214b..eea6658 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart
@@ -77,4 +77,7 @@
       );
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToRelativeImport newInstance() => ConvertToRelativeImport();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_set_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_set_literal.dart
index bf39226..dde8458 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_set_literal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_set_literal.dart
@@ -181,4 +181,7 @@
     }
     return _hasUnambiguousElement(creation);
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToSetLiteral newInstance() => ConvertToSetLiteral();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_where_type.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_where_type.dart
index fd1a83d..7d66b0e 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_where_type.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_where_type.dart
@@ -55,4 +55,7 @@
       });
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ConvertToWhereType newInstance() => ConvertToWhereType();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/inline_invocation.dart b/pkg/analysis_server/lib/src/services/correction/dart/inline_invocation.dart
index 4787df2..1788e09 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/inline_invocation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/inline_invocation.dart
@@ -60,4 +60,7 @@
       builder.addDeletion(range.node(invocation));
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static InlineInvocation newInstance() => InlineInvocation();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/inline_typedef.dart b/pkg/analysis_server/lib/src/services/correction/dart/inline_typedef.dart
index 82832ec..6235f74 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/inline_typedef.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/inline_typedef.dart
@@ -123,6 +123,9 @@
       });
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static InlineTypedef newInstance() => InlineTypedef();
 }
 
 class _ReferenceFinder extends RecursiveAstVisitor {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_if_null.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_if_null.dart
index fc64406..830007a 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_if_null.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_if_null.dart
@@ -50,4 +50,7 @@
       builder.addDeletion(sourceRange);
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static RemoveDeadIfNull newInstance() => RemoveDeadIfNull();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_if_null_operator.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_if_null_operator.dart
index aee06f8..4491682 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_if_null_operator.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_if_null_operator.dart
@@ -34,4 +34,7 @@
       builder.addDeletion(sourceRange);
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static RemoveIfNullOperator newInstance() => RemoveIfNullOperator();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_question_mark.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_question_mark.dart
index c14f141..ae50eb6 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_question_mark.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_question_mark.dart
@@ -27,4 +27,7 @@
       builder.addDeletion(range.token(questionMark));
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static RemoveQuestionMark newInstance() => RemoveQuestionMark();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused.dart
index 525a4ed..9559f6d 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused.dart
@@ -54,6 +54,9 @@
       }
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static RemoveUnusedElement newInstance() => RemoveUnusedElement();
 }
 
 class RemoveUnusedField extends _RemoveUnused {
@@ -161,6 +164,9 @@
       return range.nodeInList(parent.variables, node);
     }
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static RemoveUnusedField newInstance() => RemoveUnusedField();
 }
 
 class _ElementReferenceCollector extends RecursiveAstVisitor<void> {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_local_variable.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_local_variable.dart
index 366a7c1..c6b654c 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_local_variable.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_local_variable.dart
@@ -84,4 +84,7 @@
       return null;
     }
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static RemoveUnusedLocalVariable newInstance() => RemoveUnusedLocalVariable();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_eight_digit_hex.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_eight_digit_hex.dart
index 3353fe8..ad91c45 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_eight_digit_hex.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_eight_digit_hex.dart
@@ -36,4 +36,7 @@
       builder.addSimpleReplacement(range.node(node), replacement);
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ReplaceWithEightDigitHex newInstance() => ReplaceWithEightDigitHex();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_interpolation.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_interpolation.dart
index bdced61..2c36432 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_interpolation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_interpolation.dart
@@ -143,6 +143,9 @@
     }
     return false;
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ReplaceWithInterpolation newInstance() => ReplaceWithInterpolation();
 }
 
 class _StringStyle {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart
index 787dcb6..2f8f19a 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart
@@ -132,4 +132,7 @@
     }
     return false;
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ReplaceWithVar newInstance() => ReplaceWithVar();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/sort_child_property_last.dart b/pkg/analysis_server/lib/src/services/correction/dart/sort_child_property_last.dart
index 778bc28..c4a0c23 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/sort_child_property_last.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/sort_child_property_last.dart
@@ -54,4 +54,7 @@
       builder.setSelection(Position(file, last.end + 1));
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static SortChildPropertyLast newInstance() => SortChildPropertyLast();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/use_curly_braces.dart b/pkg/analysis_server/lib/src/services/correction/dart/use_curly_braces.dart
index 53362cc..620e21e 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/use_curly_braces.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/use_curly_braces.dart
@@ -135,4 +135,7 @@
       builder.addSimpleInsertion(body.end, '$eol$prefix}');
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static UseCurlyBraces newInstance() => UseCurlyBraces();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_future.dart b/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_future.dart
index bba9db5..62da5e5 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_future.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_future.dart
@@ -35,4 +35,7 @@
           range.node(expression), 'Future.value($value)');
     });
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static WrapInFuture newInstance() => WrapInFuture();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_text.dart b/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_text.dart
index e391f54..e45c057 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_text.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_text.dart
@@ -64,4 +64,7 @@
       }
     }
   }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static WrapInText newInstance() => WrapInText();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 71cc015..f0fd8b2 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -92,6 +92,9 @@
 /// A predicate is a one-argument function that returns a boolean value.
 typedef ElementPredicate = bool Function(Element argument);
 
+/// A function that can be executed to create a correction producer.
+typedef ProducerGenerator = CorrectionProducer Function();
+
 /// A fix contributor that provides the default set of fixes for Dart files.
 class DartFixContributor implements FixContributor {
   @override
@@ -194,15 +197,163 @@
 class FixProcessor extends BaseProcessor {
   static const int MAX_LEVENSHTEIN_DISTANCE = 3;
 
+  /// A map from the names of lint rules to a list of generators used to create
+  /// the correction producers used to build fixes for those diagnostics. The
+  /// generators used for non-lint diagnostics are in the [nonLintProducerMap].
+  static const Map<String, List<ProducerGenerator>> lintProducerMap = {
+    LintNames.always_declare_return_types: [
+      AddReturnType.newInstance,
+    ],
+    LintNames.always_specify_types: [
+      AddTypeAnnotation.newInstance,
+    ],
+    LintNames.avoid_private_typedef_functions: [
+      InlineTypedef.newInstance,
+    ],
+    LintNames.avoid_relative_lib_imports: [
+      ConvertToPackageImport.newInstance,
+    ],
+    LintNames.avoid_returning_null_for_future: [
+      WrapInFuture.newInstance,
+    ],
+    LintNames.avoid_types_as_parameter_names: [
+      ConvertToOnType.newInstance,
+    ],
+    LintNames.curly_braces_in_flow_control_structures: [
+      UseCurlyBraces.newInstance,
+    ],
+    LintNames.diagnostic_describe_all_properties: [
+      AddDiagnosticPropertyReference.newInstance,
+    ],
+    LintNames.omit_local_variable_types: [
+      ReplaceWithVar.newInstance,
+    ],
+    LintNames.prefer_collection_literals: [
+      ConvertToListLiteral.newInstance,
+      ConvertToMapLiteral.newInstance,
+      ConvertToSetLiteral.newInstance,
+    ],
+    LintNames.prefer_contains: [
+      ConvertToContains.newInstance,
+    ],
+    LintNames.prefer_expression_function_bodies: [
+      ConvertToExpressionFunctionBody.newInstance,
+    ],
+    LintNames.prefer_for_elements_to_map_fromIterable: [
+      ConvertMapFromIterableToForLiteral.newInstance,
+    ],
+    LintNames.prefer_generic_function_type_aliases: [
+      ConvertToGenericFunctionSyntax.newInstance,
+    ],
+    LintNames.prefer_if_elements_to_conditional_expressions: [
+      ConvertConditionalExpressionToIfElement.newInstance,
+    ],
+    LintNames.prefer_inlined_adds: [
+      InlineInvocation.newInstance,
+    ],
+    LintNames.prefer_int_literals: [
+      ConvertToIntLiteral.newInstance,
+    ],
+    LintNames.prefer_interpolation_to_compose_strings: [
+      ReplaceWithInterpolation.newInstance,
+    ],
+    LintNames.prefer_iterable_whereType: [
+      ConvertToWhereType.newInstance,
+    ],
+    LintNames.prefer_null_aware_operators: [
+      ConvertToNullAware.newInstance,
+    ],
+    LintNames.prefer_relative_imports: [
+      ConvertToRelativeImport.newInstance,
+    ],
+    LintNames.prefer_single_quotes: [
+      ConvertToSingleQuotes.newInstance,
+    ],
+    LintNames.prefer_spread_collections: [
+      ConvertAddAllToSpread.newInstance,
+    ],
+    LintNames.slash_for_doc_comments: [
+      ConvertDocumentationIntoLine.newInstance,
+    ],
+    LintNames.sort_child_properties_last: [
+      SortChildPropertyLast.newInstance,
+    ],
+    LintNames.type_annotate_public_apis: [
+      AddTypeAnnotation.newInstance,
+    ],
+    LintNames.unnecessary_null_in_if_null_operators: [
+      RemoveIfNullOperator.newInstance,
+    ],
+    LintNames.use_full_hex_values_for_flutter_colors: [
+      ReplaceWithEightDigitHex.newInstance,
+    ],
+    LintNames.use_function_type_syntax_for_parameters: [
+      ConvertToGenericFunctionSyntax.newInstance,
+    ],
+  };
+
+  /// A map from error codes to a list of generators used to create the
+  /// correction producers used to build fixes for those diagnostics. The
+  /// generators used for lint rules are in the [lintProducerMap].
+  static const Map<ErrorCode, List<ProducerGenerator>> nonLintProducerMap = {
+    CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER: [
+      AddRequiredKeyword.newInstance,
+    ],
+    CompileTimeErrorCode.NULLABLE_TYPE_IN_EXTENDS_CLAUSE: [
+      RemoveQuestionMark.newInstance,
+    ],
+    CompileTimeErrorCode.NULLABLE_TYPE_IN_IMPLEMENTS_CLAUSE: [
+      RemoveQuestionMark.newInstance,
+    ],
+    CompileTimeErrorCode.NULLABLE_TYPE_IN_ON_CLAUSE: [
+      RemoveQuestionMark.newInstance,
+    ],
+    CompileTimeErrorCode.NULLABLE_TYPE_IN_WITH_CLAUSE: [
+      RemoveQuestionMark.newInstance,
+    ],
+    HintCode.NULLABLE_TYPE_IN_CATCH_CLAUSE: [
+      RemoveQuestionMark.newInstance,
+    ],
+    HintCode.UNUSED_ELEMENT: [
+      RemoveUnusedElement.newInstance,
+    ],
+    HintCode.UNUSED_FIELD: [
+      RemoveUnusedField.newInstance,
+    ],
+    HintCode.UNUSED_LOCAL_VARIABLE: [
+      RemoveUnusedLocalVariable.newInstance,
+    ],
+    ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE: [
+      AddTypeAnnotation.newInstance,
+    ],
+    StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE: [
+      WrapInText.newInstance,
+    ],
+    StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION: [
+      RemoveDeadIfNull.newInstance,
+    ],
+    StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1: [
+      AddFieldFormalParameters.newInstance,
+    ],
+    StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2: [
+      AddFieldFormalParameters.newInstance,
+    ],
+    StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS: [
+      AddFieldFormalParameters.newInstance,
+    ],
+  };
+
   final DartFixContext context;
+
   final ResourceProvider resourceProvider;
   final TypeSystem typeSystem;
 
   final LibraryElement unitLibraryElement;
   final CompilationUnit unit;
-
   final AnalysisError error;
+
   final int errorOffset;
+
   final int errorLength;
 
   final List<Fix> fixes = <Fix>[];
@@ -4363,104 +4514,19 @@
     }
 
     var errorCode = error.errorCode;
-    if (errorCode == HintCode.NULLABLE_TYPE_IN_CATCH_CLAUSE) {
-      await compute(RemoveQuestionMark());
-    } else if (errorCode == HintCode.UNUSED_ELEMENT) {
-      await compute(RemoveUnusedElement());
-    } else if (errorCode == HintCode.UNUSED_FIELD) {
-      await compute(RemoveUnusedField());
-    } else if (errorCode == HintCode.UNUSED_LOCAL_VARIABLE) {
-      await compute(RemoveUnusedLocalVariable());
-    } else if (errorCode ==
-        CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER) {
-      await compute(AddRequiredKeyword());
-    } else if (errorCode ==
-        CompileTimeErrorCode.NULLABLE_TYPE_IN_EXTENDS_CLAUSE) {
-      await compute(RemoveQuestionMark());
-    } else if (errorCode ==
-        CompileTimeErrorCode.NULLABLE_TYPE_IN_IMPLEMENTS_CLAUSE) {
-      await compute(RemoveQuestionMark());
-    } else if (errorCode == CompileTimeErrorCode.NULLABLE_TYPE_IN_ON_CLAUSE) {
-      await compute(RemoveQuestionMark());
-    } else if (errorCode == CompileTimeErrorCode.NULLABLE_TYPE_IN_WITH_CLAUSE) {
-      await compute(RemoveQuestionMark());
-    } else if (errorCode == ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE) {
-      await compute(AddTypeAnnotation());
-    } else if (errorCode == StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE) {
-      await compute(WrapInText());
-    } else if (errorCode == StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION) {
-      await compute(RemoveDeadIfNull());
-    } else if (errorCode ==
-            StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1 ||
-        errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2 ||
-        errorCode ==
-            StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS) {
-      await compute(AddFieldFormalParameters());
-    } else if (errorCode is LintCode) {
-      var name = errorCode.name;
-      if (name == LintNames.always_declare_return_types) {
-        await compute(AddReturnType());
-      } else if (name == LintNames.always_specify_types) {
-        await compute(AddTypeAnnotation());
-      } else if (name == LintNames.avoid_private_typedef_functions) {
-        await compute(InlineTypedef());
-      } else if (name == LintNames.avoid_relative_lib_imports) {
-        await compute(ConvertToPackageImport());
-      } else if (name == LintNames.avoid_returning_null_for_future) {
-        await compute(WrapInFuture());
-      } else if (name == LintNames.avoid_types_as_parameter_names) {
-        await compute(ConvertToOnType());
-      } else if (name == LintNames.curly_braces_in_flow_control_structures) {
-        await compute(UseCurlyBraces());
-      } else if (name == LintNames.diagnostic_describe_all_properties) {
-        await compute(AddDiagnosticPropertyReference());
-      } else if (name == LintNames.omit_local_variable_types) {
-        await compute(ReplaceWithVar());
-      } else if (name == LintNames.prefer_collection_literals) {
-        await compute(ConvertToListLiteral());
-        await compute(ConvertToMapLiteral());
-        await compute(ConvertToSetLiteral());
-      } else if (name == LintNames.prefer_contains) {
-        await compute(ConvertToContains());
-      } else if (errorCode.name ==
-          LintNames.prefer_expression_function_bodies) {
-        await compute(ConvertToExpressionFunctionBody());
-      } else if (errorCode.name ==
-          LintNames.prefer_for_elements_to_map_fromIterable) {
-        await compute(ConvertMapFromIterableToForLiteral());
-      } else if (name == LintNames.prefer_generic_function_type_aliases) {
-        await compute(ConvertToGenericFunctionSyntax());
-      } else if (errorCode.name ==
-          LintNames.prefer_if_elements_to_conditional_expressions) {
-        await compute(ConvertConditionalExpressionToIfElement());
-      } else if (name == LintNames.prefer_inlined_adds) {
-        await compute(InlineInvocation());
-      } else if (name == LintNames.prefer_int_literals) {
-        await compute(ConvertToIntLiteral());
-      } else if (name == LintNames.prefer_interpolation_to_compose_strings) {
-        await compute(ReplaceWithInterpolation());
-      } else if (name == LintNames.prefer_iterable_whereType) {
-        await compute(ConvertToWhereType());
-      } else if (name == LintNames.prefer_null_aware_operators) {
-        await compute(ConvertToNullAware());
-      } else if (name == LintNames.prefer_relative_imports) {
-        await compute(ConvertToRelativeImport());
-      } else if (name == LintNames.prefer_single_quotes) {
-        await compute(ConvertToSingleQuotes());
-      } else if (name == LintNames.prefer_spread_collections) {
-        await compute(ConvertAddAllToSpread());
-      } else if (errorCode.name == LintNames.slash_for_doc_comments) {
-        await compute(ConvertDocumentationIntoLine());
-      } else if (name == LintNames.sort_child_properties_last) {
-        await compute(SortChildPropertyLast());
-      } else if (name == LintNames.type_annotate_public_apis) {
-        await compute(AddTypeAnnotation());
-      } else if (name == LintNames.unnecessary_null_in_if_null_operators) {
-        await compute(RemoveIfNullOperator());
-      } else if (name == LintNames.use_full_hex_values_for_flutter_colors) {
-        await compute(ReplaceWithEightDigitHex());
-      } else if (name == LintNames.use_function_type_syntax_for_parameters) {
-        await compute(ConvertToGenericFunctionSyntax());
+    if (errorCode is LintCode) {
+      var generators = lintProducerMap[errorCode.name];
+      if (generators != null) {
+        for (var generator in generators) {
+          await compute(generator());
+        }
+      }
+    } else {
+      var generators = nonLintProducerMap[errorCode];
+      if (generators != null) {
+        for (var generator in generators) {
+          await compute(generator());
+        }
       }
     }
   }
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 1db1f61..3f0d69d 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -829,14 +829,14 @@
     });
   }
 
-  Future<void> test_static() {
+  Future<void> test_static() async {
     addTestFile('class A {static b() {} c() {}} main() {A.^}');
-    return getSuggestions().then((_) {
-      expect(replacementOffset, equals(completionOffset));
-      expect(replacementLength, equals(0));
-      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
-      assertNoResult('c');
-    });
+    await getSuggestions();
+    expect(replacementOffset, equals(completionOffset));
+    expect(replacementLength, equals(0));
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'b',
+        relevance: DART_RELEVANCE_INHERITED_METHOD);
+    assertNoResult('c');
   }
 
   Future<void> test_topLevel() {
diff --git a/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart b/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
index f917fa6..2edf873 100644
--- a/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
@@ -74,7 +74,8 @@
     });
     expect(replacementOffset, equals(completionOffset));
     expect(replacementLength, equals(0));
-    assertHasResult(CompletionSuggestionKind.INVOCATION, 's1');
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 's1',
+        relevance: DART_RELEVANCE_INHERITED_FIELD);
     assertHasResult(CompletionSuggestionKind.INVOCATION, 's2',
         relevance: DART_RELEVANCE_COMMON_USAGE);
     assertNoResult('Future');
diff --git a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
index c3c7033..dae0842 100644
--- a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
@@ -28,8 +28,8 @@
     addTestSource('enum E { one, two } main() {E.^}');
     await computeSuggestions();
     assertNotSuggested('E');
-    assertSuggestEnumConst('one');
-    assertSuggestEnumConst('two');
+    assertSuggestEnumConst('one', relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertSuggestEnumConst('two', relevance: DART_RELEVANCE_LOCAL_FIELD);
     assertNotSuggested('index');
     assertSuggestField('values', 'List<E>');
   }
@@ -38,8 +38,8 @@
     addTestSource('enum E { one, two } main() {E.o^}');
     await computeSuggestions();
     assertNotSuggested('E');
-    assertSuggestEnumConst('one');
-    assertSuggestEnumConst('two');
+    assertSuggestEnumConst('one', relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertSuggestEnumConst('two', relevance: DART_RELEVANCE_LOCAL_FIELD);
     assertNotSuggested('index');
     assertSuggestField('values', 'List<E>');
   }
@@ -48,8 +48,8 @@
     addTestSource('enum E { one, two } main() {E.^ int g;}');
     await computeSuggestions();
     assertNotSuggested('E');
-    assertSuggestEnumConst('one');
-    assertSuggestEnumConst('two');
+    assertSuggestEnumConst('one', relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertSuggestEnumConst('two', relevance: DART_RELEVANCE_LOCAL_FIELD);
     assertNotSuggested('index');
     assertSuggestField('values', 'List<E>');
   }
@@ -64,8 +64,8 @@
     addTestSource('enum E { one, two } main() {E.^.}');
     await computeSuggestions();
     assertNotSuggested('E');
-    assertSuggestEnumConst('one');
-    assertSuggestEnumConst('two');
+    assertSuggestEnumConst('one', relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertSuggestEnumConst('two', relevance: DART_RELEVANCE_LOCAL_FIELD);
     assertNotSuggested('index');
     assertSuggestField('values', 'List<E>');
   }
@@ -80,19 +80,16 @@
     addTestSource('enum E { one, two } main() {E.^.o}');
     await computeSuggestions();
     assertNotSuggested('E');
-    assertSuggestEnumConst('one');
-    assertSuggestEnumConst('two');
+    assertSuggestEnumConst('one', relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertSuggestEnumConst('two', relevance: DART_RELEVANCE_LOCAL_FIELD);
     assertNotSuggested('index');
     assertSuggestField('values', 'List<E>');
   }
 
-  @failingTest
   Future<void> test_enumConst_deprecated() async {
     addTestSource('@deprecated enum E { one, two } main() {E.^}');
     await computeSuggestions();
     assertNotSuggested('E');
-    // TODO(danrubel) Investigate why enum suggestion is not marked
-    // as deprecated if enum ast element is deprecated
     assertSuggestEnumConst('one', isDeprecated: true);
     assertSuggestEnumConst('two', isDeprecated: true);
     assertNotSuggested('index');
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index d312773..c173f89 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -336,7 +336,9 @@
     } else {
       Source source;
       if (workspace is WorkspaceWithDefaultAnalysisOptions) {
-        if (path.contains('/third_party/dart/')) {
+        var separator = resourceProvider.pathContext.separator;
+        if (path
+            .contains('${separator}third_party${separator}dart${separator}')) {
           source = sourceFactory
               .forUri(WorkspaceWithDefaultAnalysisOptions.thirdPartyUri);
         } else {
diff --git a/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
index cf532a4..c0c8df6 100644
--- a/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
@@ -201,8 +201,7 @@
     InferenceContext.setType(left, _typeProvider.boolType);
     InferenceContext.setType(right, _typeProvider.boolType);
 
-    // TODO(scheglov) Do we need these checks for null?
-    left?.accept(_resolver);
+    left.accept(_resolver);
     left = node.leftOperand;
 
     if (_flowAnalysis != null) {
@@ -239,8 +238,7 @@
     InferenceContext.setType(left, _typeProvider.boolType);
     InferenceContext.setType(right, _typeProvider.boolType);
 
-    // TODO(scheglov) Do we need these checks for null?
-    left?.accept(_resolver);
+    left.accept(_resolver);
     left = node.leftOperand;
 
     flow?.logicalBinaryOp_rightBegin(left, isAnd: false);
@@ -270,11 +268,10 @@
   }
 
   void _resolveUserDefinable(BinaryExpressionImpl node) {
-    Expression left = node.leftOperand;
-    Expression right = node.rightOperand;
+    var left = node.leftOperand;
+    var right = node.rightOperand;
 
-    // TODO(scheglov) Do we need these checks for null?
-    left?.accept(_resolver);
+    left.accept(_resolver);
 
     var operator = node.operator;
     _resolveUserDefinableElement(node, operator.lexeme);
@@ -287,8 +284,7 @@
       InferenceContext.setType(right, rightParam.type);
     }
 
-    // TODO(scheglov) Do we need these checks for null?
-    right?.accept(_resolver);
+    right.accept(_resolver);
 
     _resolveUserDefinableType(node);
   }
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 0a696c6..c58545b 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -374,7 +374,9 @@
           operator == TokenType.PERCENT_EQ ||
           operator == TokenType.PLUS_EQ ||
           operator == TokenType.STAR_EQ ||
-          operator == TokenType.TILDE_SLASH_EQ) {
+          operator == TokenType.TILDE_SLASH_EQ ||
+          operator == TokenType.PLUS_PLUS ||
+          operator == TokenType.MINUS_MINUS) {
         if (rightType.isDartCoreInt) {
           InterfaceTypeImpl intType = typeProvider.intType;
           if (isNonNullableByDefault) {
@@ -1402,7 +1404,9 @@
             operator == TokenType.STAR ||
             operator == TokenType.PLUS_EQ ||
             operator == TokenType.MINUS_EQ ||
-            operator == TokenType.STAR_EQ) {
+            operator == TokenType.STAR_EQ ||
+            operator == TokenType.PLUS_PLUS ||
+            operator == TokenType.MINUS_MINUS) {
           if (isNonNullableByDefault) {
             return promoteToNonNull(leftType as TypeImpl);
           }
diff --git a/pkg/analyzer/lib/src/lint/linter.dart b/pkg/analyzer/lib/src/lint/linter.dart
index 49e76be..783cf74 100644
--- a/pkg/analyzer/lib/src/lint/linter.dart
+++ b/pkg/analyzer/lib/src/lint/linter.dart
@@ -628,6 +628,12 @@
     }
   }
 
+  void reportLintForOffset(int offset, int length,
+      {List<Object> arguments = const [], ErrorCode errorCode}) {
+    reporter.reportErrorForOffset(
+        errorCode ?? lintCode, offset, length, arguments);
+  }
+
   void reportLintForToken(Token token,
       {List<Object> arguments = const [],
       ErrorCode errorCode,
diff --git a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
index 82ce793..28ed93b 100644
--- a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
+++ b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
@@ -147,7 +147,7 @@
     implicit-casts: false
 ''');
 
-    var aPath = '/workspace/third_party/dart/aaa/lib/a.dart';
+    var aPath = convertPath('/workspace/third_party/dart/aaa/lib/a.dart');
     await assertErrorsInFile(aPath, r'''
 num a = 0;
 int b = a;
diff --git a/pkg/compiler/lib/src/universe/feature.dart b/pkg/compiler/lib/src/universe/feature.dart
index 92ded95..1cb6aff 100644
--- a/pkg/compiler/lib/src/universe/feature.dart
+++ b/pkg/compiler/lib/src/universe/feature.dart
@@ -218,7 +218,7 @@
       case RuntimeTypeUseKind.equals:
         sb.write('equals:');
         sb.write(receiverType);
-        sb.write('/');
+        sb.write('==');
         sb.write(argumentType);
         break;
       case RuntimeTypeUseKind.unknown:
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index dd8e39b..b174679 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -22,7 +22,6 @@
 import '../type_inference/type_inference_engine.dart';
 import '../type_inference/type_inferrer.dart';
 import '../type_inference/type_schema.dart' show UnknownType;
-import '../type_inference/type_schema_elimination.dart' show greatestClosure;
 import 'body_builder.dart' show combineStatements;
 import 'collections.dart'
     show
@@ -5869,7 +5868,7 @@
 
   Expression inferAssignment(TypeInferrerImpl inferrer, DartType rhsType) {
     Expression rhs = inferrer.ensureAssignable(
-        greatestClosure(variableSet.variable.type, inferrer.bottomType),
+        inferrer.computeGreatestClosure(variableSet.variable.type),
         rhsType,
         variableSet.value,
         errorTemplate: templateForInLoopElementTypeNotAssignable,
@@ -5929,7 +5928,7 @@
   @override
   Expression inferAssignment(TypeInferrerImpl inferrer, DartType rhsType) {
     Expression rhs = inferrer.ensureAssignable(
-        greatestClosure(_writeType, inferrer.bottomType), rhsType, _rhs,
+        inferrer.computeGreatestClosure(_writeType), rhsType, _rhs,
         errorTemplate: templateForInLoopElementTypeNotAssignable,
         isVoidAllowed: true);
 
@@ -5963,7 +5962,7 @@
   @override
   Expression inferAssignment(TypeInferrerImpl inferrer, DartType rhsType) {
     Expression rhs = inferrer.ensureAssignable(
-        greatestClosure(_writeType, inferrer.bottomType),
+        inferrer.computeGreatestClosure(_writeType),
         rhsType,
         superPropertySet.value,
         errorTemplate: templateForInLoopElementTypeNotAssignable,
@@ -5988,7 +5987,7 @@
   @override
   Expression inferAssignment(TypeInferrerImpl inferrer, DartType rhsType) {
     Expression rhs = inferrer.ensureAssignable(
-        greatestClosure(staticSet.target.setterType, inferrer.bottomType),
+        inferrer.computeGreatestClosure(staticSet.target.setterType),
         rhsType,
         staticSet.value,
         errorTemplate: templateForInLoopElementTypeNotAssignable,
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index ac49df7..c28a357 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -157,7 +157,7 @@
       DartType returnContext, bool needToInferReturnType) {
     assert(returnContext != null);
     DartType declaredReturnType =
-        greatestClosure(returnContext, inferrer.bottomType);
+        inferrer.computeGreatestClosure(returnContext);
     bool isAsync = asyncMarker == AsyncMarker.Async ||
         asyncMarker == AsyncMarker.AsyncStar;
     bool isGenerator = asyncMarker == AsyncMarker.SyncStar ||
@@ -293,7 +293,7 @@
         if (!identical(statement.expression, expression)) {
           statement.expression = expression..parent = statement;
           // Not assignable, use the expectation.
-          type = greatestClosure(returnOrYieldContext, inferrer.bottomType);
+          type = inferrer.computeGreatestClosure(returnOrYieldContext);
         }
       }
       DartType unwrappedType = type;
@@ -337,7 +337,7 @@
     node.expression = expression..parent = node;
     DartType type = expressionResult.inferredType;
     if (!identical(expressionResult.expression, expression)) {
-      type = greatestClosure(expectedType, inferrer.bottomType);
+      type = inferrer.computeGreatestClosure(expectedType);
     }
     if (_needToInferReturnType) {
       DartType unwrappedType = type;
@@ -381,7 +381,7 @@
         returnOrYieldContext, SubtypeCheckMode.withNullabilities)) {
       // If the inferred return type isn't a subtype of the context, we use the
       // context.
-      inferredType = greatestClosure(declaredReturnType, inferrer.bottomType);
+      inferredType = inferrer.computeGreatestClosure2(declaredReturnType);
     }
 
     for (int i = 0; i < returnStatements.length; ++i) {
@@ -608,6 +608,19 @@
       ? const NeverType(Nullability.nonNullable)
       : engine.coreTypes.nullType;
 
+  DartType computeGreatestClosure(DartType type) {
+    return greatestClosure(type, const DynamicType(), bottomType);
+  }
+
+  DartType computeGreatestClosure2(DartType type) {
+    return greatestClosure(
+        type,
+        isNonNullableByDefault
+            ? coreTypes.objectNullableRawType
+            : const DynamicType(),
+        bottomType);
+  }
+
   DartType computeNullable(DartType type) {
     if (type == coreTypes.nullType || type is NeverType) {
       return coreTypes.nullType;
@@ -749,7 +762,7 @@
     if (isTopLevel) return expression;
 
     fileOffset ??= expression.fileOffset;
-    contextType = greatestClosure(contextType, bottomType);
+    contextType = computeGreatestClosure(contextType);
 
     DartType initialContextType = contextType;
     if (isReturnFromAsync &&
@@ -2488,9 +2501,8 @@
               coreTypes.isNull(formalTypesFromContext[i])) {
             inferredType = coreTypes.objectRawType(library.nullable);
           } else {
-            inferredType = greatestClosure(
-                substitution.substituteType(formalTypesFromContext[i]),
-                bottomType);
+            inferredType = computeGreatestClosure2(
+                substitution.substituteType(formalTypesFromContext[i]));
           }
         } else {
           inferredType = const DynamicType();
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart
index 75e3d42..6401112 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart
@@ -20,13 +20,9 @@
 ///
 /// Note that the greatest closure of a type schema is always a supertype of any
 /// type which matches the schema.
-DartType greatestClosure(DartType schema, DartType bottomType) {
-  assert(bottomType == const NeverType(Nullability.nonNullable) ||
-      bottomType is InterfaceType &&
-          bottomType.classNode.enclosingLibrary.importUri.scheme == "dart" &&
-          bottomType.classNode.enclosingLibrary.importUri.path == "core" &&
-          bottomType.classNode.name == "Null");
-  return _TypeSchemaEliminationVisitor.run(false, schema, bottomType);
+DartType greatestClosure(
+    DartType schema, DartType topType, DartType bottomType) {
+  return _TypeSchemaEliminationVisitor.run(false, schema, topType, bottomType);
 }
 
 /// Returns the least closure of the given type [schema] with respect to `?`.
@@ -42,13 +38,8 @@
 ///
 /// Note that the least closure of a type schema is always a subtype of any type
 /// which matches the schema.
-DartType leastClosure(DartType schema, DartType bottomType) {
-  assert(bottomType == const NeverType(Nullability.nonNullable) ||
-      bottomType is InterfaceType &&
-          bottomType.classNode.enclosingLibrary.importUri.scheme == "dart" &&
-          bottomType.classNode.enclosingLibrary.importUri.path == "core" &&
-          bottomType.classNode.name == "Null");
-  return _TypeSchemaEliminationVisitor.run(true, schema, bottomType);
+DartType leastClosure(DartType schema, DartType topType, DartType bottomType) {
+  return _TypeSchemaEliminationVisitor.run(true, schema, topType, bottomType);
 }
 
 /// Visitor that computes least and greatest closures of a type schema.
@@ -57,11 +48,13 @@
 /// type, otherwise it returns the result of substituting `?` with `Null` or
 /// `Object`, as appropriate.
 class _TypeSchemaEliminationVisitor extends ReplacementVisitor {
+  final DartType topType;
   final DartType bottomType;
 
   bool isLeastClosure;
 
-  _TypeSchemaEliminationVisitor(this.isLeastClosure, this.bottomType);
+  _TypeSchemaEliminationVisitor(
+      this.isLeastClosure, this.topType, this.bottomType);
 
   void changeVariance() {
     isLeastClosure = !isLeastClosure;
@@ -70,7 +63,7 @@
   @override
   DartType defaultDartType(DartType node) {
     if (node is UnknownType) {
-      return isLeastClosure ? bottomType : const DynamicType();
+      return isLeastClosure ? bottomType : topType;
     }
     return null;
   }
@@ -78,10 +71,21 @@
   /// Runs an instance of the visitor on the given [schema] and returns the
   /// resulting type.  If the schema contains no instances of `?`, the original
   /// schema object is returned to avoid unnecessary allocation.
-  static DartType run(
-      bool isLeastClosure, DartType schema, DartType bottomType) {
+  static DartType run(bool isLeastClosure, DartType schema, DartType topType,
+      DartType bottomType) {
+    assert(topType == const DynamicType() ||
+        topType is InterfaceType &&
+            topType.nullability == Nullability.nullable &&
+            topType.classNode.enclosingLibrary.importUri.scheme == "dart" &&
+            topType.classNode.enclosingLibrary.importUri.path == "core" &&
+            topType.classNode.name == "Object");
+    assert(bottomType == const NeverType(Nullability.nonNullable) ||
+        bottomType is InterfaceType &&
+            bottomType.classNode.enclosingLibrary.importUri.scheme == "dart" &&
+            bottomType.classNode.enclosingLibrary.importUri.path == "core" &&
+            bottomType.classNode.name == "Null");
     _TypeSchemaEliminationVisitor visitor =
-        new _TypeSchemaEliminationVisitor(isLeastClosure, bottomType);
+        new _TypeSchemaEliminationVisitor(isLeastClosure, topType, bottomType);
     DartType result = schema.accept(visitor);
     assert(visitor.isLeastClosure == isLeastClosure);
     return result ?? schema;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
index 97af6cc..05199b3 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
@@ -434,11 +434,11 @@
       // e.g. `Iterable<?>`
       if (constraint.lower is! UnknownType) {
         return grounded
-            ? leastClosure(constraint.lower, bottomType)
+            ? leastClosure(constraint.lower, const DynamicType(), bottomType)
             : constraint.lower;
       } else {
         return grounded
-            ? greatestClosure(constraint.upper, bottomType)
+            ? greatestClosure(constraint.upper, const DynamicType(), bottomType)
             : constraint.upper;
       }
     } else {
@@ -450,11 +450,11 @@
       // e.g. `Iterable<?>`
       if (constraint.upper is! UnknownType) {
         return grounded
-            ? greatestClosure(constraint.upper, bottomType)
+            ? greatestClosure(constraint.upper, const DynamicType(), bottomType)
             : constraint.upper;
       } else {
         return grounded
-            ? leastClosure(constraint.lower, bottomType)
+            ? leastClosure(constraint.lower, const DynamicType(), bottomType)
             : constraint.lower;
       }
     }
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart
index b177855..cc03f2a 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart
@@ -28,12 +28,12 @@
 
   DartType greatestClosure(DartType schema) {
     return typeSchemaElimination.greatestClosure(
-        schema, const NeverType(Nullability.nonNullable));
+        schema, const DynamicType(), const NeverType(Nullability.nonNullable));
   }
 
   DartType leastClosure(DartType schema) {
     return typeSchemaElimination.leastClosure(
-        schema, const NeverType(Nullability.nonNullable));
+        schema, const DynamicType(), const NeverType(Nullability.nonNullable));
   }
 
   void test_greatestClosure_contravariant() {
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart
index c21fee9..d7cf9e6 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart
@@ -29,11 +29,11 @@
   DartType get objectType => coreTypes.objectLegacyRawType;
 
   DartType greatestClosure(DartType schema) {
-    return typeSchemaElimination.greatestClosure(schema, nullType);
+    return typeSchemaElimination.greatestClosure(schema, dynamicType, nullType);
   }
 
   DartType leastClosure(DartType schema) {
-    return typeSchemaElimination.leastClosure(schema, nullType);
+    return typeSchemaElimination.leastClosure(schema, dynamicType, nullType);
   }
 
   void test_greatestClosure_contravariant() {
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.outline.expect
index ea7aadc..34eb654 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.outline.expect
@@ -5,7 +5,7 @@
 
 import "dart:async";
 
-static final field asy::StreamTransformer<dynamic, dynamic> t;
+static final field asy::StreamTransformer<core::Object?, core::Object?> t;
 static final field core::List<dynamic> s1;
 static final field core::int? s2;
 static final field core::List<core::int> s3;
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect
index cad8aa5..3daaf3e 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect
@@ -68,7 +68,7 @@
 
 import "dart:async";
 
-static final field asy::StreamTransformer<dynamic, dynamic> t = new asy::_StreamHandlerTransformer::•<dynamic, dynamic>(handleData: (dynamic data, asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
+static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static final field core::List<dynamic> s1 = <dynamic>[];
 static final field core::int? s2 = let final core::List<dynamic> #t1 = self::s1 in #t1.{core::List::==}(null) ?{core::int?} null : #t1.{core::List::length};
 static final field core::List<core::int> s3 = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
index 61c0af4..df8f463 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
@@ -68,7 +68,7 @@
 
 import "dart:async";
 
-static final field asy::StreamTransformer<dynamic, dynamic> t = new asy::_StreamHandlerTransformer::•<dynamic, dynamic>(handleData: (dynamic data, asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
+static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static final field core::List<dynamic> s1 = <dynamic>[];
 static final field core::int? s2 = let final core::List<dynamic> #t1 = self::s1 in #t1.{core::List::==}(null) ?{core::int?} null : #t1.{core::List::length};
 static final field core::List<core::int> s3 = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect
index cad8aa5..3daaf3e 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect
@@ -68,7 +68,7 @@
 
 import "dart:async";
 
-static final field asy::StreamTransformer<dynamic, dynamic> t = new asy::_StreamHandlerTransformer::•<dynamic, dynamic>(handleData: (dynamic data, asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
+static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static final field core::List<dynamic> s1 = <dynamic>[];
 static final field core::int? s2 = let final core::List<dynamic> #t1 = self::s1 in #t1.{core::List::==}(null) ?{core::int?} null : #t1.{core::List::length};
 static final field core::List<core::int> s3 = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect
index 61c0af4..df8f463 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect
@@ -68,7 +68,7 @@
 
 import "dart:async";
 
-static final field asy::StreamTransformer<dynamic, dynamic> t = new asy::_StreamHandlerTransformer::•<dynamic, dynamic>(handleData: (dynamic data, asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
+static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static final field core::List<dynamic> s1 = <dynamic>[];
 static final field core::int? s2 = let final core::List<dynamic> #t1 = self::s1 in #t1.{core::List::==}(null) ?{core::int?} null : #t1.{core::List::length};
 static final field core::List<core::int> s3 = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:17:16: Error: Can't use the default List constructor.
diff --git a/pkg/front_end/testcases/nnbd/issue41103.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41103.dart.outline.expect
index 49a4279..28aee32 100644
--- a/pkg/front_end/testcases/nnbd/issue41103.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue41103.dart.outline.expect
@@ -1,9 +1,10 @@
 library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:async" as asy;
+import "dart:core" as core;
 
 import "dart:async";
 
-static final field asy::StreamTransformer<dynamic, dynamic> t;
+static final field asy::StreamTransformer<core::Object?, core::Object?> t;
 static method main() → void
   ;
diff --git a/pkg/front_end/testcases/nnbd/issue41103.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41103.dart.strong.expect
index 367e4c5..ea23f98 100644
--- a/pkg/front_end/testcases/nnbd/issue41103.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue41103.dart.strong.expect
@@ -1,8 +1,9 @@
 library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:async" as asy;
+import "dart:core" as core;
 
 import "dart:async";
 
-static final field asy::StreamTransformer<dynamic, dynamic> t = new asy::_StreamHandlerTransformer::•<dynamic, dynamic>(handleData: (dynamic data, asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
+static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41103.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41103.dart.strong.transformed.expect
index 367e4c5..ea23f98 100644
--- a/pkg/front_end/testcases/nnbd/issue41103.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41103.dart.strong.transformed.expect
@@ -1,8 +1,9 @@
 library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:async" as asy;
+import "dart:core" as core;
 
 import "dart:async";
 
-static final field asy::StreamTransformer<dynamic, dynamic> t = new asy::_StreamHandlerTransformer::•<dynamic, dynamic>(handleData: (dynamic data, asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
+static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41103.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41103.dart.weak.expect
index 367e4c5..ea23f98 100644
--- a/pkg/front_end/testcases/nnbd/issue41103.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue41103.dart.weak.expect
@@ -1,8 +1,9 @@
 library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:async" as asy;
+import "dart:core" as core;
 
 import "dart:async";
 
-static final field asy::StreamTransformer<dynamic, dynamic> t = new asy::_StreamHandlerTransformer::•<dynamic, dynamic>(handleData: (dynamic data, asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
+static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41103.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41103.dart.weak.transformed.expect
index 367e4c5..ea23f98 100644
--- a/pkg/front_end/testcases/nnbd/issue41103.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41103.dart.weak.transformed.expect
@@ -1,8 +1,9 @@
 library /*isNonNullableByDefault*/;
 import self as self;
 import "dart:async" as asy;
+import "dart:core" as core;
 
 import "dart:async";
 
-static final field asy::StreamTransformer<dynamic, dynamic> t = new asy::_StreamHandlerTransformer::•<dynamic, dynamic>(handleData: (dynamic data, asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<dynamic> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
+static final field asy::StreamTransformer<core::Object?, core::Object?> t = new asy::_StreamHandlerTransformer::•<core::Object?, core::Object?>(handleData: (core::Object? data, asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::add}(data)), handleDone: (asy::EventSink<core::Object?> sink) → asy::Future<void> => asy::Future::microtask<void>(() → void => sink.{asy::EventSink::close}()));
 static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41386.dart b/pkg/front_end/testcases/nnbd/issue41386.dart
new file mode 100644
index 0000000..8f7d938
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2020, 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.
+
+bool Function(T) predicate<T>(bool Function(T) fn) => (T val) => fn(val);
+
+void test() {
+  print(predicate((v) => v % 2 == 1)(3));
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41386.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41386.dart.outline.expect
new file mode 100644
index 0000000..16f60b9
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386.dart.outline.expect
@@ -0,0 +1,10 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method predicate<T extends core::Object? = dynamic>((self::predicate::T%) → core::bool fn) → (self::predicate::T%) → core::bool
+  ;
+static method test() → void
+  ;
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue41386.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41386.dart.strong.expect
new file mode 100644
index 0000000..6f63736
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386.dart.strong.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41386.dart:8:28: Error: The operator '%' isn't defined for the class 'Object?'.
+//  - 'Object' is from 'dart:core'.
+// Try correcting the operator to an existing operator, or defining a '%' operator.
+//   print(predicate((v) => v % 2 == 1)(3));
+//                            ^
+//
+import self as self;
+import "dart:core" as core;
+
+static method predicate<T extends core::Object? = dynamic>((self::predicate::T%) → core::bool fn) → (self::predicate::T%) → core::bool
+  return (self::predicate::T% val) → core::bool => fn.call(val);
+static method test() → void {
+  core::print(self::predicate<core::Object?>((core::Object? v) → core::bool => invalid-expression "pkg/front_end/testcases/nnbd/issue41386.dart:8:28: Error: The operator '%' isn't defined for the class 'Object?'.
+ - 'Object' is from 'dart:core'.
+Try correcting the operator to an existing operator, or defining a '%' operator.
+  print(predicate((v) => v % 2 == 1)(3));
+                           ^".{core::Object::==}(1)).call(3));
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41386.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41386.dart.strong.transformed.expect
new file mode 100644
index 0000000..6f63736
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41386.dart:8:28: Error: The operator '%' isn't defined for the class 'Object?'.
+//  - 'Object' is from 'dart:core'.
+// Try correcting the operator to an existing operator, or defining a '%' operator.
+//   print(predicate((v) => v % 2 == 1)(3));
+//                            ^
+//
+import self as self;
+import "dart:core" as core;
+
+static method predicate<T extends core::Object? = dynamic>((self::predicate::T%) → core::bool fn) → (self::predicate::T%) → core::bool
+  return (self::predicate::T% val) → core::bool => fn.call(val);
+static method test() → void {
+  core::print(self::predicate<core::Object?>((core::Object? v) → core::bool => invalid-expression "pkg/front_end/testcases/nnbd/issue41386.dart:8:28: Error: The operator '%' isn't defined for the class 'Object?'.
+ - 'Object' is from 'dart:core'.
+Try correcting the operator to an existing operator, or defining a '%' operator.
+  print(predicate((v) => v % 2 == 1)(3));
+                           ^".{core::Object::==}(1)).call(3));
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41386.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41386.dart.weak.expect
new file mode 100644
index 0000000..6f63736
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386.dart.weak.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41386.dart:8:28: Error: The operator '%' isn't defined for the class 'Object?'.
+//  - 'Object' is from 'dart:core'.
+// Try correcting the operator to an existing operator, or defining a '%' operator.
+//   print(predicate((v) => v % 2 == 1)(3));
+//                            ^
+//
+import self as self;
+import "dart:core" as core;
+
+static method predicate<T extends core::Object? = dynamic>((self::predicate::T%) → core::bool fn) → (self::predicate::T%) → core::bool
+  return (self::predicate::T% val) → core::bool => fn.call(val);
+static method test() → void {
+  core::print(self::predicate<core::Object?>((core::Object? v) → core::bool => invalid-expression "pkg/front_end/testcases/nnbd/issue41386.dart:8:28: Error: The operator '%' isn't defined for the class 'Object?'.
+ - 'Object' is from 'dart:core'.
+Try correcting the operator to an existing operator, or defining a '%' operator.
+  print(predicate((v) => v % 2 == 1)(3));
+                           ^".{core::Object::==}(1)).call(3));
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41386.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41386.dart.weak.transformed.expect
new file mode 100644
index 0000000..6f63736
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386.dart.weak.transformed.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41386.dart:8:28: Error: The operator '%' isn't defined for the class 'Object?'.
+//  - 'Object' is from 'dart:core'.
+// Try correcting the operator to an existing operator, or defining a '%' operator.
+//   print(predicate((v) => v % 2 == 1)(3));
+//                            ^
+//
+import self as self;
+import "dart:core" as core;
+
+static method predicate<T extends core::Object? = dynamic>((self::predicate::T%) → core::bool fn) → (self::predicate::T%) → core::bool
+  return (self::predicate::T% val) → core::bool => fn.call(val);
+static method test() → void {
+  core::print(self::predicate<core::Object?>((core::Object? v) → core::bool => invalid-expression "pkg/front_end/testcases/nnbd/issue41386.dart:8:28: Error: The operator '%' isn't defined for the class 'Object?'.
+ - 'Object' is from 'dart:core'.
+Try correcting the operator to an existing operator, or defining a '%' operator.
+  print(predicate((v) => v % 2 == 1)(3));
+                           ^".{core::Object::==}(1)).call(3));
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41386b.dart b/pkg/front_end/testcases/nnbd/issue41386b.dart
new file mode 100644
index 0000000..bdab2fd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386b.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, 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.
+
+void test() {
+  var map = {};
+  map[0].foo;
+  Iterable<String> elements = <String>[];
+  var list = new List.from(elements);
+  new List.from(elements).forEach((element) => element.foo);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41386b.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41386b.dart.outline.expect
new file mode 100644
index 0000000..d7d3d2f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386b.dart.outline.expect
@@ -0,0 +1,7 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+static method test() → void
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue41386b.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41386b.dart.strong.expect
new file mode 100644
index 0000000..189246c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386b.dart.strong.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  core::Map<dynamic, dynamic> map = <dynamic, dynamic>{};
+  map.{core::Map::[]}(0).foo;
+  core::Iterable<core::String> elements = <core::String>[];
+  core::List<dynamic> list = core::List::from<dynamic>(elements);
+  core::List::from<dynamic>(elements).{core::Iterable::forEach}((dynamic element) → dynamic => element.foo);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41386b.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41386b.dart.strong.transformed.expect
new file mode 100644
index 0000000..189246c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386b.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  core::Map<dynamic, dynamic> map = <dynamic, dynamic>{};
+  map.{core::Map::[]}(0).foo;
+  core::Iterable<core::String> elements = <core::String>[];
+  core::List<dynamic> list = core::List::from<dynamic>(elements);
+  core::List::from<dynamic>(elements).{core::Iterable::forEach}((dynamic element) → dynamic => element.foo);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41386b.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41386b.dart.weak.expect
new file mode 100644
index 0000000..189246c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386b.dart.weak.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  core::Map<dynamic, dynamic> map = <dynamic, dynamic>{};
+  map.{core::Map::[]}(0).foo;
+  core::Iterable<core::String> elements = <core::String>[];
+  core::List<dynamic> list = core::List::from<dynamic>(elements);
+  core::List::from<dynamic>(elements).{core::Iterable::forEach}((dynamic element) → dynamic => element.foo);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41386b.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41386b.dart.weak.transformed.expect
new file mode 100644
index 0000000..189246c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41386b.dart.weak.transformed.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  core::Map<dynamic, dynamic> map = <dynamic, dynamic>{};
+  map.{core::Map::[]}(0).foo;
+  core::Iterable<core::String> elements = <core::String>[];
+  core::List<dynamic> list = core::List::from<dynamic>(elements);
+  core::List::from<dynamic>(elements).{core::Iterable::forEach}((dynamic element) → dynamic => element.foo);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart b/pkg/front_end/testcases/nnbd/issue41415.dart
index 60e3258..1b33195 100644
--- a/pkg/front_end/testcases/nnbd/issue41415.dart
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart
@@ -2,9 +2,6 @@
 // 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.
 
-// Requirements=nnbd-strong
-import "package:expect/expect.dart";
-
 main() {
   // Pre-NNBD bottom type.
   int Function(Null) f = (x) => 1; // Runtime type is int Function(Object?)
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41415.dart.outline.expect
index 73b21aa..e2cba6b 100644
--- a/pkg/front_end/testcases/nnbd/issue41415.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart.outline.expect
@@ -1,7 +1,5 @@
 library /*isNonNullableByDefault*/;
 import self as self;
 
-import "package:expect/expect.dart";
-
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41415.dart.strong.expect
index 7e85811..4c844e6 100644
--- a/pkg/front_end/testcases/nnbd/issue41415.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart.strong.expect
@@ -2,8 +2,6 @@
 import self as self;
 import "dart:core" as core;
 
-import "package:expect/expect.dart";
-
 static method main() → dynamic {
   (core::Null?) → core::int f = (core::Object? x) → core::int => 1;
   (Never) → core::int g = (core::Object? x) → core::int => 1;
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41415.dart.strong.transformed.expect
index 7e85811..4c844e6 100644
--- a/pkg/front_end/testcases/nnbd/issue41415.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart.strong.transformed.expect
@@ -2,8 +2,6 @@
 import self as self;
 import "dart:core" as core;
 
-import "package:expect/expect.dart";
-
 static method main() → dynamic {
   (core::Null?) → core::int f = (core::Object? x) → core::int => 1;
   (Never) → core::int g = (core::Object? x) → core::int => 1;
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41415.dart.weak.expect
index 7e85811..4c844e6 100644
--- a/pkg/front_end/testcases/nnbd/issue41415.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart.weak.expect
@@ -2,8 +2,6 @@
 import self as self;
 import "dart:core" as core;
 
-import "package:expect/expect.dart";
-
 static method main() → dynamic {
   (core::Null?) → core::int f = (core::Object? x) → core::int => 1;
   (Never) → core::int g = (core::Object? x) → core::int => 1;
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41415.dart.weak.transformed.expect
index 7e85811..4c844e6 100644
--- a/pkg/front_end/testcases/nnbd/issue41415.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart.weak.transformed.expect
@@ -2,8 +2,6 @@
 import self as self;
 import "dart:core" as core;
 
-import "package:expect/expect.dart";
-
 static method main() → dynamic {
   (core::Null?) → core::int f = (core::Object? x) → core::int => 1;
   (Never) → core::int g = (core::Object? x) → core::int => 1;
diff --git a/pkg/nnbd_migration/lib/nnbd_migration.dart b/pkg/nnbd_migration/lib/nnbd_migration.dart
index 7388f0c..613c600 100644
--- a/pkg/nnbd_migration/lib/nnbd_migration.dart
+++ b/pkg/nnbd_migration/lib/nnbd_migration.dart
@@ -147,6 +147,12 @@
           'Changed a null-aware access into an ordinary access, because the target cannot be null',
       kind: NullabilityFixKind.removeDeadCode);
 
+  /// A null-aware assignment was removed because its LHS is non-nullable.
+  static const removeNullAwareAssignment = const NullabilityFixDescription._(
+      appliedMessage:
+          'Removed a null-aware assignment, because the target cannot be null',
+      kind: NullabilityFixKind.removeDeadCode);
+
   /// A message used to indicate a fix has been applied.
   final String appliedMessage;
 
diff --git a/pkg/nnbd_migration/lib/src/fix_aggregator.dart b/pkg/nnbd_migration/lib/src/fix_aggregator.dart
index e1548ab..ba4452c 100644
--- a/pkg/nnbd_migration/lib/src/fix_aggregator.dart
+++ b/pkg/nnbd_migration/lib/src/fix_aggregator.dart
@@ -304,56 +304,28 @@
 /// Implementation of [NodeChange] specialized for operating on
 /// [AssignmentExpression] nodes.
 class NodeChangeForAssignment
-    extends NodeChangeForExpression<AssignmentExpression> {
-  /// Indicates whether the user should be warned that the assignment is a
-  /// compound assignment with a bad combined type (the return type of the
-  /// combiner isn't assignable to the the write type of the LHS).
-  bool isCompoundAssignmentWithBadCombinedType = false;
-
-  /// Indicates whether the user should be warned that the assignment is a
-  /// compound assignment with a nullable source type.
-  bool isCompoundAssignmentWithNullableSource = false;
-
+    extends NodeChangeForExpression<AssignmentExpression>
+    with NodeChangeForAssignmentLike {
   /// Indicates whether the user should be warned that the assignment is a
   /// null-aware assignment that will have no effect when strong checking is
   /// enabled.
   bool isWeakNullAware = false;
 
   @override
-  Iterable<String> get _toStringParts => [
-        ...super._toStringParts,
-        if (isCompoundAssignmentWithBadCombinedType)
-          'isCompoundAssignmentWithBadCombinedType',
-        if (isCompoundAssignmentWithNullableSource)
-          'isCompoundAssignmentWithNullableSource',
-        if (isWeakNullAware) 'isWeakNullAware'
-      ];
+  Iterable<String> get _toStringParts =>
+      [...super._toStringParts, if (isWeakNullAware) 'isWeakNullAware'];
 
   @override
   NodeProducingEditPlan _apply(
       AssignmentExpression node, FixAggregator aggregator) {
     var lhsPlan = aggregator.planForNode(node.leftHandSide);
-    EditPlan operatorPlan;
-    if (isCompoundAssignmentWithNullableSource) {
-      operatorPlan = aggregator.planner.informativeMessageForToken(
-          node, node.operator,
-          info: AtomicEditInfo(
-              NullabilityFixDescription.compoundAssignmentHasNullableSource,
-              const {}));
-    } else if (isCompoundAssignmentWithBadCombinedType) {
-      operatorPlan = aggregator.planner.informativeMessageForToken(
-          node, node.operator,
-          info: AtomicEditInfo(
-              NullabilityFixDescription.compoundAssignmentHasBadCombinedType,
-              const {}));
-    } else if (isWeakNullAware) {
-      operatorPlan = aggregator.planner.informativeMessageForToken(
-          node, node.operator,
-          info: AtomicEditInfo(
-              NullabilityFixDescription
-                  .nullAwareAssignmentUnnecessaryInStrongMode,
-              const {}));
+    if (isWeakNullAware && !aggregator._warnOnWeakCode) {
+      // Just keep the LHS
+      return aggregator.planner.extract(node, lhsPlan as NodeProducingEditPlan,
+          infoAfter: AtomicEditInfo(
+              NullabilityFixDescription.removeNullAwareAssignment, const {}));
     }
+    var operatorPlan = _makeOperatorPlan(aggregator, node, node.operator);
     var rhsPlan = aggregator.planForNode(node.rightHandSide);
     var innerPlans = <EditPlan>[
       lhsPlan,
@@ -363,6 +335,59 @@
     return _applyExpression(aggregator,
         aggregator.planner.passThrough(node, innerPlans: innerPlans));
   }
+
+  EditPlan _makeOperatorPlan(
+      FixAggregator aggregator, AssignmentExpression node, Token operator) {
+    var operatorPlan = super._makeOperatorPlan(aggregator, node, operator);
+    if (operatorPlan != null) return operatorPlan;
+    if (isWeakNullAware) {
+      assert(aggregator._warnOnWeakCode);
+      return aggregator.planner.informativeMessageForToken(node, operator,
+          info: AtomicEditInfo(
+              NullabilityFixDescription
+                  .nullAwareAssignmentUnnecessaryInStrongMode,
+              const {}));
+    } else {
+      return null;
+    }
+  }
+}
+
+/// Common behaviors for expressions that can represent an assignment (possibly
+/// through desugaring).
+mixin NodeChangeForAssignmentLike<N extends Expression>
+    on NodeChangeForExpression<N> {
+  /// Indicates whether the user should be warned that the assignment has a
+  /// bad combined type (the return type of the combiner isn't assignable to the
+  /// write type of the target).
+  bool hasBadCombinedType = false;
+
+  /// Indicates whether the user should be warned that the assignment has a
+  /// nullable source type.
+  bool hasNullableSource = false;
+
+  @override
+  Iterable<String> get _toStringParts => [
+        ...super._toStringParts,
+        if (hasBadCombinedType) 'hasBadCombinedType',
+        if (hasNullableSource) 'hasNullableSource'
+      ];
+
+  EditPlan _makeOperatorPlan(FixAggregator aggregator, N node, Token operator) {
+    if (hasNullableSource) {
+      return aggregator.planner.informativeMessageForToken(node, operator,
+          info: AtomicEditInfo(
+              NullabilityFixDescription.compoundAssignmentHasNullableSource,
+              const {}));
+    } else if (hasBadCombinedType) {
+      return aggregator.planner.informativeMessageForToken(node, operator,
+          info: AtomicEditInfo(
+              NullabilityFixDescription.compoundAssignmentHasBadCombinedType,
+              const {}));
+    } else {
+      return null;
+    }
+  }
 }
 
 /// Implementation of [NodeChange] specialized for operating on
@@ -693,6 +718,44 @@
   }
 }
 
+/// Implementation of [NodeChange] specialized for operating on
+/// [PostfixExpression] nodes.
+class NodeChangeForPostfixExpression
+    extends NodeChangeForExpression<PostfixExpression>
+    with NodeChangeForAssignmentLike {
+  @override
+  NodeProducingEditPlan _apply(
+      PostfixExpression node, FixAggregator aggregator) {
+    var operandPlan = aggregator.planForNode(node.operand);
+    var operatorPlan = _makeOperatorPlan(aggregator, node, node.operator);
+    var innerPlans = <EditPlan>[
+      operandPlan,
+      if (operatorPlan != null) operatorPlan
+    ];
+    return _applyExpression(aggregator,
+        aggregator.planner.passThrough(node, innerPlans: innerPlans));
+  }
+}
+
+/// Implementation of [NodeChange] specialized for operating on
+/// [PrefixExpression] nodes.
+class NodeChangeForPrefixExpression
+    extends NodeChangeForExpression<PrefixExpression>
+    with NodeChangeForAssignmentLike {
+  @override
+  NodeProducingEditPlan _apply(
+      PrefixExpression node, FixAggregator aggregator) {
+    var operatorPlan = _makeOperatorPlan(aggregator, node, node.operator);
+    var operandPlan = aggregator.planForNode(node.operand);
+    var innerPlans = <EditPlan>[
+      if (operatorPlan != null) operatorPlan,
+      operandPlan
+    ];
+    return _applyExpression(aggregator,
+        aggregator.planner.passThrough(node, innerPlans: innerPlans));
+  }
+}
+
 /// Implementation of [NodeChange] specialized for operating on [PropertyAccess]
 /// nodes.
 class NodeChangeForPropertyAccess
@@ -934,6 +997,14 @@
       throw StateError('Unexpected node type: ${node.runtimeType}');
 
   @override
+  NodeChange visitPostfixExpression(PostfixExpression node) =>
+      NodeChangeForPostfixExpression();
+
+  @override
+  NodeChange visitPrefixExpression(PrefixExpression node) =>
+      NodeChangeForPrefixExpression();
+
+  @override
   NodeChange visitPropertyAccess(PropertyAccess node) =>
       NodeChangeForPropertyAccess();
 
diff --git a/pkg/nnbd_migration/lib/src/fix_builder.dart b/pkg/nnbd_migration/lib/src/fix_builder.dart
index bbec67f..19128d2 100644
--- a/pkg/nnbd_migration/lib/src/fix_builder.dart
+++ b/pkg/nnbd_migration/lib/src/fix_builder.dart
@@ -39,6 +39,16 @@
 import 'package:nnbd_migration/src/utilities/resolution_utils.dart';
 import 'package:nnbd_migration/src/variables.dart';
 
+bool _isIncrementOrDecrementOperator(TokenType tokenType) {
+  switch (tokenType) {
+    case TokenType.PLUS_PLUS:
+    case TokenType.MINUS_MINUS:
+      return true;
+    default:
+      return false;
+  }
+}
+
 /// Problem reported by [FixBuilder] when encountering a compound assignment
 /// for which the combination result is nullable.  This occurs if the compound
 /// assignment resolves to a user-defined operator that returns a nullable type,
@@ -289,8 +299,8 @@
 
   final Expando<bool> _shouldStayNullAware = Expando();
 
-  final Map<AssignmentExpression, _AssignmentExpressionHandler>
-      _assignmentExpressionHandlers = {};
+  final Map<Expression, _AssignmentLikeExpressionHandler>
+      _assignmentLikeExpressionHandlers = {};
 
   FlowAnalysis<AstNode, Statement, Expression, PromotableElement, DartType>
       _flowAnalysis;
@@ -429,12 +439,23 @@
       _wrapExceptions(node, () => type, () {
         var parent = node.parent;
         if (parent is AssignmentExpression) {
-          return (_assignmentExpressionHandlers[parent] ??=
+          return (_assignmentLikeExpressionHandlers[parent] ??=
                   _AssignmentExpressionHandler(parent))
               .modifySubexpressionType(this, node, type);
-        } else {
-          return _modifyRValueType(node, type);
+        } else if (parent is PrefixExpression) {
+          if (_isIncrementOrDecrementOperator(parent.operator.type)) {
+            return (_assignmentLikeExpressionHandlers[parent] ??=
+                    _PrefixExpressionHandler(parent))
+                .modifySubexpressionType(this, node, type);
+          }
+        } else if (parent is PostfixExpression) {
+          if (_isIncrementOrDecrementOperator(parent.operator.type)) {
+            return (_assignmentLikeExpressionHandlers[parent] ??=
+                    _PostfixExpressionHandler(parent))
+                .modifySubexpressionType(this, node, type);
+          }
         }
+        return _modifyRValueType(node, type);
       });
 
   @override
@@ -627,12 +648,28 @@
 /// Common supertype for problems reported by [FixBuilder._addProblem].
 abstract class Problem {}
 
-/// Data structure keeping track of intermediate results when the fix builder
-/// is handling an assignment expression.
-class _AssignmentExpressionHandler {
-  /// The assignment expression in question.
+/// Specialization of [_AssignmentLikeExpressionHandler] for
+/// [AssignmentExpression].
+class _AssignmentExpressionHandler extends _AssignmentLikeExpressionHandler {
+  @override
   final AssignmentExpression node;
 
+  _AssignmentExpressionHandler(this.node);
+
+  @override
+  MethodElement get combiner => node.staticElement;
+
+  @override
+  TokenType get combinerType => node.operator.type;
+
+  @override
+  Expression get target => node.leftHandSide;
+}
+
+/// Data structure keeping track of intermediate results when the fix builder
+/// is handling an assignment expression, or an expression that desugars to an
+/// assignment.
+abstract class _AssignmentLikeExpressionHandler {
   /// For compound and null-aware assignments, the type read from the LHS.
   /*late final*/ DartType readType;
 
@@ -642,26 +679,36 @@
   /// The type that should be used as a context type when inferring the RHS.
   DartType rhsContextType;
 
-  _AssignmentExpressionHandler(this.node);
+  /// Gets the static element representing the combiner.
+  MethodElement get combiner;
+
+  /// Gets the operator type representing the combiner.
+  TokenType get combinerType;
+
+  /// Gets the expression in question.
+  Expression get node;
+
+  /// Gets the target of the assignment.
+  Expression get target;
 
   /// Called after visiting the RHS of the assignment, to verify that for
   /// compound assignments, the return value of the assignment is assignable to
   /// [writeType].
   void handleAssignmentRhs(
       MigrationResolutionHooksImpl hooks, DartType rhsType) {
-    MethodElement combiner = node.staticElement;
+    MethodElement combiner = this.combiner;
     if (combiner != null) {
       var fixBuilder = hooks._fixBuilder;
       var combinerReturnType =
           fixBuilder._typeSystem.refineBinaryExpressionType(
         readType,
-        node.operator.type,
+        combinerType,
         rhsType,
         combiner.returnType,
       );
       if (!fixBuilder._typeSystem.isSubtypeOf(combinerReturnType, writeType)) {
-        (fixBuilder._getChange(node) as NodeChangeForAssignment)
-            .isCompoundAssignmentWithBadCombinedType = true;
+        (fixBuilder._getChange(node) as NodeChangeForAssignmentLike)
+            .hasBadCombinedType = true;
       }
     }
   }
@@ -670,18 +717,18 @@
   /// [writeType], and [rhsContextType].  Also verifies that for compound
   /// assignments, the [readType] is non-nullable, and that for null-aware
   /// assignments, the [readType] is nullable.
-  void handleLValueType(MigrationResolutionHooksImpl hooks,
-      TokenType operatorType, DartType resolvedType) {
+  void handleLValueType(
+      MigrationResolutionHooksImpl hooks, DartType resolvedType) {
     assert(resolvedType.nullabilitySuffix != NullabilitySuffix.star);
-    // Provisionally store the resolved type as the type of the lhs, so that
+    // Provisionally store the resolved type as the type of the target, so that
     // getReadType can fall back on it if necessary.
-    var lhs = node.leftHandSide;
-    lhs.staticType = resolvedType;
+    var target = this.target;
+    target.staticType = resolvedType;
     // The type passed in by the resolver for the LHS of an assignment is the
     // "write type".
     var writeType = resolvedType;
-    if (lhs is SimpleIdentifier) {
-      var element = lhs.staticElement;
+    if (target is SimpleIdentifier) {
+      var element = target.staticElement;
       if (element is PromotableElement) {
         // However, if the LHS is a reference to a local variable that has
         // been promoted, the resolver passes in the promoted type.  We
@@ -694,12 +741,12 @@
     assert(writeType.nullabilitySuffix != NullabilitySuffix.star);
     this.writeType = writeType;
     var fixBuilder = hooks._fixBuilder;
-    if (operatorType == TokenType.EQ) {
+    if (combinerType == TokenType.EQ) {
       rhsContextType = writeType;
     } else {
-      readType = getReadType(lhs);
+      readType = getReadType(target);
       assert(readType.nullabilitySuffix != NullabilitySuffix.star);
-      if (operatorType == TokenType.QUESTION_QUESTION_EQ) {
+      if (combinerType == TokenType.QUESTION_QUESTION_EQ) {
         rhsContextType = writeType;
         if (fixBuilder._typeSystem.isNonNullable(readType)) {
           (fixBuilder._getChange(node) as NodeChangeForAssignment)
@@ -708,8 +755,8 @@
       } else {
         if (!readType.isDynamic &&
             fixBuilder._typeSystem.isPotentiallyNullable(readType)) {
-          (fixBuilder._getChange(node) as NodeChangeForAssignment)
-              .isCompoundAssignmentWithNullableSource = true;
+          (fixBuilder._getChange(node) as NodeChangeForAssignmentLike)
+              .hasNullableSource = true;
         }
       }
     }
@@ -718,11 +765,18 @@
   /// Called after visiting the LHS or the RHS of the assignment.
   DartType modifySubexpressionType(MigrationResolutionHooksImpl hooks,
       Expression subexpression, DartType type) {
-    if (identical(subexpression, node.leftHandSide)) {
-      handleLValueType(hooks, node.operator.type, type);
+    if (identical(subexpression, target)) {
+      handleLValueType(hooks, type);
+      if (node is! AssignmentExpression) {
+        // Must be a pre or post increment/decrement, so the "RHS" is implicitly
+        // the integer 1.
+        handleAssignmentRhs(hooks, hooks._fixBuilder.typeProvider.intType);
+      }
       return type;
     } else {
-      assert(identical(subexpression, node.rightHandSide));
+      var node = this.node;
+      assert(node is AssignmentExpression &&
+          identical(subexpression, node.rightHandSide));
       type =
           hooks._modifyRValueType(subexpression, type, context: rhsContextType);
       handleAssignmentRhs(hooks, type);
@@ -935,3 +989,41 @@
                 _fixBuilder._variables.getNullabilityHint(source, node));
   }
 }
+
+/// Specialization of [_AssignmentLikeExpressionHandler] for
+/// [PostfixExpression].
+class _PostfixExpressionHandler extends _AssignmentLikeExpressionHandler {
+  @override
+  final PostfixExpression node;
+
+  _PostfixExpressionHandler(this.node)
+      : assert(_isIncrementOrDecrementOperator(node.operator.type));
+
+  @override
+  MethodElement get combiner => node.staticElement;
+
+  @override
+  TokenType get combinerType => node.operator.type;
+
+  @override
+  Expression get target => node.operand;
+}
+
+/// Specialization of [_AssignmentLikeExpressionHandler] for
+/// [PrefixExpression].
+class _PrefixExpressionHandler extends _AssignmentLikeExpressionHandler {
+  @override
+  final PrefixExpression node;
+
+  _PrefixExpressionHandler(this.node)
+      : assert(_isIncrementOrDecrementOperator(node.operator.type));
+
+  @override
+  MethodElement get combiner => node.staticElement;
+
+  @override
+  TokenType get combinerType => node.operator.type;
+
+  @override
+  Expression get target => node.operand;
+}
diff --git a/pkg/nnbd_migration/lib/src/front_end/info_builder.dart b/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
index e063963..2a45144 100644
--- a/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
@@ -196,7 +196,8 @@
         break;
       case NullabilityFixKind.compoundAssignmentHasBadCombinedType:
       case NullabilityFixKind.compoundAssignmentHasNullableSource:
-        // We don't offer any edits around bad compound assignments.
+        // We don't offer any edits around bad compound assignments or bad
+        // increment/decrement operations.
         break;
     }
     return edits;
diff --git a/pkg/nnbd_migration/lib/src/front_end/resources/index.html b/pkg/nnbd_migration/lib/src/front_end/resources/index.html
index a1e8242..48d7a74 100644
--- a/pkg/nnbd_migration/lib/src/front_end/resources/index.html
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/index.html
@@ -71,7 +71,7 @@
       href="https://goo.gle/dart-null-safety-migration-tool">Null safety
         migration help</a>
     <span class="wide"> </span>
-    <div>Based on {{ sdkVersion }}</div>
+    <div>Based on <span id="sdk-version">{{ sdkVersion }}</span></div>
     <button class="report-problem">Report a Problem</button>
 </footer>
 </body>
diff --git a/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart b/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
index 8a3cf79..5bef8d6 100644
--- a/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
@@ -270,7 +270,7 @@
 ''';
 
 String _index_html;
-// index_html md5 is 'f3749ede15251d6832acc370afaca966'
+// index_html md5 is 'b66394e479a3d5a43b260b7278cc74be'
 String _index_html_base64 = '''
 PGh0bWw+CjxoZWFkPgogICAgPHRpdGxlPk51bGwgU2FmZXR5IFByZXZpZXc8L3RpdGxlPgogICAgPHNj
 cmlwdCBzcmM9Int7IGhpZ2hsaWdodEpzUGF0aCB9fSI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0Pnt7IGRh
@@ -321,9 +321,9 @@
 ZWwgLS0+CjwvZGl2PjwhLS0gL3BhbmVscyAtLT4KPGZvb3Rlcj4KICAgIDxhIHRhcmdldD0iX2JsYW5r
 IgogICAgICBocmVmPSJodHRwczovL2dvby5nbGUvZGFydC1udWxsLXNhZmV0eS1taWdyYXRpb24tdG9v
 bCI+TnVsbCBzYWZldHkKICAgICAgICBtaWdyYXRpb24gaGVscDwvYT4KICAgIDxzcGFuIGNsYXNzPSJ3
-aWRlIj4gPC9zcGFuPgogICAgPGRpdj5CYXNlZCBvbiB7eyBzZGtWZXJzaW9uIH19PC9kaXY+CiAgICA8
-YnV0dG9uIGNsYXNzPSJyZXBvcnQtcHJvYmxlbSI+UmVwb3J0IGEgUHJvYmxlbTwvYnV0dG9uPgo8L2Zv
-b3Rlcj4KPC9ib2R5Pgo8L2h0bWw+Cg==
+aWRlIj4gPC9zcGFuPgogICAgPGRpdj5CYXNlZCBvbiA8c3BhbiBpZD0ic2RrLXZlcnNpb24iPnt7IHNk
+a1ZlcnNpb24gfX08L3NwYW4+PC9kaXY+CiAgICA8YnV0dG9uIGNsYXNzPSJyZXBvcnQtcHJvYmxlbSI+
+UmVwb3J0IGEgUHJvYmxlbTwvYnV0dG9uPgo8L2Zvb3Rlcj4KPC9ib2R5Pgo8L2h0bWw+Cg==
 ''';
 
 String _migration_css;
@@ -479,7 +479,7 @@
 ''';
 
 String _migration_js;
-// migration_dart md5 is 'cc4f0602969516a30d5bfaecccc3f0f1'
+// migration_dart md5 is '1304024d7fb410d20ab30af7a6a25142'
 String _migration_js_base64 = '''
 KGZ1bmN0aW9uIGRhcnRQcm9ncmFtKCl7ZnVuY3Rpb24gY29weVByb3BlcnRpZXMoYSxiKXt2YXIgdD1P
 YmplY3Qua2V5cyhhKQpmb3IodmFyIHM9MDtzPHQubGVuZ3RoO3MrKyl7dmFyIHI9dFtzXQpiW3JdPWFb
@@ -553,958 +553,890 @@
 czpzZXRPclVwZGF0ZUxlYWZUYWdzfX0oKQpmdW5jdGlvbiBpbml0aWFsaXplRGVmZXJyZWRIdW5rKGEp
 e3g9di50eXBlcy5sZW5ndGgKYShodW5rSGVscGVycyx2LHcsJCl9ZnVuY3Rpb24gZ2V0R2xvYmFsRnJv
 bU5hbWUoYSl7Zm9yKHZhciB0PTA7dDx3Lmxlbmd0aDt0Kyspe2lmKHdbdF09PUMpY29udGludWUKaWYo
-d1t0XVthXSlyZXR1cm4gd1t0XVthXX19dmFyIEM9e30sSD17Rks6ZnVuY3Rpb24gRksoKXt9LAp5Ujpm
-dW5jdGlvbihhKXtyZXR1cm4gbmV3IEgubmQoYSl9LApvbzpmdW5jdGlvbihhKXt2YXIgdCxzPWFeNDgK
-aWYoczw9OSlyZXR1cm4gcwp0PWF8MzIKaWYoOTc8PXQmJnQ8PTEwMilyZXR1cm4gdC04NwpyZXR1cm4t
-MX0sCnFDOmZ1bmN0aW9uKGEsYixjLGQpe1AuazEoYiwic3RhcnQiKQppZihjIT1udWxsKXtQLmsxKGMs
-ImVuZCIpCmlmKGI+YylILnZoKFAuVEUoYiwwLGMsInN0YXJ0IixudWxsKSl9cmV0dXJuIG5ldyBILm5I
-KGEsYixjLGQuQygibkg8MD4iKSl9LApLMTpmdW5jdGlvbihhLGIsYyxkKXtpZih1Lmd3LmIoYSkpcmV0
-dXJuIG5ldyBILnh5KGEsYixjLkMoIkA8MD4iKS5LcShkKS5DKCJ4eTwxLDI+IikpCnJldHVybiBuZXcg
-SC5pMShhLGIsYy5DKCJAPDA+IikuS3EoZCkuQygiaTE8MSwyPiIpKX0sCldwOmZ1bmN0aW9uKCl7cmV0
-dXJuIG5ldyBQLmxqKCJObyBlbGVtZW50Iil9LApkVTpmdW5jdGlvbigpe3JldHVybiBuZXcgUC5saigi
-VG9vIG1hbnkgZWxlbWVudHMiKX0sCmFyOmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBQLmxqKCJUb28gZmV3
-IGVsZW1lbnRzIil9LApuZDpmdW5jdGlvbiBuZChhKXt0aGlzLmE9YX0sCnFqOmZ1bmN0aW9uIHFqKGEp
-e3RoaXMuYT1hfSwKYlE6ZnVuY3Rpb24gYlEoKXt9LAphTDpmdW5jdGlvbiBhTCgpe30sCm5IOmZ1bmN0
-aW9uIG5IKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy4kdGk9ZH0sCmE3OmZ1
-bmN0aW9uIGE3KGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz0wCl8uZD1udWxsCl8uJHRp
-PWN9LAppMTpmdW5jdGlvbiBpMShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sCnh5
-OmZ1bmN0aW9uIHh5KGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKTUg6ZnVuY3Rp
-b24gTUgoYSxiLGMpe3ZhciBfPXRoaXMKXy5hPW51bGwKXy5iPWEKXy5jPWIKXy4kdGk9Y30sCmxKOmZ1
-bmN0aW9uIGxKKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKVTU6ZnVuY3Rpb24g
-VTUoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LApTTzpmdW5jdGlvbiBTTyhhLGIs
-Yyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sClNVOmZ1bmN0aW9uIFNVKCl7fSwKUmU6ZnVu
-Y3Rpb24gUmUoKXt9LAp3MjpmdW5jdGlvbiB3Migpe30sCnd2OmZ1bmN0aW9uIHd2KGEpe3RoaXMuYT1h
-fSwKZGM6ZnVuY3Rpb24oKXt0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSB1bm1vZGlmaWFibGUg
-TWFwIikpfSwKTlE6ZnVuY3Rpb24oYSl7dmFyIHQscz1ILkpnKGEpCmlmKHMhPW51bGwpcmV0dXJuIHMK
-dD0ibWluaWZpZWQ6IithCnJldHVybiB0fSwKd1Y6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihiIT1udWxs
-KXt0PWIueAppZih0IT1udWxsKXJldHVybiB0fXJldHVybiB1LmFVLmIoYSl9LApFajpmdW5jdGlvbihh
-KXt2YXIgdAppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIGEKaWYodHlwZW9mIGE9PSJudW1iZXIi
-KXtpZihhIT09MClyZXR1cm4iIithfWVsc2UgaWYoITA9PT1hKXJldHVybiJ0cnVlIgplbHNlIGlmKCEx
-PT09YSlyZXR1cm4iZmFsc2UiCmVsc2UgaWYoYT09bnVsbClyZXR1cm4ibnVsbCIKdD1KLmooYSkKaWYo
-dHlwZW9mIHQhPSJzdHJpbmciKXRocm93IEguYihILnRMKGEpKQpyZXR1cm4gdH0sCmVROmZ1bmN0aW9u
-KGEpe3ZhciB0PWEuJGlkZW50aXR5SGFzaAppZih0PT1udWxsKXt0PU1hdGgucmFuZG9tKCkqMHgzZmZm
-ZmZmZnwwCmEuJGlkZW50aXR5SGFzaD10fXJldHVybiB0fSwKSHA6ZnVuY3Rpb24oYSxiKXt2YXIgdCxz
-LHIscSxwLG8sbj1udWxsCmlmKHR5cGVvZiBhIT0ic3RyaW5nIilILnZoKEgudEwoYSkpCnQ9L15ccypb
-Ky1dPygoMHhbYS1mMC05XSspfChcZCspfChbYS16MC05XSspKVxzKiQvaS5leGVjKGEpCmlmKHQ9PW51
-bGwpcmV0dXJuIG4KaWYoMz49dC5sZW5ndGgpcmV0dXJuIEguT0godCwzKQpzPUguaCh0WzNdKQppZihi
-PT1udWxsKXtpZihzIT1udWxsKXJldHVybiBwYXJzZUludChhLDEwKQppZih0WzJdIT1udWxsKXJldHVy
-biBwYXJzZUludChhLDE2KQpyZXR1cm4gbn1pZihiPDJ8fGI+MzYpdGhyb3cgSC5iKFAuVEUoYiwyLDM2
-LCJyYWRpeCIsbikpCmlmKGI9PT0xMCYmcyE9bnVsbClyZXR1cm4gcGFyc2VJbnQoYSwxMCkKaWYoYjwx
-MHx8cz09bnVsbCl7cj1iPD0xMD80NytiOjg2K2IKcT10WzFdCmZvcihwPXEubGVuZ3RoLG89MDtvPHA7
-KytvKWlmKChDLnhCLlcocSxvKXwzMik+cilyZXR1cm4gbn1yZXR1cm4gcGFyc2VJbnQoYSxiKX0sCk06
-ZnVuY3Rpb24oYSl7dmFyIHQ9SC5INShhKQpyZXR1cm4gdH0sCkg1OmZ1bmN0aW9uKGEpe3ZhciB0LHMs
-cgppZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4gSC5kbShILnooYSksbnVsbCkKaWYoSi5pYShhKT09
-PUMuT2t8fHUuYWsuYihhKSl7dD1DLk80KGEpCmlmKEguQmUodCkpcmV0dXJuIHQKcz1hLmNvbnN0cnVj
-dG9yCmlmKHR5cGVvZiBzPT0iZnVuY3Rpb24iKXtyPXMubmFtZQppZih0eXBlb2Ygcj09InN0cmluZyIm
-JkguQmUocikpcmV0dXJuIHJ9fXJldHVybiBILmRtKEgueihhKSxudWxsKX0sCkJlOmZ1bmN0aW9uKGEp
-e3ZhciB0PWEhPT0iT2JqZWN0IiYmYSE9PSIiCnJldHVybiB0fSwKTTA6ZnVuY3Rpb24oKXtpZighIXNl
-bGYubG9jYXRpb24pcmV0dXJuIHNlbGYubG9jYXRpb24uaHJlZgpyZXR1cm4gbnVsbH0sClZLOmZ1bmN0
-aW9uKGEpe3ZhciB0LHMscixxLHA9YS5sZW5ndGgKaWYocDw9NTAwKXJldHVybiBTdHJpbmcuZnJvbUNo
-YXJDb2RlLmFwcGx5KG51bGwsYSkKZm9yKHQ9IiIscz0wO3M8cDtzPXIpe3I9cys1MDAKcT1yPHA/cjpw
-CnQrPVN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCxhLnNsaWNlKHMscSkpfXJldHVybiB0fSwK
-Q3E6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9SC5WTShbXSx1LnQpCmZvcih0PWEubGVuZ3RoLHM9MDtz
-PGEubGVuZ3RoO2EubGVuZ3RoPT09dHx8KDAsSC5saykoYSksKytzKXtyPWFbc10KaWYoIUgub2socikp
-dGhyb3cgSC5iKEgudEwocikpCmlmKHI8PTY1NTM1KUMuTm0uaShxLHIpCmVsc2UgaWYocjw9MTExNDEx
-MSl7Qy5ObS5pKHEsNTUyOTYrKEMuam4ud0coci02NTUzNiwxMCkmMTAyMykpCkMuTm0uaShxLDU2MzIw
-KyhyJjEwMjMpKX1lbHNlIHRocm93IEguYihILnRMKHIpKX1yZXR1cm4gSC5WSyhxKX0sCmVUOmZ1bmN0
-aW9uKGEpe3ZhciB0LHMscgpmb3IodD1hLmxlbmd0aCxzPTA7czx0Oysrcyl7cj1hW3NdCmlmKCFILm9r
-KHIpKXRocm93IEguYihILnRMKHIpKQppZihyPDApdGhyb3cgSC5iKEgudEwocikpCmlmKHI+NjU1MzUp
-cmV0dXJuIEguQ3EoYSl9cmV0dXJuIEguVksoYSl9LApmdzpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxy
-LHEKaWYoYzw9NTAwJiZiPT09MCYmYz09PWEubGVuZ3RoKXJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2Rl
-LmFwcGx5KG51bGwsYSkKZm9yKHQ9YixzPSIiO3Q8Yzt0PXIpe3I9dCs1MDAKcT1yPGM/cjpjCnMrPVN0
-cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCxhLnN1YmFycmF5KHQscSkpfXJldHVybiBzfSwKTHc6
-ZnVuY3Rpb24oYSl7dmFyIHQKaWYoMDw9YSl7aWYoYTw9NjU1MzUpcmV0dXJuIFN0cmluZy5mcm9tQ2hh
-ckNvZGUoYSkKaWYoYTw9MTExNDExMSl7dD1hLTY1NTM2CnJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2Rl
-KCg1NTI5NnxDLmpuLndHKHQsMTApKT4+PjAsNTYzMjB8dCYxMDIzKX19dGhyb3cgSC5iKFAuVEUoYSww
-LDExMTQxMTEsbnVsbCxudWxsKSl9LApvMjpmdW5jdGlvbihhKXtpZihhLmRhdGU9PT12b2lkIDApYS5k
-YXRlPW5ldyBEYXRlKGEuYSkKcmV0dXJuIGEuZGF0ZX0sCnRKOmZ1bmN0aW9uKGEpe3ZhciB0PUgubzIo
-YSkuZ2V0RnVsbFllYXIoKSswCnJldHVybiB0fSwKTlM6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihhKS5n
-ZXRNb250aCgpKzEKcmV0dXJuIHR9LApqQTpmdW5jdGlvbihhKXt2YXIgdD1ILm8yKGEpLmdldERhdGUo
-KSswCnJldHVybiB0fSwKSVg6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihhKS5nZXRIb3VycygpKzAKcmV0
-dXJuIHR9LApjaDpmdW5jdGlvbihhKXt2YXIgdD1ILm8yKGEpLmdldE1pbnV0ZXMoKSswCnJldHVybiB0
-fSwKSmQ6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihhKS5nZXRTZWNvbmRzKCkrMApyZXR1cm4gdH0sCm8x
-OmZ1bmN0aW9uKGEpe3ZhciB0PUgubzIoYSkuZ2V0TWlsbGlzZWNvbmRzKCkrMApyZXR1cm4gdH0sCnpv
-OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHI9e30Kci5hPTAKdD1bXQpzPVtdCnIuYT1iLmxlbmd0aApD
-Lk5tLkZWKHQsYikKci5iPSIiCmlmKGMhPW51bGwmJmMuYSE9PTApYy5LKDAsbmV3IEguQ2oocixzLHQp
-KQoiIityLmEKcmV0dXJuIEouSnkoYSxuZXcgSC5MSShDLlRlLDAsdCxzLDApKX0sCkVrOmZ1bmN0aW9u
-KGEsYixjKXt2YXIgdCxzLHIscQppZihiIGluc3RhbmNlb2YgQXJyYXkpdD1jPT1udWxsfHxjLmE9PT0w
-CmVsc2UgdD0hMQppZih0KXtzPWIKcj1zLmxlbmd0aAppZihyPT09MCl7aWYoISFhLiQwKXJldHVybiBh
-LiQwKCl9ZWxzZSBpZihyPT09MSl7aWYoISFhLiQxKXJldHVybiBhLiQxKHNbMF0pfWVsc2UgaWYocj09
-PTIpe2lmKCEhYS4kMilyZXR1cm4gYS4kMihzWzBdLHNbMV0pfWVsc2UgaWYocj09PTMpe2lmKCEhYS4k
-MylyZXR1cm4gYS4kMyhzWzBdLHNbMV0sc1syXSl9ZWxzZSBpZihyPT09NCl7aWYoISFhLiQ0KXJldHVy
-biBhLiQ0KHNbMF0sc1sxXSxzWzJdLHNbM10pfWVsc2UgaWYocj09PTUpaWYoISFhLiQ1KXJldHVybiBh
-LiQ1KHNbMF0sc1sxXSxzWzJdLHNbM10sc1s0XSkKcT1hWyIiKyIkIityXQppZihxIT1udWxsKXJldHVy
-biBxLmFwcGx5KGEscyl9cmV0dXJuIEguZTEoYSxiLGMpfSwKZTE6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
-LHMscixxLHAsbyxuLG0sbCxrPWIgaW5zdGFuY2VvZiBBcnJheT9iOlAuQ0goYiwhMCx1LnopLGo9ay5s
-ZW5ndGgsaT1hLiRSCmlmKGo8aSlyZXR1cm4gSC56byhhLGssYykKdD1hLiRECnM9dD09bnVsbApyPSFz
-P3QoKTpudWxsCnE9Si5pYShhKQpwPXEuJEMKaWYodHlwZW9mIHA9PSJzdHJpbmciKXA9cVtwXQppZihz
-KXtpZihjIT1udWxsJiZjLmEhPT0wKXJldHVybiBILnpvKGEsayxjKQppZihqPT09aSlyZXR1cm4gcC5h
-cHBseShhLGspCnJldHVybiBILnpvKGEsayxjKX1pZihyIGluc3RhbmNlb2YgQXJyYXkpe2lmKGMhPW51
-bGwmJmMuYSE9PTApcmV0dXJuIEguem8oYSxrLGMpCmlmKGo+aStyLmxlbmd0aClyZXR1cm4gSC56byhh
-LGssbnVsbCkKQy5ObS5GVihrLHIuc2xpY2Uoai1pKSkKcmV0dXJuIHAuYXBwbHkoYSxrKX1lbHNle2lm
-KGo+aSlyZXR1cm4gSC56byhhLGssYykKbz1PYmplY3Qua2V5cyhyKQppZihjPT1udWxsKWZvcihzPW8u
-bGVuZ3RoLG49MDtuPG8ubGVuZ3RoO28ubGVuZ3RoPT09c3x8KDAsSC5saykobyksKytuKUMuTm0uaShr
-LHJbSC5oKG9bbl0pXSkKZWxzZXtmb3Iocz1vLmxlbmd0aCxtPTAsbj0wO248by5sZW5ndGg7by5sZW5n
-dGg9PT1zfHwoMCxILmxrKShvKSwrK24pe2w9SC5oKG9bbl0pCmlmKGMueDQobCkpeysrbQpDLk5tLmko
-ayxjLnEoMCxsKSl9ZWxzZSBDLk5tLmkoayxyW2xdKX1pZihtIT09Yy5hKXJldHVybiBILnpvKGEsayxj
-KX1yZXR1cm4gcC5hcHBseShhLGspfX0sCnBZOmZ1bmN0aW9uKGEpe3Rocm93IEguYihILnRMKGEpKX0s
-Ck9IOmZ1bmN0aW9uKGEsYil7aWYoYT09bnVsbClKLkhtKGEpCnRocm93IEguYihILkhZKGEsYikpfSwK
-SFk6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPSJpbmRleCIKaWYoIUgub2soYikpcmV0dXJuIG5ldyBQLnUo
-ITAsYixzLG51bGwpCnQ9SC51UChKLkhtKGEpKQppZihiPDB8fGI+PXQpcmV0dXJuIFAuQ2YoYixhLHMs
-bnVsbCx0KQpyZXR1cm4gUC5PNyhiLHMpfSwKYXU6ZnVuY3Rpb24oYSxiLGMpe2lmKGE+YylyZXR1cm4g
-UC5URShhLDAsYywic3RhcnQiLG51bGwpCmlmKGIhPW51bGwpaWYoYjxhfHxiPmMpcmV0dXJuIFAuVEUo
-YixhLGMsImVuZCIsbnVsbCkKcmV0dXJuIG5ldyBQLnUoITAsYiwiZW5kIixudWxsKX0sCnRMOmZ1bmN0
-aW9uKGEpe3JldHVybiBuZXcgUC51KCEwLGEsbnVsbCxudWxsKX0sCmI6ZnVuY3Rpb24oYSl7dmFyIHQK
-aWYoYT09bnVsbClhPW5ldyBQLm4oKQp0PW5ldyBFcnJvcigpCnQuZGFydEV4Y2VwdGlvbj1hCmlmKCJk
-ZWZpbmVQcm9wZXJ0eSIgaW4gT2JqZWN0KXtPYmplY3QuZGVmaW5lUHJvcGVydHkodCwibWVzc2FnZSIs
-e2dldDpILnh9KQp0Lm5hbWU9IiJ9ZWxzZSB0LnRvU3RyaW5nPUgueApyZXR1cm4gdH0sCng6ZnVuY3Rp
-b24oKXtyZXR1cm4gSi5qKHRoaXMuZGFydEV4Y2VwdGlvbil9LAp2aDpmdW5jdGlvbihhKXt0aHJvdyBI
-LmIoYSl9LApsazpmdW5jdGlvbihhKXt0aHJvdyBILmIoUC5hNChhKSl9LApjTTpmdW5jdGlvbihhKXt2
-YXIgdCxzLHIscSxwLG8KYT1ILmVBKGEucmVwbGFjZShTdHJpbmcoe30pLCckcmVjZWl2ZXIkJykpCnQ9
-YS5tYXRjaCgvXFxcJFthLXpBLVpdK1xcXCQvZykKaWYodD09bnVsbCl0PUguVk0oW10sdS5zKQpzPXQu
-aW5kZXhPZigiXFwkYXJndW1lbnRzXFwkIikKcj10LmluZGV4T2YoIlxcJGFyZ3VtZW50c0V4cHJcXCQi
-KQpxPXQuaW5kZXhPZigiXFwkZXhwclxcJCIpCnA9dC5pbmRleE9mKCJcXCRtZXRob2RcXCQiKQpvPXQu
-aW5kZXhPZigiXFwkcmVjZWl2ZXJcXCQiKQpyZXR1cm4gbmV3IEguZjkoYS5yZXBsYWNlKG5ldyBSZWdF
-eHAoJ1xcXFxcXCRhcmd1bWVudHNcXFxcXFwkJywnZycpLCcoKD86eHxbXnhdKSopJykucmVwbGFjZShu
-ZXcgUmVnRXhwKCdcXFxcXFwkYXJndW1lbnRzRXhwclxcXFxcXCQnLCdnJyksJygoPzp4fFteeF0pKikn
-KS5yZXBsYWNlKG5ldyBSZWdFeHAoJ1xcXFxcXCRleHByXFxcXFxcJCcsJ2cnKSwnKCg/Onh8W154XSkq
-KScpLnJlcGxhY2UobmV3IFJlZ0V4cCgnXFxcXFxcJG1ldGhvZFxcXFxcXCQnLCdnJyksJygoPzp4fFte
-eF0pKiknKS5yZXBsYWNlKG5ldyBSZWdFeHAoJ1xcXFxcXCRyZWNlaXZlclxcXFxcXCQnLCdnJyksJygo
-Pzp4fFteeF0pKiknKSxzLHIscSxwLG8pfSwKUzc6ZnVuY3Rpb24oYSl7cmV0dXJuIGZ1bmN0aW9uKCRl
-eHByJCl7dmFyICRhcmd1bWVudHNFeHByJD0nJGFyZ3VtZW50cyQnCnRyeXskZXhwciQuJG1ldGhvZCQo
-JGFyZ3VtZW50c0V4cHIkKX1jYXRjaCh0KXtyZXR1cm4gdC5tZXNzYWdlfX0oYSl9LApNajpmdW5jdGlv
-bihhKXtyZXR1cm4gZnVuY3Rpb24oJGV4cHIkKXt0cnl7JGV4cHIkLiRtZXRob2QkfWNhdGNoKHQpe3Jl
-dHVybiB0Lm1lc3NhZ2V9fShhKX0sCklqOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILlcwKGEsYj09
-bnVsbD9udWxsOmIubWV0aG9kKX0sClQzOmZ1bmN0aW9uKGEsYil7dmFyIHQ9Yj09bnVsbCxzPXQ/bnVs
-bDpiLm1ldGhvZApyZXR1cm4gbmV3IEguYXooYSxzLHQ/bnVsbDpiLnJlY2VpdmVyKX0sClJ1OmZ1bmN0
-aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZj1udWxsLGU9bmV3IEguQW0oYSkK
-aWYoYT09bnVsbClyZXR1cm4gZgppZihhIGluc3RhbmNlb2YgSC5icSlyZXR1cm4gZS4kMShhLmEpCmlm
-KHR5cGVvZiBhIT09Im9iamVjdCIpcmV0dXJuIGEKaWYoImRhcnRFeGNlcHRpb24iIGluIGEpcmV0dXJu
-IGUuJDEoYS5kYXJ0RXhjZXB0aW9uKQplbHNlIGlmKCEoIm1lc3NhZ2UiIGluIGEpKXJldHVybiBhCnQ9
-YS5tZXNzYWdlCmlmKCJudW1iZXIiIGluIGEmJnR5cGVvZiBhLm51bWJlcj09Im51bWJlciIpe3M9YS5u
-dW1iZXIKcj1zJjY1NTM1CmlmKChDLmpuLndHKHMsMTYpJjgxOTEpPT09MTApc3dpdGNoKHIpe2Nhc2Ug
-NDM4OnJldHVybiBlLiQxKEguVDMoSC5Faih0KSsiIChFcnJvciAiK3IrIikiLGYpKQpjYXNlIDQ0NTpj
-YXNlIDUwMDc6cmV0dXJuIGUuJDEoSC5JaihILkVqKHQpKyIgKEVycm9yICIrcisiKSIsZikpfX1pZihh
-IGluc3RhbmNlb2YgVHlwZUVycm9yKXtxPSQuU24oKQpwPSQubHEoKQpvPSQuTjkoKQpuPSQuaUkoKQpt
-PSQuVU4oKQpsPSQuWmgoKQprPSQuck4oKQokLmMzKCkKaj0kLkhLKCkKaT0kLnIxKCkKaD1xLnFTKHQp
-CmlmKGghPW51bGwpcmV0dXJuIGUuJDEoSC5UMyhILmgodCksaCkpCmVsc2V7aD1wLnFTKHQpCmlmKGgh
-PW51bGwpe2gubWV0aG9kPSJjYWxsIgpyZXR1cm4gZS4kMShILlQzKEguaCh0KSxoKSl9ZWxzZXtoPW8u
-cVModCkKaWYoaD09bnVsbCl7aD1uLnFTKHQpCmlmKGg9PW51bGwpe2g9bS5xUyh0KQppZihoPT1udWxs
-KXtoPWwucVModCkKaWYoaD09bnVsbCl7aD1rLnFTKHQpCmlmKGg9PW51bGwpe2g9bi5xUyh0KQppZiho
-PT1udWxsKXtoPWoucVModCkKaWYoaD09bnVsbCl7aD1pLnFTKHQpCmc9aCE9bnVsbH1lbHNlIGc9ITB9
-ZWxzZSBnPSEwfWVsc2UgZz0hMH1lbHNlIGc9ITB9ZWxzZSBnPSEwfWVsc2UgZz0hMH1lbHNlIGc9ITAK
-aWYoZylyZXR1cm4gZS4kMShILklqKEguaCh0KSxoKSl9fXJldHVybiBlLiQxKG5ldyBILnZWKHR5cGVv
-ZiB0PT0ic3RyaW5nIj90OiIiKSl9aWYoYSBpbnN0YW5jZW9mIFJhbmdlRXJyb3Ipe2lmKHR5cGVvZiB0
-PT0ic3RyaW5nIiYmdC5pbmRleE9mKCJjYWxsIHN0YWNrIikhPT0tMSlyZXR1cm4gbmV3IFAuS1koKQp0
-PWZ1bmN0aW9uKGIpe3RyeXtyZXR1cm4gU3RyaW5nKGIpfWNhdGNoKGQpe31yZXR1cm4gbnVsbH0oYSkK
-cmV0dXJuIGUuJDEobmV3IFAudSghMSxmLGYsdHlwZW9mIHQ9PSJzdHJpbmciP3QucmVwbGFjZSgvXlJh
-bmdlRXJyb3I6XHMqLywiIik6dCkpfWlmKHR5cGVvZiBJbnRlcm5hbEVycm9yPT0iZnVuY3Rpb24iJiZh
-IGluc3RhbmNlb2YgSW50ZXJuYWxFcnJvcilpZih0eXBlb2YgdD09InN0cmluZyImJnQ9PT0idG9vIG11
-Y2ggcmVjdXJzaW9uIilyZXR1cm4gbmV3IFAuS1koKQpyZXR1cm4gYX0sCnRzOmZ1bmN0aW9uKGEpe3Zh
-ciB0CmlmKGEgaW5zdGFuY2VvZiBILmJxKXJldHVybiBhLmIKaWYoYT09bnVsbClyZXR1cm4gbmV3IEgu
-WE8oYSkKdD1hLiRjYWNoZWRUcmFjZQppZih0IT1udWxsKXJldHVybiB0CnJldHVybiBhLiRjYWNoZWRU
-cmFjZT1uZXcgSC5YTyhhKX0sCkI3OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHE9YS5sZW5ndGgKZm9y
-KHQ9MDt0PHE7dD1yKXtzPXQrMQpyPXMrMQpiLlkoMCxhW3RdLGFbc10pfXJldHVybiBifSwKZnQ6ZnVu
-Y3Rpb24oYSxiLGMsZCxlLGYpe3UuWS5hKGEpCnN3aXRjaChILnVQKGIpKXtjYXNlIDA6cmV0dXJuIGEu
-JDAoKQpjYXNlIDE6cmV0dXJuIGEuJDEoYykKY2FzZSAyOnJldHVybiBhLiQyKGMsZCkKY2FzZSAzOnJl
-dHVybiBhLiQzKGMsZCxlKQpjYXNlIDQ6cmV0dXJuIGEuJDQoYyxkLGUsZil9dGhyb3cgSC5iKG5ldyBQ
-LkNEKCJVbnN1cHBvcnRlZCBudW1iZXIgb2YgYXJndW1lbnRzIGZvciB3cmFwcGVkIGNsb3N1cmUiKSl9
-LAp0UjpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGE9PW51bGwpcmV0dXJuIG51bGwKdD1hLiRpZGVudGl0
-eQppZighIXQpcmV0dXJuIHQKdD1mdW5jdGlvbihjLGQsZSl7cmV0dXJuIGZ1bmN0aW9uKGYsZyxoLGkp
-e3JldHVybiBlKGMsZCxmLGcsaCxpKX19KGEsYixILmZ0KQphLiRpZGVudGl0eT10CnJldHVybiB0fSwK
-aUE6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHQscyxyLHEscCxvLG4sbSxsPWJbMF0saz1sLiRj
-YWxsTmFtZSxqPWU/T2JqZWN0LmNyZWF0ZShuZXcgSC56eCgpLmNvbnN0cnVjdG9yLnByb3RvdHlwZSk6
-T2JqZWN0LmNyZWF0ZShuZXcgSC5yVChudWxsLG51bGwsbnVsbCwiIikuY29uc3RydWN0b3IucHJvdG90
-eXBlKQpqLiRpbml0aWFsaXplPWouY29uc3RydWN0b3IKaWYoZSl0PWZ1bmN0aW9uIHN0YXRpY190ZWFy
-X29mZigpe3RoaXMuJGluaXRpYWxpemUoKX0KZWxzZXtzPSQueWoKaWYodHlwZW9mIHMhPT0ibnVtYmVy
-IilyZXR1cm4gcy5oKCkKJC55aj1zKzEKcz1uZXcgRnVuY3Rpb24oImEsYixjLGQiK3MsInRoaXMuJGlu
-aXRpYWxpemUoYSxiLGMsZCIrcysiKSIpCnQ9c31qLmNvbnN0cnVjdG9yPXQKdC5wcm90b3R5cGU9agpp
-ZighZSl7cj1ILmJ4KGEsbCxmKQpyLiRyZWZsZWN0aW9uSW5mbz1kfWVsc2V7ai4kc3RhdGljX25hbWU9
-ZwpyPWx9cT1ILmltKGQsZSxmKQpqLiRTPXEKaltrXT1yCmZvcihwPXIsbz0xO288Yi5sZW5ndGg7Kytv
-KXtuPWJbb10KbT1uLiRjYWxsTmFtZQppZihtIT1udWxsKXtuPWU/bjpILmJ4KGEsbixmKQpqW21dPW59
-aWYobz09PWMpe24uJHJlZmxlY3Rpb25JbmZvPWQKcD1ufX1qLiRDPXAKai4kUj1sLiRSCmouJEQ9bC4k
-RApyZXR1cm4gdH0sCmltOmZ1bmN0aW9uKGEsYixjKXt2YXIgdAppZih0eXBlb2YgYT09Im51bWJlciIp
-cmV0dXJuIGZ1bmN0aW9uKGQsZSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGQoZSl9fShILkJwLGEp
-CmlmKHR5cGVvZiBhPT0ic3RyaW5nIil7aWYoYil0aHJvdyBILmIoIkNhbm5vdCBjb21wdXRlIHNpZ25h
-dHVyZSBmb3Igc3RhdGljIHRlYXJvZmYuIikKdD1jP0guUFc6SC5UbgpyZXR1cm4gZnVuY3Rpb24oZCxl
-KXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZSh0aGlzLGQpfX0oYSx0KX10aHJvdyBILmIoIkVycm9y
-IGluIGZ1bmN0aW9uVHlwZSBvZiB0ZWFyb2ZmIil9LAp2cTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdD1I
-LkRWCnN3aXRjaChiPy0xOmEpe2Nhc2UgMDpyZXR1cm4gZnVuY3Rpb24oZSxmKXtyZXR1cm4gZnVuY3Rp
-b24oKXtyZXR1cm4gZih0aGlzKVtlXSgpfX0oYyx0KQpjYXNlIDE6cmV0dXJuIGZ1bmN0aW9uKGUsZil7
-cmV0dXJuIGZ1bmN0aW9uKGcpe3JldHVybiBmKHRoaXMpW2VdKGcpfX0oYyx0KQpjYXNlIDI6cmV0dXJu
-IGZ1bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcsaCl7cmV0dXJuIGYodGhpcylbZV0oZyxoKX19
-KGMsdCkKY2FzZSAzOnJldHVybiBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlvbihnLGgsaSl7cmV0
-dXJuIGYodGhpcylbZV0oZyxoLGkpfX0oYyx0KQpjYXNlIDQ6cmV0dXJuIGZ1bmN0aW9uKGUsZil7cmV0
-dXJuIGZ1bmN0aW9uKGcsaCxpLGope3JldHVybiBmKHRoaXMpW2VdKGcsaCxpLGopfX0oYyx0KQpjYXNl
-IDU6cmV0dXJuIGZ1bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcsaCxpLGosayl7cmV0dXJuIGYo
-dGhpcylbZV0oZyxoLGksaixrKX19KGMsdCkKZGVmYXVsdDpyZXR1cm4gZnVuY3Rpb24oZSxmKXtyZXR1
-cm4gZnVuY3Rpb24oKXtyZXR1cm4gZS5hcHBseShmKHRoaXMpLGFyZ3VtZW50cyl9fShkLHQpfX0sCmJ4
-OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbgppZihjKXJldHVybiBILkhmKGEsYikKdD1i
-LiRzdHViTmFtZQpzPWIubGVuZ3RoCnI9YVt0XQpxPWI9PW51bGw/cj09bnVsbDpiPT09cgpwPSFxfHxz
-Pj0yNwppZihwKXJldHVybiBILnZxKHMsIXEsdCxiKQppZihzPT09MCl7cT0kLnlqCmlmKHR5cGVvZiBx
-IT09Im51bWJlciIpcmV0dXJuIHEuaCgpCiQueWo9cSsxCm89InNlbGYiK3EKcmV0dXJuIG5ldyBGdW5j
-dGlvbigicmV0dXJuIGZ1bmN0aW9uKCl7dmFyICIrbysiID0gdGhpcy4iK0guRWooSC5vTigpKSsiO3Jl
-dHVybiAiK28rIi4iK0guRWoodCkrIigpO30iKSgpfW49ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6
-Ii5zcGxpdCgiIikuc3BsaWNlKDAscykuam9pbigiLCIpCnE9JC55agppZih0eXBlb2YgcSE9PSJudW1i
-ZXIiKXJldHVybiBxLmgoKQokLnlqPXErMQpuKz1xCnJldHVybiBuZXcgRnVuY3Rpb24oInJldHVybiBm
-dW5jdGlvbigiK24rIil7cmV0dXJuIHRoaXMuIitILkVqKEgub04oKSkrIi4iK0guRWoodCkrIigiK24r
-Iik7fSIpKCl9LApaNDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdD1ILkRWLHM9SC55Uwpzd2l0Y2goYj8t
-MTphKXtjYXNlIDA6dGhyb3cgSC5iKEguRWYoIkludGVyY2VwdGVkIGZ1bmN0aW9uIHdpdGggbm8gYXJn
-dW1lbnRzLiIpKQpjYXNlIDE6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24oKXty
-ZXR1cm4gZih0aGlzKVtlXShnKHRoaXMpKX19KGMsdCxzKQpjYXNlIDI6cmV0dXJuIGZ1bmN0aW9uKGUs
-ZixnKXtyZXR1cm4gZnVuY3Rpb24oaCl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSxoKX19KGMsdCxz
-KQpjYXNlIDM6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24oaCxpKXtyZXR1cm4g
-Zih0aGlzKVtlXShnKHRoaXMpLGgsaSl9fShjLHQscykKY2FzZSA0OnJldHVybiBmdW5jdGlvbihlLGYs
-Zyl7cmV0dXJuIGZ1bmN0aW9uKGgsaSxqKXtyZXR1cm4gZih0aGlzKVtlXShnKHRoaXMpLGgsaSxqKX19
-KGMsdCxzKQpjYXNlIDU6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24oaCxpLGos
-ayl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSxoLGksaixrKX19KGMsdCxzKQpjYXNlIDY6cmV0dXJu
-IGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24oaCxpLGosayxsKXtyZXR1cm4gZih0aGlzKVtl
-XShnKHRoaXMpLGgsaSxqLGssbCl9fShjLHQscykKZGVmYXVsdDpyZXR1cm4gZnVuY3Rpb24oZSxmLGcs
-aCl7cmV0dXJuIGZ1bmN0aW9uKCl7aD1bZyh0aGlzKV0KQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHko
-aCxhcmd1bWVudHMpCnJldHVybiBlLmFwcGx5KGYodGhpcyksaCl9fShkLHQscyl9fSwKSGY6ZnVuY3Rp
-b24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbj1ILm9OKCksbT0kLlA0CmlmKG09PW51bGwpbT0kLlA0PUgu
-RTIoInJlY2VpdmVyIikKdD1iLiRzdHViTmFtZQpzPWIubGVuZ3RoCnI9YVt0XQpxPWI9PW51bGw/cj09
-bnVsbDpiPT09cgpwPSFxfHxzPj0yOAppZihwKXJldHVybiBILlo0KHMsIXEsdCxiKQppZihzPT09MSl7
-cT0icmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuIitILkVqKG4pKyIuIitILkVqKHQpKyIodGhp
-cy4iK20rIik7IgpwPSQueWoKaWYodHlwZW9mIHAhPT0ibnVtYmVyIilyZXR1cm4gcC5oKCkKJC55aj1w
-KzEKcmV0dXJuIG5ldyBGdW5jdGlvbihxK3ArIn0iKSgpfW89ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3
-eHl6Ii5zcGxpdCgiIikuc3BsaWNlKDAscy0xKS5qb2luKCIsIikKcT0icmV0dXJuIGZ1bmN0aW9uKCIr
-bysiKXtyZXR1cm4gdGhpcy4iK0guRWoobikrIi4iK0guRWoodCkrIih0aGlzLiIrbSsiLCAiK28rIik7
-IgpwPSQueWoKaWYodHlwZW9mIHAhPT0ibnVtYmVyIilyZXR1cm4gcC5oKCkKJC55aj1wKzEKcmV0dXJu
-IG5ldyBGdW5jdGlvbihxK3ArIn0iKSgpfSwKS3E6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7cmV0dXJu
-IEguaUEoYSxiLGMsZCwhIWUsISFmLGcpfSwKVG46ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5jRSh2LnR5
-cGVVbml2ZXJzZSxILnooYS5hKSxiKX0sClBXOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEguY0Uodi50eXBl
-VW5pdmVyc2UsSC56KGEuYyksYil9LApEVjpmdW5jdGlvbihhKXtyZXR1cm4gYS5hfSwKeVM6ZnVuY3Rp
-b24oYSl7cmV0dXJuIGEuY30sCm9OOmZ1bmN0aW9uKCl7dmFyIHQ9JC5tSgpyZXR1cm4gdD09bnVsbD8k
-Lm1KPUguRTIoInNlbGYiKTp0fSwKRTI6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9bmV3IEguclQoInNl
-bGYiLCJ0YXJnZXQiLCJyZWNlaXZlciIsIm5hbWUiKSxwPUouRXAoT2JqZWN0LmdldE93blByb3BlcnR5
-TmFtZXMocSksdS56KQpmb3IodD1wLmxlbmd0aCxzPTA7czx0Oysrcyl7cj1wW3NdCmlmKHFbcl09PT1h
-KXJldHVybiByfXRocm93IEguYihQLnhZKCJGaWVsZCBuYW1lICIrYSsiIG5vdCBmb3VuZC4iKSl9LApv
-VDpmdW5jdGlvbihhKXtpZihhPT1udWxsKUguZk8oImJvb2xlYW4gZXhwcmVzc2lvbiBtdXN0IG5vdCBi
-ZSBudWxsIikKcmV0dXJuIGF9LApmTzpmdW5jdGlvbihhKXt0aHJvdyBILmIobmV3IEgua1koYSkpfSwK
-YWc6ZnVuY3Rpb24oYSl7dGhyb3cgSC5iKG5ldyBQLmMoYSkpfSwKRWY6ZnVuY3Rpb24oYSl7cmV0dXJu
-IG5ldyBILkVxKGEpfSwKWWc6ZnVuY3Rpb24oYSl7cmV0dXJuIHYuZ2V0SXNvbGF0ZVRhZyhhKX0sClZN
-OmZ1bmN0aW9uKGEsYil7YVt2LmFycmF5UnRpXT1iCnJldHVybiBhfSwKb1g6ZnVuY3Rpb24oYSl7aWYo
-YT09bnVsbClyZXR1cm4gbnVsbApyZXR1cm4gYS4kdGl9LApJTTpmdW5jdGlvbihhLGIsYyl7cmV0dXJu
-IEguWTkoYVsiJGEiK0guRWooYyldLEgub1goYikpfSwKWTk6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihh
-PT1udWxsKXJldHVybiBiCnQ9YS5hcHBseShudWxsLGIpCmlmKHQ9PW51bGwpcmV0dXJuIG51bGwKaWYo
-QXJyYXkuaXNBcnJheSh0KSlyZXR1cm4gdAppZih0eXBlb2YgdD09ImZ1bmN0aW9uIilyZXR1cm4gdC5h
-cHBseShudWxsLGIpCnJldHVybiBifSwKSUc6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBhLmFwcGx5KGIs
-SC5JTShKLmlhKGIpLGIsYykpfSwKaXc6ZnVuY3Rpb24oYSxiLGMpe09iamVjdC5kZWZpbmVQcm9wZXJ0
-eShhLGIse3ZhbHVlOmMsZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0
-cnVlfSl9LAp3MzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG89SC5oKCQuTkYuJDEoYSkpLG49JC5u
-d1tvXQppZihuIT1udWxsKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoYSx2LmRpc3BhdGNoUHJvcGVydHlO
-YW1lLHt2YWx1ZTpuLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1
-ZX0pCnJldHVybiBuLml9dD0kLnZ2W29dCmlmKHQhPW51bGwpcmV0dXJuIHQKcz12LmludGVyY2VwdG9y
-c0J5VGFnW29dCmlmKHM9PW51bGwpe3I9SC5rKCQuVFguJDIoYSxvKSkKaWYociE9bnVsbCl7bj0kLm53
-W3JdCmlmKG4hPW51bGwpe09iamVjdC5kZWZpbmVQcm9wZXJ0eShhLHYuZGlzcGF0Y2hQcm9wZXJ0eU5h
-bWUse3ZhbHVlOm4sZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVl
-fSkKcmV0dXJuIG4uaX10PSQudnZbcl0KaWYodCE9bnVsbClyZXR1cm4gdApzPXYuaW50ZXJjZXB0b3Jz
-QnlUYWdbcl0Kbz1yfX1pZihzPT1udWxsKXJldHVybiBudWxsCnQ9cy5wcm90b3R5cGUKcT1vWzBdCmlm
-KHE9PT0iISIpe249SC5WYSh0KQokLm53W29dPW4KT2JqZWN0LmRlZmluZVByb3BlcnR5KGEsdi5kaXNw
-YXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6bixlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29u
-ZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gbi5pfWlmKHE9PT0ifiIpeyQudnZbb109dApyZXR1cm4gdH1p
-ZihxPT09Ii0iKXtwPUguVmEodCkKT2JqZWN0LmRlZmluZVByb3BlcnR5KE9iamVjdC5nZXRQcm90b3R5
-cGVPZihhKSx2LmRpc3BhdGNoUHJvcGVydHlOYW1lLHt2YWx1ZTpwLGVudW1lcmFibGU6ZmFsc2Usd3Jp
-dGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnJldHVybiBwLml9aWYocT09PSIrIilyZXR1cm4g
-SC5MYyhhLHQpCmlmKHE9PT0iKiIpdGhyb3cgSC5iKFAuU1kobykpCmlmKHYubGVhZlRhZ3Nbb109PT10
-cnVlKXtwPUguVmEodCkKT2JqZWN0LmRlZmluZVByb3BlcnR5KE9iamVjdC5nZXRQcm90b3R5cGVPZihh
-KSx2LmRpc3BhdGNoUHJvcGVydHlOYW1lLHt2YWx1ZTpwLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6
-dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnJldHVybiBwLml9ZWxzZSByZXR1cm4gSC5MYyhhLHQpfSwK
-TGM6ZnVuY3Rpb24oYSxiKXt2YXIgdD1PYmplY3QuZ2V0UHJvdG90eXBlT2YoYSkKT2JqZWN0LmRlZmlu
-ZVByb3BlcnR5KHQsdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6Si5RdShiLHQsbnVsbCxudWxs
-KSxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4g
-Yn0sClZhOmZ1bmN0aW9uKGEpe3JldHVybiBKLlF1KGEsITEsbnVsbCwhIWEuJGlYail9LApWRjpmdW5j
-dGlvbihhLGIsYyl7dmFyIHQ9Yi5wcm90b3R5cGUKaWYodi5sZWFmVGFnc1thXT09PXRydWUpcmV0dXJu
-IEguVmEodCkKZWxzZSByZXR1cm4gSi5RdSh0LGMsbnVsbCxudWxsKX0sClhEOmZ1bmN0aW9uKCl7aWYo
-ITA9PT0kLkJ2KXJldHVybgokLkJ2PSEwCkguWjEoKX0sCloxOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEs
-cCxvLG4sbQokLm53PU9iamVjdC5jcmVhdGUobnVsbCkKJC52dj1PYmplY3QuY3JlYXRlKG51bGwpCkgu
-a08oKQp0PXYuaW50ZXJjZXB0b3JzQnlUYWcKcz1PYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0KQpp
-Zih0eXBlb2Ygd2luZG93IT0idW5kZWZpbmVkIil7d2luZG93CnI9ZnVuY3Rpb24oKXt9CmZvcihxPTA7
-cTxzLmxlbmd0aDsrK3Epe3A9c1txXQpvPSQueDcuJDEocCkKaWYobyE9bnVsbCl7bj1ILlZGKHAsdFtw
-XSxvKQppZihuIT1udWxsKXtPYmplY3QuZGVmaW5lUHJvcGVydHkobyx2LmRpc3BhdGNoUHJvcGVydHlO
-YW1lLHt2YWx1ZTpuLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1
-ZX0pCnIucHJvdG90eXBlPW99fX19Zm9yKHE9MDtxPHMubGVuZ3RoOysrcSl7cD1zW3FdCmlmKC9eW0Et
-WmEtel9dLy50ZXN0KHApKXttPXRbcF0KdFsiISIrcF09bQp0WyJ+IitwXT1tCnRbIi0iK3BdPW0KdFsi
-KyIrcF09bQp0WyIqIitwXT1tfX19LAprTzpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuPUMuWXEo
-KQpuPUgudWQoQy5LVSxILnVkKEMuZlEsSC51ZChDLmk3LEgudWQoQy5pNyxILnVkKEMueGksSC51ZChD
-LmRrLEgudWQoQy53YihDLk80KSxuKSkpKSkpKQppZih0eXBlb2YgZGFydE5hdGl2ZURpc3BhdGNoSG9v
-a3NUcmFuc2Zvcm1lciE9InVuZGVmaW5lZCIpe3Q9ZGFydE5hdGl2ZURpc3BhdGNoSG9va3NUcmFuc2Zv
-cm1lcgppZih0eXBlb2YgdD09ImZ1bmN0aW9uIil0PVt0XQppZih0LmNvbnN0cnVjdG9yPT1BcnJheSlm
-b3Iocz0wO3M8dC5sZW5ndGg7KytzKXtyPXRbc10KaWYodHlwZW9mIHI9PSJmdW5jdGlvbiIpbj1yKG4p
-fHxufX1xPW4uZ2V0VGFnCnA9bi5nZXRVbmtub3duVGFnCm89bi5wcm90b3R5cGVGb3JUYWcKJC5ORj1u
-ZXcgSC5kQyhxKQokLlRYPW5ldyBILndOKHApCiQueDc9bmV3IEguVlgobyl9LAp1ZDpmdW5jdGlvbihh
-LGIpe3JldHVybiBhKGIpfHxifSwKdjQ6ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe3ZhciB0PWI/Im0iOiIi
-LHM9Yz8iIjoiaSIscj1kPyJ1IjoiIixxPWU/InMiOiIiLHA9Zj8iZyI6IiIsbz1mdW5jdGlvbihnLGgp
-e3RyeXtyZXR1cm4gbmV3IFJlZ0V4cChnLGgpfWNhdGNoKG4pe3JldHVybiBufX0oYSx0K3MrcitxK3Ap
-CmlmKG8gaW5zdGFuY2VvZiBSZWdFeHApcmV0dXJuIG8KdGhyb3cgSC5iKFAucnIoIklsbGVnYWwgUmVn
-RXhwIHBhdHRlcm4gKCIrU3RyaW5nKG8pKyIpIixhLG51bGwpKX0sCm0yOmZ1bmN0aW9uKGEsYixjKXt2
-YXIgdAppZih0eXBlb2YgYj09InN0cmluZyIpcmV0dXJuIGEuaW5kZXhPZihiLGMpPj0wCmVsc2UgaWYo
-YiBpbnN0YW5jZW9mIEguVlIpe3Q9Qy54Qi5HKGEsYykKcmV0dXJuIGIuYi50ZXN0KHQpfWVsc2V7dD1K
-LkZMKGIsQy54Qi5HKGEsYykpCnJldHVybiF0LmdsMCh0KX19LApBNDpmdW5jdGlvbihhKXtpZihhLmlu
-ZGV4T2YoIiQiLDApPj0wKXJldHVybiBhLnJlcGxhY2UoL1wkL2csIiQkJCQiKQpyZXR1cm4gYX0sCmVB
-OmZ1bmN0aW9uKGEpe2lmKC9bW1xde30oKSorPy5cXF4kfF0vLnRlc3QoYSkpcmV0dXJuIGEucmVwbGFj
-ZSgvW1tcXXt9KCkqKz8uXFxeJHxdL2csIlxcJCYiKQpyZXR1cm4gYX0sCnlzOmZ1bmN0aW9uKGEsYixj
-KXt2YXIgdD1ILm5NKGEsYixjKQpyZXR1cm4gdH0sCm5NOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIs
-cQppZihiPT09IiIpe2lmKGE9PT0iIilyZXR1cm4gYwp0PWEubGVuZ3RoCnM9IiIrYwpmb3Iocj0wO3I8
-dDsrK3Ipcz1zK2Fbcl0rYwpyZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c31xPWEuaW5kZXhPZihi
-LDApCmlmKHE8MClyZXR1cm4gYQppZihhLmxlbmd0aDw1MDB8fGMuaW5kZXhPZigiJCIsMCk+PTApcmV0
-dXJuIGEuc3BsaXQoYikuam9pbihjKQpyZXR1cm4gYS5yZXBsYWNlKG5ldyBSZWdFeHAoSC5lQShiKSwn
-ZycpLEguQTQoYykpfSwKUEQ6ZnVuY3Rpb24gUEQoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKV1U6
-ZnVuY3Rpb24gV1UoKXt9LApMUDpmdW5jdGlvbiBMUChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8u
-Yj1iCl8uYz1jCl8uJHRpPWR9LApYUjpmdW5jdGlvbiBYUihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9
-LApMSTpmdW5jdGlvbiBMSShhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5hPWEKXy5jPWIKXy5kPWMKXy5l
-PWQKXy5mPWV9LApDajpmdW5jdGlvbiBDaihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9
-LApmOTpmdW5jdGlvbiBmOShhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9Ywpf
-LmQ9ZApfLmU9ZQpfLmY9Zn0sClcwOmZ1bmN0aW9uIFcwKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAph
-ejpmdW5jdGlvbiBheihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LAp2VjpmdW5jdGlv
-biB2VihhKXt0aGlzLmE9YX0sCmJxOmZ1bmN0aW9uIGJxKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApB
-bTpmdW5jdGlvbiBBbShhKXt0aGlzLmE9YX0sClhPOmZ1bmN0aW9uIFhPKGEpe3RoaXMuYT1hCnRoaXMu
-Yj1udWxsfSwKdjpmdW5jdGlvbiB2KCl7fSwKbGM6ZnVuY3Rpb24gbGMoKXt9LAp6eDpmdW5jdGlvbiB6
-eCgpe30sCnJUOmZ1bmN0aW9uIHJUKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMK
-Xy5kPWR9LApFcTpmdW5jdGlvbiBFcShhKXt0aGlzLmE9YX0sCmtZOmZ1bmN0aW9uIGtZKGEpe3RoaXMu
-YT1hfSwKTjU6ZnVuY3Rpb24gTjUoYSl7dmFyIF89dGhpcwpfLmE9MApfLmY9Xy5lPV8uZD1fLmM9Xy5i
-PW51bGwKXy5yPTAKXy4kdGk9YX0sCmRiOmZ1bmN0aW9uIGRiKGEsYil7dmFyIF89dGhpcwpfLmE9YQpf
-LmI9YgpfLmQ9Xy5jPW51bGx9LAppNTpmdW5jdGlvbiBpNShhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9
-LApONjpmdW5jdGlvbiBONihhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGwK
-Xy4kdGk9Y30sCmRDOmZ1bmN0aW9uIGRDKGEpe3RoaXMuYT1hfSwKd046ZnVuY3Rpb24gd04oYSl7dGhp
-cy5hPWF9LApWWDpmdW5jdGlvbiBWWChhKXt0aGlzLmE9YX0sClZSOmZ1bmN0aW9uIFZSKGEsYil7dmFy
-IF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGx9LApFSzpmdW5jdGlvbiBFSyhhKXt0aGlzLmI9
-YX0sCktXOmZ1bmN0aW9uIEtXKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClBiOmZ1
-bmN0aW9uIFBiKGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1udWxsfSwKdFE6
-ZnVuY3Rpb24gdFEoYSxiKXt0aGlzLmE9YQp0aGlzLmM9Yn0sCnVuOmZ1bmN0aW9uIHVuKGEsYixjKXt0
-aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClNkOmZ1bmN0aW9uIFNkKGEsYixjKXt2YXIgXz10aGlz
-Cl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1udWxsfSwKWEY6ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApvZDpm
-dW5jdGlvbihhLGIsYyl7aWYoYT4+PjAhPT1hfHxhPj1jKXRocm93IEguYihILkhZKGIsYSkpfSwKck06
-ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CmlmKCEoYT4+PjAhPT1hKSl0PWI+Pj4wIT09Ynx8YT5ifHxiPmMK
-ZWxzZSB0PSEwCmlmKHQpdGhyb3cgSC5iKEguYXUoYSxiLGMpKQpyZXR1cm4gYn0sCkVUOmZ1bmN0aW9u
-IEVUKCl7fSwKYjA6ZnVuY3Rpb24gYjAoKXt9LApEZzpmdW5jdGlvbiBEZygpe30sClBnOmZ1bmN0aW9u
-IFBnKCl7fSwKeGo6ZnVuY3Rpb24geGooKXt9LApkRTpmdW5jdGlvbiBkRSgpe30sClpBOmZ1bmN0aW9u
-IFpBKCl7fSwKZFQ6ZnVuY3Rpb24gZFQoKXt9LApQcTpmdW5jdGlvbiBQcSgpe30sCmVFOmZ1bmN0aW9u
-IGVFKCl7fSwKVjY6ZnVuY3Rpb24gVjYoKXt9LApSRzpmdW5jdGlvbiBSRygpe30sClZQOmZ1bmN0aW9u
-IFZQKCl7fSwKV0I6ZnVuY3Rpb24gV0IoKXt9LApaRzpmdW5jdGlvbiBaRygpe30sCmN6OmZ1bmN0aW9u
-KGEsYil7dmFyIHQ9Yi5jCnJldHVybiB0PT1udWxsP2IuYz1ILkIoYSxiLnosITApOnR9LAp4WjpmdW5j
-dGlvbihhLGIpe3ZhciB0PWIuYwpyZXR1cm4gdD09bnVsbD9iLmM9SC5KKGEsImI4IixbYi56XSk6dH0s
-ClExOmZ1bmN0aW9uKGEpe3ZhciB0PWEueQppZih0PT09Nnx8dD09PTd8fHQ9PT04KXJldHVybiBILlEx
-KGEueikKcmV0dXJuIHQ9PT0xMXx8dD09PTEyfSwKbUQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGEuY3l9LApO
-MDpmdW5jdGlvbihhKXtyZXR1cm4gSC5FKHYudHlwZVVuaXZlcnNlLGEsITEpfSwKUEw6ZnVuY3Rpb24o
-YSxiLGMsYTApe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQ9Yi55CnN3aXRjaChk
-KXtjYXNlIDU6Y2FzZSAxOmNhc2UgMjpjYXNlIDM6Y2FzZSA0OnJldHVybiBiCmNhc2UgNjp0PWIuegpz
-PUguUEwoYSx0LGMsYTApCmlmKHM9PT10KXJldHVybiBiCnJldHVybiBILkMoYSxzLCEwKQpjYXNlIDc6
-dD1iLnoKcz1ILlBMKGEsdCxjLGEwKQppZihzPT09dClyZXR1cm4gYgpyZXR1cm4gSC5CKGEscywhMCkK
-Y2FzZSA4OnQ9Yi56CnM9SC5QTChhLHQsYyxhMCkKaWYocz09PXQpcmV0dXJuIGIKcmV0dXJuIEguZihh
-LHMsITApCmNhc2UgOTpyPWIuUQpxPUguYlooYSxyLGMsYTApCmlmKHE9PT1yKXJldHVybiBiCnJldHVy
-biBILkooYSxiLnoscSkKY2FzZSAxMDpwPWIuegpvPUguUEwoYSxwLGMsYTApCm49Yi5RCm09SC5iWihh
-LG4sYyxhMCkKaWYobz09PXAmJm09PT1uKXJldHVybiBiCnJldHVybiBILmEoYSxvLG0pCmNhc2UgMTE6
-bD1iLnoKaz1ILlBMKGEsbCxjLGEwKQpqPWIuUQppPUgucVQoYSxqLGMsYTApCmlmKGs9PT1sJiZpPT09
-ailyZXR1cm4gYgpyZXR1cm4gSC5kKGEsayxpKQpjYXNlIDEyOmg9Yi5RCmEwKz1oLmxlbmd0aApnPUgu
-YlooYSxoLGMsYTApCnA9Yi56Cm89SC5QTChhLHAsYyxhMCkKaWYoZz09PWgmJm89PT1wKXJldHVybiBi
-CnJldHVybiBILkQoYSxvLGcsITApCmNhc2UgMTM6Zj1iLnoKaWYoZjxhMClyZXR1cm4gYgplPWNbZi1h
-MF0KaWYoZT09bnVsbClyZXR1cm4gYgpyZXR1cm4gZQpkZWZhdWx0OnRocm93IEguYihQLmhWKCJBdHRl
-bXB0ZWQgdG8gc3Vic3RpdHV0ZSB1bmV4cGVjdGVkIFJUSSBraW5kICIrZCkpfX0sCmJaOmZ1bmN0aW9u
-KGEsYixjLGQpe3ZhciB0LHMscixxLHA9Yi5sZW5ndGgsbz1bXQpmb3IodD0hMSxzPTA7czxwOysrcyl7
-cj1iW3NdCnE9SC5QTChhLHIsYyxkKQppZihxIT09cil0PSEwCm8ucHVzaChxKX1yZXR1cm4gdD9vOmJ9
-LAp2TzpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIscSxwLG89Yi5sZW5ndGgsbj1bXQpmb3IodD0h
-MSxzPTA7czxvO3MrPTIpe3I9YltzXQpxPWJbcysxXQpwPUguUEwoYSxxLGMsZCkKaWYocCE9PXEpdD0h
-MApuLnB1c2gocikKbi5wdXNoKHApfXJldHVybiB0P246Yn0sCnFUOmZ1bmN0aW9uKGEsYixjLGQpe3Zh
-ciB0LHM9Yi5hLHI9SC5iWihhLHMsYyxkKSxxPWIuYixwPUguYlooYSxxLGMsZCksbz1iLmMsbj1ILnZP
-KGEsbyxjLGQpCmlmKHI9PT1zJiZwPT09cSYmbj09PW8pcmV0dXJuIGIKdD1uZXcgSC5HKCkKdC5hPXIK
-dC5iPXAKdC5jPW4KcmV0dXJuIHR9LApKUzpmdW5jdGlvbihhKXt2YXIgdD1hLiRTCmlmKHQhPW51bGwp
-e2lmKHR5cGVvZiB0PT0ibnVtYmVyIilyZXR1cm4gSC5CcCh0KQpyZXR1cm4gYS4kUygpfXJldHVybiBu
-dWxsfSwKVWU6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihILlExKGIpKWlmKGEgaW5zdGFuY2VvZiBILnYp
-e3Q9SC5KUyhhKQppZih0IT1udWxsKXJldHVybiB0fXJldHVybiBILnooYSl9LAp6OmZ1bmN0aW9uKGEp
-e3ZhciB0CmlmKGEgaW5zdGFuY2VvZiBQLk1oKXt0PWEuJHRpCnJldHVybiB0IT1udWxsP3Q6SC5WVShh
-KX1pZihBcnJheS5pc0FycmF5KGEpKXJldHVybiBILnQ2KGEpCnJldHVybiBILlZVKEouaWEoYSkpfSwK
-dDY6ZnVuY3Rpb24oYSl7dmFyIHQ9YVt2LmFycmF5UnRpXSxzPXUuYgppZih0PT1udWxsKXJldHVybiBz
-CmlmKHQuY29uc3RydWN0b3IhPT1zLmNvbnN0cnVjdG9yKXJldHVybiBzCnJldHVybiB0fSwKTGg6ZnVu
-Y3Rpb24oYSl7dmFyIHQ9YS4kdGkKcmV0dXJuIHQhPW51bGw/dDpILlZVKGEpfSwKVlU6ZnVuY3Rpb24o
-YSl7dmFyIHQ9YS5jb25zdHJ1Y3RvcixzPXQuJGNjYWNoZQppZihzIT1udWxsKXJldHVybiBzCnJldHVy
-biBILnI5KGEsdCl9LApyOTpmdW5jdGlvbihhLGIpe3ZhciB0PWEgaW5zdGFuY2VvZiBILnY/YS5fX3By
-b3RvX18uX19wcm90b19fLmNvbnN0cnVjdG9yOmIscz1ILmFpKHYudHlwZVVuaXZlcnNlLHQubmFtZSkK
-Yi4kY2NhY2hlPXMKcmV0dXJuIHN9LApCcDpmdW5jdGlvbihhKXt2YXIgdCxzLHIKSC51UChhKQp0PXYu
-dHlwZXMKcz10W2FdCmlmKHR5cGVvZiBzPT0ic3RyaW5nIil7cj1ILkUodi50eXBlVW5pdmVyc2Uscywh
-MSkKdFthXT1yCnJldHVybiByfXJldHVybiBzfSwKSko6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9dGhp
-cwppZihxPT09dS5LKXJldHVybiBILlJFKHEsYSxILmtlKQppZihILkE4KHEpfHxxPT09dS5fKXJldHVy
-biBILlJFKHEsYSxILkl3KQp0PXEueQpzPXQ9PT02P3EuejpxCmlmKHM9PT11LlMpcj1ILm9rCmVsc2Ug
-aWYocz09PXUuZ1J8fHM9PT11LmRpKXI9SC5LSAplbHNlIGlmKHM9PT11Lk4pcj1ILk1NCmVsc2Ugcj1z
-PT09dS55P0gubDpudWxsCmlmKHIhPW51bGwpcmV0dXJuIEguUkUocSxhLHIpCmlmKHMueT09PTkpe3Q9
-cy56CmlmKHMuUS5ldmVyeShILmNjKSl7cS5yPSIkaSIrdApyZXR1cm4gSC5SRShxLGEsSC50NCl9fWVs
-c2UgaWYodD09PTcpcmV0dXJuIEguUkUocSxhLEguQVEpCnJldHVybiBILlJFKHEsYSxILllPKX0sClJF
-OmZ1bmN0aW9uKGEsYixjKXthLmI9YwpyZXR1cm4gYS5iKGIpfSwKQXU6ZnVuY3Rpb24oYSl7dmFyIHQs
-cz10aGlzCkguT3oKaWYoSC5BOChzKXx8cz09PXUuXyl0PUguaG4KZWxzZSBpZihzPT09dS5LKXQ9SC5U
-aQplbHNlIHQ9SC5sNApzLmE9dApyZXR1cm4gcy5hKGEpfSwKUWo6ZnVuY3Rpb24oYSl7dmFyIHQ9YS55
-CnJldHVybiBILkE4KGEpfHxhPT09dS5ffHxhPT09dS5hd3x8dD09PTd8fGE9PT11LlB9LApZTzpmdW5j
-dGlvbihhKXt2YXIgdD10aGlzCmlmKGE9PW51bGwpcmV0dXJuIEguUWoodCkKcmV0dXJuIEguV2Uodi50
-eXBlVW5pdmVyc2UsSC5VZShhLHQpLG51bGwsdCxudWxsKX0sCkFROmZ1bmN0aW9uKGEpe2lmKGE9PW51
-bGwpcmV0dXJuITAKcmV0dXJuIHRoaXMuei5iKGEpfSwKdDQ6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcyxz
-PXQucgppZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4hIWFbc10KcmV0dXJuISFKLmlhKGEpW3NdfSwK
-T3o6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcwppZihhPT1udWxsKXJldHVybiBhCmVsc2UgaWYodC5iKGEp
-KXJldHVybiBhCkgubTQoYSx0KX0sCmw0OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMKaWYoYT09bnVsbCly
-ZXR1cm4gYQppZih0LmIoYSkpcmV0dXJuIGEKSC5tNChhLHQpfSwKbTQ6ZnVuY3Rpb24oYSxiKXt0aHJv
-dyBILmIoSC5aYyhILldLKGEsSC5VZShhLGIpLEguZG0oYixudWxsKSkpKX0sCkRoOmZ1bmN0aW9uKGEs
-YixjLGQpe3ZhciB0PW51bGwKaWYoSC5XZSh2LnR5cGVVbml2ZXJzZSxhLHQsYix0KSlyZXR1cm4gYQp0
-aHJvdyBILmIoSC5aYygiVGhlIHR5cGUgYXJndW1lbnQgJyIrSC5FaihILmRtKGEsdCkpKyInIGlzIG5v
-dCBhIHN1YnR5cGUgb2YgdGhlIHR5cGUgdmFyaWFibGUgYm91bmQgJyIrSC5FaihILmRtKGIsdCkpKyIn
-IG9mIHR5cGUgdmFyaWFibGUgJyIrSC5FaihjKSsiJyBpbiAnIitILkVqKGQpKyInLiIpKX0sCldLOmZ1
-bmN0aW9uKGEsYixjKXt2YXIgdD1QLnAoYSkscz1ILmRtKGI9PW51bGw/SC56KGEpOmIsbnVsbCkKcmV0
-dXJuIHQrIjogdHlwZSAnIitILkVqKHMpKyInIGlzIG5vdCBhIHN1YnR5cGUgb2YgdHlwZSAnIitILkVq
-KGMpKyInIn0sClpjOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgSC5pTSgiVHlwZUVycm9yOiAiK2EpfSwK
-cTpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgSC5pTSgiVHlwZUVycm9yOiAiK0guV0soYSxudWxsLGIp
-KX0sCmtlOmZ1bmN0aW9uKGEpe3JldHVybiBhIT1udWxsfSwKVGk6ZnVuY3Rpb24oYSl7cmV0dXJuIGF9
-LApJdzpmdW5jdGlvbihhKXtyZXR1cm4hMH0sCmhuOmZ1bmN0aW9uKGEpe3JldHVybiBhfSwKbDpmdW5j
-dGlvbihhKXtyZXR1cm4hMD09PWF8fCExPT09YX0sCnA4OmZ1bmN0aW9uKGEpe2lmKCEwPT09YXx8ITE9
-PT1hKXJldHVybiBhCnRocm93IEguYihILnEoYSwiYm9vbCIpKX0sCnk4OmZ1bmN0aW9uKGEpe2lmKCEw
-PT09YXx8ITE9PT1hKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEgucShhLCJi
-b29sIikpfSwKQlI6ZnVuY3Rpb24oYSl7aWYoITA9PT1hfHwhMT09PWEpcmV0dXJuIGEKaWYoYT09bnVs
-bClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImJvb2w/IikpfSwKRkc6ZnVuY3Rpb24oYSl7aWYodHlw
-ZW9mIGE9PSJudW1iZXIiKXJldHVybiBhCnRocm93IEguYihILnEoYSwiZG91YmxlIikpfSwKR0g6ZnVu
-Y3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEK
-dGhyb3cgSC5iKEgucShhLCJkb3VibGUiKSl9LApRazpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51
-bWJlciIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImRvdWJsZT8i
-KSl9LApvazpmdW5jdGlvbihhKXtyZXR1cm4gdHlwZW9mIGE9PSJudW1iZXIiJiZNYXRoLmZsb29yKGEp
-PT09YX0sCklaOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5mbG9vcihhKT09
-PWEpcmV0dXJuIGEKdGhyb3cgSC5iKEgucShhLCJpbnQiKSl9LAp1UDpmdW5jdGlvbihhKXtpZih0eXBl
-b2YgYT09Im51bWJlciImJk1hdGguZmxvb3IoYSk9PT1hKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJu
-IGEKdGhyb3cgSC5iKEgucShhLCJpbnQiKSl9LApVYzpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51
-bWJlciImJk1hdGguZmxvb3IoYSk9PT1hKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cg
-SC5iKEgucShhLCJpbnQ/IikpfSwKS0g6ZnVuY3Rpb24oYSl7cmV0dXJuIHR5cGVvZiBhPT0ibnVtYmVy
-In0sCno1OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQp0aHJvdyBILmIo
-SC5xKGEsIm51bSIpKX0sCm9JOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4g
-YQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwibnVtIikpfSwKY1U6ZnVuY3Rpb24o
-YSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cg
-SC5iKEgucShhLCJudW0/IikpfSwKTU06ZnVuY3Rpb24oYSl7cmV0dXJuIHR5cGVvZiBhPT0ic3RyaW5n
-In0sCkJ0OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gYQp0aHJvdyBILmIo
-SC5xKGEsIlN0cmluZyIpKX0sCmg6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVy
-biBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEgucShhLCJTdHJpbmciKSl9LAprOmZ1bmN0
-aW9uKGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRo
-cm93IEguYihILnEoYSwiU3RyaW5nPyIpKX0sCmlvOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCmZvcih0
-PSIiLHM9IiIscj0wO3I8YS5sZW5ndGg7KytyLHM9IiwgIil0Kz1DLnhCLmgocyxILmRtKGFbcl0sYikp
-CnJldHVybiB0fSwKYkk6ZnVuY3Rpb24oYTIsYTMsYTQpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGos
-aSxoLGcsZixlLGQsYyxiLGEsYTAsYTE9IiwgIgppZihhNCE9bnVsbCl7dD1hNC5sZW5ndGgKaWYoYTM9
-PW51bGwpe2EzPUguVk0oW10sdS5zKQpzPW51bGx9ZWxzZSBzPWEzLmxlbmd0aApyPWEzLmxlbmd0aApm
-b3IocT10O3E+MDstLXEpQy5ObS5pKGEzLCJUIisocitxKSkKZm9yKHA9dS5fLG89dS5LLG49IjwiLG09
-IiIscT0wO3E8dDsrK3EsbT1hMSl7bis9bQpsPWEzLmxlbmd0aAprPWwtMS1xCmlmKGs8MClyZXR1cm4g
-SC5PSChhMyxrKQpuPUMueEIuaChuLGEzW2tdKQpqPWE0W3FdCmlmKCEoSC5BOChqKXx8aj09PXApKWw9
-IShqPT09bykKZWxzZSBsPSExCmlmKGwpbis9Qy54Qi5oKCIgZXh0ZW5kcyAiLEguZG0oaixhMykpfW4r
-PSI+In1lbHNle249IiIKcz1udWxsfXA9YTIuegppPWEyLlEKaD1pLmEKZz1oLmxlbmd0aApmPWkuYgpl
-PWYubGVuZ3RoCmQ9aS5jCmM9ZC5sZW5ndGgKYj1ILmRtKHAsYTMpCmZvcihhPSIiLGEwPSIiLHE9MDtx
-PGc7KytxLGEwPWExKWErPUMueEIuaChhMCxILmRtKGhbcV0sYTMpKQppZihlPjApe2ErPWEwKyJbIgpm
-b3IoYTA9IiIscT0wO3E8ZTsrK3EsYTA9YTEpYSs9Qy54Qi5oKGEwLEguZG0oZltxXSxhMykpCmErPSJd
-In1pZihjPjApe2ErPWEwKyJ7Igpmb3IoYTA9IiIscT0wO3E8YztxKz0yLGEwPWExKWErPUMueEIuaChh
-MCxILmRtKGRbcSsxXSxhMykpKyIgIitkW3FdCmErPSJ9In1pZihzIT1udWxsKXthMy50b1N0cmluZwph
-My5sZW5ndGg9c31yZXR1cm4gbisiKCIrYSsiKSA9PiAiK0guRWooYil9LApkbTpmdW5jdGlvbihhLGIp
-e3ZhciB0LHMscixxLHAsbyxuLG09YS55CmlmKG09PT01KXJldHVybiJlcmFzZWQiCmlmKG09PT0yKXJl
-dHVybiJkeW5hbWljIgppZihtPT09MylyZXR1cm4idm9pZCIKaWYobT09PTEpcmV0dXJuIk5ldmVyIgpp
-ZihtPT09NClyZXR1cm4iYW55IgppZihtPT09Nil7dD1ILmRtKGEueixiKQpyZXR1cm4gdH1pZihtPT09
-Nyl7cz1hLnoKdD1ILmRtKHMsYikKcj1zLnkKcmV0dXJuIEouYmIocj09PTExfHxyPT09MTI/Qy54Qi5o
-KCIoIix0KSsiKSI6dCwiPyIpfWlmKG09PT04KXJldHVybiJGdXR1cmVPcjwiK0guRWooSC5kbShhLnos
-YikpKyI+IgppZihtPT09OSl7cT1ILm8zKGEueikKcD1hLlEKcmV0dXJuIHAubGVuZ3RoIT09MD9xKygi
-PCIrSC5pbyhwLGIpKyI+Iik6cX1pZihtPT09MTEpcmV0dXJuIEguYkkoYSxiLG51bGwpCmlmKG09PT0x
-MilyZXR1cm4gSC5iSShhLnosYixhLlEpCmlmKG09PT0xMyl7Yi50b1N0cmluZwpvPWEuegpuPWIubGVu
-Z3RoCm89bi0xLW8KaWYobzwwfHxvPj1uKXJldHVybiBILk9IKGIsbykKcmV0dXJuIGJbb119cmV0dXJu
-Ij8ifSwKbzM6ZnVuY3Rpb24oYSl7dmFyIHQscz1ILkpnKGEpCmlmKHMhPW51bGwpcmV0dXJuIHMKdD0i
-bWluaWZpZWQ6IithCnJldHVybiB0fSwKUW86ZnVuY3Rpb24oYSxiKXt2YXIgdD1hLnRSW2JdCmZvcig7
-dHlwZW9mIHQ9PSJzdHJpbmciOyl0PWEudFJbdF0KcmV0dXJuIHR9LAphaTpmdW5jdGlvbihhLGIpe3Zh
-ciB0LHMscixxLHAsbz1hLmVULG49b1tiXQppZihuPT1udWxsKXJldHVybiBILkUoYSxiLCExKQplbHNl
-IGlmKHR5cGVvZiBuPT0ibnVtYmVyIil7dD1uCnM9SC5tKGEsNSwiIyIpCnI9W10KZm9yKHE9MDtxPHQ7
-KytxKXIucHVzaChzKQpwPUguSihhLGIscikKb1tiXT1wCnJldHVybiBwfWVsc2UgcmV0dXJuIG59LAp4
-YjpmdW5jdGlvbihhLGIpe3JldHVybiBILkl4KGEudFIsYil9LApGRjpmdW5jdGlvbihhLGIpe3JldHVy
-biBILkl4KGEuZVQsYil9LApFOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPWEuZUMscj1zLmdldChiKQpp
-ZihyIT1udWxsKXJldHVybiByCnQ9SC5pKEgubyhhLG51bGwsYixjKSkKcy5zZXQoYix0KQpyZXR1cm4g
-dH0sCmNFOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHI9Yi5jaAppZihyPT1udWxsKXI9Yi5jaD1uZXcg
-TWFwKCkKdD1yLmdldChjKQppZih0IT1udWxsKXJldHVybiB0CnM9SC5pKEgubyhhLGIsYywhMCkpCnIu
-c2V0KGMscykKcmV0dXJuIHN9LAp2NTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHE9Yi5jeAppZihx
-PT1udWxsKXE9Yi5jeD1uZXcgTWFwKCkKdD1jLmN5CnM9cS5nZXQodCkKaWYocyE9bnVsbClyZXR1cm4g
-cwpyPUguYShhLGIsYy55PT09MTA/Yy5ROltjXSkKcS5zZXQodCxyKQpyZXR1cm4gcn0sCkJEOmZ1bmN0
-aW9uKGEsYil7Yi5hPUguQXUKYi5iPUguSkoKcmV0dXJuIGJ9LAptOmZ1bmN0aW9uKGEsYixjKXt2YXIg
-dCxzLHI9YS5lQy5nZXQoYykKaWYociE9bnVsbClyZXR1cm4gcgp0PW5ldyBILkpjKG51bGwsbnVsbCkK
-dC55PWIKdC5jeT1jCnM9SC5CRChhLHQpCmEuZUMuc2V0KGMscykKcmV0dXJuIHN9LApDOmZ1bmN0aW9u
-KGEsYixjKXt2YXIgdCxzPWIuY3krIioiLHI9YS5lQy5nZXQocykKaWYociE9bnVsbClyZXR1cm4gcgp0
-PUguWjcoYSxiLHMsYykKYS5lQy5zZXQocyx0KQpyZXR1cm4gdH0sClo3OmZ1bmN0aW9uKGEsYixjLGQp
-e3ZhciB0LHMKaWYoZCl7dD1iLnkKaWYoSC5BOChiKXx8Yj09PXUuX3x8Yj09PXUuUHx8dD09PTd8fHQ9
-PT02KXJldHVybiBifXM9bmV3IEguSmMobnVsbCxudWxsKQpzLnk9NgpzLno9YgpzLmN5PWMKcmV0dXJu
-IEguQkQoYSxzKX0sCkI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9Yi5jeSsiPyIscj1hLmVDLmdldChz
-KQppZihyIT1udWxsKXJldHVybiByCnQ9SC5sbChhLGIscyxjKQphLmVDLnNldChzLHQpCnJldHVybiB0
-fSwKbGw6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEKaWYoZCl7dD1iLnkKaWYoIUguQTgoYikp
-aWYoIShiPT09dS5QKSlpZih0IT09NylzPXQ9PT04JiZILmxSKGIueikKZWxzZSBzPSEwCmVsc2Ugcz0h
-MAplbHNlIHM9ITAKaWYocylyZXR1cm4gYgplbHNlIGlmKHQ9PT0xfHxiPT09dS5hdylyZXR1cm4gdS5Q
-CmVsc2UgaWYodD09PTYpe3I9Yi56CmlmKHIueT09PTgmJkgubFIoci56KSlyZXR1cm4gcgplbHNlIHJl
-dHVybiBILmN6KGEsYil9fXE9bmV3IEguSmMobnVsbCxudWxsKQpxLnk9NwpxLno9YgpxLmN5PWMKcmV0
-dXJuIEguQkQoYSxxKX0sCmY6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9Yi5jeSsiLyIscj1hLmVDLmdl
-dChzKQppZihyIT1udWxsKXJldHVybiByCnQ9SC5lVihhLGIscyxjKQphLmVDLnNldChzLHQpCnJldHVy
-biB0fSwKZVY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscwppZihkKXt0PWIueQppZihILkE4KGIpfHxi
-PT09dS5ffHxiPT09dS5LKXJldHVybiBiCmVsc2UgaWYodD09PTEpcmV0dXJuIEguSihhLCJiOCIsW2Jd
-KQplbHNlIGlmKGI9PT11LlApcmV0dXJuIHUuYkd9cz1uZXcgSC5KYyhudWxsLG51bGwpCnMueT04CnMu
-ej1iCnMuY3k9YwpyZXR1cm4gSC5CRChhLHMpfSwKSDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj0iIiti
-KyJeIixxPWEuZUMuZ2V0KHIpCmlmKHEhPW51bGwpcmV0dXJuIHEKdD1uZXcgSC5KYyhudWxsLG51bGwp
-CnQueT0xMwp0Lno9Ygp0LmN5PXIKcz1ILkJEKGEsdCkKYS5lQy5zZXQocixzKQpyZXR1cm4gc30sClV4
-OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPWEubGVuZ3RoCmZvcih0PSIiLHM9IiIscj0wO3I8cTsrK3Is
-cz0iLCIpdCs9cythW3JdLmN5CnJldHVybiB0fSwKUzQ6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxv
-PWEubGVuZ3RoCmZvcih0PSIiLHM9IiIscj0wO3I8bztyKz0yLHM9IiwiKXtxPWFbcl0KcD1hW3IrMV0u
-Y3kKdCs9cytxKyI6IitwfXJldHVybiB0fSwKSjpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHE9Ygpp
-ZihjLmxlbmd0aCE9PTApcSs9IjwiK0guVXgoYykrIj4iCnQ9YS5lQy5nZXQocSkKaWYodCE9bnVsbCly
-ZXR1cm4gdApzPW5ldyBILkpjKG51bGwsbnVsbCkKcy55PTkKcy56PWIKcy5RPWMKaWYoYy5sZW5ndGg+
-MClzLmM9Y1swXQpzLmN5PXEKcj1ILkJEKGEscykKYS5lQy5zZXQocSxyKQpyZXR1cm4gcn0sCmE6ZnVu
-Y3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbwppZihiLnk9PT0xMCl7dD1iLnoKcz1iLlEuY29uY2F0
-KGMpfWVsc2V7cz1jCnQ9Yn1yPXQuY3krIjsiKygiPCIrSC5VeChzKSsiPiIpCnE9YS5lQy5nZXQocikK
-aWYocSE9bnVsbClyZXR1cm4gcQpwPW5ldyBILkpjKG51bGwsbnVsbCkKcC55PTEwCnAuej10CnAuUT1z
-CnAuY3k9cgpvPUguQkQoYSxwKQphLmVDLnNldChyLG8pCnJldHVybiBvfSwKZDpmdW5jdGlvbihhLGIs
-Yyl7dmFyIHQscyxyLHEscD1iLmN5LG89Yy5hLG49by5sZW5ndGgsbT1jLmIsbD1tLmxlbmd0aCxrPWMu
-YyxqPWsubGVuZ3RoLGk9IigiK0guVXgobykKaWYobD4wKWkrPShuPjA/IiwiOiIiKSsiWyIrSC5VeCht
-KSsiXSIKaWYoaj4wKWkrPShuPjA/IiwiOiIiKSsieyIrSC5TNChrKSsifSIKdD1wKyhpKyIpIikKcz1h
-LmVDLmdldCh0KQppZihzIT1udWxsKXJldHVybiBzCnI9bmV3IEguSmMobnVsbCxudWxsKQpyLnk9MTEK
-ci56PWIKci5RPWMKci5jeT10CnE9SC5CRChhLHIpCmEuZUMuc2V0KHQscSkKcmV0dXJuIHF9LApEOmZ1
-bmN0aW9uKGEsYixjLGQpe3ZhciB0LHM9Yi5jeSsiPCIrSC5VeChjKSsiPiIscj1hLmVDLmdldChzKQpp
-ZihyIT1udWxsKXJldHVybiByCnQ9SC5odyhhLGIsYyxzLGQpCmEuZUMuc2V0KHMsdCkKcmV0dXJuIHR9
-LApodzpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscixxLHAsbyxuLG0KaWYoZSl7dD1jLmxlbmd0
-aApzPW5ldyBBcnJheSh0KQpmb3Iocj0wLHE9MDtxPHQ7KytxKXtwPWNbcV0KaWYocC55PT09MSl7c1tx
-XT1wOysrcn19aWYocj4wKXtvPUguUEwoYSxiLHMsMCkKbj1ILmJaKGEsYyxzLDApCnJldHVybiBILkQo
-YSxvLG4sYyE9PW4pfX1tPW5ldyBILkpjKG51bGwsbnVsbCkKbS55PTEyCm0uej1iCm0uUT1jCm0uY3k9
-ZApyZXR1cm4gSC5CRChhLG0pfSwKbzpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm57dTphLGU6YixyOmMs
-czpbXSxwOjAsbjpkfX0sCmk6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpPWEu
-cixoPWEucwpmb3IodD1pLmxlbmd0aCxzPTA7czx0Oyl7cj1pLmNoYXJDb2RlQXQocykKaWYocj49NDgm
-JnI8PTU3KXM9SC5BKHMrMSxyLGksaCkKZWxzZSBpZigoKChyfDMyKT4+PjApLTk3JjY1NTM1KTwyNnx8
-cj09PTk1fHxyPT09MzYpcz1ILnQoYSxzLGksaCwhMSkKZWxzZSBpZihyPT09NDYpcz1ILnQoYSxzLGks
-aCwhMCkKZWxzZXsrK3MKc3dpdGNoKHIpe2Nhc2UgNDQ6YnJlYWsKY2FzZSA1ODpicmVhawpjYXNlIDU5
-OmgucHVzaChILksoYS51LGEuZSxoLnBvcCgpKSkKYnJlYWsKY2FzZSA5NDpoLnB1c2goSC5IKGEudSxo
-LnBvcCgpKSkKYnJlYWsKY2FzZSAzNTpoLnB1c2goSC5tKGEudSw1LCIjIikpCmJyZWFrCmNhc2UgNjQ6
-aC5wdXNoKEgubShhLnUsMiwiQCIpKQpicmVhawpjYXNlIDEyNjpoLnB1c2goSC5tKGEudSwzLCJ+Iikp
-CmJyZWFrCmNhc2UgNjA6aC5wdXNoKGEucCkKYS5wPWgubGVuZ3RoCmJyZWFrCmNhc2UgNjI6cT1hLnUK
-cD1oLnNwbGljZShhLnApCkgucihhLnUsYS5lLHApCmEucD1oLnBvcCgpCm89aC5wb3AoKQppZih0eXBl
-b2Ygbz09InN0cmluZyIpaC5wdXNoKEguSihxLG8scCkpCmVsc2V7bj1ILksocSxhLmUsbykKc3dpdGNo
-KG4ueSl7Y2FzZSAxMTpoLnB1c2goSC5EKHEsbixwLGEubikpCmJyZWFrCmRlZmF1bHQ6aC5wdXNoKEgu
-YShxLG4scCkpCmJyZWFrfX1icmVhawpjYXNlIDM4OkguSShhLGgpCmJyZWFrCmNhc2UgNDI6cT1hLnUK
-aC5wdXNoKEguQyhxLEguSyhxLGEuZSxoLnBvcCgpKSxhLm4pKQpicmVhawpjYXNlIDYzOnE9YS51Cmgu
-cHVzaChILkIocSxILksocSxhLmUsaC5wb3AoKSksYS5uKSkKYnJlYWsKY2FzZSA0NzpxPWEudQpoLnB1
-c2goSC5mKHEsSC5LKHEsYS5lLGgucG9wKCkpLGEubikpCmJyZWFrCmNhc2UgNDA6aC5wdXNoKGEucCkK
-YS5wPWgubGVuZ3RoCmJyZWFrCmNhc2UgNDE6cT1hLnUKbT1uZXcgSC5HKCkKbD1xLnNFQQprPXEuc0VB
-Cm89aC5wb3AoKQppZih0eXBlb2Ygbz09Im51bWJlciIpc3dpdGNoKG8pe2Nhc2UtMTpsPWgucG9wKCkK
-YnJlYWsKY2FzZS0yOms9aC5wb3AoKQpicmVhawpkZWZhdWx0OmgucHVzaChvKQpicmVha31lbHNlIGgu
-cHVzaChvKQpwPWguc3BsaWNlKGEucCkKSC5yKGEudSxhLmUscCkKYS5wPWgucG9wKCkKbS5hPXAKbS5i
-PWwKbS5jPWsKaC5wdXNoKEguZChxLEguSyhxLGEuZSxoLnBvcCgpKSxtKSkKYnJlYWsKY2FzZSA5MTpo
-LnB1c2goYS5wKQphLnA9aC5sZW5ndGgKYnJlYWsKY2FzZSA5MzpwPWguc3BsaWNlKGEucCkKSC5yKGEu
-dSxhLmUscCkKYS5wPWgucG9wKCkKaC5wdXNoKHApCmgucHVzaCgtMSkKYnJlYWsKY2FzZSAxMjM6aC5w
-dXNoKGEucCkKYS5wPWgubGVuZ3RoCmJyZWFrCmNhc2UgMTI1OnA9aC5zcGxpY2UoYS5wKQpILnkoYS51
-LGEuZSxwKQphLnA9aC5wb3AoKQpoLnB1c2gocCkKaC5wdXNoKC0yKQpicmVhawpkZWZhdWx0OnRocm93
-IkJhZCBjaGFyYWN0ZXIgIityfX19aj1oLnBvcCgpCnJldHVybiBILksoYS51LGEuZSxqKX0sCkE6ZnVu
-Y3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyPWItNDgKZm9yKHQ9Yy5sZW5ndGg7YTx0OysrYSl7cz1jLmNo
-YXJDb2RlQXQoYSkKaWYoIShzPj00OCYmczw9NTcpKWJyZWFrCnI9cioxMCsocy00OCl9ZC5wdXNoKHIp
-CnJldHVybiBhfSwKdDpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscixxLHAsbyxuPWIrMQpmb3Io
-dD1jLmxlbmd0aDtuPHQ7KytuKXtzPWMuY2hhckNvZGVBdChuKQppZihzPT09NDYpe2lmKGUpYnJlYWsK
-ZT0hMH1lbHNle2lmKCEoKCgoc3wzMik+Pj4wKS05NyY2NTUzNSk8MjZ8fHM9PT05NXx8cz09PTM2KSly
-PXM+PTQ4JiZzPD01NwplbHNlIHI9ITAKaWYoIXIpYnJlYWt9fXE9Yy5zdWJzdHJpbmcoYixuKQppZihl
-KXt0PWEudQpwPWEuZQppZihwLnk9PT0xMClwPXAuegpvPUguUW8odCxwLnopW3FdCmlmKG89PW51bGwp
-SC52aCgnTm8gIicrcSsnIiBpbiAiJytILm1EKHApKyciJykKZC5wdXNoKEguY0UodCxwLG8pKX1lbHNl
-IGQucHVzaChxKQpyZXR1cm4gbn0sCkk6ZnVuY3Rpb24oYSxiKXt2YXIgdD1iLnBvcCgpCmlmKDA9PT10
-KXtiLnB1c2goSC5tKGEudSwxLCIwJiIpKQpyZXR1cm59aWYoMT09PXQpe2IucHVzaChILm0oYS51LDQs
-IjEmIikpCnJldHVybn10aHJvdyBILmIoUC5oVigiVW5leHBlY3RlZCBleHRlbmRlZCBvcGVyYXRpb24g
-IitILkVqKHQpKSl9LApLOmZ1bmN0aW9uKGEsYixjKXtpZih0eXBlb2YgYz09InN0cmluZyIpcmV0dXJu
-IEguSihhLGMsYS5zRUEpCmVsc2UgaWYodHlwZW9mIGM9PSJudW1iZXIiKXJldHVybiBILlRWKGEsYixj
-KQplbHNlIHJldHVybiBjfSwKcjpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz1jLmxlbmd0aApmb3IodD0w
-O3Q8czsrK3QpY1t0XT1ILksoYSxiLGNbdF0pfSwKeTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz1jLmxl
-bmd0aApmb3IodD0xO3Q8czt0Kz0yKWNbdF09SC5LKGEsYixjW3RdKX0sClRWOmZ1bmN0aW9uKGEsYixj
-KXt2YXIgdCxzLHI9Yi55CmlmKHI9PT0xMCl7aWYoYz09PTApcmV0dXJuIGIuegp0PWIuUQpzPXQubGVu
-Z3RoCmlmKGM8PXMpcmV0dXJuIHRbYy0xXQpjLT1zCmI9Yi56CnI9Yi55fWVsc2UgaWYoYz09PTApcmV0
-dXJuIGIKaWYociE9PTkpdGhyb3cgSC5iKFAuaFYoIkluZGV4ZWQgYmFzZSBtdXN0IGJlIGFuIGludGVy
-ZmFjZSB0eXBlIikpCnQ9Yi5RCmlmKGM8PXQubGVuZ3RoKXJldHVybiB0W2MtMV0KdGhyb3cgSC5iKFAu
-aFYoIkJhZCBpbmRleCAiK2MrIiBmb3IgIitiLncoMCkpKX0sCldlOmZ1bmN0aW9uKGEsYixjLGQsZSl7
-dmFyIHQscyxyLHEscCxvLG4sbSxsLGsKaWYoYj09PWQpcmV0dXJuITAKaWYoSC5BOChkKXx8ZD09PXUu
-XylyZXR1cm4hMAp0PWIueQppZih0PT09NClyZXR1cm4hMAppZihILkE4KGIpKXJldHVybiExCmlmKGI9
-PT11LlApcmV0dXJuITAKcz10PT09MTMKaWYocylpZihILldlKGEsY1tiLnpdLGMsZCxlKSlyZXR1cm4h
-MApyPWQueQppZih0PT09NilyZXR1cm4gSC5XZShhLGIueixjLGQsZSkKaWYocj09PTYpe3E9ZC56CnJl
-dHVybiBILldlKGEsYixjLHEsZSl9aWYodD09PTgpe2lmKCFILldlKGEsYi56LGMsZCxlKSlyZXR1cm4h
-MQpyZXR1cm4gSC5XZShhLEgueFooYSxiKSxjLGQsZSl9aWYodD09PTcpe3E9SC5XZShhLGIueixjLGQs
-ZSkKcmV0dXJuIHF9aWYocj09PTgpe2lmKEguV2UoYSxiLGMsZC56LGUpKXJldHVybiEwCnJldHVybiBI
-LldlKGEsYixjLEgueFooYSxkKSxlKX1pZihyPT09Nyl7cT1ILldlKGEsYixjLGQueixlKQpyZXR1cm4g
-cX1pZihzKXJldHVybiExCnE9dCE9PTExCmlmKCghcXx8dD09PTEyKSYmZD09PXUuWSlyZXR1cm4hMApp
-ZihyPT09MTIpe2lmKGI9PT11LnIpcmV0dXJuITAKaWYodCE9PTEyKXJldHVybiExCnA9Yi5RCm89ZC5R
-Cm49cC5sZW5ndGgKaWYobiE9PW8ubGVuZ3RoKXJldHVybiExCmM9Yz09bnVsbD9wOnAuY29uY2F0KGMp
-CmU9ZT09bnVsbD9vOm8uY29uY2F0KGUpCmZvcihtPTA7bTxuOysrbSl7bD1wW21dCms9b1ttXQppZigh
-SC5XZShhLGwsYyxrLGUpfHwhSC5XZShhLGssZSxsLGMpKXJldHVybiExfXJldHVybiBILmJPKGEsYi56
-LGMsZC56LGUpfWlmKHI9PT0xMSl7aWYoYj09PXUucilyZXR1cm4hMAppZihxKXJldHVybiExCnJldHVy
-biBILmJPKGEsYixjLGQsZSl9aWYodD09PTkpe2lmKHIhPT05KXJldHVybiExCnJldHVybiBILnBHKGEs
-YixjLGQsZSl9cmV0dXJuITF9LApiTzpmdW5jdGlvbihhMCxhMSxhMixhMyxhNCl7dmFyIHQscyxyLHEs
-cCxvLG4sbSxsLGssaixpLGgsZyxmLGUsZCxjLGIsYQppZighSC5XZShhMCxhMS56LGEyLGEzLnosYTQp
-KXJldHVybiExCnQ9YTEuUQpzPWEzLlEKcj10LmEKcT1zLmEKcD1yLmxlbmd0aApvPXEubGVuZ3RoCmlm
-KHA+bylyZXR1cm4hMQpuPW8tcAptPXQuYgpsPXMuYgprPW0ubGVuZ3RoCmo9bC5sZW5ndGgKaWYocCtr
-PG8railyZXR1cm4hMQpmb3IoaT0wO2k8cDsrK2kpe2g9cltpXQppZighSC5XZShhMCxxW2ldLGE0LGgs
-YTIpKXJldHVybiExfWZvcihpPTA7aTxuOysraSl7aD1tW2ldCmlmKCFILldlKGEwLHFbcCtpXSxhNCxo
-LGEyKSlyZXR1cm4hMX1mb3IoaT0wO2k8ajsrK2kpe2g9bVtuK2ldCmlmKCFILldlKGEwLGxbaV0sYTQs
-aCxhMikpcmV0dXJuITF9Zz10LmMKZj1zLmMKZT1nLmxlbmd0aApkPWYubGVuZ3RoCmZvcihpPTAsYz0w
-O2M8ZDtjKz0yKXtiPWZbY10KZG97aWYoaT49ZSlyZXR1cm4hMQphPWdbaV0KaSs9Mn13aGlsZShhPGIp
-CmlmKGI8YSlyZXR1cm4hMQpoPWdbaS0xXQppZighSC5XZShhMCxmW2MrMV0sYTQsaCxhMikpcmV0dXJu
-ITF9cmV0dXJuITB9LApwRzpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscixxLHAsbyxuLG0sbD1i
-Lnosaz1kLnoKaWYobD09PWspe3Q9Yi5RCnM9ZC5RCnI9dC5sZW5ndGgKZm9yKHE9MDtxPHI7KytxKXtw
-PXRbcV0Kbz1zW3FdCmlmKCFILldlKGEscCxjLG8sZSkpcmV0dXJuITF9cmV0dXJuITB9aWYoZD09PXUu
-SylyZXR1cm4hMApuPUguUW8oYSxsKQppZihuPT1udWxsKXJldHVybiExCm09bltrXQppZihtPT1udWxs
-KXJldHVybiExCnI9bS5sZW5ndGgKcz1kLlEKZm9yKHE9MDtxPHI7KytxKWlmKCFILldlKGEsSC5jRShh
-LGIsbVtxXSksYyxzW3FdLGUpKXJldHVybiExCnJldHVybiEwfSwKbFI6ZnVuY3Rpb24oYSl7dmFyIHQs
-cz1hLnkKaWYoIShhPT09dS5QKSlpZighSC5BOChhKSlpZihzIT09NylpZighKHM9PT02JiZILmxSKGEu
-eikpKXQ9cz09PTgmJkgubFIoYS56KQplbHNlIHQ9ITAKZWxzZSB0PSEwCmVsc2UgdD0hMAplbHNlIHQ9
-ITAKcmV0dXJuIHR9LApjYzpmdW5jdGlvbihhKXtyZXR1cm4gSC5BOChhKXx8YT09PXUuX30sCkE4OmZ1
-bmN0aW9uKGEpe3ZhciB0LHM9YS55CmlmKHMhPT0yKWlmKHMhPT0zKWlmKHMhPT00KWlmKHMhPT01KXQ9
-YT09PXUuY0sKZWxzZSB0PSEwCmVsc2UgdD0hMAplbHNlIHQ9ITAKZWxzZSB0PSEwCnJldHVybiB0fSwK
-SXg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9T2JqZWN0LmtleXMoYikscT1yLmxlbmd0aApmb3IodD0w
-O3Q8cTsrK3Qpe3M9clt0XQphW3NdPWJbc119fSwKSmM6ZnVuY3Rpb24gSmMoYSxiKXt2YXIgXz10aGlz
-Cl8uYT1hCl8uYj1iCl8ueD1fLnI9Xy5jPW51bGwKXy55PTAKXy5jeT1fLmN4PV8uY2g9Xy5RPV8uej1u
-dWxsfSwKRzpmdW5jdGlvbiBHKCl7dGhpcy5jPXRoaXMuYj10aGlzLmE9bnVsbH0sCnU5OmZ1bmN0aW9u
-IHU5KCl7fSwKaU06ZnVuY3Rpb24gaU0oYSl7dGhpcy5hPWF9LApSOTpmdW5jdGlvbihhKXtyZXR1cm4g
-dS53LmIoYSl8fHUuQi5iKGEpfHx1LmR6LmIoYSl8fHUuSS5iKGEpfHx1LkEuYihhKXx8dS5nNC5iKGEp
-fHx1LmcyLmIoYSl9LApKZzpmdW5jdGlvbihhKXtyZXR1cm4gdi5tYW5nbGVkR2xvYmFsTmFtZXNbYV19
-fSxKPXsKUXU6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJue2k6YSxwOmIsZTpjLHg6ZH19LAprczpmdW5j
-dGlvbihhKXt2YXIgdCxzLHIscSxwPWFbdi5kaXNwYXRjaFByb3BlcnR5TmFtZV0KaWYocD09bnVsbClp
-ZigkLkJ2PT1udWxsKXtILlhEKCkKcD1hW3YuZGlzcGF0Y2hQcm9wZXJ0eU5hbWVdfWlmKHAhPW51bGwp
-e3Q9cC5wCmlmKCExPT09dClyZXR1cm4gcC5pCmlmKCEwPT09dClyZXR1cm4gYQpzPU9iamVjdC5nZXRQ
-cm90b3R5cGVPZihhKQppZih0PT09cylyZXR1cm4gcC5pCmlmKHAuZT09PXMpdGhyb3cgSC5iKFAuU1ko
-IlJldHVybiBpbnRlcmNlcHRvciBmb3IgIitILkVqKHQoYSxwKSkpKX1yPWEuY29uc3RydWN0b3IKcT1y
-PT1udWxsP251bGw6cltKLlJQKCldCmlmKHEhPW51bGwpcmV0dXJuIHEKcT1ILnczKGEpCmlmKHEhPW51
-bGwpcmV0dXJuIHEKaWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEMuREcKdD1PYmplY3QuZ2V0
-UHJvdG90eXBlT2YoYSkKaWYodD09bnVsbClyZXR1cm4gQy5aUQppZih0PT09T2JqZWN0LnByb3RvdHlw
-ZSlyZXR1cm4gQy5aUQppZih0eXBlb2Ygcj09ImZ1bmN0aW9uIil7T2JqZWN0LmRlZmluZVByb3BlcnR5
-KHIsSi5SUCgpLHt2YWx1ZTpDLnZCLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1
-cmFibGU6dHJ1ZX0pCnJldHVybiBDLnZCfXJldHVybiBDLnZCfSwKUlA6ZnVuY3Rpb24oKXt2YXIgdD0k
-LnptCnJldHVybiB0PT1udWxsPyQuem09di5nZXRJc29sYXRlVGFnKCJfJGRhcnRfanMiKTp0fSwKUWk6
-ZnVuY3Rpb24oYSxiKXtpZihhPDB8fGE+NDI5NDk2NzI5NSl0aHJvdyBILmIoUC5URShhLDAsNDI5NDk2
-NzI5NSwibGVuZ3RoIixudWxsKSkKcmV0dXJuIEoucHkobmV3IEFycmF5KGEpLGIpfSwKS2g6ZnVuY3Rp
-b24oYSxiKXtpZihhPDApdGhyb3cgSC5iKFAueFkoIkxlbmd0aCBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZl
-IGludGVnZXI6ICIrYSkpCnJldHVybiBILlZNKG5ldyBBcnJheShhKSxiLkMoImpkPDA+IikpfSwKcHk6
-ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5FcChILlZNKGEsYi5DKCJqZDwwPiIpKSxiKX0sCkVwOmZ1bmN0
-aW9uKGEsYil7YS5maXhlZCRsZW5ndGg9QXJyYXkKcmV0dXJuIGF9LAp6QzpmdW5jdGlvbihhKXthLmZp
-eGVkJGxlbmd0aD1BcnJheQphLmltbXV0YWJsZSRsaXN0PUFycmF5CnJldHVybiBhfSwKR2E6ZnVuY3Rp
-b24oYSl7aWYoYTwyNTYpc3dpdGNoKGEpe2Nhc2UgOTpjYXNlIDEwOmNhc2UgMTE6Y2FzZSAxMjpjYXNl
-IDEzOmNhc2UgMzI6Y2FzZSAxMzM6Y2FzZSAxNjA6cmV0dXJuITAKZGVmYXVsdDpyZXR1cm4hMX1zd2l0
-Y2goYSl7Y2FzZSA1NzYwOmNhc2UgODE5MjpjYXNlIDgxOTM6Y2FzZSA4MTk0OmNhc2UgODE5NTpjYXNl
-IDgxOTY6Y2FzZSA4MTk3OmNhc2UgODE5ODpjYXNlIDgxOTk6Y2FzZSA4MjAwOmNhc2UgODIwMTpjYXNl
-IDgyMDI6Y2FzZSA4MjMyOmNhc2UgODIzMzpjYXNlIDgyMzk6Y2FzZSA4Mjg3OmNhc2UgMTIyODg6Y2Fz
-ZSA2NTI3OTpyZXR1cm4hMApkZWZhdWx0OnJldHVybiExfX0sCm1tOmZ1bmN0aW9uKGEsYil7dmFyIHQs
-cwpmb3IodD1hLmxlbmd0aDtiPHQ7KXtzPUMueEIuVyhhLGIpCmlmKHMhPT0zMiYmcyE9PTEzJiYhSi5H
-YShzKSlicmVhazsrK2J9cmV0dXJuIGJ9LApjMTpmdW5jdGlvbihhLGIpe3ZhciB0LHMKZm9yKDtiPjA7
-Yj10KXt0PWItMQpzPUMueEIubShhLHQpCmlmKHMhPT0zMiYmcyE9PTEzJiYhSi5HYShzKSlicmVha31y
-ZXR1cm4gYn0sClRKOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gSi5xSS5w
-cm90b3R5cGUKaWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBKLkRyLnByb3RvdHlwZQppZihhPT1u
-dWxsKXJldHVybiBhCmlmKGEuY29uc3RydWN0b3I9PUFycmF5KXJldHVybiBKLmpkLnByb3RvdHlwZQpp
-Zih0eXBlb2YgYSE9Im9iamVjdCIpe2lmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBKLmM1LnBy
-b3RvdHlwZQpyZXR1cm4gYX1pZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4gYQpyZXR1cm4gSi5rcyhh
-KX0sClU2OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5
-cGUKaWYoYT09bnVsbClyZXR1cm4gYQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5w
-cm90b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1
-cm4gSi5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIGEKcmV0
-dXJuIEoua3MoYSl9LApZRTpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJldHVybiBhCmlmKHR5cGVvZiBh
-IT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJl
-dHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLk1oKXJldHVybiBhCnJldHVybiBKLmtzKGEpfSwKaWE6ZnVu
-Y3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXtpZihNYXRoLmZsb29yKGEpPT1hKXJldHVybiBK
-LnVyLnByb3RvdHlwZQpyZXR1cm4gSi5WQS5wcm90b3R5cGV9aWYodHlwZW9mIGE9PSJzdHJpbmciKXJl
-dHVybiBKLkRyLnByb3RvdHlwZQppZihhPT1udWxsKXJldHVybiBKLndlLnByb3RvdHlwZQppZih0eXBl
-b2YgYT09ImJvb2xlYW4iKXJldHVybiBKLnlFLnByb3RvdHlwZQppZihhLmNvbnN0cnVjdG9yPT1BcnJh
-eSlyZXR1cm4gSi5qZC5wcm90b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09
-ImZ1bmN0aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAu
-TWgpcmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LApyWTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09InN0
-cmluZyIpcmV0dXJuIEouRHIucHJvdG90eXBlCmlmKGE9PW51bGwpcmV0dXJuIGEKaWYoIShhIGluc3Rh
-bmNlb2YgUC5NaCkpcmV0dXJuIEoua2QucHJvdG90eXBlCnJldHVybiBhfSwKdzE6ZnVuY3Rpb24oYSl7
-aWYoYT09bnVsbClyZXR1cm4gYQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5wcm90
-b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4g
-Si5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIGEKcmV0dXJu
-IEoua3MoYSl9LApDTTpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gSi5ZRShhKS5kdShhLGIsYyxkKX0s
-CkVoOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi5ZRShhKS5tSyhhLGIsYyl9LApGTDpmdW5jdGlvbihh
-LGIpe3JldHVybiBKLnJZKGEpLmRkKGEsYil9LApHQTpmdW5jdGlvbihhLGIpe3JldHVybiBKLncxKGEp
-LkUoYSxiKX0sCkdyOmZ1bmN0aW9uKGEpe3JldHVybiBKLllFKGEpLmdtVyhhKX0sCkhtOmZ1bmN0aW9u
-KGEpe3JldHVybiBKLlU2KGEpLmdBKGEpfSwKSVQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEoudzEoYSkuZ2t6
-KGEpfSwKSnk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5pYShhKS5lNyhhLGIpfSwKS1Y6ZnVuY3Rpb24o
-YSxiKXtyZXR1cm4gSi5yWShhKS5HKGEsYil9LApMdDpmdW5jdGlvbihhKXtyZXR1cm4gSi5ZRShhKS53
-ZyhhKX0sCk0xOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi53MShhKS5FMihhLGIsYyl9LApRejpmdW5j
-dGlvbihhLGIpe3JldHVybiBKLnJZKGEpLlcoYSxiKX0sClJNOmZ1bmN0aW9uKGEsYil7aWYoYT09bnVs
-bClyZXR1cm4gYj09bnVsbAppZih0eXBlb2YgYSE9Im9iamVjdCIpcmV0dXJuIGIhPW51bGwmJmE9PT1i
-CnJldHVybiBKLmlhKGEpLkROKGEsYil9LApUMDpmdW5jdGlvbihhKXtyZXR1cm4gSi5yWShhKS5iUyhh
-KX0sCmE2OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkubShhLGIpfSwKYlQ6ZnVuY3Rpb24oYSl7
-cmV0dXJuIEouWUUoYSkuRDQoYSl9LApiYjpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBhPT0ibnVtYmVy
-IiYmdHlwZW9mIGI9PSJudW1iZXIiKXJldHVybiBhK2IKcmV0dXJuIEouVEooYSkuaChhLGIpfSwKY0g6
-ZnVuY3Rpb24oYSl7cmV0dXJuIEouclkoYSkuaGMoYSl9LApkUjpmdW5jdGlvbihhKXtyZXR1cm4gSi5Z
-RShhKS5nUChhKX0sCmRaOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBKLllFKGEpLk9uKGEsYixjLGQp
-fSwKZGc6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIEouclkoYSkuaTcoYSxiLGMsZCl9LApkaDpmdW5j
-dGlvbihhKXtyZXR1cm4gSi5ZRShhKS5GRihhKX0sCmRyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouWUUo
-YSkuc2E0KGEsYil9LApoZjpmdW5jdGlvbihhKXtyZXR1cm4gSi5pYShhKS5naU8oYSl9LAppZzpmdW5j
-dGlvbihhKXtyZXR1cm4gSi5ZRShhKS5nUWcoYSl9LApqOmZ1bmN0aW9uKGEpe3JldHVybiBKLmlhKGEp
-LncoYSl9LApsNTpmdW5jdGlvbihhLGIpe3JldHVybiBKLllFKGEpLnNoZihhLGIpfSwKbGQ6ZnVuY3Rp
-b24oYSxiLGMpe3JldHVybiBKLnJZKGEpLk5qKGEsYixjKX0sCnA0OmZ1bmN0aW9uKGEsYil7cmV0dXJu
-IEouclkoYSkuVGMoYSxiKX0sCnEwOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi5yWShhKS5RaShhLGIs
-Yyl9LApxRjpmdW5jdGlvbihhKXtyZXR1cm4gSi5ZRShhKS5nVmwoYSl9LAp0SDpmdW5jdGlvbihhLGIs
-Yyl7cmV0dXJuIEouWUUoYSkucGsoYSxiLGMpfSwKd2Y6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5ZRShh
-KS5zUk4oYSxiKX0sCng5OmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGI9PT0ibnVtYmVyIilpZihhLmNv
-bnN0cnVjdG9yPT1BcnJheXx8dHlwZW9mIGE9PSJzdHJpbmcifHxILndWKGEsYVt2LmRpc3BhdGNoUHJv
-cGVydHlOYW1lXSkpaWYoYj4+PjA9PT1iJiZiPGEubGVuZ3RoKXJldHVybiBhW2JdCnJldHVybiBKLlU2
-KGEpLnEoYSxiKX0sCnpsOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouVTYoYSkudGcoYSxiKX0sCnZCOmZ1
-bmN0aW9uIHZCKCl7fSwKeUU6ZnVuY3Rpb24geUUoKXt9LAp3ZTpmdW5jdGlvbiB3ZSgpe30sCk1GOmZ1
-bmN0aW9uIE1GKCl7fSwKaUM6ZnVuY3Rpb24gaUMoKXt9LAprZDpmdW5jdGlvbiBrZCgpe30sCmM1OmZ1
-bmN0aW9uIGM1KCl7fSwKamQ6ZnVuY3Rpb24gamQoYSl7dGhpcy4kdGk9YX0sClBvOmZ1bmN0aW9uIFBv
-KGEpe3RoaXMuJHRpPWF9LAptMTpmdW5jdGlvbiBtMShhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9
-YgpfLmM9MApfLmQ9bnVsbApfLiR0aT1jfSwKcUk6ZnVuY3Rpb24gcUkoKXt9LAp1cjpmdW5jdGlvbiB1
-cigpe30sClZBOmZ1bmN0aW9uIFZBKCl7fSwKRHI6ZnVuY3Rpb24gRHIoKXt9fSxQPXsKT2o6ZnVuY3Rp
-b24oKXt2YXIgdCxzLHI9e30KaWYoc2VsZi5zY2hlZHVsZUltbWVkaWF0ZSE9bnVsbClyZXR1cm4gUC5F
-WCgpCmlmKHNlbGYuTXV0YXRpb25PYnNlcnZlciE9bnVsbCYmc2VsZi5kb2N1bWVudCE9bnVsbCl7dD1z
-ZWxmLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpCnM9c2VsZi5kb2N1bWVudC5jcmVhdGVFbGVt
-ZW50KCJzcGFuIikKci5hPW51bGwKbmV3IHNlbGYuTXV0YXRpb25PYnNlcnZlcihILnRSKG5ldyBQLnRo
-KHIpLDEpKS5vYnNlcnZlKHQse2NoaWxkTGlzdDp0cnVlfSkKcmV0dXJuIG5ldyBQLmhhKHIsdCxzKX1l
-bHNlIGlmKHNlbGYuc2V0SW1tZWRpYXRlIT1udWxsKXJldHVybiBQLnl0KCkKcmV0dXJuIFAucVcoKX0s
-ClpWOmZ1bmN0aW9uKGEpe3NlbGYuc2NoZWR1bGVJbW1lZGlhdGUoSC50UihuZXcgUC5Wcyh1Lk0uYShh
-KSksMCkpfSwKb0E6ZnVuY3Rpb24oYSl7c2VsZi5zZXRJbW1lZGlhdGUoSC50UihuZXcgUC5GdCh1Lk0u
-YShhKSksMCkpfSwKQno6ZnVuY3Rpb24oYSl7dS5NLmEoYSkKUC5RTigwLGEpfSwKUU46ZnVuY3Rpb24o
-YSxiKXt2YXIgdD1uZXcgUC5XMygpCnQuQ1koYSxiKQpyZXR1cm4gdH0sCkZYOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBuZXcgUC5paChuZXcgUC52cygkLlgzLGEuQygidnM8MD4iKSksYS5DKCJpaDwwPiIpKX0sCkRJ
-OmZ1bmN0aW9uKGEsYil7YS4kMigwLG51bGwpCmIuYj0hMApyZXR1cm4gYi5hfSwKalE6ZnVuY3Rpb24o
-YSxiKXtQLkplKGEsYil9LAp5QzpmdW5jdGlvbihhLGIpe2IuYU0oMCxhKX0sCmYzOmZ1bmN0aW9uKGEs
-Yil7Yi53MChILlJ1KGEpLEgudHMoYSkpfSwKSmU6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9bmV3IFAu
-V00oYikscT1uZXcgUC5TWChiKQppZihhIGluc3RhbmNlb2YgUC52cylhLlFkKHIscSx1LnopCmVsc2V7
-dD11LnoKaWYodS5kLmIoYSkpYS5TcShyLHEsdCkKZWxzZXtzPW5ldyBQLnZzKCQuWDMsdS5jKQpzLmE9
-NApzLmM9YQpzLlFkKHIscSx0KX19fSwKbHo6ZnVuY3Rpb24oYSl7dmFyIHQ9ZnVuY3Rpb24oYixjKXty
-ZXR1cm4gZnVuY3Rpb24oZCxlKXt3aGlsZSh0cnVlKXRyeXtiKGQsZSkKYnJlYWt9Y2F0Y2gocyl7ZT1z
-CmQ9Y319fShhLDEpCnJldHVybiAkLlgzLkxqKG5ldyBQLkdzKHQpLHUuUCx1LlMsdS56KX0sCkdROmZ1
-bmN0aW9uKGEpe3JldHVybiBuZXcgUC5GeShhLDEpfSwKVGg6ZnVuY3Rpb24oKXtyZXR1cm4gQy53UX0s
-ClltOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5GeShhLDMpfSwKbDA6ZnVuY3Rpb24oYSxiKXtyZXR1
-cm4gbmV3IFAucTQoYSxiLkMoInE0PDA+IikpfSwKazM6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIKYi5h
-PTEKdHJ5e2EuU3EobmV3IFAucFYoYiksbmV3IFAuVTcoYiksdS5QKX1jYXRjaChyKXt0PUguUnUocikK
-cz1ILnRzKHIpClAucmIobmV3IFAudnIoYix0LHMpKX19LApBOTpmdW5jdGlvbihhLGIpe3ZhciB0LHMs
-cgpmb3IodD11LmM7cz1hLmEscz09PTI7KWE9dC5hKGEuYykKaWYocz49NCl7cj1iLmFoKCkKYi5hPWEu
-YQpiLmM9YS5jClAuSFooYixyKX1lbHNle3I9dS5GLmEoYi5jKQpiLmE9MgpiLmM9YQphLmpRKHIpfX0s
-CkhaOmZ1bmN0aW9uKGEsYTApe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQ9bnVs
-bCxjPXt9LGI9Yy5hPWEKZm9yKHQ9dS5uLHM9dS5GLHI9dS5kOyEwOyl7cT17fQpwPWIuYT09PTgKaWYo
-YTA9PW51bGwpe2lmKHApe289dC5hKGIuYykKUC5MMihkLGQsYi5iLG8uYSxvLmIpfXJldHVybn1xLmE9
-YTAKbj1hMC5hCmZvcihiPWEwO24hPW51bGw7Yj1uLG49bSl7Yi5hPW51bGwKUC5IWihjLmEsYikKcS5h
-PW4KbT1uLmF9bD1jLmEKaz1sLmMKcS5iPXAKcS5jPWsKaj0hcAppZihqKXtpPWIuYwppPShpJjEpIT09
-MHx8KGkmMTUpPT09OH1lbHNlIGk9ITAKaWYoaSl7aD1iLmIuYgppZihwKXtpPWwuYj09PWgKaT0hKGl8
-fGkpfWVsc2UgaT0hMQppZihpKXt0LmEoaykKUC5MMihkLGQsbC5iLGsuYSxrLmIpCnJldHVybn1nPSQu
-WDMKaWYoZyE9PWgpJC5YMz1oCmVsc2UgZz1kCmI9Yi5jCmlmKChiJjE1KT09PTgpbmV3IFAuUlQocSxj
-LHApLiQwKCkKZWxzZSBpZihqKXtpZigoYiYxKSE9PTApbmV3IFAucnEocSxrKS4kMCgpfWVsc2UgaWYo
-KGImMikhPT0wKW5ldyBQLlJXKGMscSkuJDAoKQppZihnIT1udWxsKSQuWDM9ZwpiPXEuYwppZihyLmIo
-Yikpe2Y9cS5hLmIKaWYoYi5hPj00KXtlPXMuYShmLmMpCmYuYz1udWxsCmEwPWYuTjgoZSkKZi5hPWIu
-YQpmLmM9Yi5jCmMuYT1iCmNvbnRpbnVlfWVsc2UgUC5BOShiLGYpCnJldHVybn19Zj1xLmEuYgplPXMu
-YShmLmMpCmYuYz1udWxsCmEwPWYuTjgoZSkKYj1xLmIKbD1xLmMKaWYoIWIpe2YuJHRpLmMuYShsKQpm
-LmE9NApmLmM9bH1lbHNle3QuYShsKQpmLmE9OApmLmM9bH1jLmE9ZgpiPWZ9fSwKVkg6ZnVuY3Rpb24o
-YSxiKXt2YXIgdAppZih1LmFnLmIoYSkpcmV0dXJuIGIuTGooYSx1LnosdS5LLHUubCkKdD11LmJJCmlm
-KHQuYihhKSlyZXR1cm4gdC5hKGEpCnRocm93IEguYihQLkwzKGEsIm9uRXJyb3IiLCJFcnJvciBoYW5k
-bGVyIG11c3QgYWNjZXB0IG9uZSBPYmplY3Qgb3Igb25lIE9iamVjdCBhbmQgYSBTdGFja1RyYWNlIGFz
-IGFyZ3VtZW50cywgYW5kIHJldHVybiBhIGEgdmFsaWQgcmVzdWx0IikpfSwKcHU6ZnVuY3Rpb24oKXt2
-YXIgdCxzCmZvcih0PSQuUzY7dCE9bnVsbDt0PSQuUzYpeyQubWc9bnVsbApzPXQuYgokLlM2PXMKaWYo
-cz09bnVsbCkkLms4PW51bGwKdC5hLiQwKCl9fSwKZU46ZnVuY3Rpb24oKXskLlVEPSEwCnRyeXtQLnB1
-KCl9ZmluYWxseXskLm1nPW51bGwKJC5VRD0hMQppZigkLlM2IT1udWxsKSQudXQoKS4kMShQLlY5KCkp
-fX0sCmVXOmZ1bmN0aW9uKGEpe3ZhciB0PW5ldyBQLk9NKGEpLHM9JC5rOAppZihzPT1udWxsKXskLlM2
-PSQuazg9dAppZighJC5VRCkkLnV0KCkuJDEoUC5WOSgpKX1lbHNlICQuazg9cy5iPXR9LApyUjpmdW5j
-dGlvbihhKXt2YXIgdCxzLHIscT0kLlM2CmlmKHE9PW51bGwpe1AuZVcoYSkKJC5tZz0kLms4CnJldHVy
-bn10PW5ldyBQLk9NKGEpCnM9JC5tZwppZihzPT1udWxsKXt0LmI9cQokLlM2PSQubWc9dH1lbHNle3I9
-cy5iCnQuYj1yCiQubWc9cy5iPXQKaWYocj09bnVsbCkkLms4PXR9fSwKcmI6ZnVuY3Rpb24oYSl7dmFy
-IHQ9bnVsbCxzPSQuWDMKaWYoQy5OVT09PXMpe1AuVGsodCx0LEMuTlUsYSkKcmV0dXJufVAuVGsodCx0
-LHMsdS5NLmEocy5HWShhKSkpfSwKUXc6ZnVuY3Rpb24oYSxiKXtQLlVJKGEsInN0cmVhbSIsYi5DKCJx
-aDwwPiIpKQpyZXR1cm4gbmV3IFAueEkoYi5DKCJ4STwwPiIpKX0sClRsOmZ1bmN0aW9uKGEsYil7dmFy
-IHQ9Yj09bnVsbD9QLnYwKGEpOmIKUC5VSShhLCJlcnJvciIsdS5LKQpyZXR1cm4gbmV3IFAuQ3coYSx0
-KX0sCnYwOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKHUuVy5iKGEpKXt0PWEuZ0lJKCkKaWYodCE9bnVsbCly
-ZXR1cm4gdH1yZXR1cm4gQy5wZH0sCkwyOmZ1bmN0aW9uKGEsYixjLGQsZSl7UC5yUihuZXcgUC5wSyhk
-LGUpKX0sClQ4OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVybiBk
-LiQwKCkKJC5YMz1jCnQ9cwp0cnl7cz1kLiQwKCkKcmV0dXJuIHN9ZmluYWxseXskLlgzPXR9fSwKeXY6
-ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQxKGUp
-CiQuWDM9Ywp0PXMKdHJ5e3M9ZC4kMShlKQpyZXR1cm4gc31maW5hbGx5eyQuWDM9dH19LApReDpmdW5j
-dGlvbihhLGIsYyxkLGUsZixnLGgsaSl7dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQyKGUs
-ZikKJC5YMz1jCnQ9cwp0cnl7cz1kLiQyKGUsZikKcmV0dXJuIHN9ZmluYWxseXskLlgzPXR9fSwKVGs6
-ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQKdS5NLmEoZCkKdD1DLk5VIT09YwppZih0KWQ9ISghdHx8ITEp
-P2MuR1koZCk6Yy5SVChkLHUuSCkKUC5lVyhkKX0sCnRoOmZ1bmN0aW9uIHRoKGEpe3RoaXMuYT1hfSwK
-aGE6ZnVuY3Rpb24gaGEoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKVnM6ZnVuY3Rp
-b24gVnMoYSl7dGhpcy5hPWF9LApGdDpmdW5jdGlvbiBGdChhKXt0aGlzLmE9YX0sClczOmZ1bmN0aW9u
-IFczKCl7fSwKeUg6ZnVuY3Rpb24geUgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCmloOmZ1bmN0aW9u
-IGloKGEsYil7dGhpcy5hPWEKdGhpcy5iPSExCnRoaXMuJHRpPWJ9LApXTTpmdW5jdGlvbiBXTShhKXt0
-aGlzLmE9YX0sClNYOmZ1bmN0aW9uIFNYKGEpe3RoaXMuYT1hfSwKR3M6ZnVuY3Rpb24gR3MoYSl7dGhp
-cy5hPWF9LApGeTpmdW5jdGlvbiBGeShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKR1Y6ZnVuY3Rpb24g
-R1YoYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uZD1fLmM9Xy5iPW51bGwKXy4kdGk9Yn0sCnE0OmZ1bmN0
-aW9uIHE0KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCmI4OmZ1bmN0aW9uIGI4KCl7fSwKUGY6ZnVu
-Y3Rpb24gUGYoKXt9LApaZjpmdW5jdGlvbiBaZihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApGZTpm
-dW5jdGlvbiBGZShhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5hPW51bGwKXy5iPWEKXy5jPWIKXy5kPWMK
-Xy5lPWQKXy4kdGk9ZX0sCnZzOmZ1bmN0aW9uIHZzKGEsYil7dmFyIF89dGhpcwpfLmE9MApfLmI9YQpf
-LmM9bnVsbApfLiR0aT1ifSwKZGE6ZnVuY3Rpb24gZGEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCm9R
-OmZ1bmN0aW9uIG9RKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApwVjpmdW5jdGlvbiBwVihhKXt0aGlz
-LmE9YX0sClU3OmZ1bmN0aW9uIFU3KGEpe3RoaXMuYT1hfSwKdnI6ZnVuY3Rpb24gdnIoYSxiLGMpe3Ro
-aXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKcnQ6ZnVuY3Rpb24gcnQoYSxiKXt0aGlzLmE9YQp0aGlz
-LmI9Yn0sCktGOmZ1bmN0aW9uIEtGKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApaTDpmdW5jdGlvbiBa
-TChhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApSVDpmdW5jdGlvbiBSVChhLGIsYyl7
-dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApqWjpmdW5jdGlvbiBqWihhKXt0aGlzLmE9YX0sCnJx
-OmZ1bmN0aW9uIHJxKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApSVzpmdW5jdGlvbiBSVyhhLGIpe3Ro
-aXMuYT1hCnRoaXMuYj1ifSwKT006ZnVuY3Rpb24gT00oYSl7dGhpcy5hPWEKdGhpcy5iPW51bGx9LApx
-aDpmdW5jdGlvbiBxaCgpe30sCkI1OmZ1bmN0aW9uIEI1KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp1
-TzpmdW5jdGlvbiB1TyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKTU86ZnVuY3Rpb24gTU8oKXt9LApr
-VDpmdW5jdGlvbiBrVCgpe30sCnhJOmZ1bmN0aW9uIHhJKGEpe3RoaXMuJHRpPWF9LApDdzpmdW5jdGlv
-biBDdyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKbTA6ZnVuY3Rpb24gbTAoKXt9LApwSzpmdW5jdGlv
-biBwSyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKSmk6ZnVuY3Rpb24gSmkoKXt9LApoajpmdW5jdGlv
-biBoaihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApWcDpmdW5jdGlvbiBWcChhLGIp
-e3RoaXMuYT1hCnRoaXMuYj1ifSwKT1I6ZnVuY3Rpb24gT1IoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1i
-CnRoaXMuYz1jfSwKRUY6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBiLkMoIkA8MD4iKS5LcShjKS5DKCJG
-bzwxLDI+IikuYShILkI3KGEsbmV3IEguTjUoYi5DKCJAPDA+IikuS3EoYykuQygiTjU8MSwyPiIpKSkp
-fSwKRmw6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEguTjUoYS5DKCJAPDA+IikuS3EoYikuQygiTjU8
-MSwyPiIpKX0sCkxzOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5iNihhLkMoImI2PDA+IikpfSwKVDI6
-ZnVuY3Rpb24oKXt2YXIgdD1PYmplY3QuY3JlYXRlKG51bGwpCnRbIjxub24taWRlbnRpZmllci1rZXk+
-Il09dApkZWxldGUgdFsiPG5vbi1pZGVudGlmaWVyLWtleT4iXQpyZXR1cm4gdH0sCnJqOmZ1bmN0aW9u
-KGEsYixjKXt2YXIgdD1uZXcgUC5sbShhLGIsYy5DKCJsbTwwPiIpKQp0LmM9YS5lCnJldHVybiB0fSwK
-RVA6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMKaWYoUC5oQihhKSl7aWYoYj09PSIoIiYmYz09PSIpIily
-ZXR1cm4iKC4uLikiCnJldHVybiBiKyIuLi4iK2N9dD1ILlZNKFtdLHUucykKQy5ObS5pKCQueGcsYSkK
-dHJ5e1AuVnIoYSx0KX1maW5hbGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILk9IKCQueGcsLTEp
-CiQueGcucG9wKCl9cz1QLnZnKGIsdS5tLmEodCksIiwgIikrYwpyZXR1cm4gcy5jaGFyQ29kZUF0KDAp
-PT0wP3M6c30sCldFOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzCmlmKFAuaEIoYSkpcmV0dXJuIGIrIi4u
-LiIrYwp0PW5ldyBQLlJuKGIpCkMuTm0uaSgkLnhnLGEpCnRyeXtzPXQKcy5hPVAudmcocy5hLGEsIiwg
-Iil9ZmluYWxseXtpZigwPj0kLnhnLmxlbmd0aClyZXR1cm4gSC5PSCgkLnhnLC0xKQokLnhnLnBvcCgp
-fXQuYSs9YwpzPXQuYQpyZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c30sCmhCOmZ1bmN0aW9uKGEp
-e3ZhciB0LHMKZm9yKHQ9JC54Zy5sZW5ndGgscz0wO3M8dDsrK3MpaWYoYT09PSQueGdbc10pcmV0dXJu
-ITAKcmV0dXJuITF9LApWcjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuLG09YS5na3ooYSks
-bD0wLGs9MAp3aGlsZSghMCl7aWYoIShsPDgwfHxrPDMpKWJyZWFrCmlmKCFtLkYoKSlyZXR1cm4KdD1I
-LkVqKG0uZ2woKSkKQy5ObS5pKGIsdCkKbCs9dC5sZW5ndGgrMjsrK2t9aWYoIW0uRigpKXtpZihrPD01
-KXJldHVybgppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5PSChiLC0xKQpzPWIucG9wKCkKaWYoMD49Yi5s
-ZW5ndGgpcmV0dXJuIEguT0goYiwtMSkKcj1iLnBvcCgpfWVsc2V7cT1tLmdsKCk7KytrCmlmKCFtLkYo
-KSl7aWYoazw9NCl7Qy5ObS5pKGIsSC5FaihxKSkKcmV0dXJufXM9SC5FaihxKQppZigwPj1iLmxlbmd0
-aClyZXR1cm4gSC5PSChiLC0xKQpyPWIucG9wKCkKbCs9cy5sZW5ndGgrMn1lbHNle3A9bS5nbCgpOysr
-awpmb3IoO20uRigpO3E9cCxwPW8pe289bS5nbCgpOysrawppZihrPjEwMCl7d2hpbGUoITApe2lmKCEo
-bD43NSYmaz4zKSlicmVhawppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5PSChiLC0xKQpsLT1iLnBvcCgp
-Lmxlbmd0aCsyOy0ta31DLk5tLmkoYiwiLi4uIikKcmV0dXJufX1yPUguRWoocSkKcz1ILkVqKHApCmwr
-PXMubGVuZ3RoK3IubGVuZ3RoKzR9fWlmKGs+Yi5sZW5ndGgrMil7bCs9NQpuPSIuLi4ifWVsc2Ugbj1u
-dWxsCndoaWxlKCEwKXtpZighKGw+ODAmJmIubGVuZ3RoPjMpKWJyZWFrCmlmKDA+PWIubGVuZ3RoKXJl
-dHVybiBILk9IKGIsLTEpCmwtPWIucG9wKCkubGVuZ3RoKzIKaWYobj09bnVsbCl7bCs9NQpuPSIuLi4i
-fX1pZihuIT1udWxsKUMuTm0uaShiLG4pCkMuTm0uaShiLHIpCkMuTm0uaShiLHMpfSwKdE06ZnVuY3Rp
-b24oYSxiKXt2YXIgdCxzLHI9UC5McyhiKQpmb3IodD1hLmxlbmd0aCxzPTA7czxhLmxlbmd0aDthLmxl
-bmd0aD09PXR8fCgwLEgubGspKGEpLCsrcylyLmkoMCxiLmEoYVtzXSkpCnJldHVybiByfSwKbk86ZnVu
-Y3Rpb24oYSl7dmFyIHQscz17fQppZihQLmhCKGEpKXJldHVybiJ7Li4ufSIKdD1uZXcgUC5SbigiIikK
-dHJ5e0MuTm0uaSgkLnhnLGEpCnQuYSs9InsiCnMuYT0hMAphLksoMCxuZXcgUC5yYShzLHQpKQp0LmEr
-PSJ9In1maW5hbGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILk9IKCQueGcsLTEpCiQueGcucG9w
-KCl9cz10LmEKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9LApiNjpmdW5jdGlvbiBiNihhKXt2
-YXIgXz10aGlzCl8uYT0wCl8uZj1fLmU9Xy5kPV8uYz1fLmI9bnVsbApfLnI9MApfLiR0aT1hfSwKYm46
-ZnVuY3Rpb24gYm4oYSl7dGhpcy5hPWEKdGhpcy5jPXRoaXMuYj1udWxsfSwKbG06ZnVuY3Rpb24gbG0o
-YSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPV8uYz1udWxsCl8uJHRpPWN9LAptVzpmdW5j
-dGlvbiBtVygpe30sCkxVOmZ1bmN0aW9uIExVKCl7fSwKbEQ6ZnVuY3Rpb24gbEQoKXt9LAppbDpmdW5j
-dGlvbiBpbCgpe30sCnJhOmZ1bmN0aW9uIHJhKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApZazpmdW5j
-dGlvbiBZaygpe30sCnlROmZ1bmN0aW9uIHlRKGEpe3RoaXMuYT1hfSwKS1A6ZnVuY3Rpb24gS1AoKXt9
-LApQbjpmdW5jdGlvbiBQbigpe30sCkdqOmZ1bmN0aW9uIEdqKGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9
-Yn0sCk1hOmZ1bmN0aW9uIE1hKCl7fSwKVmo6ZnVuY3Rpb24gVmooKXt9LApYdjpmdW5jdGlvbiBYdigp
-e30sCm5ZOmZ1bmN0aW9uIG5ZKCl7fSwKV1k6ZnVuY3Rpb24gV1koKXt9LApSVTpmdW5jdGlvbiBSVSgp
-e30sCkJTOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEKaWYodHlwZW9mIGEhPSJzdHJpbmciKXRocm93
-IEguYihILnRMKGEpKQp0PW51bGwKdHJ5e3Q9SlNPTi5wYXJzZShhKX1jYXRjaChyKXtzPUguUnUocikK
-cT1QLnJyKFN0cmluZyhzKSxudWxsLG51bGwpCnRocm93IEguYihxKX1xPVAuUWUodCkKcmV0dXJuIHF9
-LApRZTpmdW5jdGlvbihhKXt2YXIgdAppZihhPT1udWxsKXJldHVybiBudWxsCmlmKHR5cGVvZiBhIT0i
-b2JqZWN0IilyZXR1cm4gYQppZihPYmplY3QuZ2V0UHJvdG90eXBlT2YoYSkhPT1BcnJheS5wcm90b3R5
-cGUpcmV0dXJuIG5ldyBQLnV3KGEsT2JqZWN0LmNyZWF0ZShudWxsKSkKZm9yKHQ9MDt0PGEubGVuZ3Ro
-OysrdClhW3RdPVAuUWUoYVt0XSkKcmV0dXJuIGF9LApreTpmdW5jdGlvbihhLGIsYyxkKXtpZihiIGlu
-c3RhbmNlb2YgVWludDhBcnJheSlyZXR1cm4gUC5DRyghMSxiLGMsZCkKcmV0dXJuIG51bGx9LApDRzpm
-dW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHI9JC5yZigpCmlmKHI9PW51bGwpcmV0dXJuIG51bGwKdD0w
-PT09YwppZih0JiYhMClyZXR1cm4gUC5PUShyLGIpCnM9Yi5sZW5ndGgKZD1QLmpCKGMsZCxzKQppZih0
-JiZkPT09cylyZXR1cm4gUC5PUShyLGIpCnJldHVybiBQLk9RKHIsYi5zdWJhcnJheShjLGQpKX0sCk9R
-OmZ1bmN0aW9uKGEsYil7aWYoUC5BaihiKSlyZXR1cm4gbnVsbApyZXR1cm4gUC5KaChhLGIpfSwKSmg6
-ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCnRyeXt0PWEuZGVjb2RlKGIpCnJldHVybiB0fWNhdGNoKHMpe0gu
-UnUocyl9cmV0dXJuIG51bGx9LApBajpmdW5jdGlvbihhKXt2YXIgdCxzPWEubGVuZ3RoLTIKZm9yKHQ9
-MDt0PHM7Kyt0KWlmKGFbdF09PT0yMzcpaWYoKGFbdCsxXSYyMjQpPT09MTYwKXJldHVybiEwCnJldHVy
-biExfSwKY1A6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscgpmb3IodD1KLlU2KGEpLHM9YjtzPGM7Kytz
-KXtyPXQucShhLHMpCmlmKHR5cGVvZiByIT09Im51bWJlciIpcmV0dXJuIHIuek0oKQppZigociYxMjcp
-IT09cilyZXR1cm4gcy1ifXJldHVybiBjLWJ9LAp4TTpmdW5jdGlvbihhLGIsYyxkLGUsZil7aWYoQy5q
-bi56WShmLDQpIT09MCl0aHJvdyBILmIoUC5ycigiSW52YWxpZCBiYXNlNjQgcGFkZGluZywgcGFkZGVk
-IGxlbmd0aCBtdXN0IGJlIG11bHRpcGxlIG9mIGZvdXIsIGlzICIrZixhLGMpKQppZihkK2UhPT1mKXRo
-cm93IEguYihQLnJyKCJJbnZhbGlkIGJhc2U2NCBwYWRkaW5nLCAnPScgbm90IGF0IHRoZSBlbmQiLGEs
-YikpCmlmKGU+Mil0aHJvdyBILmIoUC5ycigiSW52YWxpZCBiYXNlNjQgcGFkZGluZywgbW9yZSB0aGFu
-IHR3byAnPScgY2hhcmFjdGVycyIsYSxiKSl9LAp1dzpmdW5jdGlvbiB1dyhhLGIpe3RoaXMuYT1hCnRo
-aXMuYj1iCnRoaXMuYz1udWxsfSwKaTg6ZnVuY3Rpb24gaTgoYSl7dGhpcy5hPWF9LApwZzpmdW5jdGlv
-biBwZygpe30sCkNWOmZ1bmN0aW9uIENWKCl7fSwKVTg6ZnVuY3Rpb24gVTgoKXt9LApVazpmdW5jdGlv
-biBVaygpe30sCndJOmZ1bmN0aW9uIHdJKCl7fSwKWmk6ZnVuY3Rpb24gWmkoKXt9LApieTpmdW5jdGlv
-biBieSgpe30sCk14OmZ1bmN0aW9uIE14KGEpe3RoaXMuYT1hfSwKdTU6ZnVuY3Rpb24gdTUoKXt9LApF
-MzpmdW5jdGlvbiBFMygpe30sClJ3OmZ1bmN0aW9uIFJ3KGEpe3RoaXMuYj0wCnRoaXMuYz1hfSwKR1k6
-ZnVuY3Rpb24gR1koYSl7dGhpcy5hPWF9LApiejpmdW5jdGlvbiBieihhLGIpe3ZhciBfPXRoaXMKXy5h
-PWEKXy5iPWIKXy5jPSEwCl8uZj1fLmU9Xy5kPTB9LApRQTpmdW5jdGlvbihhLGIpe3ZhciB0PUguSHAo
-YSxiKQppZih0IT1udWxsKXJldHVybiB0CnRocm93IEguYihQLnJyKGEsbnVsbCxudWxsKSl9LApGOmZ1
-bmN0aW9uKGEpe2lmKGEgaW5zdGFuY2VvZiBILnYpcmV0dXJuIGEudygwKQpyZXR1cm4iSW5zdGFuY2Ug
-b2YgJyIrSC5FaihILk0oYSkpKyInIn0sCk84OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHM9Si5RaShh
-LGQpCmlmKGEhPT0wJiZiIT1udWxsKWZvcih0PTA7dDxzLmxlbmd0aDsrK3Qpc1t0XT1iCnJldHVybiBz
-fSwKQ0g6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9SC5WTShbXSxjLkMoImpkPDA+IikpCmZvcih0PUou
-SVQoYSk7dC5GKCk7KUMuTm0uaShzLGMuYSh0LmdsKCkpKQppZihiKXJldHVybiBzCnJldHVybiBKLkVw
-KHMsYyl9LApkSDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzPUouS2goYSxkKQpmb3IodD0wO3Q8YTsr
-K3QpQy5ObS5ZKHMsdCxiLiQxKHQpKQpyZXR1cm4gc30sCkFGOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEou
-ekMoUC5DSChhLCExLGIpKX0sCkhNOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzCmlmKEFycmF5LmlzQXJy
-YXkoYSkpe3Q9YQpzPXQubGVuZ3RoCmM9UC5qQihiLGMscykKcmV0dXJuIEguZVQoYj4wfHxjPHM/dC5z
-bGljZShiLGMpOnQpfWlmKHUuYm0uYihhKSlyZXR1cm4gSC5mdyhhLGIsUC5qQihiLGMsYS5sZW5ndGgp
-KQpyZXR1cm4gUC5idyhhLGIsYyl9LApPbzpmdW5jdGlvbihhKXtyZXR1cm4gSC5MdyhhKX0sCmJ3OmZ1
-bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwPW51bGwKaWYoYjwwKXRocm93IEguYihQLlRFKGIsMCxK
-LkhtKGEpLHAscCkpCnQ9Yz09bnVsbAppZighdCYmYzxiKXRocm93IEguYihQLlRFKGMsYixKLkhtKGEp
-LHAscCkpCnM9Si5JVChhKQpmb3Iocj0wO3I8YjsrK3IpaWYoIXMuRigpKXRocm93IEguYihQLlRFKGIs
-MCxyLHAscCkpCnE9W10KaWYodClmb3IoO3MuRigpOylxLnB1c2gocy5nbCgpKQplbHNlIGZvcihyPWI7
-cjxjOysrcil7aWYoIXMuRigpKXRocm93IEguYihQLlRFKGMsYixyLHAscCkpCnEucHVzaChzLmdsKCkp
-fXJldHVybiBILmVUKHEpfSwKbnU6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILlZSKGEsSC52NChhLCEx
-LCEwLCExLCExLCExKSl9LAp2ZzpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9Si5JVChiKQppZighdC5GKCkp
-cmV0dXJuIGEKaWYoYy5sZW5ndGg9PT0wKXtkbyBhKz1ILkVqKHQuZ2woKSkKd2hpbGUodC5GKCkpfWVs
-c2V7YSs9SC5Faih0LmdsKCkpCmZvcig7dC5GKCk7KWE9YStjK0guRWoodC5nbCgpKX1yZXR1cm4gYX0s
-CmxyOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBuZXcgUC5tcChhLGIsYyxkKX0sCnVvOmZ1bmN0aW9u
-KCl7dmFyIHQ9SC5NMCgpCmlmKHQhPW51bGwpcmV0dXJuIFAuaEsodCkKdGhyb3cgSC5iKFAuTDQoIidV
-cmkuYmFzZScgaXMgbm90IHN1cHBvcnRlZCIpKX0sCmVQOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMs
-cixxLHAsbyxuPSIwMTIzNDU2Nzg5QUJDREVGIgppZihjPT09Qy54TSl7dD0kLno0KCkuYgppZih0eXBl
-b2YgYiE9InN0cmluZyIpSC52aChILnRMKGIpKQp0PXQudGVzdChiKX1lbHNlIHQ9ITEKaWYodClyZXR1
-cm4gYgpILkxoKGMpLkMoIlVrLlMiKS5hKGIpCnM9Yy5nWkUoKS5XSihiKQpmb3IodD1zLmxlbmd0aCxy
-PTAscT0iIjtyPHQ7KytyKXtwPXNbcl0KaWYocDwxMjgpe289cD4+PjQKaWYobz49OClyZXR1cm4gSC5P
-SChhLG8pCm89KGFbb10mMTw8KHAmMTUpKSE9PTB9ZWxzZSBvPSExCmlmKG8pcSs9SC5MdyhwKQplbHNl
-IHE9ZCYmcD09PTMyP3ErIisiOnErIiUiK25bcD4+PjQmMTVdK25bcCYxNV19cmV0dXJuIHEuY2hhckNv
-ZGVBdCgwKT09MD9xOnF9LApHcTpmdW5jdGlvbihhKXt2YXIgdD1NYXRoLmFicyhhKSxzPWE8MD8iLSI6
-IiIKaWYodD49MTAwMClyZXR1cm4iIithCmlmKHQ+PTEwMClyZXR1cm4gcysiMCIrdAppZih0Pj0xMCly
-ZXR1cm4gcysiMDAiK3QKcmV0dXJuIHMrIjAwMCIrdH0sClZ4OmZ1bmN0aW9uKGEpe2lmKGE+PTEwMCly
-ZXR1cm4iIithCmlmKGE+PTEwKXJldHVybiIwIithCnJldHVybiIwMCIrYX0sCmgwOmZ1bmN0aW9uKGEp
-e2lmKGE+PTEwKXJldHVybiIiK2EKcmV0dXJuIjAiK2F9LApwOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBh
-PT0ibnVtYmVyInx8SC5sKGEpfHxudWxsPT1hKXJldHVybiBKLmooYSkKaWYodHlwZW9mIGE9PSJzdHJp
-bmciKXJldHVybiBKU09OLnN0cmluZ2lmeShhKQpyZXR1cm4gUC5GKGEpfSwKaFY6ZnVuY3Rpb24oYSl7
-cmV0dXJuIG5ldyBQLkM2KGEpfSwKeFk6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnUoITEsbnVsbCxu
-dWxsLGEpfSwKTDM6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBuZXcgUC51KCEwLGEsYixjKX0sClVJOmZ1
-bmN0aW9uKGEsYixjKXtpZihhPT1udWxsKXRocm93IEguYihuZXcgUC51KCExLG51bGwsYiwiTXVzdCBu
-b3QgYmUgbnVsbCIpKQpyZXR1cm4gYX0sCk83OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQLmJKKG51
-bGwsbnVsbCwhMCxhLGIsIlZhbHVlIG5vdCBpbiByYW5nZSIpfSwKVEU6ZnVuY3Rpb24oYSxiLGMsZCxl
-KXtyZXR1cm4gbmV3IFAuYkooYixjLCEwLGEsZCwiSW52YWxpZCB2YWx1ZSIpfSwKd0E6ZnVuY3Rpb24o
-YSxiLGMsZCl7aWYoYTxifHxhPmMpdGhyb3cgSC5iKFAuVEUoYSxiLGMsZCxudWxsKSkKcmV0dXJuIGF9
-LApqQjpmdW5jdGlvbihhLGIsYyl7aWYoMD5hfHxhPmMpdGhyb3cgSC5iKFAuVEUoYSwwLGMsInN0YXJ0
-IixudWxsKSkKaWYoYiE9bnVsbCl7aWYoYT5ifHxiPmMpdGhyb3cgSC5iKFAuVEUoYixhLGMsImVuZCIs
-bnVsbCkpCnJldHVybiBifXJldHVybiBjfSwKazE6ZnVuY3Rpb24oYSxiKXtpZihhPDApdGhyb3cgSC5i
-KFAuVEUoYSwwLG51bGwsYixudWxsKSkKcmV0dXJuIGF9LApDZjpmdW5jdGlvbihhLGIsYyxkLGUpe3Zh
-ciB0PUgudVAoZT09bnVsbD9KLkhtKGIpOmUpCnJldHVybiBuZXcgUC5lWSh0LCEwLGEsYywiSW5kZXgg
-b3V0IG9mIHJhbmdlIil9LApMNDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAudWIoYSl9LApTWTpmdW5j
-dGlvbihhKXtyZXR1cm4gbmV3IFAuZHMoYSl9LApQVjpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAubGoo
-YSl9LAphNDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuVVYoYSl9LApycjpmdW5jdGlvbihhLGIsYyl7
-cmV0dXJuIG5ldyBQLmFFKGEsYixjKX0sCmhLOmZ1bmN0aW9uKGE0KXt2YXIgdCxzLHIscSxwLG8sbixt
-LGwsayxqLGksaCxnLGYsZSxkLGMsYixhLGEwLGExLGEyPW51bGwsYTM9YTQubGVuZ3RoCmlmKGEzPj01
-KXt0PSgoSi5ReihhNCw0KV41OCkqM3xDLnhCLlcoYTQsMCleMTAwfEMueEIuVyhhNCwxKV45N3xDLnhC
-LlcoYTQsMileMTE2fEMueEIuVyhhNCwzKV45Nyk+Pj4wCmlmKHQ9PT0wKXJldHVybiBQLktEKGEzPGEz
-P0MueEIuTmooYTQsMCxhMyk6YTQsNSxhMikuZ2xSKCkKZWxzZSBpZih0PT09MzIpcmV0dXJuIFAuS0Qo
-Qy54Qi5OaihhNCw1LGEzKSwwLGEyKS5nbFIoKX1zPVAuTzgoOCwwLCExLHUuUykKQy5ObS5ZKHMsMCww
-KQpDLk5tLlkocywxLC0xKQpDLk5tLlkocywyLC0xKQpDLk5tLlkocyw3LC0xKQpDLk5tLlkocywzLDAp
-CkMuTm0uWShzLDQsMCkKQy5ObS5ZKHMsNSxhMykKQy5ObS5ZKHMsNixhMykKaWYoUC5VQihhNCwwLGEz
-LDAscyk+PTE0KUMuTm0uWShzLDcsYTMpCmlmKDE+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsMSkKcj1z
-WzFdCmlmKHI+PTApaWYoUC5VQihhNCwwLHIsMjAscyk9PT0yMCl7aWYoNz49cy5sZW5ndGgpcmV0dXJu
-IEguT0gocyw3KQpzWzddPXJ9cT1zLmxlbmd0aAppZigyPj1xKXJldHVybiBILk9IKHMsMikKcD1zWzJd
-KzEKaWYoMz49cSlyZXR1cm4gSC5PSChzLDMpCm89c1szXQppZig0Pj1xKXJldHVybiBILk9IKHMsNCkK
-bj1zWzRdCmlmKDU+PXEpcmV0dXJuIEguT0gocyw1KQptPXNbNV0KaWYoNj49cSlyZXR1cm4gSC5PSChz
-LDYpCmw9c1s2XQppZihsPG0pbT1sCmlmKG48cCluPW0KZWxzZSBpZihuPD1yKW49cisxCmlmKG88cClv
-PW4KaWYoNz49cSlyZXR1cm4gSC5PSChzLDcpCms9c1s3XTwwCmlmKGspaWYocD5yKzMpe2o9YTIKaz0h
-MX1lbHNle3E9bz4wCmlmKHEmJm8rMT09PW4pe2o9YTIKaz0hMX1lbHNle2lmKCEobTxhMyYmbT09PW4r
-MiYmSi5xMChhNCwiLi4iLG4pKSlpPW0+bisyJiZKLnEwKGE0LCIvLi4iLG0tMykKZWxzZSBpPSEwCmlm
-KGkpe2o9YTIKaz0hMX1lbHNle2lmKHI9PT00KWlmKEoucTAoYTQsImZpbGUiLDApKXtpZihwPD0wKXtp
-ZighQy54Qi5RaShhNCwiLyIsbikpe2g9ImZpbGU6Ly8vIgp0PTN9ZWxzZXtoPSJmaWxlOi8vIgp0PTJ9
-YTQ9aCtDLnhCLk5qKGE0LG4sYTMpCnItPTAKcT10LTAKbSs9cQpsKz1xCmEzPWE0Lmxlbmd0aApwPTcK
-bz03Cm49N31lbHNlIGlmKG49PT1tKXsrK2wKZz1tKzEKYTQ9Qy54Qi5pNyhhNCxuLG0sIi8iKTsrK2Ez
-Cm09Z31qPSJmaWxlIn1lbHNlIGlmKEMueEIuUWkoYTQsImh0dHAiLDApKXtpZihxJiZvKzM9PT1uJiZD
-LnhCLlFpKGE0LCI4MCIsbysxKSl7bC09MwpmPW4tMwptLT0zCmE0PUMueEIuaTcoYTQsbyxuLCIiKQph
-My09MwpuPWZ9aj0iaHR0cCJ9ZWxzZSBqPWEyCmVsc2UgaWYocj09PTUmJkoucTAoYTQsImh0dHBzIiww
-KSl7aWYocSYmbys0PT09biYmSi5xMChhNCwiNDQzIixvKzEpKXtsLT00CmY9bi00Cm0tPTQKYTQ9Si5k
-ZyhhNCxvLG4sIiIpCmEzLT0zCm49Zn1qPSJodHRwcyJ9ZWxzZSBqPWEyCms9ITB9fX1lbHNlIGo9YTIK
-aWYoayl7cT1hNC5sZW5ndGgKaWYoYTM8cSl7YTQ9Si5sZChhNCwwLGEzKQpyLT0wCnAtPTAKby09MApu
-LT0wCm0tPTAKbC09MH1yZXR1cm4gbmV3IFAuVWYoYTQscixwLG8sbixtLGwsail9aWYoaj09bnVsbClp
-ZihyPjApaj1QLlBpKGE0LDAscikKZWxzZXtpZihyPT09MClQLlIzKGE0LDAsIkludmFsaWQgZW1wdHkg
-c2NoZW1lIikKaj0iIn1pZihwPjApe2U9ciszCmQ9ZTxwP1AuelIoYTQsZSxwLTEpOiIiCmM9UC5PZShh
-NCxwLG8sITEpCnE9bysxCmlmKHE8bil7Yj1ILkhwKEoubGQoYTQscSxuKSxhMikKYT1QLndCKGI9PW51
-bGw/SC52aChQLnJyKCJJbnZhbGlkIHBvcnQiLGE0LHEpKTpiLGopfWVsc2UgYT1hMn1lbHNle2E9YTIK
-Yz1hCmQ9IiJ9YTA9UC5rYShhNCxuLG0sYTIsaixjIT1udWxsKQphMT1tPGw/UC5sZShhNCxtKzEsbCxh
-Mik6YTIKcmV0dXJuIG5ldyBQLkRuKGosZCxjLGEsYTAsYTEsbDxhMz9QLnRHKGE0LGwrMSxhMyk6YTIp
-fSwKTXQ6ZnVuY3Rpb24oYSl7SC5oKGEpCnJldHVybiBQLmt1KGEsMCxhLmxlbmd0aCxDLnhNLCExKX0s
-CldYOmZ1bmN0aW9uKGEpe3ZhciB0PXUuTgpyZXR1cm4gQy5ObS5OMChILlZNKGEuc3BsaXQoIiYiKSx1
-LnMpLFAuRmwodCx0KSxuZXcgUC5uMShDLnhNKSx1LmYpfSwKSGg6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
-LHMscixxLHAsbyxuLG09IklQdjQgYWRkcmVzcyBzaG91bGQgY29udGFpbiBleGFjdGx5IDQgcGFydHMi
-LGw9ImVhY2ggcGFydCBtdXN0IGJlIGluIHRoZSByYW5nZSAwLi4yNTUiLGs9bmV3IFAuY1MoYSksaj1u
-ZXcgVWludDhBcnJheSg0KQpmb3IodD1qLmxlbmd0aCxzPWIscj1zLHE9MDtzPGM7KytzKXtwPUMueEIu
-bShhLHMpCmlmKHAhPT00Nil7aWYoKHBeNDgpPjkpay4kMigiaW52YWxpZCBjaGFyYWN0ZXIiLHMpfWVs
-c2V7aWYocT09PTMpay4kMihtLHMpCm89UC5RQShDLnhCLk5qKGEscixzKSxudWxsKQppZih0eXBlb2Yg
-byE9PSJudW1iZXIiKXJldHVybiBvLm9zKCkKaWYobz4yNTUpay4kMihsLHIpCm49cSsxCmlmKHE+PXQp
-cmV0dXJuIEguT0goaixxKQpqW3FdPW8Kcj1zKzEKcT1ufX1pZihxIT09MylrLiQyKG0sYykKbz1QLlFB
-KEMueEIuTmooYSxyLGMpLG51bGwpCmlmKHR5cGVvZiBvIT09Im51bWJlciIpcmV0dXJuIG8ub3MoKQpp
-ZihvPjI1NSlrLiQyKGwscikKaWYocT49dClyZXR1cm4gSC5PSChqLHEpCmpbcV09bwpyZXR1cm4gan0s
+d1t0XVthXSlyZXR1cm4gd1t0XVthXX19dmFyIEM9e30sSD17ZW86ZnVuY3Rpb24gZW8oKXt9LApvbzpm
+dW5jdGlvbihhKXt2YXIgdCxzPWFeNDgKaWYoczw9OSlyZXR1cm4gcwp0PWF8MzIKaWYoOTc8PXQmJnQ8
+PTEwMilyZXR1cm4gdC04NwpyZXR1cm4tMX0sCnFDOmZ1bmN0aW9uKGEsYixjLGQpe1AuazEoYiwic3Rh
+cnQiKQppZihjIT1udWxsKXtQLmsxKGMsImVuZCIpCmlmKGI+YylILnZoKFAuVEUoYiwwLGMsInN0YXJ0
+IixudWxsKSl9cmV0dXJuIG5ldyBILm5IKGEsYixjLGQuQygibkg8MD4iKSl9LApLMTpmdW5jdGlvbihh
+LGIsYyxkKXtpZih1Lmd3LmMoYSkpcmV0dXJuIG5ldyBILnh5KGEsYixjLkMoIkA8MD4iKS5LcShkKS5D
+KCJ4eTwxLDI+IikpCnJldHVybiBuZXcgSC5pMShhLGIsYy5DKCJAPDA+IikuS3EoZCkuQygiaTE8MSwy
+PiIpKX0sCldwOmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBQLmxqKCJObyBlbGVtZW50Iil9LApkVTpmdW5j
+dGlvbigpe3JldHVybiBuZXcgUC5saigiVG9vIG1hbnkgZWxlbWVudHMiKX0sCmFyOmZ1bmN0aW9uKCl7
+cmV0dXJuIG5ldyBQLmxqKCJUb28gZmV3IGVsZW1lbnRzIil9LApxajpmdW5jdGlvbiBxaihhKXt0aGlz
+LmE9YX0sCmJROmZ1bmN0aW9uIGJRKCl7fSwKYUw6ZnVuY3Rpb24gYUwoKXt9LApuSDpmdW5jdGlvbiBu
+SChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uJHRpPWR9LAphNzpmdW5jdGlv
+biBhNyhhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9MApfLmQ9bnVsbApfLiR0aT1jfSwK
+aTE6ZnVuY3Rpb24gaTEoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LAp4eTpmdW5j
+dGlvbiB4eShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sCk1IOmZ1bmN0aW9uIE1I
+KGEsYixjKXt2YXIgXz10aGlzCl8uYT1udWxsCl8uYj1hCl8uYz1iCl8uJHRpPWN9LApBODpmdW5jdGlv
+biBBOChhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sClU1OmZ1bmN0aW9uIFU1KGEs
+YixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKU086ZnVuY3Rpb24gU08oYSxiLGMpe3Ro
+aXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LApTVTpmdW5jdGlvbiBTVSgpe30sClJlOmZ1bmN0aW9u
+IFJlKCl7fSwKWEM6ZnVuY3Rpb24gWEMoKXt9LAp3djpmdW5jdGlvbiB3dihhKXt0aGlzLmE9YX0sCmRj
+OmZ1bmN0aW9uKCl7dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgdW5tb2RpZmlhYmxlIE1hcCIp
+KX0sCk5ROmZ1bmN0aW9uKGEpe3ZhciB0LHM9SC5KZyhhKQppZih0eXBlb2Ygcz09InN0cmluZyIpcmV0
+dXJuIHMKdD0ibWluaWZpZWQ6IithCnJldHVybiB0fSwKd1Y6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihi
+IT1udWxsKXt0PWIueAppZih0IT1udWxsKXJldHVybiB0fXJldHVybiB1LmFVLmMoYSl9LApkOmZ1bmN0
+aW9uKGEpe3ZhciB0CmlmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gYQppZih0eXBlb2YgYT09Im51
+bWJlciIpe2lmKGEhPT0wKXJldHVybiIiK2F9ZWxzZSBpZighMD09PWEpcmV0dXJuInRydWUiCmVsc2Ug
+aWYoITE9PT1hKXJldHVybiJmYWxzZSIKZWxzZSBpZihhPT1udWxsKXJldHVybiJudWxsIgp0PUouaihh
+KQppZih0eXBlb2YgdCE9InN0cmluZyIpdGhyb3cgSC5iKEgudEwoYSkpCnJldHVybiB0fSwKZVE6ZnVu
+Y3Rpb24oYSl7dmFyIHQ9YS4kaWRlbnRpdHlIYXNoCmlmKHQ9PW51bGwpe3Q9TWF0aC5yYW5kb20oKSow
+eDNmZmZmZmZmfDAKYS4kaWRlbnRpdHlIYXNoPXR9cmV0dXJuIHR9LApIcDpmdW5jdGlvbihhLGIpe3Zh
+ciB0LHMscixxLHAsbyxuPW51bGwKaWYodHlwZW9mIGEhPSJzdHJpbmciKUgudmgoSC50TChhKSkKdD0v
+XlxzKlsrLV0/KCgweFthLWYwLTldKyl8KFxkKyl8KFthLXowLTldKykpXHMqJC9pLmV4ZWMoYSkKaWYo
+dD09bnVsbClyZXR1cm4gbgppZigzPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LDMpCnM9SC55KHRbM10p
+CmlmKGI9PW51bGwpe2lmKHMhPW51bGwpcmV0dXJuIHBhcnNlSW50KGEsMTApCmlmKHRbMl0hPW51bGwp
+cmV0dXJuIHBhcnNlSW50KGEsMTYpCnJldHVybiBufWlmKGI8Mnx8Yj4zNil0aHJvdyBILmIoUC5URShi
+LDIsMzYsInJhZGl4IixuKSkKaWYoYj09PTEwJiZzIT1udWxsKXJldHVybiBwYXJzZUludChhLDEwKQpp
+ZihiPDEwfHxzPT1udWxsKXtyPWI8PTEwPzQ3K2I6ODYrYgpxPXRbMV0KZm9yKHA9cS5sZW5ndGgsbz0w
+O288cDsrK28paWYoKEMueEIuVyhxLG8pfDMyKT5yKXJldHVybiBufXJldHVybiBwYXJzZUludChhLGIp
+fSwKTTpmdW5jdGlvbihhKXt2YXIgdD1ILkg1KGEpCnJldHVybiB0fSwKSDU6ZnVuY3Rpb24oYSl7dmFy
+IHQscyxyCmlmKGEgaW5zdGFuY2VvZiBQLmspcmV0dXJuIEguZG0oSC56SyhhKSxudWxsKQppZihKLmlh
+KGEpPT09Qy5Pa3x8dS5hay5jKGEpKXt0PUMuTzQoYSkKaWYoSC5mKHQpKXJldHVybiB0CnM9YS5jb25z
+dHJ1Y3RvcgppZih0eXBlb2Ygcz09ImZ1bmN0aW9uIil7cj1zLm5hbWUKaWYodHlwZW9mIHI9PSJzdHJp
+bmciJiZILmYocikpcmV0dXJuIHJ9fXJldHVybiBILmRtKEgueksoYSksbnVsbCl9LApmOmZ1bmN0aW9u
+KGEpe3ZhciB0PWEhPT0iT2JqZWN0IiYmYSE9PSIiCnJldHVybiB0fSwKTTA6ZnVuY3Rpb24oKXtpZigh
+IXNlbGYubG9jYXRpb24pcmV0dXJuIHNlbGYubG9jYXRpb24uaHJlZgpyZXR1cm4gbnVsbH0sClZLOmZ1
+bmN0aW9uKGEpe3ZhciB0LHMscixxLHA9YS5sZW5ndGgKaWYocDw9NTAwKXJldHVybiBTdHJpbmcuZnJv
+bUNoYXJDb2RlLmFwcGx5KG51bGwsYSkKZm9yKHQ9IiIscz0wO3M8cDtzPXIpe3I9cys1MDAKcT1yPHA/
+cjpwCnQrPVN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCxhLnNsaWNlKHMscSkpfXJldHVybiB0
+fSwKQ3E6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9SC5WTShbXSx1LnQpCmZvcih0PWEubGVuZ3RoLHM9
+MDtzPGEubGVuZ3RoO2EubGVuZ3RoPT09dHx8KDAsSC5saykoYSksKytzKXtyPWFbc10KaWYoIUgub2so
+cikpdGhyb3cgSC5iKEgudEwocikpCmlmKHI8PTY1NTM1KUMuTm0uaShxLHIpCmVsc2UgaWYocjw9MTEx
+NDExMSl7Qy5ObS5pKHEsNTUyOTYrKEMuam4ud0coci02NTUzNiwxMCkmMTAyMykpCkMuTm0uaShxLDU2
+MzIwKyhyJjEwMjMpKX1lbHNlIHRocm93IEguYihILnRMKHIpKX1yZXR1cm4gSC5WSyhxKX0sCmVUOmZ1
+bmN0aW9uKGEpe3ZhciB0LHMscgpmb3IodD1hLmxlbmd0aCxzPTA7czx0Oysrcyl7cj1hW3NdCmlmKCFI
+Lm9rKHIpKXRocm93IEguYihILnRMKHIpKQppZihyPDApdGhyb3cgSC5iKEgudEwocikpCmlmKHI+NjU1
+MzUpcmV0dXJuIEguQ3EoYSl9cmV0dXJuIEguVksoYSl9LApmdzpmdW5jdGlvbihhLGIsYyl7dmFyIHQs
+cyxyLHEKaWYoYzw9NTAwJiZiPT09MCYmYz09PWEubGVuZ3RoKXJldHVybiBTdHJpbmcuZnJvbUNoYXJD
+b2RlLmFwcGx5KG51bGwsYSkKZm9yKHQ9YixzPSIiO3Q8Yzt0PXIpe3I9dCs1MDAKcT1yPGM/cjpjCnMr
+PVN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCxhLnN1YmFycmF5KHQscSkpfXJldHVybiBzfSwK
+THc6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoMDw9YSl7aWYoYTw9NjU1MzUpcmV0dXJuIFN0cmluZy5mcm9t
+Q2hhckNvZGUoYSkKaWYoYTw9MTExNDExMSl7dD1hLTY1NTM2CnJldHVybiBTdHJpbmcuZnJvbUNoYXJD
+b2RlKCg1NTI5NnxDLmpuLndHKHQsMTApKT4+PjAsNTYzMjB8dCYxMDIzKX19dGhyb3cgSC5iKFAuVEUo
+YSwwLDExMTQxMTEsbnVsbCxudWxsKSl9LApvMjpmdW5jdGlvbihhKXtpZihhLmRhdGU9PT12b2lkIDAp
+YS5kYXRlPW5ldyBEYXRlKGEuYSkKcmV0dXJuIGEuZGF0ZX0sCnRKOmZ1bmN0aW9uKGEpe3ZhciB0PUgu
+bzIoYSkuZ2V0RnVsbFllYXIoKSswCnJldHVybiB0fSwKTlM6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihh
+KS5nZXRNb250aCgpKzEKcmV0dXJuIHR9LApqQTpmdW5jdGlvbihhKXt2YXIgdD1ILm8yKGEpLmdldERh
+dGUoKSswCnJldHVybiB0fSwKSVg6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihhKS5nZXRIb3VycygpKzAK
+cmV0dXJuIHR9LApjaDpmdW5jdGlvbihhKXt2YXIgdD1ILm8yKGEpLmdldE1pbnV0ZXMoKSswCnJldHVy
+biB0fSwKSmQ6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihhKS5nZXRTZWNvbmRzKCkrMApyZXR1cm4gdH0s
+Cm8xOmZ1bmN0aW9uKGEpe3ZhciB0PUgubzIoYSkuZ2V0TWlsbGlzZWNvbmRzKCkrMApyZXR1cm4gdH0s
+CnpvOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHI9e30Kci5hPTAKdD1bXQpzPVtdCnIuYT1iLmxlbmd0
+aApDLk5tLkZWKHQsYikKci5iPSIiCmlmKGMhPW51bGwmJmMuYSE9PTApYy5LKDAsbmV3IEguQ2oocixz
+LHQpKQoiIityLmEKcmV0dXJuIEouSnkoYSxuZXcgSC5MSShDLlRlLDAsdCxzLDApKX0sCkVrOmZ1bmN0
+aW9uKGEsYixjKXt2YXIgdCxzLHIscQppZihiIGluc3RhbmNlb2YgQXJyYXkpdD1jPT1udWxsfHxjLmE9
+PT0wCmVsc2UgdD0hMQppZih0KXtzPWIKcj1zLmxlbmd0aAppZihyPT09MCl7aWYoISFhLiQwKXJldHVy
+biBhLiQwKCl9ZWxzZSBpZihyPT09MSl7aWYoISFhLiQxKXJldHVybiBhLiQxKHNbMF0pfWVsc2UgaWYo
+cj09PTIpe2lmKCEhYS4kMilyZXR1cm4gYS4kMihzWzBdLHNbMV0pfWVsc2UgaWYocj09PTMpe2lmKCEh
+YS4kMylyZXR1cm4gYS4kMyhzWzBdLHNbMV0sc1syXSl9ZWxzZSBpZihyPT09NCl7aWYoISFhLiQ0KXJl
+dHVybiBhLiQ0KHNbMF0sc1sxXSxzWzJdLHNbM10pfWVsc2UgaWYocj09PTUpaWYoISFhLiQ1KXJldHVy
+biBhLiQ1KHNbMF0sc1sxXSxzWzJdLHNbM10sc1s0XSkKcT1hWyIiKyIkIityXQppZihxIT1udWxsKXJl
+dHVybiBxLmFwcGx5KGEscyl9cmV0dXJuIEguRXcoYSxiLGMpfSwKRXc6ZnVuY3Rpb24oYSxiLGMpe3Zh
+ciB0LHMscixxLHAsbyxuLG0sbCxrPWIgaW5zdGFuY2VvZiBBcnJheT9iOlAuQ0goYiwhMCx1LnopLGo9
+ay5sZW5ndGgsaT1hLiRSCmlmKGo8aSlyZXR1cm4gSC56byhhLGssYykKdD1hLiRECnM9dD09bnVsbApy
+PSFzP3QoKTpudWxsCnE9Si5pYShhKQpwPXEuJEMKaWYodHlwZW9mIHA9PSJzdHJpbmciKXA9cVtwXQpp
+ZihzKXtpZihjIT1udWxsJiZjLmEhPT0wKXJldHVybiBILnpvKGEsayxjKQppZihqPT09aSlyZXR1cm4g
+cC5hcHBseShhLGspCnJldHVybiBILnpvKGEsayxjKX1pZihyIGluc3RhbmNlb2YgQXJyYXkpe2lmKGMh
+PW51bGwmJmMuYSE9PTApcmV0dXJuIEguem8oYSxrLGMpCmlmKGo+aStyLmxlbmd0aClyZXR1cm4gSC56
+byhhLGssbnVsbCkKQy5ObS5GVihrLHIuc2xpY2Uoai1pKSkKcmV0dXJuIHAuYXBwbHkoYSxrKX1lbHNl
+e2lmKGo+aSlyZXR1cm4gSC56byhhLGssYykKbz1PYmplY3Qua2V5cyhyKQppZihjPT1udWxsKWZvcihz
+PW8ubGVuZ3RoLG49MDtuPG8ubGVuZ3RoO28ubGVuZ3RoPT09c3x8KDAsSC5saykobyksKytuKUMuTm0u
+aShrLHJbSC55KG9bbl0pXSkKZWxzZXtmb3Iocz1vLmxlbmd0aCxtPTAsbj0wO248by5sZW5ndGg7by5s
+ZW5ndGg9PT1zfHwoMCxILmxrKShvKSwrK24pe2w9SC55KG9bbl0pCmlmKGMueDQobCkpeysrbQpDLk5t
+LmkoayxjLnEoMCxsKSl9ZWxzZSBDLk5tLmkoayxyW2xdKX1pZihtIT09Yy5hKXJldHVybiBILnpvKGEs
+ayxjKX1yZXR1cm4gcC5hcHBseShhLGspfX0sCnBZOmZ1bmN0aW9uKGEpe3Rocm93IEguYihILnRMKGEp
+KX0sCk9IOmZ1bmN0aW9uKGEsYil7aWYoYT09bnVsbClKLkhtKGEpCnRocm93IEguYihILkhZKGEsYikp
+fSwKSFk6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9ImluZGV4IgppZighSC5vayhiKSlyZXR1cm4gbmV3
+IFAudSghMCxiLHIsbnVsbCkKdD1ILlNjKEouSG0oYSkpCmlmKCEoYjwwKSl7aWYodHlwZW9mIHQhPT0i
+bnVtYmVyIilyZXR1cm4gSC5wWSh0KQpzPWI+PXR9ZWxzZSBzPSEwCmlmKHMpcmV0dXJuIFAuQ2YoYixh
+LHIsbnVsbCx0KQpyZXR1cm4gUC54KGIscil9LAphdTpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9IkludmFs
+aWQgdmFsdWUiCmlmKGE+YylyZXR1cm4gbmV3IFAuYkooMCxjLCEwLGEsInN0YXJ0Iix0KQppZihiIT1u
+dWxsKXtpZighSC5vayhiKSlyZXR1cm4gbmV3IFAudSghMCxiLCJlbmQiLG51bGwpCmlmKGI8YXx8Yj5j
+KXJldHVybiBuZXcgUC5iSihhLGMsITAsYiwiZW5kIix0KX1yZXR1cm4gbmV3IFAudSghMCxiLCJlbmQi
+LG51bGwpfSwKdEw6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnUoITAsYSxudWxsLG51bGwpfSwKYjpm
+dW5jdGlvbihhKXt2YXIgdAppZihhPT1udWxsKWE9bmV3IFAubigpCnQ9bmV3IEVycm9yKCkKdC5kYXJ0
+RXhjZXB0aW9uPWEKaWYoImRlZmluZVByb3BlcnR5IiBpbiBPYmplY3Qpe09iamVjdC5kZWZpbmVQcm9w
+ZXJ0eSh0LCJtZXNzYWdlIix7Z2V0OkguaH0pCnQubmFtZT0iIn1lbHNlIHQudG9TdHJpbmc9SC5oCnJl
+dHVybiB0fSwKaDpmdW5jdGlvbigpe3JldHVybiBKLmoodGhpcy5kYXJ0RXhjZXB0aW9uKX0sCnZoOmZ1
+bmN0aW9uKGEpe3Rocm93IEguYihhKX0sCmxrOmZ1bmN0aW9uKGEpe3Rocm93IEguYihQLmE0KGEpKX0s
+CmNNOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbwphPUguZUEoYS5yZXBsYWNlKFN0cmluZyh7fSks
+JyRyZWNlaXZlciQnKSkKdD1hLm1hdGNoKC9cXFwkW2EtekEtWl0rXFxcJC9nKQppZih0PT1udWxsKXQ9
+SC5WTShbXSx1LnMpCnM9dC5pbmRleE9mKCJcXCRhcmd1bWVudHNcXCQiKQpyPXQuaW5kZXhPZigiXFwk
+YXJndW1lbnRzRXhwclxcJCIpCnE9dC5pbmRleE9mKCJcXCRleHByXFwkIikKcD10LmluZGV4T2YoIlxc
+JG1ldGhvZFxcJCIpCm89dC5pbmRleE9mKCJcXCRyZWNlaXZlclxcJCIpCnJldHVybiBuZXcgSC5mOShh
+LnJlcGxhY2UobmV3IFJlZ0V4cCgnXFxcXFxcJGFyZ3VtZW50c1xcXFxcXCQnLCdnJyksJygoPzp4fFte
+eF0pKiknKS5yZXBsYWNlKG5ldyBSZWdFeHAoJ1xcXFxcXCRhcmd1bWVudHNFeHByXFxcXFxcJCcsJ2cn
+KSwnKCg/Onh8W154XSkqKScpLnJlcGxhY2UobmV3IFJlZ0V4cCgnXFxcXFxcJGV4cHJcXFxcXFwkJywn
+ZycpLCcoKD86eHxbXnhdKSopJykucmVwbGFjZShuZXcgUmVnRXhwKCdcXFxcXFwkbWV0aG9kXFxcXFxc
+JCcsJ2cnKSwnKCg/Onh8W154XSkqKScpLnJlcGxhY2UobmV3IFJlZ0V4cCgnXFxcXFxcJHJlY2VpdmVy
+XFxcXFxcJCcsJ2cnKSwnKCg/Onh8W154XSkqKScpLHMscixxLHAsbyl9LApTNzpmdW5jdGlvbihhKXty
+ZXR1cm4gZnVuY3Rpb24oJGV4cHIkKXt2YXIgJGFyZ3VtZW50c0V4cHIkPSckYXJndW1lbnRzJCcKdHJ5
+eyRleHByJC4kbWV0aG9kJCgkYXJndW1lbnRzRXhwciQpfWNhdGNoKHQpe3JldHVybiB0Lm1lc3NhZ2V9
+fShhKX0sCk1qOmZ1bmN0aW9uKGEpe3JldHVybiBmdW5jdGlvbigkZXhwciQpe3RyeXskZXhwciQuJG1l
+dGhvZCR9Y2F0Y2godCl7cmV0dXJuIHQubWVzc2FnZX19KGEpfSwKSWo6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gbmV3IEguVzAoYSxiPT1udWxsP251bGw6Yi5tZXRob2QpfSwKVDM6ZnVuY3Rpb24oYSxiKXt2YXIg
+dD1iPT1udWxsLHM9dD9udWxsOmIubWV0aG9kCnJldHVybiBuZXcgSC5heihhLHMsdD9udWxsOmIucmVj
+ZWl2ZXIpfSwKUnU6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmPW51
+bGwsZT1uZXcgSC5BbShhKQppZihhPT1udWxsKXJldHVybiBmCmlmKGEgaW5zdGFuY2VvZiBILmJxKXJl
+dHVybiBlLiQxKGEuYSkKaWYodHlwZW9mIGEhPT0ib2JqZWN0IilyZXR1cm4gYQppZigiZGFydEV4Y2Vw
+dGlvbiIgaW4gYSlyZXR1cm4gZS4kMShhLmRhcnRFeGNlcHRpb24pCmVsc2UgaWYoISgibWVzc2FnZSIg
+aW4gYSkpcmV0dXJuIGEKdD1hLm1lc3NhZ2UKaWYoIm51bWJlciIgaW4gYSYmdHlwZW9mIGEubnVtYmVy
+PT0ibnVtYmVyIil7cz1hLm51bWJlcgpyPXMmNjU1MzUKaWYoKEMuam4ud0cocywxNikmODE5MSk9PT0x
+MClzd2l0Y2gocil7Y2FzZSA0Mzg6cmV0dXJuIGUuJDEoSC5UMyhILmQodCkrIiAoRXJyb3IgIityKyIp
+IixmKSkKY2FzZSA0NDU6Y2FzZSA1MDA3OnJldHVybiBlLiQxKEguSWooSC5kKHQpKyIgKEVycm9yICIr
+cisiKSIsZikpfX1pZihhIGluc3RhbmNlb2YgVHlwZUVycm9yKXtxPSQuU24oKQpwPSQubHEoKQpvPSQu
+TjkoKQpuPSQuaUkoKQptPSQuS2YoKQpsPSQuWmgoKQprPSQuck4oKQokLmMzKCkKaj0kLkhLKCkKaT0k
+LnIxKCkKaD1xLnFTKHQpCmlmKGghPW51bGwpcmV0dXJuIGUuJDEoSC5UMyhILnkodCksaCkpCmVsc2V7
+aD1wLnFTKHQpCmlmKGghPW51bGwpe2gubWV0aG9kPSJjYWxsIgpyZXR1cm4gZS4kMShILlQzKEgueSh0
+KSxoKSl9ZWxzZXtoPW8ucVModCkKaWYoaD09bnVsbCl7aD1uLnFTKHQpCmlmKGg9PW51bGwpe2g9bS5x
+Uyh0KQppZihoPT1udWxsKXtoPWwucVModCkKaWYoaD09bnVsbCl7aD1rLnFTKHQpCmlmKGg9PW51bGwp
+e2g9bi5xUyh0KQppZihoPT1udWxsKXtoPWoucVModCkKaWYoaD09bnVsbCl7aD1pLnFTKHQpCmc9aCE9
+bnVsbH1lbHNlIGc9ITB9ZWxzZSBnPSEwfWVsc2UgZz0hMH1lbHNlIGc9ITB9ZWxzZSBnPSEwfWVsc2Ug
+Zz0hMH1lbHNlIGc9ITAKaWYoZylyZXR1cm4gZS4kMShILklqKEgueSh0KSxoKSl9fXJldHVybiBlLiQx
+KG5ldyBILnZWKHR5cGVvZiB0PT0ic3RyaW5nIj90OiIiKSl9aWYoYSBpbnN0YW5jZW9mIFJhbmdlRXJy
+b3Ipe2lmKHR5cGVvZiB0PT0ic3RyaW5nIiYmdC5pbmRleE9mKCJjYWxsIHN0YWNrIikhPT0tMSlyZXR1
+cm4gbmV3IFAuS1koKQp0PWZ1bmN0aW9uKGIpe3RyeXtyZXR1cm4gU3RyaW5nKGIpfWNhdGNoKGQpe31y
+ZXR1cm4gbnVsbH0oYSkKcmV0dXJuIGUuJDEobmV3IFAudSghMSxmLGYsdHlwZW9mIHQ9PSJzdHJpbmci
+P3QucmVwbGFjZSgvXlJhbmdlRXJyb3I6XHMqLywiIik6dCkpfWlmKHR5cGVvZiBJbnRlcm5hbEVycm9y
+PT0iZnVuY3Rpb24iJiZhIGluc3RhbmNlb2YgSW50ZXJuYWxFcnJvcilpZih0eXBlb2YgdD09InN0cmlu
+ZyImJnQ9PT0idG9vIG11Y2ggcmVjdXJzaW9uIilyZXR1cm4gbmV3IFAuS1koKQpyZXR1cm4gYX0sCnRz
+OmZ1bmN0aW9uKGEpe3ZhciB0CmlmKGEgaW5zdGFuY2VvZiBILmJxKXJldHVybiBhLmIKaWYoYT09bnVs
+bClyZXR1cm4gbmV3IEguWE8oYSkKdD1hLiRjYWNoZWRUcmFjZQppZih0IT1udWxsKXJldHVybiB0CnJl
+dHVybiBhLiRjYWNoZWRUcmFjZT1uZXcgSC5YTyhhKX0sCkI3OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxy
+LHE9YS5sZW5ndGgKZm9yKHQ9MDt0PHE7dD1yKXtzPXQrMQpyPXMrMQpiLlkoMCxhW3RdLGFbc10pfXJl
+dHVybiBifSwKZnQ6ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe3UuWi5iKGEpCnN3aXRjaChILlNjKGIpKXtj
+YXNlIDA6cmV0dXJuIGEuJDAoKQpjYXNlIDE6cmV0dXJuIGEuJDEoYykKY2FzZSAyOnJldHVybiBhLiQy
+KGMsZCkKY2FzZSAzOnJldHVybiBhLiQzKGMsZCxlKQpjYXNlIDQ6cmV0dXJuIGEuJDQoYyxkLGUsZil9
+dGhyb3cgSC5iKG5ldyBQLkNEKCJVbnN1cHBvcnRlZCBudW1iZXIgb2YgYXJndW1lbnRzIGZvciB3cmFw
+cGVkIGNsb3N1cmUiKSl9LAp0UjpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGE9PW51bGwpcmV0dXJuIG51
+bGwKdD1hLiRpZGVudGl0eQppZighIXQpcmV0dXJuIHQKdD1mdW5jdGlvbihjLGQsZSl7cmV0dXJuIGZ1
+bmN0aW9uKGYsZyxoLGkpe3JldHVybiBlKGMsZCxmLGcsaCxpKX19KGEsYixILmZ0KQphLiRpZGVudGl0
+eT10CnJldHVybiB0fSwKaUE6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHQscyxyLHEscCxvLG4s
+bSxsPW51bGwsaz1iWzBdLGo9ay4kY2FsbE5hbWUsaT1lP09iamVjdC5jcmVhdGUobmV3IEguengoKS5j
+b25zdHJ1Y3Rvci5wcm90b3R5cGUpOk9iamVjdC5jcmVhdGUobmV3IEguclQobCxsLGwsbCkuY29uc3Ry
+dWN0b3IucHJvdG90eXBlKQppLiRpbml0aWFsaXplPWkuY29uc3RydWN0b3IKaWYoZSl0PWZ1bmN0aW9u
+IHN0YXRpY190ZWFyX29mZigpe3RoaXMuJGluaXRpYWxpemUoKX0KZWxzZXtzPSQueWoKaWYodHlwZW9m
+IHMhPT0ibnVtYmVyIilyZXR1cm4gcy5oKCkKJC55aj1zKzEKcz1uZXcgRnVuY3Rpb24oImEsYixjLGQi
+K3MsInRoaXMuJGluaXRpYWxpemUoYSxiLGMsZCIrcysiKSIpCnQ9c31pLmNvbnN0cnVjdG9yPXQKdC5w
+cm90b3R5cGU9aQppZighZSl7cj1ILmJ4KGEsayxmKQpyLiRyZWZsZWN0aW9uSW5mbz1kfWVsc2V7aS4k
+c3RhdGljX25hbWU9ZwpyPWt9cT1ILmltKGQsZSxmKQppLiRTPXEKaVtqXT1yCmZvcihwPXIsbz0xO288
+Yi5sZW5ndGg7KytvKXtuPWJbb10KbT1uLiRjYWxsTmFtZQppZihtIT1udWxsKXtuPWU/bjpILmJ4KGEs
+bixmKQppW21dPW59aWYobz09PWMpe24uJHJlZmxlY3Rpb25JbmZvPWQKcD1ufX1pLiRDPXAKaS4kUj1r
+LiRSCmkuJEQ9ay4kRApyZXR1cm4gdH0sCmltOmZ1bmN0aW9uKGEsYixjKXt2YXIgdAppZih0eXBlb2Yg
+YT09Im51bWJlciIpcmV0dXJuIGZ1bmN0aW9uKGQsZSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGQo
+ZSl9fShILkJwLGEpCmlmKHR5cGVvZiBhPT0ic3RyaW5nIil7aWYoYil0aHJvdyBILmIoIkNhbm5vdCBj
+b21wdXRlIHNpZ25hdHVyZSBmb3Igc3RhdGljIHRlYXJvZmYuIikKdD1jP0guUFc6SC5UbgpyZXR1cm4g
+ZnVuY3Rpb24oZCxlKXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZSh0aGlzLGQpfX0oYSx0KX10aHJv
+dyBILmIoIkVycm9yIGluIGZ1bmN0aW9uVHlwZSBvZiB0ZWFyb2ZmIil9LAp2cTpmdW5jdGlvbihhLGIs
+YyxkKXt2YXIgdD1ILkRWCnN3aXRjaChiPy0xOmEpe2Nhc2UgMDpyZXR1cm4gZnVuY3Rpb24oZSxmKXty
+ZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZih0aGlzKVtlXSgpfX0oYyx0KQpjYXNlIDE6cmV0dXJuIGZ1
+bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcpe3JldHVybiBmKHRoaXMpW2VdKGcpfX0oYyx0KQpj
+YXNlIDI6cmV0dXJuIGZ1bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcsaCl7cmV0dXJuIGYodGhp
+cylbZV0oZyxoKX19KGMsdCkKY2FzZSAzOnJldHVybiBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlv
+bihnLGgsaSl7cmV0dXJuIGYodGhpcylbZV0oZyxoLGkpfX0oYyx0KQpjYXNlIDQ6cmV0dXJuIGZ1bmN0
+aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcsaCxpLGope3JldHVybiBmKHRoaXMpW2VdKGcsaCxpLGop
+fX0oYyx0KQpjYXNlIDU6cmV0dXJuIGZ1bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcsaCxpLGos
+ayl7cmV0dXJuIGYodGhpcylbZV0oZyxoLGksaixrKX19KGMsdCkKZGVmYXVsdDpyZXR1cm4gZnVuY3Rp
+b24oZSxmKXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZS5hcHBseShmKHRoaXMpLGFyZ3VtZW50cyl9
+fShkLHQpfX0sCmJ4OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbgppZihjKXJldHVybiBI
+LkhmKGEsYikKdD1iLiRzdHViTmFtZQpzPWIubGVuZ3RoCnI9YVt0XQpxPWI9PW51bGw/cj09bnVsbDpi
+PT09cgpwPSFxfHxzPj0yNwppZihwKXJldHVybiBILnZxKHMsIXEsdCxiKQppZihzPT09MCl7cT0kLnlq
+CmlmKHR5cGVvZiBxIT09Im51bWJlciIpcmV0dXJuIHEuaCgpCiQueWo9cSsxCm89InNlbGYiK3EKcT0i
+cmV0dXJuIGZ1bmN0aW9uKCl7dmFyICIrbysiID0gdGhpcy4iCnA9JC5tSgpyZXR1cm4gbmV3IEZ1bmN0
+aW9uKHErSC5kKHA9PW51bGw/JC5tSj1ILkUyKCJzZWxmIik6cCkrIjtyZXR1cm4gIitvKyIuIitILmQo
+dCkrIigpO30iKSgpfW49ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6Ii5zcGxpdCgiIikuc3BsaWNl
+KDAscykuam9pbigiLCIpCnE9JC55agppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBxLmgoKQok
+LnlqPXErMQpuKz1xCnE9InJldHVybiBmdW5jdGlvbigiK24rIil7cmV0dXJuIHRoaXMuIgpwPSQubUoK
+cmV0dXJuIG5ldyBGdW5jdGlvbihxK0guZChwPT1udWxsPyQubUo9SC5FMigic2VsZiIpOnApKyIuIitI
+LmQodCkrIigiK24rIik7fSIpKCl9LApaNDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdD1ILkRWLHM9SC55
+Uwpzd2l0Y2goYj8tMTphKXtjYXNlIDA6dGhyb3cgSC5iKEguRWYoIkludGVyY2VwdGVkIGZ1bmN0aW9u
+IHdpdGggbm8gYXJndW1lbnRzLiIpKQpjYXNlIDE6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4g
+ZnVuY3Rpb24oKXtyZXR1cm4gZih0aGlzKVtlXShnKHRoaXMpKX19KGMsdCxzKQpjYXNlIDI6cmV0dXJu
+IGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24oaCl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlz
+KSxoKX19KGMsdCxzKQpjYXNlIDM6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24o
+aCxpKXtyZXR1cm4gZih0aGlzKVtlXShnKHRoaXMpLGgsaSl9fShjLHQscykKY2FzZSA0OnJldHVybiBm
+dW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1bmN0aW9uKGgsaSxqKXtyZXR1cm4gZih0aGlzKVtlXShnKHRo
+aXMpLGgsaSxqKX19KGMsdCxzKQpjYXNlIDU6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVu
+Y3Rpb24oaCxpLGosayl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSxoLGksaixrKX19KGMsdCxzKQpj
+YXNlIDY6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24oaCxpLGosayxsKXtyZXR1
+cm4gZih0aGlzKVtlXShnKHRoaXMpLGgsaSxqLGssbCl9fShjLHQscykKZGVmYXVsdDpyZXR1cm4gZnVu
+Y3Rpb24oZSxmLGcsaCl7cmV0dXJuIGZ1bmN0aW9uKCl7aD1bZyh0aGlzKV0KQXJyYXkucHJvdG90eXBl
+LnB1c2guYXBwbHkoaCxhcmd1bWVudHMpCnJldHVybiBlLmFwcGx5KGYodGhpcyksaCl9fShkLHQscyl9
+fSwKSGY6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtPSQubUoKaWYobT09bnVsbCltPSQu
+bUo9SC5FMigic2VsZiIpCnQ9JC5QNAppZih0PT1udWxsKXQ9JC5QND1ILkUyKCJyZWNlaXZlciIpCnM9
+Yi4kc3R1Yk5hbWUKcj1iLmxlbmd0aApxPWFbc10KcD1iPT1udWxsP3E9PW51bGw6Yj09PXEKbz0hcHx8
+cj49MjgKaWYobylyZXR1cm4gSC5aNChyLCFwLHMsYikKaWYocj09PTEpe209InJldHVybiBmdW5jdGlv
+bigpe3JldHVybiB0aGlzLiIrSC5kKG0pKyIuIitILmQocykrIih0aGlzLiIrSC5kKHQpKyIpOyIKdD0k
+LnlqCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuaCgpCiQueWo9dCsxCnJldHVybiBuZXcg
+RnVuY3Rpb24obSt0KyJ9IikoKX1uPSJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiIuc3BsaXQoIiIp
+LnNwbGljZSgwLHItMSkuam9pbigiLCIpCm09InJldHVybiBmdW5jdGlvbigiK24rIil7cmV0dXJuIHRo
+aXMuIitILmQobSkrIi4iK0guZChzKSsiKHRoaXMuIitILmQodCkrIiwgIituKyIpOyIKdD0kLnlqCmlm
+KHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuaCgpCiQueWo9dCsxCnJldHVybiBuZXcgRnVuY3Rp
+b24obSt0KyJ9IikoKX0sCktxOmZ1bmN0aW9uKGEsYixjLGQsZSxmLGcpe3JldHVybiBILmlBKGEsYixj
+LGQsISFlLCEhZixnKX0sClRuOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEguY0Uodi50eXBlVW5pdmVyc2Us
+SC56SyhhLmEpLGIpfSwKUFc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5jRSh2LnR5cGVVbml2ZXJzZSxI
+LnpLKGEuYyksYil9LApEVjpmdW5jdGlvbihhKXtyZXR1cm4gYS5hfSwKeVM6ZnVuY3Rpb24oYSl7cmV0
+dXJuIGEuY30sCkUyOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPW5ldyBILnJUKCJzZWxmIiwidGFyZ2V0
+IiwicmVjZWl2ZXIiLCJuYW1lIikscD1KLkVwKE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHEpKQpm
+b3IodD1wLmxlbmd0aCxzPTA7czx0Oysrcyl7cj1wW3NdCmlmKHFbcl09PT1hKXJldHVybiByfX0sCm9U
+OmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpSC5mTygiYm9vbGVhbiBleHByZXNzaW9uIG11c3Qgbm90IGJl
+IG51bGwiKQpyZXR1cm4gYX0sCmZPOmZ1bmN0aW9uKGEpe3Rocm93IEguYihuZXcgSC5rWShhKSl9LAph
+ZzpmdW5jdGlvbihhKXt0aHJvdyBILmIobmV3IFAuYyhhKSl9LApFZjpmdW5jdGlvbihhKXtyZXR1cm4g
+bmV3IEguRXEoYSl9LApZZzpmdW5jdGlvbihhKXtyZXR1cm4gdi5nZXRJc29sYXRlVGFnKGEpfSwKVk06
+ZnVuY3Rpb24oYSxiKXthLiR0aT1iCnJldHVybiBhfSwKb1g6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbCly
+ZXR1cm4gbnVsbApyZXR1cm4gYS4kdGl9LApJTTpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEguWTkoYVsi
+JGEiK0guZChjKV0sSC5vWChiKSl9LApZOTpmdW5jdGlvbihhLGIpe2lmKGE9PW51bGwpcmV0dXJuIGIK
+YT1hLmFwcGx5KG51bGwsYikKaWYoYT09bnVsbClyZXR1cm4gbnVsbAppZihBcnJheS5pc0FycmF5KGEp
+KXJldHVybiBhCmlmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBhLmFwcGx5KG51bGwsYikKcmV0
+dXJuIGJ9LApJRzpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIGEuYXBwbHkoYixILlk5KEouaWEoYilbIiRh
+IitILmQoYyldLEgub1goYikpKX0sCml3OmZ1bmN0aW9uKGEsYixjKXtPYmplY3QuZGVmaW5lUHJvcGVy
+dHkoYSxiLHt2YWx1ZTpjLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6
+dHJ1ZX0pfSwKdzM6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscD1ILnkoJC5ORi4kMShhKSksbz0kLm53
+W3BdCmlmKG8hPW51bGwpe09iamVjdC5kZWZpbmVQcm9wZXJ0eShhLHYuZGlzcGF0Y2hQcm9wZXJ0eU5h
+bWUse3ZhbHVlOm8sZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVl
+fSkKcmV0dXJuIG8uaX10PSQudnZbcF0KaWYodCE9bnVsbClyZXR1cm4gdApzPXYuaW50ZXJjZXB0b3Jz
+QnlUYWdbcF0KaWYocz09bnVsbCl7cD1ILnkoJC5UWC4kMihhLHApKQppZihwIT1udWxsKXtvPSQubndb
+cF0KaWYobyE9bnVsbCl7T2JqZWN0LmRlZmluZVByb3BlcnR5KGEsdi5kaXNwYXRjaFByb3BlcnR5TmFt
+ZSx7dmFsdWU6byxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9
+KQpyZXR1cm4gby5pfXQ9JC52dltwXQppZih0IT1udWxsKXJldHVybiB0CnM9di5pbnRlcmNlcHRvcnNC
+eVRhZ1twXX19aWYocz09bnVsbClyZXR1cm4gbnVsbAp0PXMucHJvdG90eXBlCnI9cFswXQppZihyPT09
+IiEiKXtvPUguVmEodCkKJC5ud1twXT1vCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShhLHYuZGlzcGF0Y2hQ
+cm9wZXJ0eU5hbWUse3ZhbHVlOm8sZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3Vy
+YWJsZTp0cnVlfSkKcmV0dXJuIG8uaX1pZihyPT09In4iKXskLnZ2W3BdPXQKcmV0dXJuIHR9aWYocj09
+PSItIil7cT1ILlZhKHQpCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShPYmplY3QuZ2V0UHJvdG90eXBlT2Yo
+YSksdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6cSxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxl
+OnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gcS5pfWlmKHI9PT0iKyIpcmV0dXJuIEguTGMo
+YSx0KQppZihyPT09IioiKXRocm93IEguYihQLlNZKHApKQppZih2LmxlYWZUYWdzW3BdPT09dHJ1ZSl7
+cT1ILlZhKHQpCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShPYmplY3QuZ2V0UHJvdG90eXBlT2YoYSksdi5k
+aXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6cSxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUs
+Y29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gcS5pfWVsc2UgcmV0dXJuIEguTGMoYSx0KX0sCkxjOmZ1
+bmN0aW9uKGEsYil7dmFyIHQ9T2JqZWN0LmdldFByb3RvdHlwZU9mKGEpCk9iamVjdC5kZWZpbmVQcm9w
+ZXJ0eSh0LHYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWUse3ZhbHVlOkouUXUoYix0LG51bGwsbnVsbCksZW51
+bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSkKcmV0dXJuIGJ9LApW
+YTpmdW5jdGlvbihhKXtyZXR1cm4gSi5RdShhLCExLG51bGwsISFhLiRpWGopfSwKVkY6ZnVuY3Rpb24o
+YSxiLGMpe3ZhciB0PWIucHJvdG90eXBlCmlmKHYubGVhZlRhZ3NbYV09PT10cnVlKXJldHVybiBILlZh
+KHQpCmVsc2UgcmV0dXJuIEouUXUodCxjLG51bGwsbnVsbCl9LApYRDpmdW5jdGlvbigpe2lmKCEwPT09
+JC5CdilyZXR1cm4KJC5Cdj0hMApILloxKCl9LApaMTpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxu
+LG0KJC5udz1PYmplY3QuY3JlYXRlKG51bGwpCiQudnY9T2JqZWN0LmNyZWF0ZShudWxsKQpILmtPKCkK
+dD12LmludGVyY2VwdG9yc0J5VGFnCnM9T2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModCkKaWYodHlw
+ZW9mIHdpbmRvdyE9InVuZGVmaW5lZCIpe3dpbmRvdwpyPWZ1bmN0aW9uKCl7fQpmb3IocT0wO3E8cy5s
+ZW5ndGg7KytxKXtwPXNbcV0Kbz0kLng3LiQxKHApCmlmKG8hPW51bGwpe249SC5WRihwLHRbcF0sbykK
+aWYobiE9bnVsbCl7T2JqZWN0LmRlZmluZVByb3BlcnR5KG8sdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7
+dmFsdWU6bixlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpy
+LnByb3RvdHlwZT1vfX19fWZvcihxPTA7cTxzLmxlbmd0aDsrK3Epe3A9c1txXQppZigvXltBLVphLXpf
+XS8udGVzdChwKSl7bT10W3BdCnRbIiEiK3BdPW0KdFsifiIrcF09bQp0WyItIitwXT1tCnRbIisiK3Bd
+PW0KdFsiKiIrcF09bX19fSwKa086ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbj1DLllxKCkKbj1I
+LnVkKEMuS1UsSC51ZChDLmZRLEgudWQoQy5pNyxILnVkKEMuaTcsSC51ZChDLnhpLEgudWQoQy5kayxI
+LnVkKEMud2IoQy5PNCksbikpKSkpKSkKaWYodHlwZW9mIGRhcnROYXRpdmVEaXNwYXRjaEhvb2tzVHJh
+bnNmb3JtZXIhPSJ1bmRlZmluZWQiKXt0PWRhcnROYXRpdmVEaXNwYXRjaEhvb2tzVHJhbnNmb3JtZXIK
+aWYodHlwZW9mIHQ9PSJmdW5jdGlvbiIpdD1bdF0KaWYodC5jb25zdHJ1Y3Rvcj09QXJyYXkpZm9yKHM9
+MDtzPHQubGVuZ3RoOysrcyl7cj10W3NdCmlmKHR5cGVvZiByPT0iZnVuY3Rpb24iKW49cihuKXx8bn19
+cT1uLmdldFRhZwpwPW4uZ2V0VW5rbm93blRhZwpvPW4ucHJvdG90eXBlRm9yVGFnCiQuTkY9bmV3IEgu
+ZEMocSkKJC5UWD1uZXcgSC53TihwKQokLng3PW5ldyBILlZYKG8pfSwKdWQ6ZnVuY3Rpb24oYSxiKXty
+ZXR1cm4gYShiKXx8Yn0sCnY0OmZ1bmN0aW9uKGEsYixjLGQsZSxmKXt2YXIgdD1iPyJtIjoiIixzPWM/
+IiI6ImkiLHI9ZD8idSI6IiIscT1lPyJzIjoiIixwPWY/ImciOiIiLG89ZnVuY3Rpb24oZyxoKXt0cnl7
+cmV0dXJuIG5ldyBSZWdFeHAoZyxoKX1jYXRjaChuKXtyZXR1cm4gbn19KGEsdCtzK3IrcStwKQppZihv
+IGluc3RhbmNlb2YgUmVnRXhwKXJldHVybiBvCnRocm93IEguYihQLnJyKCJJbGxlZ2FsIFJlZ0V4cCBw
+YXR0ZXJuICgiK1N0cmluZyhvKSsiKSIsYSxudWxsKSl9LAptMjpmdW5jdGlvbihhLGIsYyl7dmFyIHQK
+aWYodHlwZW9mIGI9PSJzdHJpbmciKXJldHVybiBhLmluZGV4T2YoYixjKT49MAplbHNlIGlmKGIgaW5z
+dGFuY2VvZiBILlZSKXt0PUMueEIuRyhhLGMpCnJldHVybiBiLmIudGVzdCh0KX1lbHNle3Q9Si5GTChi
+LEMueEIuRyhhLGMpKQpyZXR1cm4hdC5nbDAodCl9fSwKQTQ6ZnVuY3Rpb24oYSl7aWYoYS5pbmRleE9m
+KCIkIiwwKT49MClyZXR1cm4gYS5yZXBsYWNlKC9cJC9nLCIkJCQkIikKcmV0dXJuIGF9LAplQTpmdW5j
+dGlvbihhKXtpZigvW1tcXXt9KCkqKz8uXFxeJHxdLy50ZXN0KGEpKXJldHVybiBhLnJlcGxhY2UoL1tb
+XF17fSgpKis/LlxcXiR8XS9nLCJcXCQmIikKcmV0dXJuIGF9LAp5czpmdW5jdGlvbihhLGIsYyl7dmFy
+IHQ9SC5uTShhLGIsYykKcmV0dXJuIHR9LApuTTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEKaWYo
+Yj09PSIiKXtpZihhPT09IiIpcmV0dXJuIGMKdD1hLmxlbmd0aApmb3Iocz1jLHI9MDtyPHQ7KytyKXM9
+cythW3JdK2MKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9cT1hLmluZGV4T2YoYiwwKQppZihx
+PDApcmV0dXJuIGEKaWYoYS5sZW5ndGg8NTAwfHxjLmluZGV4T2YoIiQiLDApPj0wKXJldHVybiBhLnNw
+bGl0KGIpLmpvaW4oYykKcmV0dXJuIGEucmVwbGFjZShuZXcgUmVnRXhwKEguZUEoYiksJ2cnKSxILkE0
+KGMpKX0sClBEOmZ1bmN0aW9uIFBEKGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCldVOmZ1bmN0aW9u
+IFdVKCl7fSwKTFA6ZnVuY3Rpb24gTFAoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9
+YwpfLiR0aT1kfSwKWFI6ZnVuY3Rpb24gWFIoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKTEk6ZnVu
+Y3Rpb24gTEkoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uYT1hCl8uYz1iCl8uZD1jCl8uZT1kCl8uZj1l
+fSwKQ2o6ZnVuY3Rpb24gQ2ooYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKZjk6ZnVu
+Y3Rpb24gZjkoYSxiLGMsZCxlLGYpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5l
+PWUKXy5mPWZ9LApXMDpmdW5jdGlvbiBXMChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKYXo6ZnVuY3Rp
+b24gYXooYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKdlY6ZnVuY3Rpb24gdlYoYSl7
+dGhpcy5hPWF9LApicTpmdW5jdGlvbiBicShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQW06ZnVuY3Rp
+b24gQW0oYSl7dGhpcy5hPWF9LApYTzpmdW5jdGlvbiBYTyhhKXt0aGlzLmE9YQp0aGlzLmI9bnVsbH0s
+ClRwOmZ1bmN0aW9uIFRwKCl7fSwKbGM6ZnVuY3Rpb24gbGMoKXt9LAp6eDpmdW5jdGlvbiB6eCgpe30s
+CnJUOmZ1bmN0aW9uIHJUKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9
+LApFcTpmdW5jdGlvbiBFcShhKXt0aGlzLmE9YX0sCmtZOmZ1bmN0aW9uIGtZKGEpe3RoaXMuYT1hfSwK
+TjU6ZnVuY3Rpb24gTjUoYSl7dmFyIF89dGhpcwpfLmE9MApfLmY9Xy5lPV8uZD1fLmM9Xy5iPW51bGwK
+Xy5yPTAKXy4kdGk9YX0sCmRiOmZ1bmN0aW9uIGRiKGEsYil7dmFyIF89dGhpcwpfLmE9YQpfLmI9Ygpf
+LmQ9Xy5jPW51bGx9LAppNTpmdW5jdGlvbiBpNShhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApONjpm
+dW5jdGlvbiBONihhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGwKXy4kdGk9
+Y30sCmRDOmZ1bmN0aW9uIGRDKGEpe3RoaXMuYT1hfSwKd046ZnVuY3Rpb24gd04oYSl7dGhpcy5hPWF9
+LApWWDpmdW5jdGlvbiBWWChhKXt0aGlzLmE9YX0sClZSOmZ1bmN0aW9uIFZSKGEsYil7dmFyIF89dGhp
+cwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGx9LApFSzpmdW5jdGlvbiBFSyhhKXt0aGlzLmI9YX0sCktX
+OmZ1bmN0aW9uIEtXKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClBiOmZ1bmN0aW9u
+IFBiKGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1udWxsfSwKdFE6ZnVuY3Rp
+b24gdFEoYSxiKXt0aGlzLmE9YQp0aGlzLmM9Yn0sCnVuOmZ1bmN0aW9uIHVuKGEsYixjKXt0aGlzLmE9
+YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClNkOmZ1bmN0aW9uIFNkKGEsYixjKXt2YXIgXz10aGlzCl8uYT1h
+Cl8uYj1iCl8uYz1jCl8uZD1udWxsfSwKWEY6ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApEUTpmdW5jdGlv
+bihhKXtyZXR1cm4gbmV3IEludDhBcnJheShhKX0sCm9kOmZ1bmN0aW9uKGEsYixjKXtpZihhPj4+MCE9
+PWF8fGE+PWMpdGhyb3cgSC5iKEguSFkoYixhKSl9LApyTTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKaWYo
+IShhPj4+MCE9PWEpKXQ9Yj4+PjAhPT1ifHxhPmJ8fGI+YwplbHNlIHQ9ITAKaWYodCl0aHJvdyBILmIo
+SC5hdShhLGIsYykpCnJldHVybiBifSwKRVQ6ZnVuY3Rpb24gRVQoKXt9LApiMDpmdW5jdGlvbiBiMCgp
+e30sCkRnOmZ1bmN0aW9uIERnKCl7fSwKUGc6ZnVuY3Rpb24gUGcoKXt9LAp4ajpmdW5jdGlvbiB4aigp
+e30sCmRFOmZ1bmN0aW9uIGRFKCl7fSwKWkE6ZnVuY3Rpb24gWkEoKXt9LAp3ZjpmdW5jdGlvbiB3Zigp
+e30sClBxOmZ1bmN0aW9uIFBxKCl7fSwKZUU6ZnVuY3Rpb24gZUUoKXt9LApWNjpmdW5jdGlvbiBWNigp
+e30sClJHOmZ1bmN0aW9uIFJHKCl7fSwKVlA6ZnVuY3Rpb24gVlAoKXt9LApXQjpmdW5jdGlvbiBXQigp
+e30sClpHOmZ1bmN0aW9uIFpHKCl7fSwKeFo6ZnVuY3Rpb24oYSxiKXt2YXIgdD1iLmQKcmV0dXJuIHQ9
+PW51bGw/Yi5kPUguSihhLCJiOCIsW2IuUV0pOnR9LApRMTpmdW5jdGlvbihhKXt2YXIgdD1hLnoKaWYo
+dD09PTZ8fHQ9PT03fHx0PT09OClyZXR1cm4gSC5RMShhLlEpCnJldHVybiB0PT09MTF8fHQ9PT0xMn0s
+Cm1EOmZ1bmN0aW9uKGEpe3JldHVybiBhLmRifSwKTjA6ZnVuY3Rpb24oYSl7cmV0dXJuIEguRSh2LnR5
+cGVVbml2ZXJzZSxhKX0sCkpTOmZ1bmN0aW9uKGEpe3ZhciB0PWEuJFMKaWYodCE9bnVsbCl7aWYodHlw
+ZW9mIHQ9PSJudW1iZXIiKXJldHVybiBILkJwKHQpCnJldHVybiBhLiRTKCl9cmV0dXJuIG51bGx9LApV
+ZTpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKEguUTEoYikpaWYoYSBpbnN0YW5jZW9mIEguVHApe3Q9SC5K
+UyhhKQppZih0IT1udWxsKXJldHVybiB0fXJldHVybiBILnpLKGEpfSwKeks6ZnVuY3Rpb24oYSl7dmFy
+IHQKaWYoYSBpbnN0YW5jZW9mIFAuayl7dD1hLiR0aQpyZXR1cm4gdCE9bnVsbD90OkguVlUoYSl9aWYo
+QXJyYXkuaXNBcnJheShhKSlyZXR1cm4gSC50NihhKQpyZXR1cm4gSC5WVShKLmlhKGEpKX0sCnQ2OmZ1
+bmN0aW9uKGEpe3ZhciB0PWEuJHRpLHM9dS5tCmlmKHQ9PW51bGwpcmV0dXJuIHMKaWYodC5jb25zdHJ1
+Y3RvciE9PXMuY29uc3RydWN0b3IpcmV0dXJuIHMKcmV0dXJuIHR9LApMaDpmdW5jdGlvbihhKXt2YXIg
+dD1hLiR0aQpyZXR1cm4gdCE9bnVsbD90OkguVlUoYSl9LApWVTpmdW5jdGlvbihhKXt2YXIgdD1hLmNv
+bnN0cnVjdG9yLHM9dC4kY2NhY2hlCmlmKHMhPW51bGwpcmV0dXJuIHMKcmV0dXJuIEgucjkoYSx0KX0s
+CnI5OmZ1bmN0aW9uKGEsYil7dmFyIHQ9YSBpbnN0YW5jZW9mIEguVHA/YS5fX3Byb3RvX18uX19wcm90
+b19fLmNvbnN0cnVjdG9yOmIscz1ILmFpKHYudHlwZVVuaXZlcnNlLHQubmFtZSkKYi4kY2NhY2hlPXMK
+cmV0dXJuIHN9LApCcDpmdW5jdGlvbihhKXt2YXIgdCxzPWEscj12LnR5cGVzLHE9cltzXQppZih0eXBl
+b2YgcT09InN0cmluZyIpe3Q9SC5FKHYudHlwZVVuaXZlcnNlLHEpCnJbc109dApyZXR1cm4gdH1yZXR1
+cm4gcX0sCkpKOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcyxyPXMueixxPUguWU8KaWYoSC5jYyhzKSl7
+cT1ILkl3CnMuYj1zLmE9SC5obn1lbHNlIGlmKHI9PT05KXt0PXMuZGIKaWYoIktOIj09PXQpcT1ILm9r
+CmVsc2UgaWYoIkNQIj09PXQpcT1ILktICmVsc2UgaWYoIkZLIj09PXQpcT1ILktICmVsc2UgaWYoInFV
+Ij09PXQpcT1ILk1NCmVsc2UgaWYoImEyIj09PXQpcT1ILmwKZWxzZXtyPXMuUQppZihzLmNoLmV2ZXJ5
+KEguY2MpKXtzLng9IiRpIityCnE9SC50NH19fXMuYz1xCnJldHVybiBzLmMoYSl9LApZTzpmdW5jdGlv
+bihhKXt2YXIgdD10aGlzCnJldHVybiBILldlKHYudHlwZVVuaXZlcnNlLEguVWUoYSx0KSxudWxsLHQs
+bnVsbCl9LAp0NDpmdW5jdGlvbihhKXt2YXIgdD10aGlzLngKaWYoYSBpbnN0YW5jZW9mIFAuaylyZXR1
+cm4hIWFbdF0KcmV0dXJuISFKLmlhKGEpW3RdfSwKT3o6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoYT09bnVs
+bClyZXR1cm4gYQp0PXRoaXMKaWYodC5jKGEpKXJldHVybiBhCnRocm93IEguYihILlE1KEguV0soYSxI
+LlVlKGEsdCksSC5kbSh0LG51bGwpKSkpfSwKQXY6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoYT09bnVsbCly
+ZXR1cm4gYQp0PXRoaXMKaWYodC5jKGEpKXJldHVybiBhCnRocm93IEguYihILlpjKEguV0soYSxILlVl
+KGEsdCksSC5kbSh0LG51bGwpKSkpfSwKRGg6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQ9bnVsbAppZihI
+LldlKHYudHlwZVVuaXZlcnNlLGEsdCxiLHQpKXJldHVybiBhCnRocm93IEguYihILlpjKCJUaGUgdHlw
+ZSBhcmd1bWVudCAnIitILmQoSC5kbShhLHQpKSsiJyBpcyBub3QgYSBzdWJ0eXBlIG9mIHRoZSB0eXBl
+IHZhcmlhYmxlIGJvdW5kICciK0guZChILmRtKGIsdCkpKyInIG9mIHR5cGUgdmFyaWFibGUgJyIrYysi
+JyBpbiAnIitILmQoZCkrIicuIikpfSwKV0s6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PVAucChhKSxzPUgu
+ZG0oYj09bnVsbD9ILnpLKGEpOmIsbnVsbCkKcmV0dXJuIHQrIjogdHlwZSAnIitILmQocykrIicgaXMg
+bm90IGEgc3VidHlwZSBvZiB0eXBlICciK0guZChjKSsiJyJ9LApRNTpmdW5jdGlvbihhKXtyZXR1cm4g
+bmV3IEguaHooIkNhc3RFcnJvcjogIithKX0sClB2OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILmh6
+KCJDYXN0RXJyb3I6ICIrSC5XSyhhLG51bGwsYikpfSwKWmM6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBI
+LmlNKCJUeXBlRXJyb3I6ICIrYSl9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILmlNKCJUeXBl
+RXJyb3I6ICIrSC5XSyhhLG51bGwsYikpfSwKSXc6ZnVuY3Rpb24oYSl7cmV0dXJuITB9LApobjpmdW5j
+dGlvbihhKXtyZXR1cm4gYX0sCmw6ZnVuY3Rpb24oYSl7cmV0dXJuITA9PT1hfHwhMT09PWF9LApFOTpm
+dW5jdGlvbihhKXtpZighMD09PWF8fCExPT09YSlyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRo
+cm93IEguYihILlB2KGEsImJvb2wiKSl9LAp4ZDpmdW5jdGlvbihhKXtpZighMD09PWF8fCExPT09YSly
+ZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwiYm9vbCIpKX0sCmRqOmZ1
+bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBh
+CnRocm93IEguYihILlB2KGEsImRvdWJsZSIpKX0sCklnOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0i
+bnVtYmVyIilyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwiZG91Ymxl
+IikpfSwKb2s6ZnVuY3Rpb24oYSl7cmV0dXJuIHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5mbG9vcihh
+KT09PWF9LApXWTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciImJk1hdGguZmxvb3IoYSk9
+PT1hKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEguUHYoYSwiaW50IikpfSwK
+U2M6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiJiZNYXRoLmZsb29yKGEpPT09YSlyZXR1
+cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwiaW50IikpfSwKS0g6ZnVuY3Rp
+b24oYSl7cmV0dXJuIHR5cGVvZiBhPT0ibnVtYmVyIn0sCnVVOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBh
+PT0ibnVtYmVyIilyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILlB2KGEsIm51
+bSIpKX0sCkROOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQppZihhPT1u
+dWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwibnVtIikpfSwKTU06ZnVuY3Rpb24oYSl7cmV0dXJu
+IHR5cGVvZiBhPT0ic3RyaW5nIn0sCmMwOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIily
+ZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILlB2KGEsIlN0cmluZyIpKX0sCnk6
+ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJu
+IGEKdGhyb3cgSC5iKEgucShhLCJTdHJpbmciKSl9LAppbzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscgpm
+b3IodD0iIixzPSIiLHI9MDtyPGEubGVuZ3RoOysrcixzPSIsICIpdCs9Qy54Qi5oKHMsSC5kbShhW3Jd
+LGIpKQpyZXR1cm4gdH0sCmJJOmZ1bmN0aW9uKGEwLGExLGEyKXt2YXIgdCxzLHIscSxwLG8sbixtLGws
+ayxqLGksaCxnLGYsZSxkLGMsYixhPSIsICIKaWYoYTIhPW51bGwpe3Q9YTIubGVuZ3RoCmlmKGExPT1u
+dWxsKXthMT1ILlZNKFtdLHUucykKcz1udWxsfWVsc2Ugcz1hMS5sZW5ndGgKcj1hMS5sZW5ndGgKZm9y
+KHE9dDtxPjA7LS1xKUMuTm0uaShhMSwiVCIrKHIrcSkpCmZvcihwPSI8IixvPSIiLHE9MDtxPHQ7Kytx
+LG89YSl7cCs9bwpuPWExLmxlbmd0aAptPW4tMS1xCmlmKG08MClyZXR1cm4gSC5PSChhMSxtKQpwPUMu
+eEIuaChwLGExW21dKQpsPWEyW3FdCmlmKCFILmNjKGwpKXArPUMueEIuaCgiIGV4dGVuZHMgIixILmRt
+KGwsYTEpKX1wKz0iPiJ9ZWxzZXtwPSIiCnM9bnVsbH1uPWEwLlEKaz1hMC5jaApqPWsuYQppPWoubGVu
+Z3RoCmg9ay5iCmc9aC5sZW5ndGgKZj1rLmMKZT1mLmxlbmd0aApkPUguZG0obixhMSkKZm9yKGM9IiIs
+Yj0iIixxPTA7cTxpOysrcSxiPWEpYys9Qy54Qi5oKGIsSC5kbShqW3FdLGExKSkKaWYoZz4wKXtjKz1i
+KyJbIgpmb3IoYj0iIixxPTA7cTxnOysrcSxiPWEpYys9Qy54Qi5oKGIsSC5kbShoW3FdLGExKSkKYys9
+Il0ifWlmKGU+MCl7Yys9YisieyIKZm9yKGI9IiIscT0wO3E8ZTtxKz0yLGI9YSljKz1DLnhCLmgoYixI
+LmRtKGZbcSsxXSxhMSkpKyIgIitmW3FdCmMrPSJ9In1pZihzIT1udWxsKWExLmxlbmd0aD1zCnJldHVy
+biBwKyIoIitjKyIpID0+ICIrSC5kKGQpfSwKZG06ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwPWEu
+egppZihwPT09NSlyZXR1cm4iZXJhc2VkIgppZihwPT09MilyZXR1cm4iZHluYW1pYyIKaWYocD09PTMp
+cmV0dXJuInZvaWQiCmlmKHA9PT0xKXJldHVybiJOZXZlciIKaWYocD09PTQpcmV0dXJuImFueSIKaWYo
+cD09PTYpcmV0dXJuIEguZChILmRtKGEuUSxiKSkrIioiCmlmKHA9PT03KXJldHVybiBILmQoSC5kbShh
+LlEsYikpKyI/IgppZihwPT09OClyZXR1cm4iRnV0dXJlT3I8IitILmQoSC5kbShhLlEsYikpKyI+Igpp
+ZihwPT09OSl7dD1ILm8zKGEuUSkKcz1hLmNoCnJldHVybiBzLmxlbmd0aCE9PTA/dCsoIjwiK0guaW8o
+cyxiKSsiPiIpOnR9aWYocD09PTExKXJldHVybiBILmJJKGEsYixudWxsKQppZihwPT09MTIpcmV0dXJu
+IEguYkkoYS5RLGIsYS5jaCkKaWYocD09PTEzKXtyPWEuUQpxPWIubGVuZ3RoCnI9cS0xLXIKaWYocjww
+fHxyPj1xKXJldHVybiBILk9IKGIscikKcmV0dXJuIGJbcl19cmV0dXJuIj8ifSwKbzM6ZnVuY3Rpb24o
+YSl7dmFyIHQscz1ILkpnKGEpCmlmKHMhPW51bGwpcmV0dXJuIHMKdD0ibWluaWZpZWQ6IithCnJldHVy
+biB0fSwKUW86ZnVuY3Rpb24oYSxiKXt2YXIgdD1hLnRSW2JdCmZvcig7dHlwZW9mIHQ9PSJzdHJpbmci
+Oyl0PWEudFJbdF0KcmV0dXJuIHR9LAphaTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbz1hLmVU
+LG49b1tiXQppZihuPT1udWxsKXJldHVybiBILkUoYSxiKQplbHNlIGlmKHR5cGVvZiBuPT0ibnVtYmVy
+Iil7dD1uCnM9SC5tKGEsNSwiIyIpCnI9W10KZm9yKHE9MDtxPHQ7KytxKXIucHVzaChzKQpwPUguSihh
+LGIscikKb1tiXT1wCnJldHVybiBwfWVsc2UgcmV0dXJuIG59LAp4YjpmdW5jdGlvbihhLGIpe3JldHVy
+biBILkl4KGEudFIsYil9LApGRjpmdW5jdGlvbihhLGIpe3JldHVybiBILkl4KGEuZVQsYil9LApFOmZ1
+bmN0aW9uKGEsYil7dmFyIHQscz1hLmVDLHI9cy5nZXQoYikKaWYociE9bnVsbClyZXR1cm4gcgp0PUgu
+eihhLG51bGwsYikKcy5zZXQoYix0KQpyZXR1cm4gdH0sCmNFOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxz
+LHI9Yi5jeAppZihyPT1udWxsKXI9Yi5jeD1uZXcgTWFwKCkKdD1yLmdldChjKQppZih0IT1udWxsKXJl
+dHVybiB0CnM9SC56KGEsYixjKQpyLnNldChjLHMpCnJldHVybiBzfSwKdjU6ZnVuY3Rpb24oYSxiLGMp
+e3ZhciB0LHMscixxPWIuY3kKaWYocT09bnVsbClxPWIuY3k9bmV3IE1hcCgpCnQ9Yy5kYgpzPXEuZ2V0
+KHQpCmlmKHMhPW51bGwpcmV0dXJuIHMKcj1ILmEoYSxiLGMuej09PTEwP2MuY2g6W2NdKQpxLnNldCh0
+LHIpCnJldHVybiByfSwKejpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5pKEgubyhhLGIsYykpCnJldHVy
+biB0fSwKV0c6ZnVuY3Rpb24oYSxiKXt2YXIgdD1iLmRiCmEuZUMuc2V0KHQsYikKYi5hPUguT3oKYi5i
+PUguQXYKYi5jPUguSkoKcmV0dXJuIGJ9LAptOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPWEuZUMuZ2V0
+KGMpCmlmKHMhPW51bGwpcmV0dXJuIHMKdD1uZXcgSC5KYyhudWxsLG51bGwsbnVsbCkKdC56PWIKdC5k
+Yj1jCnJldHVybiBILldHKGEsdCl9LAp2OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHM9YS5lQy5nZXQo
+ZCkKaWYocyE9bnVsbClyZXR1cm4gcwp0PW5ldyBILkpjKG51bGwsbnVsbCxudWxsKQp0Lno9Ygp0LlE9
+Ywp0LmRiPWQKcmV0dXJuIEguV0coYSx0KX0sCkg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPSIiK2IrIl4i
+LHI9YS5lQy5nZXQocykKaWYociE9bnVsbClyZXR1cm4gcgp0PW5ldyBILkpjKG51bGwsbnVsbCxudWxs
+KQp0Lno9MTMKdC5RPWIKdC5kYj1zCnJldHVybiBILldHKGEsdCl9LApVeDpmdW5jdGlvbihhKXt2YXIg
+dCxzLHIscT1hLmxlbmd0aApmb3IodD0iIixzPSIiLHI9MDtyPHE7KytyLHM9IiwiKXQrPXMrYVtyXS5k
+YgpyZXR1cm4gdH0sClM0OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbz1hLmxlbmd0aApmb3IodD0i
+IixzPSIiLHI9MDtyPG87cis9MixzPSIsIil7cT1hW3JdCnA9YVtyKzFdLmRiCnQrPXMrcSsiOiIrcH1y
+ZXR1cm4gdH0sCko6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj1iCmlmKGMubGVuZ3RoIT09MClyKz0i
+PCIrSC5VeChjKSsiPiIKdD1hLmVDLmdldChyKQppZih0IT1udWxsKXJldHVybiB0CnM9bmV3IEguSmMo
+bnVsbCxudWxsLG51bGwpCnMuej05CnMuUT1iCnMuY2g9YwppZihjLmxlbmd0aD4wKXMuZD1jWzBdCnMu
+ZGI9cgpyZXR1cm4gSC5XRyhhLHMpfSwKYTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscAppZihi
+Lno9PT0xMCl7dD1iLlEKcz1iLmNoLmNvbmNhdChjKX1lbHNle3M9Ywp0PWJ9cj10LmRiKyI7IisoIjwi
+K0guVXgocykrIj4iKQpxPWEuZUMuZ2V0KHIpCmlmKHEhPW51bGwpcmV0dXJuIHEKcD1uZXcgSC5KYyhu
+dWxsLG51bGwsbnVsbCkKcC56PTEwCnAuUT10CnAuY2g9cwpwLmRiPXIKcmV0dXJuIEguV0coYSxwKX0s
+CkM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxPWIuZGIscD1jLmEsbz1wLmxlbmd0aCxuPWMuYixt
+PW4ubGVuZ3RoLGw9Yy5jLGs9bC5sZW5ndGgsaj0iKCIrSC5VeChwKQppZihtPjApais9KG8+MD8iLCI6
+IiIpKyJbIitILlV4KG4pKyJdIgppZihrPjApais9KG8+MD8iLCI6IiIpKyJ7IitILlM0KGwpKyJ9Igp0
+PXErKGorIikiKQpzPWEuZUMuZ2V0KHQpCmlmKHMhPW51bGwpcmV0dXJuIHMKcj1uZXcgSC5KYyhudWxs
+LG51bGwsbnVsbCkKci56PTExCnIuUT1iCnIuY2g9YwpyLmRiPXQKcmV0dXJuIEguV0coYSxyKX0sCkQ6
+ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9Yi5kYisiPCIrSC5VeChjKSsiPiIscj1hLmVDLmdldChzKQpp
+ZihyIT1udWxsKXJldHVybiByCnQ9bmV3IEguSmMobnVsbCxudWxsLG51bGwpCnQuej0xMgp0LlE9Ygp0
+LmNoPWMKdC5kYj1zCnJldHVybiBILldHKGEsdCl9LApvOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm57dTph
+LGU6YixyOmMsczpbXSxwOjB9fSwKaTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxq
+LGksaCxnPWEucixmPWEucwpmb3IodD1nLmxlbmd0aCxzPTA7czx0Oyl7cj1nLmNoYXJDb2RlQXQocykK
+aWYocj49NDgmJnI8PTU3KXM9SC5BKHMrMSxyLGcsZikKZWxzZSBpZigoKChyfDMyKT4+PjApLTk3JjY1
+NTM1KTwyNnx8cj09PTk1fHxyPT09MzYpcz1ILnQoYSxzLGcsZiwhMSkKZWxzZSBpZihyPT09NDYpcz1I
+LnQoYSxzLGcsZiwhMCkKZWxzZXsrK3MKc3dpdGNoKHIpe2Nhc2UgNDQ6YnJlYWsKY2FzZSA1ODpicmVh
+awpjYXNlIDU5OmYucHVzaChILksoYS51LGEuZSxmLnBvcCgpKSkKYnJlYWsKY2FzZSA5NDpmLnB1c2go
+SC5IKGEudSxmLnBvcCgpKSkKYnJlYWsKY2FzZSAzNTpmLnB1c2goSC5tKGEudSw1LCIjIikpCmJyZWFr
+CmNhc2UgNjQ6Zi5wdXNoKEgubShhLnUsMiwiQCIpKQpicmVhawpjYXNlIDEyNjpmLnB1c2goSC5tKGEu
+dSwzLCJ+IikpCmJyZWFrCmNhc2UgNjA6Zi5wdXNoKGEucCkKYS5wPWYubGVuZ3RoCmJyZWFrCmNhc2Ug
+NjI6cT1hLnUKcD1mLnNwbGljZShhLnApCkgucihhLnUsYS5lLHApCmEucD1mLnBvcCgpCm89Zi5wb3Ao
+KQppZih0eXBlb2Ygbz09InN0cmluZyIpZi5wdXNoKEguSihxLG8scCkpCmVsc2V7bj1ILksocSxhLmUs
+bykKc3dpdGNoKG4ueil7Y2FzZSAxMTpmLnB1c2goSC5EKHEsbixwKSkKYnJlYWsKZGVmYXVsdDpmLnB1
+c2goSC5hKHEsbixwKSkKYnJlYWt9fWJyZWFrCmNhc2UgMzg6SC5JKGEsZikKYnJlYWsKY2FzZSA0Mjpt
+PWEudQpsPUguSyhtLGEuZSxmLnBvcCgpKQpmLnB1c2goSC52KG0sNixsLGwuZGIrIioiKSkKYnJlYWsK
+Y2FzZSA2MzptPWEudQpsPUguSyhtLGEuZSxmLnBvcCgpKQpmLnB1c2goSC52KG0sNyxsLGwuZGIrIj8i
+KSkKYnJlYWsKY2FzZSA0NzptPWEudQpsPUguSyhtLGEuZSxmLnBvcCgpKQpmLnB1c2goSC52KG0sOCxs
+LGwuZGIrIi8iKSkKYnJlYWsKY2FzZSA0MDpmLnB1c2goYS5wKQphLnA9Zi5sZW5ndGgKYnJlYWsKY2Fz
+ZSA0MTpxPWEudQprPW5ldyBILkcoKQpqPXEuc0VBCmk9cS5zRUEKbz1mLnBvcCgpCmlmKHR5cGVvZiBv
+PT0ibnVtYmVyIilzd2l0Y2gobyl7Y2FzZS0xOmo9Zi5wb3AoKQpicmVhawpjYXNlLTI6aT1mLnBvcCgp
+CmJyZWFrCmRlZmF1bHQ6Zi5wdXNoKG8pCmJyZWFrfWVsc2UgZi5wdXNoKG8pCnA9Zi5zcGxpY2UoYS5w
+KQpILnIoYS51LGEuZSxwKQphLnA9Zi5wb3AoKQprLmE9cAprLmI9agprLmM9aQpmLnB1c2goSC5DKHEs
+SC5LKHEsYS5lLGYucG9wKCkpLGspKQpicmVhawpjYXNlIDkxOmYucHVzaChhLnApCmEucD1mLmxlbmd0
+aApicmVhawpjYXNlIDkzOnA9Zi5zcGxpY2UoYS5wKQpILnIoYS51LGEuZSxwKQphLnA9Zi5wb3AoKQpm
+LnB1c2gocCkKZi5wdXNoKC0xKQpicmVhawpjYXNlIDEyMzpmLnB1c2goYS5wKQphLnA9Zi5sZW5ndGgK
+YnJlYWsKY2FzZSAxMjU6cD1mLnNwbGljZShhLnApCkguQihhLnUsYS5lLHApCmEucD1mLnBvcCgpCmYu
+cHVzaChwKQpmLnB1c2goLTIpCmJyZWFrCmRlZmF1bHQ6dGhyb3ciQmFkIGNoYXJhY3RlciAiK3J9fX1o
+PWYucG9wKCkKcmV0dXJuIEguSyhhLnUsYS5lLGgpfSwKQTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxz
+LHI9Yi00OApmb3IodD1jLmxlbmd0aDthPHQ7KythKXtzPWMuY2hhckNvZGVBdChhKQppZighKHM+PTQ4
+JiZzPD01NykpYnJlYWsKcj1yKjEwKyhzLTQ4KX1kLnB1c2gocikKcmV0dXJuIGF9LAp0OmZ1bmN0aW9u
+KGEsYixjLGQsZSl7dmFyIHQscyxyLHEscCxvLG49YisxCmZvcih0PWMubGVuZ3RoO248dDsrK24pe3M9
+Yy5jaGFyQ29kZUF0KG4pCmlmKHM9PT00Nil7aWYoZSlicmVhawplPSEwfWVsc2V7aWYoISgoKChzfDMy
+KT4+PjApLTk3JjY1NTM1KTwyNnx8cz09PTk1fHxzPT09MzYpKXI9cz49NDgmJnM8PTU3CmVsc2Ugcj0h
+MAppZighcilicmVha319cT1jLnN1YnN0cmluZyhiLG4pCmlmKGUpe3Q9YS51CnA9YS5lCmlmKHAuej09
+PTEwKXA9cC5RCm89SC5Rbyh0LHAuUSlbcV0KaWYobz09bnVsbClILnZoKCdObyAiJytxKyciIGluICIn
+K0gubUQocCkrJyInKQpkLnB1c2goSC5jRSh0LHAsbykpfWVsc2UgZC5wdXNoKHEpCnJldHVybiBufSwK
+STpmdW5jdGlvbihhLGIpe3ZhciB0PWIucG9wKCkKaWYoMD09PXQpe2IucHVzaChILm0oYS51LDEsIjAm
+IikpCnJldHVybn1pZigxPT09dCl7Yi5wdXNoKEgubShhLnUsNCwiMSYiKSkKcmV0dXJufXRocm93IEgu
+YihQLmhWKCJVbmV4cGVjdGVkIGV4dGVuZGVkIG9wZXJhdGlvbiAiK0guZCh0KSkpfSwKSzpmdW5jdGlv
+bihhLGIsYyl7aWYodHlwZW9mIGM9PSJzdHJpbmciKXJldHVybiBILkooYSxjLGEuc0VBKQplbHNlIGlm
+KHR5cGVvZiBjPT0ibnVtYmVyIilyZXR1cm4gSC5UVihhLGIsYykKZWxzZSByZXR1cm4gY30sCnI6ZnVu
+Y3Rpb24oYSxiLGMpe3ZhciB0LHM9Yy5sZW5ndGgKZm9yKHQ9MDt0PHM7Kyt0KWNbdF09SC5LKGEsYixj
+W3RdKX0sCkI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9Yy5sZW5ndGgKZm9yKHQ9MTt0PHM7dCs9Milj
+W3RdPUguSyhhLGIsY1t0XSl9LApUVjpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyPWIuegppZihyPT09
+MTApe2lmKGM9PT0wKXJldHVybiBiLlEKdD1iLmNoCnM9dC5sZW5ndGgKaWYoYzw9cylyZXR1cm4gdFtj
+LTFdCmMtPXMKYj1iLlEKcj1iLnp9ZWxzZSBpZihjPT09MClyZXR1cm4gYgppZihyIT09OSl0aHJvdyBI
+LmIoUC5oVigiSW5kZXhlZCBiYXNlIG11c3QgYmUgYW4gaW50ZXJmYWNlIHR5cGUiKSkKdD1iLmNoCmlm
+KGM8PXQubGVuZ3RoKXJldHVybiB0W2MtMV0KdGhyb3cgSC5iKFAuaFYoIkJhZCBpbmRleCAiK2MrIiBm
+b3IgIitiLncoMCkpKX0sCldlOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyLHEscCxvLG4sbSxs
+LGsKaWYoYj09PWQpcmV0dXJuITAKaWYoSC5jYyhkKSlyZXR1cm4hMAp0PWIuegppZih0PT09NClyZXR1
+cm4hMAppZihILmNjKGIpKXJldHVybiExCmlmKGI9PT11LlApcmV0dXJuITAKcz10PT09MTMKaWYocylp
+ZihILldlKGEsY1tiLlFdLGMsZCxlKSlyZXR1cm4hMApyPWQuegppZih0PT09NilyZXR1cm4gSC5XZShh
+LGIuUSxjLGQsZSkKaWYocj09PTYpe3E9ZC5RCnJldHVybiBILldlKGEsYixjLHEsZSl9aWYodD09PTgp
+e2lmKCFILldlKGEsYi5RLGMsZCxlKSlyZXR1cm4hMQpyZXR1cm4gSC5XZShhLEgueFooYSxiKSxjLGQs
+ZSl9aWYodD09PTcpe3E9SC5XZShhLGIuUSxjLGQsZSkKcmV0dXJuIHF9aWYocj09PTgpe2lmKEguV2Uo
+YSxiLGMsZC5RLGUpKXJldHVybiEwCnJldHVybiBILldlKGEsYixjLEgueFooYSxkKSxlKX1pZihyPT09
+Nyl7cT1ILldlKGEsYixjLGQuUSxlKQpyZXR1cm4gcX1pZihzKXJldHVybiExCnE9dCE9PTExCmlmKCgh
+cXx8dD09PTEyKSYmZD09PXUuWilyZXR1cm4hMAppZihyPT09MTIpe2lmKGI9PT11LmcpcmV0dXJuITAK
+aWYodCE9PTEyKXJldHVybiExCnA9Yi5jaApvPWQuY2gKbj1wLmxlbmd0aAppZihuIT09by5sZW5ndGgp
+cmV0dXJuITEKZm9yKHE9dS5hdixtPTA7bTxuOysrbSl7bD1wW21dCms9b1ttXQpxLmIobCkKcS5iKGsp
+CmlmKCFILldlKGEsbCxjLGssZSl8fCFILldlKGEsayxlLGwsYykpcmV0dXJuITF9Yz1jPT1udWxsP3A6
+cC5jb25jYXQoYykKZT1lPT1udWxsP286by5jb25jYXQoZSkKcmV0dXJuIEguYk8oYSxiLlEsYyxkLlEs
+ZSl9aWYocj09PTExKXtpZihiPT09dS5nKXJldHVybiEwCmlmKHEpcmV0dXJuITEKcmV0dXJuIEguYk8o
+YSxiLGMsZCxlKX1pZih0PT09OSl7aWYociE9PTkpcmV0dXJuITEKcmV0dXJuIEgucEcoYSxiLGMsZCxl
+KX1yZXR1cm4hMX0sCmJPOmZ1bmN0aW9uKGEwLGExLGEyLGEzLGE0KXt2YXIgdCxzLHIscSxwLG8sbixt
+LGwsayxqLGksaCxnLGYsZSxkLGMsYixhCmlmKCFILldlKGEwLGExLlEsYTIsYTMuUSxhNCkpcmV0dXJu
+ITEKdD1hMS5jaApzPWEzLmNoCnI9dC5hCnE9cy5hCnA9ci5sZW5ndGgKbz1xLmxlbmd0aAppZihwPm8p
+cmV0dXJuITEKbj1vLXAKbT10LmIKbD1zLmIKaz1tLmxlbmd0aApqPWwubGVuZ3RoCmlmKHArazxvK2op
+cmV0dXJuITEKZm9yKGk9MDtpPHA7KytpKXtoPXJbaV0KaWYoIUguV2UoYTAscVtpXSxhNCxoLGEyKSly
+ZXR1cm4hMX1mb3IoaT0wO2k8bjsrK2kpe2g9bVtpXQppZighSC5XZShhMCxxW3AraV0sYTQsaCxhMikp
+cmV0dXJuITF9Zm9yKGk9MDtpPGo7KytpKXtoPW1bbitpXQppZighSC5XZShhMCxsW2ldLGE0LGgsYTIp
+KXJldHVybiExfWc9dC5jCmY9cy5jCmU9Zy5sZW5ndGgKZD1mLmxlbmd0aApmb3IoaT0wLGM9MDtjPGQ7
+Yys9Mil7Yj1mW2NdCmRve2lmKGk+PWUpcmV0dXJuITEKYT1nW2ldCmkrPTJ9d2hpbGUoYTxiKQppZihi
+PGEpcmV0dXJuITEKaD1nW2ktMV0KaWYoIUguV2UoYTAsZltjKzFdLGE0LGgsYTIpKXJldHVybiExfXJl
+dHVybiEwfSwKcEc6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9Yi5RLGs9
+ZC5RCmlmKGw9PT1rKXt0PWIuY2gKcz1kLmNoCnI9dC5sZW5ndGgKZm9yKHE9MDtxPHI7KytxKXtwPXRb
+cV0Kbz1zW3FdCmlmKCFILldlKGEscCxjLG8sZSkpcmV0dXJuITF9cmV0dXJuITB9bj1ILlFvKGEsbCkK
+aWYobj09bnVsbClyZXR1cm4hMQptPW5ba10KaWYobT09bnVsbClyZXR1cm4hMQpyPW0ubGVuZ3RoCnM9
+ZC5jaApmb3IocT0wO3E8cjsrK3EpaWYoIUguV2UoYSxILmNFKGEsYixtW3FdKSxjLHNbcV0sZSkpcmV0
+dXJuITEKcmV0dXJuITB9LApjYzpmdW5jdGlvbihhKXt2YXIgdCxzCmlmKGE9PT11LkspcmV0dXJuITAK
+dD1hLnoKaWYodCE9PTIpaWYodCE9PTMpaWYodCE9PTQpaWYodCE9PTUpcz10PT09OCYmSC5jYyhhLlEp
+CmVsc2Ugcz0hMAplbHNlIHM9ITAKZWxzZSBzPSEwCmVsc2Ugcz0hMApyZXR1cm4gc30sCkl4OmZ1bmN0
+aW9uKGEsYil7dmFyIHQscyxyPU9iamVjdC5rZXlzKGIpLHE9ci5sZW5ndGgKZm9yKHQ9MDt0PHE7Kyt0
+KXtzPXJbdF0KYVtzXT1iW3NdfX0sCkpjOmZ1bmN0aW9uIEpjKGEsYixjKXt2YXIgXz10aGlzCl8uYT1h
+Cl8uYj1iCl8uYz1jCl8ueT1fLng9Xy5kPW51bGwKXy56PTAKXy5kYj1fLmN5PV8uY3g9Xy5jaD1fLlE9
+bnVsbH0sCkc6ZnVuY3Rpb24gRygpe3RoaXMuYz10aGlzLmI9dGhpcy5hPW51bGx9LAp1OTpmdW5jdGlv
+biB1OSgpe30sCmh6OmZ1bmN0aW9uIGh6KGEpe3RoaXMuYT1hfSwKaU06ZnVuY3Rpb24gaU0oYSl7dGhp
+cy5hPWF9LApSOTpmdW5jdGlvbihhKXtyZXR1cm4gdS5kLmMoYSl8fHUuQi5jKGEpfHx1LmR6LmMoYSl8
+fHUuSS5jKGEpfHx1LkEuYyhhKXx8dS5nNC5jKGEpfHx1LmcyLmMoYSl9LApKZzpmdW5jdGlvbihhKXty
+ZXR1cm4gdi5tYW5nbGVkR2xvYmFsTmFtZXNbYV19fSxKPXsKUXU6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0
+dXJue2k6YSxwOmIsZTpjLHg6ZH19LAprczpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwPWFbdi5kaXNw
+YXRjaFByb3BlcnR5TmFtZV0KaWYocD09bnVsbClpZigkLkJ2PT1udWxsKXtILlhEKCkKcD1hW3YuZGlz
+cGF0Y2hQcm9wZXJ0eU5hbWVdfWlmKHAhPW51bGwpe3Q9cC5wCmlmKCExPT09dClyZXR1cm4gcC5pCmlm
+KCEwPT09dClyZXR1cm4gYQpzPU9iamVjdC5nZXRQcm90b3R5cGVPZihhKQppZih0PT09cylyZXR1cm4g
+cC5pCmlmKHAuZT09PXMpdGhyb3cgSC5iKFAuU1koIlJldHVybiBpbnRlcmNlcHRvciBmb3IgIitILmQo
+dChhLHApKSkpfXI9YS5jb25zdHJ1Y3RvcgpxPXI9PW51bGw/bnVsbDpyWyQuVU4oKV0KaWYocSE9bnVs
+bClyZXR1cm4gcQpxPUgudzMoYSkKaWYocSE9bnVsbClyZXR1cm4gcQppZih0eXBlb2YgYT09ImZ1bmN0
+aW9uIilyZXR1cm4gQy5ERwp0PU9iamVjdC5nZXRQcm90b3R5cGVPZihhKQppZih0PT1udWxsKXJldHVy
+biBDLlpRCmlmKHQ9PT1PYmplY3QucHJvdG90eXBlKXJldHVybiBDLlpRCmlmKHR5cGVvZiByPT0iZnVu
+Y3Rpb24iKXtPYmplY3QuZGVmaW5lUHJvcGVydHkociwkLlVOKCkse3ZhbHVlOkMudkIsZW51bWVyYWJs
+ZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSkKcmV0dXJuIEMudkJ9cmV0dXJu
+IEMudkJ9LApRaTpmdW5jdGlvbihhLGIpe2lmKGE8MHx8YT40Mjk0OTY3Mjk1KXRocm93IEguYihQLlRF
+KGEsMCw0Mjk0OTY3Mjk1LCJsZW5ndGgiLG51bGwpKQpyZXR1cm4gSi5weShuZXcgQXJyYXkoYSksYil9
+LApweTpmdW5jdGlvbihhLGIpe3JldHVybiBKLkVwKEguVk0oYSxiLkMoImpkPDA+IikpKX0sCkVwOmZ1
+bmN0aW9uKGEpe2EuZml4ZWQkbGVuZ3RoPUFycmF5CnJldHVybiBhfSwKekM6ZnVuY3Rpb24oYSl7YS5m
+aXhlZCRsZW5ndGg9QXJyYXkKYS5pbW11dGFibGUkbGlzdD1BcnJheQpyZXR1cm4gYX0sCkdhOmZ1bmN0
+aW9uKGEpe2lmKGE8MjU2KXN3aXRjaChhKXtjYXNlIDk6Y2FzZSAxMDpjYXNlIDExOmNhc2UgMTI6Y2Fz
+ZSAxMzpjYXNlIDMyOmNhc2UgMTMzOmNhc2UgMTYwOnJldHVybiEwCmRlZmF1bHQ6cmV0dXJuITF9c3dp
+dGNoKGEpe2Nhc2UgNTc2MDpjYXNlIDgxOTI6Y2FzZSA4MTkzOmNhc2UgODE5NDpjYXNlIDgxOTU6Y2Fz
+ZSA4MTk2OmNhc2UgODE5NzpjYXNlIDgxOTg6Y2FzZSA4MTk5OmNhc2UgODIwMDpjYXNlIDgyMDE6Y2Fz
+ZSA4MjAyOmNhc2UgODIzMjpjYXNlIDgyMzM6Y2FzZSA4MjM5OmNhc2UgODI4NzpjYXNlIDEyMjg4OmNh
+c2UgNjUyNzk6cmV0dXJuITAKZGVmYXVsdDpyZXR1cm4hMX19LAptbTpmdW5jdGlvbihhLGIpe3ZhciB0
+LHMKZm9yKHQ9YS5sZW5ndGg7Yjx0Oyl7cz1DLnhCLlcoYSxiKQppZihzIT09MzImJnMhPT0xMyYmIUou
+R2EocykpYnJlYWs7KytifXJldHVybiBifSwKYzE6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCmZvcig7Yj4w
+O2I9dCl7dD1iLTEKcz1DLnhCLm0oYSx0KQppZihzIT09MzImJnMhPT0xMyYmIUouR2EocykpYnJlYWt9
+cmV0dXJuIGJ9LApSRTpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJldHVybiBhCmlmKHR5cGVvZiBhIT0i
+b2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVy
+biBhfWlmKGEgaW5zdGFuY2VvZiBQLmspcmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LApUSjpmdW5jdGlv
+bihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIEoucUkucHJvdG90eXBlCmlmKHR5cGVvZiBh
+PT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5cGUKaWYoYT09bnVsbClyZXR1cm4gYQppZihhLmNv
+bnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5wcm90b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3Qi
+KXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYo
+YSBpbnN0YW5jZW9mIFAuaylyZXR1cm4gYQpyZXR1cm4gSi5rcyhhKX0sClU2OmZ1bmN0aW9uKGEpe2lm
+KHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5cGUKaWYoYT09bnVsbClyZXR1cm4g
+YQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5wcm90b3R5cGUKaWYodHlwZW9mIGEh
+PSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5cGUKcmV0
+dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuaylyZXR1cm4gYQpyZXR1cm4gSi5rcyhhKX0sCmlhOmZ1bmN0
+aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIil7aWYoTWF0aC5mbG9vcihhKT09YSlyZXR1cm4gSi51
+ci5wcm90b3R5cGUKcmV0dXJuIEouVkEucHJvdG90eXBlfWlmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1
+cm4gSi5Eci5wcm90b3R5cGUKaWYoYT09bnVsbClyZXR1cm4gSi5ZRS5wcm90b3R5cGUKaWYodHlwZW9m
+IGE9PSJib29sZWFuIilyZXR1cm4gSi55RS5wcm90b3R5cGUKaWYoYS5jb25zdHJ1Y3Rvcj09QXJyYXkp
+cmV0dXJuIEouamQucHJvdG90eXBlCmlmKHR5cGVvZiBhIT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJm
+dW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLmsp
+cmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LApyWTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09InN0cmlu
+ZyIpcmV0dXJuIEouRHIucHJvdG90eXBlCmlmKGE9PW51bGwpcmV0dXJuIGEKaWYoIShhIGluc3RhbmNl
+b2YgUC5rKSlyZXR1cm4gSi5rZC5wcm90b3R5cGUKcmV0dXJuIGF9LAp3MTpmdW5jdGlvbihhKXtpZihh
+PT1udWxsKXJldHVybiBhCmlmKGEuY29uc3RydWN0b3I9PUFycmF5KXJldHVybiBKLmpkLnByb3RvdHlw
+ZQppZih0eXBlb2YgYSE9Im9iamVjdCIpe2lmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBKLmM1
+LnByb3RvdHlwZQpyZXR1cm4gYX1pZihhIGluc3RhbmNlb2YgUC5rKXJldHVybiBhCnJldHVybiBKLmtz
+KGEpfSwKQ006ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIEouUkUoYSkuZHUoYSxiLGMsZCl9LApGTDpm
+dW5jdGlvbihhLGIpe3JldHVybiBKLnJZKGEpLmRkKGEsYil9LApHQTpmdW5jdGlvbihhLGIpe3JldHVy
+biBKLncxKGEpLkUoYSxiKX0sCkdyOmZ1bmN0aW9uKGEpe3JldHVybiBKLlJFKGEpLmdtVyhhKX0sCkht
+OmZ1bmN0aW9uKGEpe3JldHVybiBKLlU2KGEpLmdBKGEpfSwKSVQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEou
+dzEoYSkuZ2t6KGEpfSwKSnk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5pYShhKS5lNyhhLGIpfSwKS1Y6
+ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5yWShhKS5HKGEsYil9LApMdDpmdW5jdGlvbihhKXtyZXR1cm4g
+Si5SRShhKS53ZyhhKX0sCk0xOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi53MShhKS5FMihhLGIsYyl9
+LApRejpmdW5jdGlvbihhLGIpe3JldHVybiBKLnJZKGEpLlcoYSxiKX0sClJNOmZ1bmN0aW9uKGEsYil7
+aWYoYT09bnVsbClyZXR1cm4gYj09bnVsbAppZih0eXBlb2YgYSE9Im9iamVjdCIpcmV0dXJuIGIhPW51
+bGwmJmE9PT1iCnJldHVybiBKLmlhKGEpLkROKGEsYil9LApUMDpmdW5jdGlvbihhKXtyZXR1cm4gSi5y
+WShhKS5iUyhhKX0sCmE2OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkubShhLGIpfSwKYlQ6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIEouUkUoYSkuRDQoYSl9LApiYjpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBh
+PT0ibnVtYmVyIiYmdHlwZW9mIGI9PSJudW1iZXIiKXJldHVybiBhK2IKcmV0dXJuIEouVEooYSkuaChh
+LGIpfSwKY0g6ZnVuY3Rpb24oYSl7cmV0dXJuIEouclkoYSkuaGMoYSl9LApkUjpmdW5jdGlvbihhKXty
+ZXR1cm4gSi5SRShhKS5nUChhKX0sCmRaOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBKLlJFKGEpLk9u
+KGEsYixjLGQpfSwKZGc6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIEouclkoYSkuaTcoYSxiLGMsZCl9
+LApkaDpmdW5jdGlvbihhKXtyZXR1cm4gSi5SRShhKS5GRihhKX0sCmhmOmZ1bmN0aW9uKGEpe3JldHVy
+biBKLmlhKGEpLmdpTyhhKX0sCmh3OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkuVGMoYSxiKX0s
+CmlnOmZ1bmN0aW9uKGEpe3JldHVybiBKLlJFKGEpLmdRZyhhKX0sCmo6ZnVuY3Rpb24oYSl7cmV0dXJu
+IEouaWEoYSkudyhhKX0sCmw1OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouUkUoYSkuc2hmKGEsYil9LAps
+ZDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEouclkoYSkuTmooYSxiLGMpfSwKcTA6ZnVuY3Rpb24oYSxi
+LGMpe3JldHVybiBKLnJZKGEpLlFpKGEsYixjKX0sCnFGOmZ1bmN0aW9uKGEpe3JldHVybiBKLlJFKGEp
+LmdWbChhKX0sCnRIOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi5SRShhKS5wayhhLGIsYyl9LAp3Mjpm
+dW5jdGlvbihhLGIpe2lmKHR5cGVvZiBiPT09Im51bWJlciIpaWYoYS5jb25zdHJ1Y3Rvcj09QXJyYXl8
+fHR5cGVvZiBhPT0ic3RyaW5nInx8SC53VihhLGFbdi5kaXNwYXRjaFByb3BlcnR5TmFtZV0pKWlmKGI+
+Pj4wPT09YiYmYjxhLmxlbmd0aClyZXR1cm4gYVtiXQpyZXR1cm4gSi5VNihhKS5xKGEsYil9LAp6bDpm
+dW5jdGlvbihhLGIpe3JldHVybiBKLlU2KGEpLnRnKGEsYil9LAp2QjpmdW5jdGlvbiB2Qigpe30sCnlF
+OmZ1bmN0aW9uIHlFKCl7fSwKWUU6ZnVuY3Rpb24gWUUoKXt9LApNRjpmdW5jdGlvbiBNRigpe30sCmlD
+OmZ1bmN0aW9uIGlDKCl7fSwKa2Q6ZnVuY3Rpb24ga2QoKXt9LApjNTpmdW5jdGlvbiBjNSgpe30sCmpk
+OmZ1bmN0aW9uIGpkKGEpe3RoaXMuJHRpPWF9LApQbzpmdW5jdGlvbiBQbyhhKXt0aGlzLiR0aT1hfSwK
+bTE6ZnVuY3Rpb24gbTEoYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPTAKXy5kPW51bGwK
+Xy4kdGk9Y30sCnFJOmZ1bmN0aW9uIHFJKCl7fSwKdXI6ZnVuY3Rpb24gdXIoKXt9LApWQTpmdW5jdGlv
+biBWQSgpe30sCkRyOmZ1bmN0aW9uIERyKCl7fX0sUD17Ck9qOmZ1bmN0aW9uKCl7dmFyIHQscyxyPXt9
+CmlmKHNlbGYuc2NoZWR1bGVJbW1lZGlhdGUhPW51bGwpcmV0dXJuIFAuRVgoKQppZihzZWxmLk11dGF0
+aW9uT2JzZXJ2ZXIhPW51bGwmJnNlbGYuZG9jdW1lbnQhPW51bGwpe3Q9c2VsZi5kb2N1bWVudC5jcmVh
+dGVFbGVtZW50KCJkaXYiKQpzPXNlbGYuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3BhbiIpCnIuYT1u
+dWxsCm5ldyBzZWxmLk11dGF0aW9uT2JzZXJ2ZXIoSC50UihuZXcgUC50aChyKSwxKSkub2JzZXJ2ZSh0
+LHtjaGlsZExpc3Q6dHJ1ZX0pCnJldHVybiBuZXcgUC5oYShyLHQscyl9ZWxzZSBpZihzZWxmLnNldElt
+bWVkaWF0ZSE9bnVsbClyZXR1cm4gUC55dCgpCnJldHVybiBQLnFXKCl9LApaVjpmdW5jdGlvbihhKXtz
+ZWxmLnNjaGVkdWxlSW1tZWRpYXRlKEgudFIobmV3IFAuVnModS5NLmIoYSkpLDApKX0sCm9BOmZ1bmN0
+aW9uKGEpe3NlbGYuc2V0SW1tZWRpYXRlKEgudFIobmV3IFAuRnQodS5NLmIoYSkpLDApKX0sCkJ6OmZ1
+bmN0aW9uKGEpe3UuTS5iKGEpClAuUU4oMCxhKX0sClFOOmZ1bmN0aW9uKGEsYil7dmFyIHQ9bmV3IFAu
+VzMoKQp0LkNZKGEsYikKcmV0dXJuIHR9LApGWDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuaWgobmV3
+IFAudnMoJC5YMyxhLkMoInZzPDA+IikpLGEuQygiaWg8MD4iKSl9LApESTpmdW5jdGlvbihhLGIpe2Eu
+JDIoMCxudWxsKQpiLmI9ITAKcmV0dXJuIGIuYX0sCmpROmZ1bmN0aW9uKGEsYil7UC5KZShhLGIpfSwK
+eUM6ZnVuY3Rpb24oYSxiKXtiLmFNKDAsYSl9LApmMzpmdW5jdGlvbihhLGIpe2IudzAoSC5SdShhKSxI
+LnRzKGEpKX0sCkplOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPW5ldyBQLldNKGIpLHE9bmV3IFAuU1go
+YikKaWYoYSBpbnN0YW5jZW9mIFAudnMpYS5RZChyLHEsdS56KQplbHNle3Q9dS56CmlmKHUuYy5jKGEp
+KWEuU3EocixxLHQpCmVsc2V7cz1uZXcgUC52cygkLlgzLHUuXykKcy5hPTQKcy5jPWEKcy5RZChyLG51
+bGwsdCl9fX0sCmx6OmZ1bmN0aW9uKGEpe3ZhciB0PWZ1bmN0aW9uKGIsYyl7cmV0dXJuIGZ1bmN0aW9u
+KGQsZSl7d2hpbGUodHJ1ZSl0cnl7YihkLGUpCmJyZWFrfWNhdGNoKHMpe2U9cwpkPWN9fX0oYSwxKQpy
+ZXR1cm4gJC5YMy5MaihuZXcgUC5Hcyh0KSx1LlAsdS5lZyx1LnopfSwKR1E6ZnVuY3Rpb24oYSl7cmV0
+dXJuIG5ldyBQLkZ5KGEsMSl9LApUaDpmdW5jdGlvbigpe3JldHVybiBDLndRfSwKWW06ZnVuY3Rpb24o
+YSl7cmV0dXJuIG5ldyBQLkZ5KGEsMyl9LApsMDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgUC5xNChh
+LGIuQygicTQ8MD4iKSl9LAprMzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscgpiLmE9MQp0cnl7YS5TcShu
+ZXcgUC5wVihiKSxuZXcgUC5VNyhiKSx1LlApfWNhdGNoKHIpe3Q9SC5SdShyKQpzPUgudHMocikKUC5y
+YihuZXcgUC52cihiLHQscykpfX0sCkE5OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCmZvcih0PXUuXztz
+PWEuYSxzPT09MjspYT10LmIoYS5jKQppZihzPj00KXtyPWIuYWgoKQpiLmE9YS5hCmIuYz1hLmMKUC5I
+WihiLHIpfWVsc2V7cj11LnguYihiLmMpCmIuYT0yCmIuYz1hCmEualEocil9fSwKSFo6ZnVuY3Rpb24o
+YSxiKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZT1udWxsLGQ9e30sYz1kLmE9YQpm
+b3IodD11Lm4scz11Lngscj11LmM7ITA7KXtxPXt9CnA9Yy5hPT09OAppZihiPT1udWxsKXtpZihwKXtv
+PXQuYihjLmMpClAuTDIoZSxlLGMuYixvLmEsby5iKX1yZXR1cm59Zm9yKDtuPWIuYSxuIT1udWxsO2I9
+bil7Yi5hPW51bGwKUC5IWihkLmEsYil9Yz1kLmEKbT1jLmMKcS5hPXAKcS5iPW0KbD0hcAppZihsKXtr
+PWIuYwprPShrJjEpIT09MHx8KGsmMTUpPT09OH1lbHNlIGs9ITAKaWYoayl7az1iLmIKaj1rLmIKaWYo
+cCl7aT1jLmI9PT1qCmk9IShpfHxpKX1lbHNlIGk9ITEKaWYoaSl7dC5iKG0pClAuTDIoZSxlLGMuYixt
+LmEsbS5iKQpyZXR1cm59aD0kLlgzCmlmKGghPT1qKSQuWDM9agplbHNlIGg9ZQpjPWIuYwppZigoYyYx
+NSk9PT04KW5ldyBQLlJUKGQscSxiLHApLiQwKCkKZWxzZSBpZihsKXtpZigoYyYxKSE9PTApbmV3IFAu
+cnEocSxiLG0pLiQwKCl9ZWxzZSBpZigoYyYyKSE9PTApbmV3IFAuUlcoZCxxLGIpLiQwKCkKaWYoaCE9
+bnVsbCkkLlgzPWgKYz1xLmIKaWYoci5jKGMpKXtpZihjLmE+PTQpe2c9cy5iKGsuYykKay5jPW51bGwK
+Yj1rLk44KGcpCmsuYT1jLmEKay5jPWMuYwpkLmE9Ywpjb250aW51ZX1lbHNlIFAuQTkoYyxrKQpyZXR1
+cm59fWY9Yi5iCmc9cy5iKGYuYykKZi5jPW51bGwKYj1mLk44KGcpCmM9cS5hCmw9cS5iCmlmKCFjKXtm
+LiR0aS5kLmIobCkKZi5hPTQKZi5jPWx9ZWxzZXt0LmIobCkKZi5hPTgKZi5jPWx9ZC5hPWYKYz1mfX0s
+ClZIOmZ1bmN0aW9uKGEsYil7dmFyIHQKaWYodS5GLmMoYSkpcmV0dXJuIGIuTGooYSx1LnosdS5LLHUu
+bCkKdD11LnkKaWYodC5jKGEpKXJldHVybiB0LmIoYSkKdGhyb3cgSC5iKFAuTDMoYSwib25FcnJvciIs
+IkVycm9yIGhhbmRsZXIgbXVzdCBhY2NlcHQgb25lIE9iamVjdCBvciBvbmUgT2JqZWN0IGFuZCBhIFN0
+YWNrVHJhY2UgYXMgYXJndW1lbnRzLCBhbmQgcmV0dXJuIGEgYSB2YWxpZCByZXN1bHQiKSl9LApwdTpm
+dW5jdGlvbigpe3ZhciB0LHMKZm9yKDt0PSQuUzYsdCE9bnVsbDspeyQubWc9bnVsbApzPXQuYgokLlM2
+PXMKaWYocz09bnVsbCkkLms4PW51bGwKdC5hLiQwKCl9fSwKZU46ZnVuY3Rpb24oKXskLlVEPSEwCnRy
+eXtQLnB1KCl9ZmluYWxseXskLm1nPW51bGwKJC5VRD0hMQppZigkLlM2IT1udWxsKSQudXQoKS4kMShQ
+LlVJKCkpfX0sCmVXOmZ1bmN0aW9uKGEpe3ZhciB0PW5ldyBQLk9NKGEpCmlmKCQuUzY9PW51bGwpeyQu
+UzY9JC5rOD10CmlmKCEkLlVEKSQudXQoKS4kMShQLlVJKCkpfWVsc2UgJC5rOD0kLms4LmI9dH0sCnJS
+OmZ1bmN0aW9uKGEpe3ZhciB0LHMscj0kLlM2CmlmKHI9PW51bGwpe1AuZVcoYSkKJC5tZz0kLms4CnJl
+dHVybn10PW5ldyBQLk9NKGEpCnM9JC5tZwppZihzPT1udWxsKXt0LmI9cgokLlM2PSQubWc9dH1lbHNl
+e3QuYj1zLmIKJC5tZz1zLmI9dAppZih0LmI9PW51bGwpJC5rOD10fX0sCnJiOmZ1bmN0aW9uKGEpe3Zh
+ciB0PW51bGwscz0kLlgzCmlmKEMuTlU9PT1zKXtQLlRrKHQsdCxDLk5VLGEpCnJldHVybn1QLlRrKHQs
+dCxzLHUuTS5iKHMuR1koYSkpKX0sClF3OmZ1bmN0aW9uKGEsYil7aWYoYT09bnVsbClILnZoKFAuRWUo
+InN0cmVhbSIpKQpyZXR1cm4gbmV3IFAueEkoYi5DKCJ4STwwPiIpKX0sCkwyOmZ1bmN0aW9uKGEsYixj
+LGQsZSl7dmFyIHQ9e30KdC5hPWQKUC5yUihuZXcgUC5wSyh0LGUpKX0sClQ4OmZ1bmN0aW9uKGEsYixj
+LGQsZSl7dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQwKCkKJC5YMz1jCnQ9cwp0cnl7cz1k
+LiQwKCkKcmV0dXJuIHN9ZmluYWxseXskLlgzPXR9fSwKeXY6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7
+dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQxKGUpCiQuWDM9Ywp0PXMKdHJ5e3M9ZC4kMShl
+KQpyZXR1cm4gc31maW5hbGx5eyQuWDM9dH19LApReDpmdW5jdGlvbihhLGIsYyxkLGUsZixnLGgsaSl7
+dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQyKGUsZikKJC5YMz1jCnQ9cwp0cnl7cz1kLiQy
+KGUsZikKcmV0dXJuIHN9ZmluYWxseXskLlgzPXR9fSwKVGs6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQK
+dS5NLmIoZCkKdD1DLk5VIT09YwppZih0KWQ9ISghdHx8ITEpP2MuR1koZCk6Yy5SVChkLHUuSCkKUC5l
+VyhkKX0sCnRoOmZ1bmN0aW9uIHRoKGEpe3RoaXMuYT1hfSwKaGE6ZnVuY3Rpb24gaGEoYSxiLGMpe3Ro
+aXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKVnM6ZnVuY3Rpb24gVnMoYSl7dGhpcy5hPWF9LApGdDpm
+dW5jdGlvbiBGdChhKXt0aGlzLmE9YX0sClczOmZ1bmN0aW9uIFczKCl7fSwKeUg6ZnVuY3Rpb24geUgo
+YSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCmloOmZ1bmN0aW9uIGloKGEsYil7dGhpcy5hPWEKdGhpcy5i
+PSExCnRoaXMuJHRpPWJ9LApXTTpmdW5jdGlvbiBXTShhKXt0aGlzLmE9YX0sClNYOmZ1bmN0aW9uIFNY
+KGEpe3RoaXMuYT1hfSwKR3M6ZnVuY3Rpb24gR3MoYSl7dGhpcy5hPWF9LApGeTpmdW5jdGlvbiBGeShh
+LGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKR1Y6ZnVuY3Rpb24gR1YoYSxiKXt2YXIgXz10aGlzCl8uYT1h
+Cl8uZD1fLmM9Xy5iPW51bGwKXy4kdGk9Yn0sCnE0OmZ1bmN0aW9uIHE0KGEsYil7dGhpcy5hPWEKdGhp
+cy4kdGk9Yn0sCmI4OmZ1bmN0aW9uIGI4KCl7fSwKUGY6ZnVuY3Rpb24gUGYoKXt9LApaZjpmdW5jdGlv
+biBaZihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApGZTpmdW5jdGlvbiBGZShhLGIsYyxkLGUpe3Zh
+ciBfPXRoaXMKXy5hPW51bGwKXy5iPWEKXy5jPWIKXy5kPWMKXy5lPWQKXy4kdGk9ZX0sCnZzOmZ1bmN0
+aW9uIHZzKGEsYil7dmFyIF89dGhpcwpfLmE9MApfLmI9YQpfLmM9bnVsbApfLiR0aT1ifSwKZGE6ZnVu
+Y3Rpb24gZGEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCm9ROmZ1bmN0aW9uIG9RKGEsYil7dGhpcy5h
+PWEKdGhpcy5iPWJ9LApwVjpmdW5jdGlvbiBwVihhKXt0aGlzLmE9YX0sClU3OmZ1bmN0aW9uIFU3KGEp
+e3RoaXMuYT1hfSwKdnI6ZnVuY3Rpb24gdnIoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1j
+fSwKckg6ZnVuY3Rpb24gckgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCktGOmZ1bmN0aW9uIEtGKGEs
+Yil7dGhpcy5hPWEKdGhpcy5iPWJ9LApaTDpmdW5jdGlvbiBaTChhLGIsYyl7dGhpcy5hPWEKdGhpcy5i
+PWIKdGhpcy5jPWN9LApSVDpmdW5jdGlvbiBSVChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1i
+Cl8uYz1jCl8uZD1kfSwKalo6ZnVuY3Rpb24galooYSl7dGhpcy5hPWF9LApycTpmdW5jdGlvbiBycShh
+LGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApSVzpmdW5jdGlvbiBSVyhhLGIsYyl7dGhp
+cy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApPTTpmdW5jdGlvbiBPTShhKXt0aGlzLmE9YQp0aGlzLmI9
+bnVsbH0sCnFoOmZ1bmN0aW9uIHFoKCl7fSwKQjU6ZnVuY3Rpb24gQjUoYSxiKXt0aGlzLmE9YQp0aGlz
+LmI9Yn0sCnVPOmZ1bmN0aW9uIHVPKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApNTzpmdW5jdGlvbiBN
+Tygpe30sCmtUOmZ1bmN0aW9uIGtUKCl7fSwKeEk6ZnVuY3Rpb24geEkoYSl7dGhpcy4kdGk9YX0sCkN3
+OmZ1bmN0aW9uIEN3KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAptMDpmdW5jdGlvbiBtMCgpe30sCnBL
+OmZ1bmN0aW9uIHBLKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApKaTpmdW5jdGlvbiBKaSgpe30sCmhq
+OmZ1bmN0aW9uIGhqKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClZwOmZ1bmN0aW9u
+IFZwKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApPUjpmdW5jdGlvbiBPUihhLGIsYyl7dGhpcy5hPWEK
+dGhpcy5iPWIKdGhpcy5jPWN9LApFRjpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIGIuQygiQDwwPiIpLktx
+KGMpLkMoIkZvPDEsMj4iKS5iKEguQjcoYSxuZXcgSC5ONShiLkMoIkA8MD4iKS5LcShjKS5DKCJONTwx
+LDI+IikpKSl9LApGbDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgSC5ONShhLkMoIkA8MD4iKS5LcShi
+KS5DKCJONTwxLDI+IikpfSwKTHM6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLmI2KGEuQygiYjY8MD4i
+KSl9LApUMjpmdW5jdGlvbigpe3ZhciB0PU9iamVjdC5jcmVhdGUobnVsbCkKdFsiPG5vbi1pZGVudGlm
+aWVyLWtleT4iXT10CmRlbGV0ZSB0WyI8bm9uLWlkZW50aWZpZXIta2V5PiJdCnJldHVybiB0fSwKcmo6
+ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PW5ldyBQLmxtKGEsYixjLkMoImxtPDA+IikpCnQuYz1hLmUKcmV0
+dXJuIHR9LApFUDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscwppZihQLmhCKGEpKXtpZihiPT09IigiJiZj
+PT09IikiKXJldHVybiIoLi4uKSIKcmV0dXJuIGIrIi4uLiIrY310PUguVk0oW10sdS5zKQpDLk5tLmko
+JC54ZyxhKQp0cnl7UC5WcihhLHQpfWZpbmFsbHl7aWYoMD49JC54Zy5sZW5ndGgpcmV0dXJuIEguT0go
+JC54ZywtMSkKJC54Zy5wb3AoKX1zPVAudmcoYix1LlIuYih0KSwiLCAiKStjCnJldHVybiBzLmNoYXJD
+b2RlQXQoMCk9PTA/czpzfSwKV0U6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMKaWYoUC5oQihhKSlyZXR1
+cm4gYisiLi4uIitjCnQ9bmV3IFAuUm4oYikKQy5ObS5pKCQueGcsYSkKdHJ5e3M9dApzLmE9UC52Zyhz
+LmEsYSwiLCAiKX1maW5hbGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILk9IKCQueGcsLTEpCiQu
+eGcucG9wKCl9dC5hKz1jCnM9dC5hCnJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpzfSwKaEI6ZnVu
+Y3Rpb24oYSl7dmFyIHQscwpmb3IodD0kLnhnLmxlbmd0aCxzPTA7czx0OysrcylpZihhPT09JC54Z1tz
+XSlyZXR1cm4hMApyZXR1cm4hMX0sClZyOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG4sbT1h
+LmdreihhKSxsPTAsaz0wCndoaWxlKCEwKXtpZighKGw8ODB8fGs8MykpYnJlYWsKaWYoIW0uRigpKXJl
+dHVybgp0PUguZChtLmdsKCkpCkMuTm0uaShiLHQpCmwrPXQubGVuZ3RoKzI7KytrfWlmKCFtLkYoKSl7
+aWYoazw9NSlyZXR1cm4KaWYoMD49Yi5sZW5ndGgpcmV0dXJuIEguT0goYiwtMSkKcz1iLnBvcCgpCmlm
+KDA+PWIubGVuZ3RoKXJldHVybiBILk9IKGIsLTEpCnI9Yi5wb3AoKX1lbHNle3E9bS5nbCgpOysrawpp
+ZighbS5GKCkpe2lmKGs8PTQpe0MuTm0uaShiLEguZChxKSkKcmV0dXJufXM9SC5kKHEpCmlmKDA+PWIu
+bGVuZ3RoKXJldHVybiBILk9IKGIsLTEpCnI9Yi5wb3AoKQpsKz1zLmxlbmd0aCsyfWVsc2V7cD1tLmds
+KCk7KytrCmZvcig7bS5GKCk7cT1wLHA9byl7bz1tLmdsKCk7KytrCmlmKGs+MTAwKXt3aGlsZSghMCl7
+aWYoIShsPjc1JiZrPjMpKWJyZWFrCmlmKDA+PWIubGVuZ3RoKXJldHVybiBILk9IKGIsLTEpCmwtPWIu
+cG9wKCkubGVuZ3RoKzI7LS1rfUMuTm0uaShiLCIuLi4iKQpyZXR1cm59fXI9SC5kKHEpCnM9SC5kKHAp
+CmwrPXMubGVuZ3RoK3IubGVuZ3RoKzR9fWlmKGs+Yi5sZW5ndGgrMil7bCs9NQpuPSIuLi4ifWVsc2Ug
+bj1udWxsCndoaWxlKCEwKXtpZighKGw+ODAmJmIubGVuZ3RoPjMpKWJyZWFrCmlmKDA+PWIubGVuZ3Ro
+KXJldHVybiBILk9IKGIsLTEpCmwtPWIucG9wKCkubGVuZ3RoKzIKaWYobj09bnVsbCl7bCs9NQpuPSIu
+Li4ifX1pZihuIT1udWxsKUMuTm0uaShiLG4pCkMuTm0uaShiLHIpCkMuTm0uaShiLHMpfSwKdE06ZnVu
+Y3Rpb24oYSxiKXt2YXIgdCxzLHI9UC5McyhiKQpmb3IodD1hLmxlbmd0aCxzPTA7czxhLmxlbmd0aDth
+Lmxlbmd0aD09PXR8fCgwLEgubGspKGEpLCsrcylyLmkoMCxiLmIoYVtzXSkpCnJldHVybiByfSwKbk86
+ZnVuY3Rpb24oYSl7dmFyIHQscz17fQppZihQLmhCKGEpKXJldHVybiJ7Li4ufSIKdD1uZXcgUC5Sbigi
+IikKdHJ5e0MuTm0uaSgkLnhnLGEpCnQuYSs9InsiCnMuYT0hMAphLksoMCxuZXcgUC5yYShzLHQpKQp0
+LmErPSJ9In1maW5hbGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILk9IKCQueGcsLTEpCiQueGcu
+cG9wKCl9cz10LmEKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9LApiNjpmdW5jdGlvbiBiNihh
+KXt2YXIgXz10aGlzCl8uYT0wCl8uZj1fLmU9Xy5kPV8uYz1fLmI9bnVsbApfLnI9MApfLiR0aT1hfSwK
+Ym46ZnVuY3Rpb24gYm4oYSl7dGhpcy5hPWEKdGhpcy5jPXRoaXMuYj1udWxsfSwKbG06ZnVuY3Rpb24g
+bG0oYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPV8uYz1udWxsCl8uJHRpPWN9LAptVzpm
+dW5jdGlvbiBtVygpe30sCkxVOmZ1bmN0aW9uIExVKCl7fSwKbEQ6ZnVuY3Rpb24gbEQoKXt9LAppbDpm
+dW5jdGlvbiBpbCgpe30sCnJhOmZ1bmN0aW9uIHJhKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApZazpm
+dW5jdGlvbiBZaygpe30sCnlROmZ1bmN0aW9uIHlRKGEpe3RoaXMuYT1hfSwKS1A6ZnVuY3Rpb24gS1Ao
+KXt9LApQbjpmdW5jdGlvbiBQbigpe30sCkdqOmZ1bmN0aW9uIEdqKGEsYil7dGhpcy5hPWEKdGhpcy4k
+dGk9Yn0sCmxmOmZ1bmN0aW9uIGxmKCl7fSwKVmo6ZnVuY3Rpb24gVmooKXt9LApYdjpmdW5jdGlvbiBY
+digpe30sCm5ZOmZ1bmN0aW9uIG5ZKCl7fSwKVEM6ZnVuY3Rpb24gVEMoKXt9LApSVTpmdW5jdGlvbiBS
+VSgpe30sCkJTOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEKaWYodHlwZW9mIGEhPSJzdHJpbmciKXRo
+cm93IEguYihILnRMKGEpKQp0PW51bGwKdHJ5e3Q9SlNPTi5wYXJzZShhKX1jYXRjaChyKXtzPUguUnUo
+cikKcT1QLnJyKFN0cmluZyhzKSxudWxsLG51bGwpCnRocm93IEguYihxKX1xPVAuUWUodCkKcmV0dXJu
+IHF9LApRZTpmdW5jdGlvbihhKXt2YXIgdAppZihhPT1udWxsKXJldHVybiBudWxsCmlmKHR5cGVvZiBh
+IT0ib2JqZWN0IilyZXR1cm4gYQppZihPYmplY3QuZ2V0UHJvdG90eXBlT2YoYSkhPT1BcnJheS5wcm90
+b3R5cGUpcmV0dXJuIG5ldyBQLnV3KGEsT2JqZWN0LmNyZWF0ZShudWxsKSkKZm9yKHQ9MDt0PGEubGVu
+Z3RoOysrdClhW3RdPVAuUWUoYVt0XSkKcmV0dXJuIGF9LApreTpmdW5jdGlvbihhLGIsYyxkKXtpZihi
+IGluc3RhbmNlb2YgVWludDhBcnJheSlyZXR1cm4gUC5SUCghMSxiLGMsZCkKcmV0dXJuIG51bGx9LApS
+UDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHI9JC5yZigpCmlmKHI9PW51bGwpcmV0dXJuIG51bGwK
+dD0wPT09YwppZih0JiYhMClyZXR1cm4gUC5PUShyLGIpCnM9Yi5sZW5ndGgKZD1QLmpCKGMsZCxzKQpp
+Zih0JiZkPT09cylyZXR1cm4gUC5PUShyLGIpCnJldHVybiBQLk9RKHIsYi5zdWJhcnJheShjLGQpKX0s
+Ck9ROmZ1bmN0aW9uKGEsYil7aWYoUC5CZShiKSlyZXR1cm4gbnVsbApyZXR1cm4gUC5KaChhLGIpfSwK
+Smg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCnRyeXt0PWEuZGVjb2RlKGIpCnJldHVybiB0fWNhdGNoKHMp
+e0guUnUocyl9cmV0dXJuIG51bGx9LApCZTpmdW5jdGlvbihhKXt2YXIgdCxzPWEubGVuZ3RoLTIKZm9y
+KHQ9MDt0PHM7Kyt0KWlmKGFbdF09PT0yMzcpaWYoKGFbdCsxXSYyMjQpPT09MTYwKXJldHVybiEwCnJl
+dHVybiExfSwKV0k6ZnVuY3Rpb24oKXt2YXIgdCxzCnRyeXt0PW5ldyBUZXh0RGVjb2RlcigidXRmLTgi
+LHtmYXRhbDp0cnVlfSkKcmV0dXJuIHR9Y2F0Y2gocyl7SC5SdShzKX1yZXR1cm4gbnVsbH0sCmNQOmZ1
+bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIKZm9yKHQ9Si5VNihhKSxzPWI7czxjOysrcyl7cj10LnEoYSxz
+KQppZih0eXBlb2YgciE9PSJudW1iZXIiKXJldHVybiByLnpNKCkKaWYoKHImMTI3KSE9PXIpcmV0dXJu
+IHMtYn1yZXR1cm4gYy1ifSwKeE06ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe2lmKEMuam4uelkoZiw0KSE9
+PTApdGhyb3cgSC5iKFAucnIoIkludmFsaWQgYmFzZTY0IHBhZGRpbmcsIHBhZGRlZCBsZW5ndGggbXVz
+dCBiZSBtdWx0aXBsZSBvZiBmb3VyLCBpcyAiK2YsYSxjKSkKaWYoZCtlIT09Zil0aHJvdyBILmIoUC5y
+cigiSW52YWxpZCBiYXNlNjQgcGFkZGluZywgJz0nIG5vdCBhdCB0aGUgZW5kIixhLGIpKQppZihlPjIp
+dGhyb3cgSC5iKFAucnIoIkludmFsaWQgYmFzZTY0IHBhZGRpbmcsIG1vcmUgdGhhbiB0d28gJz0nIGNo
+YXJhY3RlcnMiLGEsYikpfSwKdXc6ZnVuY3Rpb24gdXcoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlz
+LmM9bnVsbH0sCmk4OmZ1bmN0aW9uIGk4KGEpe3RoaXMuYT1hfSwKQ1Y6ZnVuY3Rpb24gQ1YoKXt9LApV
+ODpmdW5jdGlvbiBVOCgpe30sClVrOmZ1bmN0aW9uIFVrKCl7fSwKd0k6ZnVuY3Rpb24gd0koKXt9LApa
+aTpmdW5jdGlvbiBaaSgpe30sCmJ5OmZ1bmN0aW9uIGJ5KCl7fSwKTXg6ZnVuY3Rpb24gTXgoYSl7dGhp
+cy5hPWF9LAp1NTpmdW5jdGlvbiB1NSgpe30sCkUzOmZ1bmN0aW9uIEUzKCl7fSwKUnc6ZnVuY3Rpb24g
+UncoYSl7dGhpcy5iPTAKdGhpcy5jPWF9LApHWTpmdW5jdGlvbiBHWShhKXt0aGlzLmE9YX0sCmJ6OmZ1
+bmN0aW9uIGJ6KGEsYil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9ITAKXy5mPV8uZT1fLmQ9MH0s
+ClFBOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILkhwKGEsYykKaWYodCE9bnVsbClyZXR1cm4gdAppZihi
+IT1udWxsKXJldHVybiBiLiQxKGEpCnRocm93IEguYihQLnJyKGEsbnVsbCxudWxsKSl9LApGOmZ1bmN0
+aW9uKGEpe2lmKGEgaW5zdGFuY2VvZiBILlRwKXJldHVybiBhLncoMCkKcmV0dXJuIkluc3RhbmNlIG9m
+ICciK0guZChILk0oYSkpKyInIn0sCk84OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPUouUWkoYSxjKQpp
+ZihhIT09MCYmITApZm9yKHQ9MDt0PHMubGVuZ3RoOysrdClDLk5tLlkocyx0LGIpCnJldHVybiBzfSwK
+Q0g6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9SC5WTShbXSxjLkMoImpkPDA+IikpCmZvcih0PUouSVQo
+YSk7dC5GKCk7KUMuTm0uaShzLGMuYih0LmdsKCkpKQppZihiKXJldHVybiBzCnJldHVybiBjLkMoInpN
+PDA+IikuYihKLkVwKHMpKX0sCkFGOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGIuQygiek08MD4iKS5iKEou
+ekMoUC5DSChhLCExLGIpKSl9LApITTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKaWYoQXJyYXkuaXNBcnJh
+eShhKSl7dS50LmIoYSkKdD1hLmxlbmd0aApjPVAuakIoYixjLHQpCnJldHVybiBILmVUKGI+MHx8Yzx0
+P0MuTm0uRDYoYSxiLGMpOmEpfWlmKHUuYm0uYyhhKSlyZXR1cm4gSC5mdyhhLGIsUC5qQihiLGMsYS5s
+ZW5ndGgpKQpyZXR1cm4gUC5idyhhLGIsYyl9LApPbzpmdW5jdGlvbihhKXtyZXR1cm4gSC5MdyhhKX0s
+CmJ3OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwPW51bGwKaWYoYjwwKXRocm93IEguYihQLlRF
+KGIsMCxKLkhtKGEpLHAscCkpCnQ9Yz09bnVsbAppZighdCYmYzxiKXRocm93IEguYihQLlRFKGMsYixK
+LkhtKGEpLHAscCkpCnM9Si5JVChhKQpmb3Iocj0wO3I8YjsrK3IpaWYoIXMuRigpKXRocm93IEguYihQ
+LlRFKGIsMCxyLHAscCkpCnE9W10KaWYodClmb3IoO3MuRigpOylxLnB1c2gocy5nbCgpKQplbHNlIGZv
+cihyPWI7cjxjOysrcil7aWYoIXMuRigpKXRocm93IEguYihQLlRFKGMsYixyLHAscCkpCnEucHVzaChz
+LmdsKCkpfXJldHVybiBILmVUKHEpfSwKbnU6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILlZSKGEsSC52
+NChhLCExLCEwLCExLCExLCExKSl9LAp2ZzpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9Si5JVChiKQppZigh
+dC5GKCkpcmV0dXJuIGEKaWYoYy5sZW5ndGg9PT0wKXtkbyBhKz1ILmQodC5nbCgpKQp3aGlsZSh0LkYo
+KSl9ZWxzZXthKz1ILmQodC5nbCgpKQpmb3IoO3QuRigpOylhPWErYytILmQodC5nbCgpKX1yZXR1cm4g
+YX0sCmxyOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBuZXcgUC5tcChhLGIsYyxkKX0sCnVvOmZ1bmN0
+aW9uKCl7dmFyIHQ9SC5NMCgpCmlmKHQhPW51bGwpcmV0dXJuIFAuaEsodCkKdGhyb3cgSC5iKFAuTDQo
+IidVcmkuYmFzZScgaXMgbm90IHN1cHBvcnRlZCIpKX0sCmVQOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0
+LHMscixxLHAsbyxuPSIwMTIzNDU2Nzg5QUJDREVGIgppZihjPT09Qy54TSl7dD0kLno0KCkuYgppZih0
+eXBlb2YgYiE9InN0cmluZyIpSC52aChILnRMKGIpKQp0PXQudGVzdChiKX1lbHNlIHQ9ITEKaWYodCly
+ZXR1cm4gYgpILkxoKGMpLkMoIlVrLlMiKS5iKGIpCnM9Yy5nWkUoKS5XSihiKQpmb3IodD1zLmxlbmd0
+aCxyPTAscT0iIjtyPHQ7KytyKXtwPXNbcl0KaWYocDwxMjgpe289cD4+PjQKaWYobz49OClyZXR1cm4g
+SC5PSChhLG8pCm89KGFbb10mMTw8KHAmMTUpKSE9PTB9ZWxzZSBvPSExCmlmKG8pcSs9SC5MdyhwKQpl
+bHNlIHE9ZCYmcD09PTMyP3ErIisiOnErIiUiK25bcD4+PjQmMTVdK25bcCYxNV19cmV0dXJuIHEuY2hh
+ckNvZGVBdCgwKT09MD9xOnF9LApHcTpmdW5jdGlvbihhKXt2YXIgdD1NYXRoLmFicyhhKSxzPWE8MD8i
+LSI6IiIKaWYodD49MTAwMClyZXR1cm4iIithCmlmKHQ+PTEwMClyZXR1cm4gcysiMCIrdAppZih0Pj0x
+MClyZXR1cm4gcysiMDAiK3QKcmV0dXJuIHMrIjAwMCIrdH0sClZ4OmZ1bmN0aW9uKGEpe2lmKGE+PTEw
+MClyZXR1cm4iIithCmlmKGE+PTEwKXJldHVybiIwIithCnJldHVybiIwMCIrYX0sCmgwOmZ1bmN0aW9u
+KGEpe2lmKGE+PTEwKXJldHVybiIiK2EKcmV0dXJuIjAiK2F9LApwOmZ1bmN0aW9uKGEpe2lmKHR5cGVv
+ZiBhPT0ibnVtYmVyInx8SC5sKGEpfHxudWxsPT1hKXJldHVybiBKLmooYSkKaWYodHlwZW9mIGE9PSJz
+dHJpbmciKXJldHVybiBKU09OLnN0cmluZ2lmeShhKQpyZXR1cm4gUC5GKGEpfSwKaFY6ZnVuY3Rpb24o
+YSl7cmV0dXJuIG5ldyBQLkM2KGEpfSwKeFk6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnUoITEsbnVs
+bCxudWxsLGEpfSwKTDM6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBuZXcgUC51KCEwLGEsYixjKX0sCkVl
+OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC51KCExLG51bGwsYSwiTXVzdCBub3QgYmUgbnVsbCIpfSwK
+eDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgUC5iSihudWxsLG51bGwsITAsYSxiLCJWYWx1ZSBub3Qg
+aW4gcmFuZ2UiKX0sClRFOmZ1bmN0aW9uKGEsYixjLGQsZSl7cmV0dXJuIG5ldyBQLmJKKGIsYywhMCxh
+LGQsIkludmFsaWQgdmFsdWUiKX0sCndBOmZ1bmN0aW9uKGEsYixjLGQpe2lmKGE8Ynx8YT5jKXRocm93
+IEguYihQLlRFKGEsYixjLGQsbnVsbCkpfSwKakI6ZnVuY3Rpb24oYSxiLGMpe2lmKDA+YXx8YT5jKXRo
+cm93IEguYihQLlRFKGEsMCxjLCJzdGFydCIsbnVsbCkpCmlmKGIhPW51bGwpe2lmKGE+Ynx8Yj5jKXRo
+cm93IEguYihQLlRFKGIsYSxjLCJlbmQiLG51bGwpKQpyZXR1cm4gYn1yZXR1cm4gY30sCmsxOmZ1bmN0
+aW9uKGEsYil7aWYodHlwZW9mIGEhPT0ibnVtYmVyIilyZXR1cm4gYS5KKCkKaWYoYTwwKXRocm93IEgu
+YihQLlRFKGEsMCxudWxsLGIsbnVsbCkpfSwKQ2Y6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdD1ILlNj
+KGU9PW51bGw/Si5IbShiKTplKQpyZXR1cm4gbmV3IFAuZVkodCwhMCxhLGMsIkluZGV4IG91dCBvZiBy
+YW5nZSIpfSwKTDQ6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnViKGEpfSwKU1k6ZnVuY3Rpb24oYSl7
+cmV0dXJuIG5ldyBQLmRzKGEpfSwKUFY6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLmxqKGEpfSwKYTQ6
+ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLlVWKGEpfSwKcnI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBu
+ZXcgUC5hRShhLGIsYyl9LApkSDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzPUguVk0oW10sZC5DKCJq
+ZDwwPiIpKQpDLk5tLnNBKHMsYSkKZm9yKHQ9MDt0PGE7Kyt0KUMuTm0uWShzLHQsYi4kMSh0KSkKcmV0
+dXJuIHN9LApoSzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZT1u
+dWxsLGQ9YS5sZW5ndGgKaWYoZD49NSl7dD0oKEouUXooYSw0KV41OCkqM3xDLnhCLlcoYSwwKV4xMDB8
+Qy54Qi5XKGEsMSleOTd8Qy54Qi5XKGEsMileMTE2fEMueEIuVyhhLDMpXjk3KT4+PjAKaWYodD09PTAp
+cmV0dXJuIFAuS0QoZDxkP0MueEIuTmooYSwwLGQpOmEsNSxlKS5nbFIoKQplbHNlIGlmKHQ9PT0zMily
+ZXR1cm4gUC5LRChDLnhCLk5qKGEsNSxkKSwwLGUpLmdsUigpfXM9bmV3IEFycmF5KDgpCnMuZml4ZWQk
+bGVuZ3RoPUFycmF5CnI9SC5WTShzLHUudCkKQy5ObS5ZKHIsMCwwKQpDLk5tLlkociwxLC0xKQpDLk5t
+LlkociwyLC0xKQpDLk5tLlkociw3LC0xKQpDLk5tLlkociwzLDApCkMuTm0uWShyLDQsMCkKQy5ObS5Z
+KHIsNSxkKQpDLk5tLlkociw2LGQpCmlmKFAuVUIoYSwwLGQsMCxyKT49MTQpQy5ObS5ZKHIsNyxkKQpx
+PXJbMV0KaWYodHlwZW9mIHEhPT0ibnVtYmVyIilyZXR1cm4gcS50QigpCmlmKHE+PTApaWYoUC5VQihh
+LDAscSwyMCxyKT09PTIwKXJbN109cQpzPXJbMl0KaWYodHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4g
+cy5oKCkKcD1zKzEKbz1yWzNdCm49cls0XQptPXJbNV0KbD1yWzZdCmlmKHR5cGVvZiBsIT09Im51bWJl
+ciIpcmV0dXJuIGwuSigpCmlmKHR5cGVvZiBtIT09Im51bWJlciIpcmV0dXJuIEgucFkobSkKaWYobDxt
+KW09bAppZih0eXBlb2YgbiE9PSJudW1iZXIiKXJldHVybiBuLkooKQppZihuPHApbj1tCmVsc2UgaWYo
+bjw9cSluPXErMQppZih0eXBlb2YgbyE9PSJudW1iZXIiKXJldHVybiBvLkooKQppZihvPHApbz1uCnM9
+cls3XQppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLkooKQprPXM8MAppZihrKWlmKHA+cSsz
+KXtqPWUKaz0hMX1lbHNle3M9bz4wCmlmKHMmJm8rMT09PW4pe2o9ZQprPSExfWVsc2V7aWYoIShtPGQm
+Jm09PT1uKzImJkoucTAoYSwiLi4iLG4pKSlpPW0+bisyJiZKLnEwKGEsIi8uLiIsbS0zKQplbHNlIGk9
+ITAKaWYoaSl7aj1lCms9ITF9ZWxzZXtpZihxPT09NClpZihKLnEwKGEsImZpbGUiLDApKXtpZihwPD0w
+KXtpZighQy54Qi5RaShhLCIvIixuKSl7aD0iZmlsZTovLy8iCnQ9M31lbHNle2g9ImZpbGU6Ly8iCnQ9
+Mn1hPWgrQy54Qi5OaihhLG4sZCkKcS09MApzPXQtMAptKz1zCmwrPXMKZD1hLmxlbmd0aApwPTcKbz03
+Cm49N31lbHNlIGlmKG49PT1tKXtnPW0rMTsrK2wKYT1DLnhCLmk3KGEsbixtLCIvIik7KytkCm09Z31q
+PSJmaWxlIn1lbHNlIGlmKEMueEIuUWkoYSwiaHR0cCIsMCkpe2lmKHMmJm8rMz09PW4mJkMueEIuUWko
+YSwiODAiLG8rMSkpe2Y9bi0zCm0tPTMKbC09MwphPUMueEIuaTcoYSxvLG4sIiIpCmQtPTMKbj1mfWo9
+Imh0dHAifWVsc2Ugaj1lCmVsc2UgaWYocT09PTUmJkoucTAoYSwiaHR0cHMiLDApKXtpZihzJiZvKzQ9
+PT1uJiZKLnEwKGEsIjQ0MyIsbysxKSl7Zj1uLTQKbS09NApsLT00CmE9Si5kZyhhLG8sbiwiIikKZC09
+MwpuPWZ9aj0iaHR0cHMifWVsc2Ugaj1lCms9ITB9fX1lbHNlIGo9ZQppZihrKXtzPWEubGVuZ3RoCmlm
+KGQ8cyl7YT1KLmxkKGEsMCxkKQpxLT0wCnAtPTAKby09MApuLT0wCm0tPTAKbC09MH1yZXR1cm4gbmV3
+IFAuVWYoYSxxLHAsbyxuLG0sbCxqKX1yZXR1cm4gUC5qdihhLDAsZCxxLHAsbyxuLG0sbCxqKX0sCk10
+OmZ1bmN0aW9uKGEpe0gueShhKQpyZXR1cm4gUC5rdShhLDAsYS5sZW5ndGgsQy54TSwhMSl9LApXWDpm
+dW5jdGlvbihhKXt2YXIgdD11Lk4KcmV0dXJuIEMuTm0uTjAoSC5WTShhLnNwbGl0KCImIiksdS5zKSxQ
+LkZsKHQsdCksbmV3IFAubjEoQy54TSksdS5mKX0sCkhoOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIs
+cSxwLG8sbixtPW51bGwsbD0iSVB2NCBhZGRyZXNzIHNob3VsZCBjb250YWluIGV4YWN0bHkgNCBwYXJ0
+cyIsaz0iZWFjaCBwYXJ0IG11c3QgYmUgaW4gdGhlIHJhbmdlIDAuLjI1NSIsaj1uZXcgUC5jUyhhKSxp
+PW5ldyBVaW50OEFycmF5KDQpCmZvcih0PWkubGVuZ3RoLHM9YixyPXMscT0wO3M8YzsrK3Mpe3A9Qy54
+Qi5tKGEscykKaWYocCE9PTQ2KXtpZigocF40OCk+OSlqLiQyKCJpbnZhbGlkIGNoYXJhY3RlciIscyl9
+ZWxzZXtpZihxPT09MylqLiQyKGwscykKbz1QLlFBKEMueEIuTmooYSxyLHMpLG0sbSkKaWYodHlwZW9m
+IG8hPT0ibnVtYmVyIilyZXR1cm4gby5vcygpCmlmKG8+MjU1KWouJDIoayxyKQpuPXErMQppZihxPj10
+KXJldHVybiBILk9IKGkscSkKaVtxXT1vCnI9cysxCnE9bn19aWYocSE9PTMpai4kMihsLGMpCm89UC5R
+QShDLnhCLk5qKGEscixjKSxtLG0pCmlmKHR5cGVvZiBvIT09Im51bWJlciIpcmV0dXJuIG8ub3MoKQpp
+ZihvPjI1NSlqLiQyKGsscikKaWYocT49dClyZXR1cm4gSC5PSChpLHEpCmlbcV09bwpyZXR1cm4gaX0s
 CmVnOmZ1bmN0aW9uKGEsYixhMCl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGUsZD1u
 ZXcgUC5WQyhhKSxjPW5ldyBQLkpUKGQsYSkKaWYoYS5sZW5ndGg8MilkLiQxKCJhZGRyZXNzIGlzIHRv
 byBzaG9ydCIpCnQ9SC5WTShbXSx1LnQpCmZvcihzPWIscj1zLHE9ITEscD0hMTtzPGEwOysrcyl7bz1D
@@ -1523,8 +1455,16 @@
 e2lmKGg8MHx8aD49ailyZXR1cm4gSC5PSChrLGgpCmtbaF09MAplPWgrMQppZihlPj1qKXJldHVybiBI
 Lk9IKGssZSkKa1tlXT0wCmgrPTJ9ZWxzZXtlPUMuam4ud0coZyw4KQppZihoPDB8fGg+PWopcmV0dXJu
 IEguT0goayxoKQprW2hdPWUKZT1oKzEKaWYoZT49ailyZXR1cm4gSC5PSChrLGUpCmtbZV09ZyYyNTUK
-aCs9Mn19cmV0dXJuIGt9LApLTDpmdW5jdGlvbihhLGIsYyxkLGUsZixnKXt2YXIgdCxzLHIscSxwLG8K
-Zj1mPT1udWxsPyIiOlAuUGkoZiwwLGYubGVuZ3RoKQpnPVAuelIoZywwLGc9PW51bGw/MDpnLmxlbmd0
+aCs9Mn19cmV0dXJuIGt9LApqdjpmdW5jdGlvbihhLGIsYyxkLGUsZixnLGgsaSxqKXt2YXIgdCxzLHIs
+cSxwLG8sbixtPW51bGwKaWYoaj09bnVsbClpZihkPmIpaj1QLlBpKGEsYixkKQplbHNle2lmKGQ9PT1i
+KVAuUjMoYSxiLCJJbnZhbGlkIGVtcHR5IHNjaGVtZSIpCmo9IiJ9aWYoZT5iKXt0PWQrMwpzPXQ8ZT9Q
+LnpSKGEsdCxlLTEpOiIiCnI9UC5PZShhLGUsZiwhMSkKaWYodHlwZW9mIGYhPT0ibnVtYmVyIilyZXR1
+cm4gZi5oKCkKcT1mKzEKaWYodHlwZW9mIGchPT0ibnVtYmVyIilyZXR1cm4gSC5wWShnKQpwPXE8Zz9Q
+LndCKFAuUUEoSi5sZChhLHEsZyksbmV3IFAuZTEoYSxmKSxtKSxqKTptfWVsc2V7cD1tCnI9cApzPSIi
+fW89UC5rYShhLGcsaCxtLGosciE9bnVsbCkKaWYodHlwZW9mIGghPT0ibnVtYmVyIilyZXR1cm4gaC5K
+KCkKbj1oPGk/UC5sZShhLGgrMSxpLG0pOm0KcmV0dXJuIG5ldyBQLkRuKGoscyxyLHAsbyxuLGk8Yz9Q
+LnRHKGEsaSsxLGMpOm0pfSwKS0w6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHQscyxyLHEscCxv
+CmY9UC5QaShmLDAsZj09bnVsbD8wOmYubGVuZ3RoKQpnPVAuelIoZywwLGc9PW51bGw/MDpnLmxlbmd0
 aCkKYT1QLk9lKGEsMCxhPT1udWxsPzA6YS5sZW5ndGgsITEpCnQ9UC5sZShudWxsLDAsMCxlKQpzPVAu
 dEcobnVsbCwwLDApCmQ9UC53QihkLGYpCnI9Zj09PSJmaWxlIgppZihhPT1udWxsKXE9Zy5sZW5ndGgh
 PT0wfHxkIT1udWxsfHxyCmVsc2UgcT0hMQppZihxKWE9IiIKcT1hPT1udWxsCnA9IXEKYj1QLmthKGIs
@@ -1541,44 +1481,45 @@
 IkludmFsaWQgSVB2NiBob3N0IGVudHJ5LiIsYixzKSkKbT1wPDA/cTpwClAuZWcoYixzKzEsbSk7Kytx
 CmlmKHEhPT1oJiZDLnhCLlcoYixxKSE9PTU4KXRocm93IEguYihQLnJyKCJJbnZhbGlkIGVuZCBvZiBh
 dXRob3JpdHkiLGIscSkpfWVsc2UgcT1zCndoaWxlKCEwKXtpZighKHE8aCkpe2w9aQpicmVha31pZihD
-LnhCLlcoYixxKT09PTU4KXtrPUMueEIuRyhiLHErMSkKbD1rLmxlbmd0aCE9PTA/UC5RQShrLGkpOmkK
-YnJlYWt9KytxfWo9Qy54Qi5OaihiLHMscSl9ZWxzZXtsPWkKaj1sCnQ9IiJ9cmV0dXJuIFAuS0woaixp
-LEguVk0oYy5zcGxpdCgiLyIpLHUucyksbCxkLGEsdCl9LAprRTpmdW5jdGlvbihhLGIpe3ZhciB0LHMs
-cixxLHAKZm9yKHQ9YS5sZW5ndGgscz0wO3M8dDsrK3Mpe3I9YVtzXQpyLnRvU3RyaW5nCnE9Si5VNihy
-KQpwPXEuZ0EocikKaWYoMD5wKUgudmgoUC5URSgwLDAscS5nQShyKSxudWxsLG51bGwpKQppZihILm0y
-KHIsIi8iLDApKXt0PVAuTDQoIklsbGVnYWwgcGF0aCBjaGFyYWN0ZXIgIitILkVqKHIpKQp0aHJvdyBI
-LmIodCl9fX0sCkhOOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIKZm9yKHQ9SC5xQyhhLGMsbnVsbCxI
-LnQ2KGEpLmMpLHQ9bmV3IEguYTcodCx0LmdBKHQpLHQuJHRpLkMoImE3PGFMLkU+IikpO3QuRigpOyl7
-cz10LmQKcj1QLm51KCdbIiovOjw+P1xcXFx8XScpCnMudG9TdHJpbmcKaWYoSC5tMihzLHIsMCkpe3Q9
-UC5MNCgiSWxsZWdhbCBjaGFyYWN0ZXIgaW4gcGF0aDogIitzKQp0aHJvdyBILmIodCl9fX0sCnJnOmZ1
-bmN0aW9uKGEsYil7dmFyIHQKaWYoISg2NTw9YSYmYTw9OTApKXQ9OTc8PWEmJmE8PTEyMgplbHNlIHQ9
-ITAKaWYodClyZXR1cm4KdD1QLkw0KCJJbGxlZ2FsIGRyaXZlIGxldHRlciAiK1AuT28oYSkpCnRocm93
-IEguYih0KX0sCndCOmZ1bmN0aW9uKGEsYil7aWYoYSE9bnVsbCYmYT09PVAud0soYikpcmV0dXJuIG51
-bGwKcmV0dXJuIGF9LApPZTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIscSxwLG8KaWYoYT09bnVs
-bClyZXR1cm4gbnVsbAppZihiPT09YylyZXR1cm4iIgppZihDLnhCLm0oYSxiKT09PTkxKXt0PWMtMQpp
-ZihDLnhCLm0oYSx0KSE9PTkzKVAuUjMoYSxiLCJNaXNzaW5nIGVuZCBgXWAgdG8gbWF0Y2ggYFtgIGlu
-IGhvc3QiKQpzPWIrMQpyPVAudG8oYSxzLHQpCmlmKHI8dCl7cT1yKzEKcD1QLk9BKGEsQy54Qi5RaShh
-LCIyNSIscSk/ciszOnEsdCwiJTI1Iil9ZWxzZSBwPSIiClAuZWcoYSxzLHIpCnJldHVybiBDLnhCLk5q
-KGEsYixyKS50b0xvd2VyQ2FzZSgpK3ArIl0ifWZvcihvPWI7bzxjOysrbylpZihDLnhCLm0oYSxvKT09
-PTU4KXtyPUMueEIuWFUoYSwiJSIsYikKcj1yPj1iJiZyPGM/cjpjCmlmKHI8Yyl7cT1yKzEKcD1QLk9B
-KGEsQy54Qi5RaShhLCIyNSIscSk/ciszOnEsYywiJTI1Iil9ZWxzZSBwPSIiClAuZWcoYSxiLHIpCnJl
-dHVybiJbIitDLnhCLk5qKGEsYixyKStwKyJdIn1yZXR1cm4gUC5PTChhLGIsYyl9LAp0bzpmdW5jdGlv
-bihhLGIsYyl7dmFyIHQ9Qy54Qi5YVShhLCIlIixiKQpyZXR1cm4gdD49YiYmdDxjP3Q6Y30sCk9BOmZ1
-bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGo9ZCE9PSIiP25ldyBQLlJuKGQp
-Om51bGwKZm9yKHQ9YixzPXQscj0hMDt0PGM7KXtxPUMueEIubShhLHQpCmlmKHE9PT0zNyl7cD1QLnJ2
-KGEsdCwhMCkKbz1wPT1udWxsCmlmKG8mJnIpe3QrPTMKY29udGludWV9aWYoaj09bnVsbClqPW5ldyBQ
-LlJuKCIiKQpuPWouYSs9Qy54Qi5OaihhLHMsdCkKaWYobylwPUMueEIuTmooYSx0LHQrMykKZWxzZSBp
-ZihwPT09IiUiKVAuUjMoYSx0LCJab25lSUQgc2hvdWxkIG5vdCBjb250YWluICUgYW55bW9yZSIpCmou
-YT1uK3AKdCs9MwpzPXQKcj0hMH1lbHNle2lmKHE8MTI3KXtvPXE+Pj40CmlmKG8+PTgpcmV0dXJuIEgu
-T0goQy5GMyxvKQpvPShDLkYzW29dJjE8PChxJjE1KSkhPT0wfWVsc2Ugbz0hMQppZihvKXtpZihyJiY2
-NTw9cSYmOTA+PXEpe2lmKGo9PW51bGwpaj1uZXcgUC5SbigiIikKaWYoczx0KXtqLmErPUMueEIuTmoo
-YSxzLHQpCnM9dH1yPSExfSsrdH1lbHNle2lmKChxJjY0NTEyKT09PTU1Mjk2JiZ0KzE8Yyl7bT1DLnhC
-Lm0oYSx0KzEpCmlmKChtJjY0NTEyKT09PTU2MzIwKXtxPTY1NTM2fChxJjEwMjMpPDwxMHxtJjEwMjMK
-bD0yfWVsc2UgbD0xfWVsc2UgbD0xCms9Qy54Qi5OaihhLHMsdCkKaWYoaj09bnVsbCl7aj1uZXcgUC5S
-bigiIikKbz1qfWVsc2Ugbz1qCm8uYSs9awpvLmErPVAuelgocSkKdCs9bApzPXR9fX1pZihqPT1udWxs
-KXJldHVybiBDLnhCLk5qKGEsYixjKQppZihzPGMpai5hKz1DLnhCLk5qKGEscyxjKQpvPWouYQpyZXR1
-cm4gby5jaGFyQ29kZUF0KDApPT0wP286b30sCk9MOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxw
-LG8sbixtLGwsayxqCmZvcih0PWIscz10LHI9bnVsbCxxPSEwO3Q8Yzspe3A9Qy54Qi5tKGEsdCkKaWYo
+LnhCLlcoYixxKT09PTU4KXtrPUMueEIuRyhiLHErMSkKbD1rLmxlbmd0aCE9PTA/UC5RQShrLGksaSk6
+aQpicmVha30rK3F9aj1DLnhCLk5qKGIscyxxKX1lbHNle2w9aQpqPWwKdD0iIn1yZXR1cm4gUC5LTChq
+LGksSC5WTShjLnNwbGl0KCIvIiksdS5zKSxsLGQsYSx0KX0sCmtFOmZ1bmN0aW9uKGEsYil7Qy5ObS5L
+KGEsbmV3IFAuTlkoITEpKX0sCkhOOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIKZm9yKHQ9SC5xQyhh
+LGMsbnVsbCxILnQ2KGEpLmQpLHQ9bmV3IEguYTcodCx0LmdBKHQpLHQuJHRpLkMoImE3PGFMLkU+Iikp
+O3QuRigpOyl7cz10LmQKcj1QLm51KCdbIiovOjw+P1xcXFx8XScpCnMudG9TdHJpbmcKaWYoSC5tMihz
+LHIsMCkpe3Q9UC5MNCgiSWxsZWdhbCBjaGFyYWN0ZXIgaW4gcGF0aDogIitzKQp0aHJvdyBILmIodCl9
+fX0sCnJnOmZ1bmN0aW9uKGEsYil7dmFyIHQKaWYoISg2NTw9YSYmYTw9OTApKXQ9OTc8PWEmJmE8PTEy
+MgplbHNlIHQ9ITAKaWYodClyZXR1cm4KdD1QLkw0KCJJbGxlZ2FsIGRyaXZlIGxldHRlciAiK1AuT28o
+YSkpCnRocm93IEguYih0KX0sCndCOmZ1bmN0aW9uKGEsYil7aWYoYSE9bnVsbCYmYT09PVAud0soYikp
+cmV0dXJuIG51bGwKcmV0dXJuIGF9LApPZTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIscSxwLG8K
+aWYoYT09bnVsbClyZXR1cm4gbnVsbAppZihiPT09YylyZXR1cm4iIgppZihDLnhCLm0oYSxiKT09PTkx
+KXtpZih0eXBlb2YgYyE9PSJudW1iZXIiKXJldHVybiBjLkhOKCkKdD1jLTEKaWYoQy54Qi5tKGEsdCkh
+PT05MylQLlIzKGEsYiwiTWlzc2luZyBlbmQgYF1gIHRvIG1hdGNoIGBbYCBpbiBob3N0IikKcz1iKzEK
+cj1QLnRvKGEscyx0KQppZih0eXBlb2YgciE9PSJudW1iZXIiKXJldHVybiByLkooKQppZihyPHQpe3E9
+cisxCnA9UC5PQShhLEMueEIuUWkoYSwiMjUiLHEpP3IrMzpxLHQsIiUyNSIpfWVsc2UgcD0iIgpQLmVn
+KGEscyxyKQpyZXR1cm4gQy54Qi5OaihhLGIscikudG9Mb3dlckNhc2UoKStwKyJdIn1pZih0eXBlb2Yg
+YyE9PSJudW1iZXIiKXJldHVybiBILnBZKGMpCm89Ygpmb3IoO288YzsrK28paWYoQy54Qi5tKGEsbyk9
+PT01OCl7cj1DLnhCLlhVKGEsIiUiLGIpCmlmKCEocj49YiYmcjxjKSlyPWMKaWYocjxjKXtxPXIrMQpw
+PVAuT0EoYSxDLnhCLlFpKGEsIjI1IixxKT9yKzM6cSxjLCIlMjUiKX1lbHNlIHA9IiIKUC5lZyhhLGIs
+cikKcmV0dXJuIlsiK0MueEIuTmooYSxiLHIpK3ArIl0ifXJldHVybiBQLk9MKGEsYixjKX0sCnRvOmZ1
+bmN0aW9uKGEsYixjKXt2YXIgdCxzPUMueEIuWFUoYSwiJSIsYikKaWYocz49Yil7aWYodHlwZW9mIGMh
+PT0ibnVtYmVyIilyZXR1cm4gSC5wWShjKQp0PXM8Y31lbHNlIHQ9ITEKcmV0dXJuIHQ/czpjfSwKT0E6
+ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGs9ZCE9PSIiP25ldyBQLlJuKGQp
+Om51bGwKaWYodHlwZW9mIGMhPT0ibnVtYmVyIilyZXR1cm4gSC5wWShjKQp0PWIKcz10CnI9ITAKZm9y
+KDt0PGM7KXtxPUMueEIubShhLHQpCmlmKHE9PT0zNyl7cD1QLnJ2KGEsdCwhMCkKbz1wPT1udWxsCmlm
+KG8mJnIpe3QrPTMKY29udGludWV9aWYoaz09bnVsbClrPW5ldyBQLlJuKCIiKQpuPWsuYSs9Qy54Qi5O
+aihhLHMsdCkKaWYobylwPUMueEIuTmooYSx0LHQrMykKZWxzZSBpZihwPT09IiUiKVAuUjMoYSx0LCJa
+b25lSUQgc2hvdWxkIG5vdCBjb250YWluICUgYW55bW9yZSIpCmsuYT1uK3AKdCs9MwpzPXQKcj0hMH1l
+bHNle2lmKHE8MTI3KXtvPXE+Pj40CmlmKG8+PTgpcmV0dXJuIEguT0goQy5GMyxvKQpvPShDLkYzW29d
+JjE8PChxJjE1KSkhPT0wfWVsc2Ugbz0hMQppZihvKXtpZihyJiY2NTw9cSYmOTA+PXEpe2lmKGs9PW51
+bGwpaz1uZXcgUC5SbigiIikKaWYoczx0KXtrLmErPUMueEIuTmooYSxzLHQpCnM9dH1yPSExfSsrdH1l
+bHNle2lmKChxJjY0NTEyKT09PTU1Mjk2JiZ0KzE8Yyl7bT1DLnhCLm0oYSx0KzEpCmlmKChtJjY0NTEy
+KT09PTU2MzIwKXtxPTY1NTM2fChxJjEwMjMpPDwxMHxtJjEwMjMKbD0yfWVsc2UgbD0xfWVsc2UgbD0x
+CmlmKGs9PW51bGwpaz1uZXcgUC5SbigiIikKay5hKz1DLnhCLk5qKGEscyx0KQprLmErPVAuelgocSkK
+dCs9bApzPXR9fX1pZihrPT1udWxsKXJldHVybiBDLnhCLk5qKGEsYixjKQppZihzPGMpay5hKz1DLnhC
+Lk5qKGEscyxjKQpvPWsuYQpyZXR1cm4gby5jaGFyQ29kZUF0KDApPT0wP286b30sCk9MOmZ1bmN0aW9u
+KGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqCmlmKHR5cGVvZiBjIT09Im51bWJlciIpcmV0
+dXJuIEgucFkoYykKdD1iCnM9dApyPW51bGwKcT0hMApmb3IoO3Q8Yzspe3A9Qy54Qi5tKGEsdCkKaWYo
 cD09PTM3KXtvPVAucnYoYSx0LCEwKQpuPW89PW51bGwKaWYobiYmcSl7dCs9Mwpjb250aW51ZX1pZihy
 PT1udWxsKXI9bmV3IFAuUm4oIiIpCm09Qy54Qi5OaihhLHMsdCkKbD1yLmErPSFxP20udG9Mb3dlckNh
 c2UoKTptCmlmKG4pe289Qy54Qi5OaihhLHQsdCszKQprPTN9ZWxzZSBpZihvPT09IiUiKXtvPSIlMjUi
@@ -1589,223 +1530,224 @@
 ZihuPj04KXJldHVybiBILk9IKEMuYWssbikKbj0oQy5ha1tuXSYxPDwocCYxNSkpIT09MH1lbHNlIG49
 ITEKaWYobilQLlIzKGEsdCwiSW52YWxpZCBjaGFyYWN0ZXIiKQplbHNle2lmKChwJjY0NTEyKT09PTU1
 Mjk2JiZ0KzE8Yyl7aj1DLnhCLm0oYSx0KzEpCmlmKChqJjY0NTEyKT09PTU2MzIwKXtwPTY1NTM2fChw
-JjEwMjMpPDwxMHxqJjEwMjMKaz0yfWVsc2Ugaz0xfWVsc2Ugaz0xCm09Qy54Qi5OaihhLHMsdCkKaWYo
-IXEpbT1tLnRvTG93ZXJDYXNlKCkKaWYocj09bnVsbCl7cj1uZXcgUC5SbigiIikKbj1yfWVsc2Ugbj1y
-Cm4uYSs9bQpuLmErPVAuelgocCkKdCs9awpzPXR9fX19aWYocj09bnVsbClyZXR1cm4gQy54Qi5Oaihh
-LGIsYykKaWYoczxjKXttPUMueEIuTmooYSxzLGMpCnIuYSs9IXE/bS50b0xvd2VyQ2FzZSgpOm19bj1y
-LmEKcmV0dXJuIG4uY2hhckNvZGVBdCgwKT09MD9uOm59LApQaTpmdW5jdGlvbihhLGIsYyl7dmFyIHQs
-cyxyLHEKaWYoYj09PWMpcmV0dXJuIiIKaWYoIVAuRXQoSi5yWShhKS5XKGEsYikpKVAuUjMoYSxiLCJT
-Y2hlbWUgbm90IHN0YXJ0aW5nIHdpdGggYWxwaGFiZXRpYyBjaGFyYWN0ZXIiKQpmb3IodD1iLHM9ITE7
-dDxjOysrdCl7cj1DLnhCLlcoYSx0KQppZihyPDEyOCl7cT1yPj4+NAppZihxPj04KXJldHVybiBILk9I
-KEMubUsscSkKcT0oQy5tS1txXSYxPDwociYxNSkpIT09MH1lbHNlIHE9ITEKaWYoIXEpUC5SMyhhLHQs
-IklsbGVnYWwgc2NoZW1lIGNoYXJhY3RlciIpCmlmKDY1PD1yJiZyPD05MClzPSEwfWE9Qy54Qi5Oaihh
-LGIsYykKcmV0dXJuIFAuWWEocz9hLnRvTG93ZXJDYXNlKCk6YSl9LApZYTpmdW5jdGlvbihhKXtpZihh
-PT09Imh0dHAiKXJldHVybiJodHRwIgppZihhPT09ImZpbGUiKXJldHVybiJmaWxlIgppZihhPT09Imh0
-dHBzIilyZXR1cm4iaHR0cHMiCmlmKGE9PT0icGFja2FnZSIpcmV0dXJuInBhY2thZ2UiCnJldHVybiBh
-fSwKelI6ZnVuY3Rpb24oYSxiLGMpe2lmKGE9PW51bGwpcmV0dXJuIiIKcmV0dXJuIFAuUEkoYSxiLGMs
-Qy50bywhMSl9LAprYTpmdW5jdGlvbihhLGIsYyxkLGUsZil7dmFyIHQscyxyPWU9PT0iZmlsZSIscT1y
-fHxmCmlmKGE9PW51bGwpe2lmKGQ9PW51bGwpcmV0dXJuIHI/Ii8iOiIiCnQ9SC50NihkKQpzPW5ldyBI
-LmxKKGQsdC5DKCJxVSgxKSIpLmEobmV3IFAuUlooKSksdC5DKCJsSjwxLHFVPiIpKS56VigwLCIvIil9
-ZWxzZSBpZihkIT1udWxsKXRocm93IEguYihQLnhZKCJCb3RoIHBhdGggYW5kIHBhdGhTZWdtZW50cyBz
-cGVjaWZpZWQiKSkKZWxzZSBzPVAuUEkoYSxiLGMsQy5XZCwhMCkKaWYocy5sZW5ndGg9PT0wKXtpZihy
-KXJldHVybiIvIn1lbHNlIGlmKHEmJiFDLnhCLm4ocywiLyIpKXM9Ii8iK3MKcmV0dXJuIFAuSnIocyxl
-LGYpfSwKSnI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PWIubGVuZ3RoPT09MAppZih0JiYhYyYmIUMueEIu
-bihhLCIvIikpcmV0dXJuIFAud0YoYSwhdHx8YykKcmV0dXJuIFAueGUoYSl9LApsZTpmdW5jdGlvbihh
-LGIsYyxkKXt2YXIgdCxzPXt9CmlmKGEhPW51bGwpe2lmKGQhPW51bGwpdGhyb3cgSC5iKFAueFkoIkJv
-dGggcXVlcnkgYW5kIHF1ZXJ5UGFyYW1ldGVycyBzcGVjaWZpZWQiKSkKcmV0dXJuIFAuUEkoYSxiLGMs
-Qy5WQywhMCl9aWYoZD09bnVsbClyZXR1cm4gbnVsbAp0PW5ldyBQLlJuKCIiKQpzLmE9IiIKZC5LKDAs
-bmV3IFAueTUobmV3IFAuTUUocyx0KSkpCnM9dC5hCnJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpz
-fSwKdEc6ZnVuY3Rpb24oYSxiLGMpe2lmKGE9PW51bGwpcmV0dXJuIG51bGwKcmV0dXJuIFAuUEkoYSxi
-LGMsQy5WQywhMCl9LApydjpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvPWIrMgppZihvPj1h
-Lmxlbmd0aClyZXR1cm4iJSIKdD1DLnhCLm0oYSxiKzEpCnM9Qy54Qi5tKGEsbykKcj1ILm9vKHQpCnE9
-SC5vbyhzKQppZihyPDB8fHE8MClyZXR1cm4iJSIKcD1yKjE2K3EKaWYocDwxMjcpe289Qy5qbi53Ryhw
-LDQpCmlmKG8+PTgpcmV0dXJuIEguT0goQy5GMyxvKQpvPShDLkYzW29dJjE8PChwJjE1KSkhPT0wfWVs
-c2Ugbz0hMQppZihvKXJldHVybiBILkx3KGMmJjY1PD1wJiY5MD49cD8ocHwzMik+Pj4wOnApCmlmKHQ+
-PTk3fHxzPj05NylyZXR1cm4gQy54Qi5OaihhLGIsYiszKS50b1VwcGVyQ2FzZSgpCnJldHVybiBudWxs
-fSwKelg6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsPSIwMTIzNDU2Nzg5QUJDREVGIgpp
-ZihhPDEyOCl7dD1uZXcgVWludDhBcnJheSgzKQpzPXQubGVuZ3RoCmlmKDA+PXMpcmV0dXJuIEguT0go
-dCwwKQp0WzBdPTM3CnI9Qy54Qi5XKGwsYT4+PjQpCmlmKDE+PXMpcmV0dXJuIEguT0godCwxKQp0WzFd
-PXIKcj1DLnhCLlcobCxhJjE1KQppZigyPj1zKXJldHVybiBILk9IKHQsMikKdFsyXT1yfWVsc2V7aWYo
-YT4yMDQ3KWlmKGE+NjU1MzUpe3E9MjQwCnA9NH1lbHNle3E9MjI0CnA9M31lbHNle3E9MTkyCnA9Mn10
-PW5ldyBVaW50OEFycmF5KDMqcCkKZm9yKHM9dC5sZW5ndGgsbz0wOy0tcCxwPj0wO3E9MTI4KXtuPUMu
-am4uYmYoYSw2KnApJjYzfHEKaWYobz49cylyZXR1cm4gSC5PSCh0LG8pCnRbb109MzcKcj1vKzEKbT1D
-LnhCLlcobCxuPj4+NCkKaWYocj49cylyZXR1cm4gSC5PSCh0LHIpCnRbcl09bQptPW8rMgpyPUMueEIu
-VyhsLG4mMTUpCmlmKG0+PXMpcmV0dXJuIEguT0godCxtKQp0W21dPXIKbys9M319cmV0dXJuIFAuSE0o
-dCwwLG51bGwpfSwKUEk6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdD1QLlVsKGEsYixjLGQsZSkKcmV0
-dXJuIHQ9PW51bGw/Qy54Qi5OaihhLGIsYyk6dH0sClVsOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQs
-cyxyLHEscCxvLG4sbSxsLGs9bnVsbApmb3IodD0hZSxzPWIscj1zLHE9aztzPGM7KXtwPUMueEIubShh
-LHMpCmlmKHA8MTI3KXtvPXA+Pj40CmlmKG8+PTgpcmV0dXJuIEguT0goZCxvKQpvPShkW29dJjE8PChw
-JjE1KSkhPT0wfWVsc2Ugbz0hMQppZihvKSsrcwplbHNle2lmKHA9PT0zNyl7bj1QLnJ2KGEscywhMSkK
-aWYobj09bnVsbCl7cys9Mwpjb250aW51ZX1pZigiJSI9PT1uKXtuPSIlMjUiCm09MX1lbHNlIG09M31l
-bHNle2lmKHQpaWYocDw9OTMpe289cD4+PjQKaWYobz49OClyZXR1cm4gSC5PSChDLmFrLG8pCm89KEMu
-YWtbb10mMTw8KHAmMTUpKSE9PTB9ZWxzZSBvPSExCmVsc2Ugbz0hMQppZihvKXtQLlIzKGEscywiSW52
-YWxpZCBjaGFyYWN0ZXIiKQptPWsKbj1tfWVsc2V7aWYoKHAmNjQ1MTIpPT09NTUyOTYpe289cysxCmlm
-KG88Yyl7bD1DLnhCLm0oYSxvKQppZigobCY2NDUxMik9PT01NjMyMCl7cD02NTUzNnwocCYxMDIzKTw8
-MTB8bCYxMDIzCm09Mn1lbHNlIG09MX1lbHNlIG09MX1lbHNlIG09MQpuPVAuelgocCl9fWlmKHE9PW51
-bGwpe3E9bmV3IFAuUm4oIiIpCm89cX1lbHNlIG89cQpvLmErPUMueEIuTmooYSxyLHMpCm8uYSs9SC5F
-aihuKQppZih0eXBlb2YgbSE9PSJudW1iZXIiKXJldHVybiBILnBZKG0pCnMrPW0Kcj1zfX1pZihxPT1u
-dWxsKXJldHVybiBrCmlmKHI8YylxLmErPUMueEIuTmooYSxyLGMpCnQ9cS5hCnJldHVybiB0LmNoYXJD
-b2RlQXQoMCk9PTA/dDp0fSwKeUI6ZnVuY3Rpb24oYSl7aWYoQy54Qi5uKGEsIi4iKSlyZXR1cm4hMApy
-ZXR1cm4gQy54Qi5PWShhLCIvLiIpIT09LTF9LAp4ZTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8s
-bgppZighUC55QihhKSlyZXR1cm4gYQp0PUguVk0oW10sdS5zKQpmb3Iocz1hLnNwbGl0KCIvIikscj1z
-Lmxlbmd0aCxxPSExLHA9MDtwPHI7KytwKXtvPXNbcF0KaWYoSi5STShvLCIuLiIpKXtuPXQubGVuZ3Ro
-CmlmKG4hPT0wKXtpZigwPj1uKXJldHVybiBILk9IKHQsLTEpCnQucG9wKCkKaWYodC5sZW5ndGg9PT0w
-KUMuTm0uaSh0LCIiKX1xPSEwfWVsc2UgaWYoIi4iPT09bylxPSEwCmVsc2V7Qy5ObS5pKHQsbykKcT0h
-MX19aWYocSlDLk5tLmkodCwiIikKcmV0dXJuIEMuTm0uelYodCwiLyIpfSwKd0Y6ZnVuY3Rpb24oYSxi
-KXt2YXIgdCxzLHIscSxwLG8KaWYoIVAueUIoYSkpcmV0dXJuIWI/UC5DMShhKTphCnQ9SC5WTShbXSx1
-LnMpCmZvcihzPWEuc3BsaXQoIi8iKSxyPXMubGVuZ3RoLHE9ITEscD0wO3A8cjsrK3Ape289c1twXQpp
-ZigiLi4iPT09bylpZih0Lmxlbmd0aCE9PTAmJkMuTm0uZ3JaKHQpIT09Ii4uIil7aWYoMD49dC5sZW5n
-dGgpcmV0dXJuIEguT0godCwtMSkKdC5wb3AoKQpxPSEwfWVsc2V7Qy5ObS5pKHQsIi4uIikKcT0hMX1l
-bHNlIGlmKCIuIj09PW8pcT0hMAplbHNle0MuTm0uaSh0LG8pCnE9ITF9fXM9dC5sZW5ndGgKaWYocyE9
-PTApaWYocz09PTEpe2lmKDA+PXMpcmV0dXJuIEguT0godCwwKQpzPXRbMF0ubGVuZ3RoPT09MH1lbHNl
-IHM9ITEKZWxzZSBzPSEwCmlmKHMpcmV0dXJuIi4vIgppZihxfHxDLk5tLmdyWih0KT09PSIuLiIpQy5O
-bS5pKHQsIiIpCmlmKCFiKXtpZigwPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LDApCkMuTm0uWSh0LDAs
-UC5DMSh0WzBdKSl9cmV0dXJuIEMuTm0uelYodCwiLyIpfSwKQzE6ZnVuY3Rpb24oYSl7dmFyIHQscyxy
-LHE9YS5sZW5ndGgKaWYocT49MiYmUC5FdChKLlF6KGEsMCkpKWZvcih0PTE7dDxxOysrdCl7cz1DLnhC
-LlcoYSx0KQppZihzPT09NTgpcmV0dXJuIEMueEIuTmooYSwwLHQpKyIlM0EiK0MueEIuRyhhLHQrMSkK
-aWYoczw9MTI3KXtyPXM+Pj40CmlmKHI+PTgpcmV0dXJuIEguT0goQy5tSyxyKQpyPShDLm1LW3JdJjE8
-PChzJjE1KSk9PT0wfWVsc2Ugcj0hMAppZihyKWJyZWFrfXJldHVybiBhfSwKbW46ZnVuY3Rpb24oYSl7
-dmFyIHQscyxyLHE9YS5nRmooKSxwPXEubGVuZ3RoCmlmKHA+MCYmSi5IbShxWzBdKT09PTImJkouYTYo
-cVswXSwxKT09PTU4KXtpZigwPj1wKXJldHVybiBILk9IKHEsMCkKUC5yZyhKLmE2KHFbMF0sMCksITEp
-ClAuSE4ocSwhMSwxKQp0PSEwfWVsc2V7UC5ITihxLCExLDApCnQ9ITF9cz1hLmd0VCgpJiYhdD8iIisi
-XFwiOiIiCmlmKGEuZ2NqKCkpe3I9YS5nSmYoYSkKaWYoci5sZW5ndGghPT0wKXM9cysiXFwiK3IrIlxc
-In1zPVAudmcocyxxLCJcXCIpCnA9dCYmcD09PTE/cysiXFwiOnMKcmV0dXJuIHAuY2hhckNvZGVBdCgw
-KT09MD9wOnB9LApJaDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscgpmb3IodD0wLHM9MDtzPDI7KytzKXty
-PUMueEIuVyhhLGIrcykKaWYoNDg8PXImJnI8PTU3KXQ9dCoxNityLTQ4CmVsc2V7cnw9MzIKaWYoOTc8
-PXImJnI8PTEwMil0PXQqMTYrci04NwplbHNlIHRocm93IEguYihQLnhZKCJJbnZhbGlkIFVSTCBlbmNv
-ZGluZyIpKX19cmV0dXJuIHR9LAprdTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscixxLHA9Si5y
-WShhKSxvPWIKd2hpbGUoITApe2lmKCEobzxjKSl7dD0hMApicmVha31zPXAuVyhhLG8pCmlmKHM8PTEy
-NylpZihzIT09Mzcpcj1lJiZzPT09NDMKZWxzZSByPSEwCmVsc2Ugcj0hMAppZihyKXt0PSExCmJyZWFr
-fSsrb31pZih0KXtpZihDLnhNIT09ZClyPSExCmVsc2Ugcj0hMAppZihyKXJldHVybiBwLk5qKGEsYixj
-KQplbHNlIHE9bmV3IEgucWoocC5OaihhLGIsYykpfWVsc2V7cT1ILlZNKFtdLHUudCkKZm9yKG89Yjtv
-PGM7KytvKXtzPXAuVyhhLG8pCmlmKHM+MTI3KXRocm93IEguYihQLnhZKCJJbGxlZ2FsIHBlcmNlbnQg
-ZW5jb2RpbmcgaW4gVVJJIikpCmlmKHM9PT0zNyl7aWYobyszPmEubGVuZ3RoKXRocm93IEguYihQLnhZ
-KCJUcnVuY2F0ZWQgVVJJIikpCkMuTm0uaShxLFAuSWgoYSxvKzEpKQpvKz0yfWVsc2UgaWYoZSYmcz09
-PTQzKUMuTm0uaShxLDMyKQplbHNlIEMuTm0uaShxLHMpfX11LkwuYShxKQpyZXR1cm4gbmV3IFAuR1ko
-ITEpLldKKHEpfSwKRXQ6ZnVuY3Rpb24oYSl7dmFyIHQ9YXwzMgpyZXR1cm4gOTc8PXQmJnQ8PTEyMn0s
-CktEOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9IkludmFsaWQgTUlNRSB0eXBl
-IixrPUguVk0oW2ItMV0sdS50KQpmb3IodD1hLmxlbmd0aCxzPWIscj0tMSxxPW51bGw7czx0Oysrcyl7
-cT1DLnhCLlcoYSxzKQppZihxPT09NDR8fHE9PT01OSlicmVhawppZihxPT09NDcpe2lmKHI8MCl7cj1z
-CmNvbnRpbnVlfXRocm93IEguYihQLnJyKGwsYSxzKSl9fWlmKHI8MCYmcz5iKXRocm93IEguYihQLnJy
-KGwsYSxzKSkKZm9yKDtxIT09NDQ7KXtDLk5tLmkoayxzKTsrK3MKZm9yKHA9LTE7czx0Oysrcyl7cT1D
-LnhCLlcoYSxzKQppZihxPT09NjEpe2lmKHA8MClwPXN9ZWxzZSBpZihxPT09NTl8fHE9PT00NClicmVh
-a31pZihwPj0wKUMuTm0uaShrLHApCmVsc2V7bz1DLk5tLmdyWihrKQppZihxIT09NDR8fHMhPT1vKzd8
-fCFDLnhCLlFpKGEsImJhc2U2NCIsbysxKSl0aHJvdyBILmIoUC5ycigiRXhwZWN0aW5nICc9JyIsYSxz
-KSkKYnJlYWt9fUMuTm0uaShrLHMpCm49cysxCmlmKChrLmxlbmd0aCYxKT09PTEpYT1DLmg5LnlyKGEs
-bix0KQplbHNle209UC5VbChhLG4sdCxDLlZDLCEwKQppZihtIT1udWxsKWE9Qy54Qi5pNyhhLG4sdCxt
-KX1yZXR1cm4gbmV3IFAuUEUoYSxrLGMpfSwKS046ZnVuY3Rpb24oKXt2YXIgdD0iMDEyMzQ1Njc4OUFC
-Q0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXotLl9+ISQmJygp
-KissOz0iLHM9Ii4iLHI9IjoiLHE9Ii8iLHA9Ij8iLG89IiMiLG49dS5nYyxtPVAuZEgoMjIsbmV3IFAu
-cTMoKSwhMCxuKSxsPW5ldyBQLnlJKG0pLGs9bmV3IFAuYzYoKSxqPW5ldyBQLnFkKCksaT1uLmEobC4k
-MigwLDIyNSkpCmsuJDMoaSx0LDEpCmsuJDMoaSxzLDE0KQprLiQzKGksciwzNCkKay4kMyhpLHEsMykK
-ay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTQsMjI1KSkKay4kMyhpLHQsMSkK
-ay4kMyhpLHMsMTUpCmsuJDMoaSxyLDM0KQprLiQzKGkscSwyMzQpCmsuJDMoaSxwLDE3MikKay4kMyhp
-LG8sMjA1KQppPW4uYShsLiQyKDE1LDIyNSkpCmsuJDMoaSx0LDEpCmsuJDMoaSwiJSIsMjI1KQprLiQz
-KGksciwzNCkKay4kMyhpLHEsOSkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIo
-MSwyMjUpKQprLiQzKGksdCwxKQprLiQzKGksciwzNCkKay4kMyhpLHEsMTApCmsuJDMoaSxwLDE3MikK
-ay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDIsMjM1KSkKay4kMyhpLHQsMTM5KQprLiQzKGkscSwxMzEp
-CmsuJDMoaSxzLDE0NikKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMywyMzUp
-KQprLiQzKGksdCwxMSkKay4kMyhpLHEsNjgpCmsuJDMoaSxzLDE4KQprLiQzKGkscCwxNzIpCmsuJDMo
-aSxvLDIwNSkKaT1uLmEobC4kMig0LDIyOSkpCmsuJDMoaSx0LDUpCmouJDMoaSwiQVoiLDIyOSkKay4k
-MyhpLHIsMTAyKQprLiQzKGksIkAiLDY4KQprLiQzKGksIlsiLDIzMikKay4kMyhpLHEsMTM4KQprLiQz
-KGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMig1LDIyOSkpCmsuJDMoaSx0LDUpCmouJDMo
-aSwiQVoiLDIyOSkKay4kMyhpLHIsMTAyKQprLiQzKGksIkAiLDY4KQprLiQzKGkscSwxMzgpCmsuJDMo
-aSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDYsMjMxKSkKai4kMyhpLCIxOSIsNykKay4k
-MyhpLCJAIiw2OCkKay4kMyhpLHEsMTM4KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEo
-bC4kMig3LDIzMSkpCmouJDMoaSwiMDkiLDcpCmsuJDMoaSwiQCIsNjgpCmsuJDMoaSxxLDEzOCkKay4k
-MyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmsuJDMobi5hKGwuJDIoOCw4KSksIl0iLDUpCmk9bi5hKGwu
-JDIoOSwyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHMsMTYpCmsuJDMoaSxxLDIzNCkKay4kMyhpLHAs
-MTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTYsMjM1KSkKay4kMyhpLHQsMTEpCmsuJDMoaSxz
-LDE3KQprLiQzKGkscSwyMzQpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDE3
-LDIzNSkpCmsuJDMoaSx0LDExKQprLiQzKGkscSw5KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkK
-aT1uLmEobC4kMigxMCwyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHMsMTgpCmsuJDMoaSxxLDIzNCkK
-ay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTgsMjM1KSkKay4kMyhpLHQsMTEp
-CmsuJDMoaSxzLDE5KQprLiQzKGkscSwyMzQpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4u
-YShsLiQyKDE5LDIzNSkpCmsuJDMoaSx0LDExKQprLiQzKGkscSwyMzQpCmsuJDMoaSxwLDE3MikKay4k
-MyhpLG8sMjA1KQppPW4uYShsLiQyKDExLDIzNSkpCmsuJDMoaSx0LDExKQprLiQzKGkscSwxMCkKay4k
-MyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTIsMjM2KSkKay4kMyhpLHQsMTIpCmsu
-JDMoaSxwLDEyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTMsMjM3KSkKay4kMyhpLHQsMTMpCmsu
-JDMoaSxwLDEzKQpqLiQzKG4uYShsLiQyKDIwLDI0NSkpLCJheiIsMjEpCmw9bi5hKGwuJDIoMjEsMjQ1
-KSkKai4kMyhsLCJheiIsMjEpCmouJDMobCwiMDkiLDIxKQprLiQzKGwsIistLiIsMjEpCnJldHVybiBt
-fSwKVUI6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHIscSxwLG89JC52WigpCmZvcih0PUouclko
-YSkscz1iO3M8YzsrK3Mpe2lmKGQ8MHx8ZD49by5sZW5ndGgpcmV0dXJuIEguT0gobyxkKQpyPW9bZF0K
-cT10LlcoYSxzKV45NgppZihxPjk1KXE9MzEKaWYocT49ci5sZW5ndGgpcmV0dXJuIEguT0gocixxKQpw
-PXJbcV0KZD1wJjMxCkMuTm0uWShlLHA+Pj41LHMpfXJldHVybiBkfSwKV0Y6ZnVuY3Rpb24gV0YoYSxi
-KXt0aGlzLmE9YQp0aGlzLmI9Yn0sCmEyOmZ1bmN0aW9uIGEyKCl7fSwKaVA6ZnVuY3Rpb24gaVAoYSxi
-KXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkNQOmZ1bmN0aW9uIENQKCl7fSwKWFM6ZnVuY3Rpb24gWFMoKXt9
-LApDNjpmdW5jdGlvbiBDNihhKXt0aGlzLmE9YX0sCm46ZnVuY3Rpb24gbigpe30sCnU6ZnVuY3Rpb24g
-dShhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kfSwKYko6ZnVuY3Rpb24g
-YkooYSxiLGMsZCxlLGYpe3ZhciBfPXRoaXMKXy5lPWEKXy5mPWIKXy5hPWMKXy5iPWQKXy5jPWUKXy5k
-PWZ9LAplWTpmdW5jdGlvbiBlWShhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5mPWEKXy5hPWIKXy5iPWMK
-Xy5jPWQKXy5kPWV9LAptcDpmdW5jdGlvbiBtcChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1i
-Cl8uYz1jCl8uZD1kfSwKdWI6ZnVuY3Rpb24gdWIoYSl7dGhpcy5hPWF9LApkczpmdW5jdGlvbiBkcyhh
-KXt0aGlzLmE9YX0sCmxqOmZ1bmN0aW9uIGxqKGEpe3RoaXMuYT1hfSwKVVY6ZnVuY3Rpb24gVVYoYSl7
-dGhpcy5hPWF9LAprNTpmdW5jdGlvbiBrNSgpe30sCktZOmZ1bmN0aW9uIEtZKCl7fSwKYzpmdW5jdGlv
-biBjKGEpe3RoaXMuYT1hfSwKQ0Q6ZnVuY3Rpb24gQ0QoYSl7dGhpcy5hPWF9LAphRTpmdW5jdGlvbiBh
-RShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApFSDpmdW5jdGlvbiBFSCgpe30sCklm
-OmZ1bmN0aW9uIElmKCl7fSwKY1g6ZnVuY3Rpb24gY1goKXt9LApBbjpmdW5jdGlvbiBBbigpe30sCnpN
-OmZ1bmN0aW9uIHpNKCl7fSwKWjA6ZnVuY3Rpb24gWjAoKXt9LApOMzpmdW5jdGlvbiBOMyhhLGIsYyl7
-dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sCmM4OmZ1bmN0aW9uIGM4KCl7fSwKbGY6ZnVuY3Rp
-b24gbGYoKXt9LApNaDpmdW5jdGlvbiBNaCgpe30sCk9kOmZ1bmN0aW9uIE9kKCl7fSwKaWI6ZnVuY3Rp
-b24gaWIoKXt9LAp4dTpmdW5jdGlvbiB4dSgpe30sCkd6OmZ1bmN0aW9uIEd6KCl7fSwKWmQ6ZnVuY3Rp
-b24gWmQoKXt9LApxVTpmdW5jdGlvbiBxVSgpe30sClJuOmZ1bmN0aW9uIFJuKGEpe3RoaXMuYT1hfSwK
-R0Q6ZnVuY3Rpb24gR0QoKXt9LApuMTpmdW5jdGlvbiBuMShhKXt0aGlzLmE9YX0sCmNTOmZ1bmN0aW9u
-IGNTKGEpe3RoaXMuYT1hfSwKVkM6ZnVuY3Rpb24gVkMoYSl7dGhpcy5hPWF9LApKVDpmdW5jdGlvbiBK
-VChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKRG46ZnVuY3Rpb24gRG4oYSxiLGMsZCxlLGYsZyl7dmFy
-IF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZQpfLmY9ZgpfLnI9ZwpfLlE9Xy56PV8u
-eT1fLng9bnVsbH0sClJaOmZ1bmN0aW9uIFJaKCl7fSwKTUU6ZnVuY3Rpb24gTUUoYSxiKXt0aGlzLmE9
-YQp0aGlzLmI9Yn0sCnk1OmZ1bmN0aW9uIHk1KGEpe3RoaXMuYT1hfSwKUEU6ZnVuY3Rpb24gUEUoYSxi
-LGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKcTM6ZnVuY3Rpb24gcTMoKXt9LAp5STpmdW5j
-dGlvbiB5SShhKXt0aGlzLmE9YX0sCmM2OmZ1bmN0aW9uIGM2KCl7fSwKcWQ6ZnVuY3Rpb24gcWQoKXt9
-LApVZjpmdW5jdGlvbiBVZihhLGIsYyxkLGUsZixnLGgpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5j
-PWMKXy5kPWQKXy5lPWUKXy5mPWYKXy5yPWcKXy54PWgKXy55PW51bGx9LApxZTpmdW5jdGlvbiBxZShh
-LGIsYyxkLGUsZixnKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lCl8uZj1m
-Cl8ucj1nCl8uUT1fLno9Xy55PV8ueD1udWxsfSwKaUo6ZnVuY3Rpb24gaUooKXt9LApqZzpmdW5jdGlv
-biBqZyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKVGE6ZnVuY3Rpb24gVGEoYSxiKXt0aGlzLmE9YQp0
-aGlzLmI9Yn0sCkJmOmZ1bmN0aW9uIEJmKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApBczpmdW5jdGlv
-biBBcygpe30sCkdFOmZ1bmN0aW9uIEdFKGEpe3RoaXMuYT1hfSwKTjc6ZnVuY3Rpb24gTjcoYSxiKXt0
-aGlzLmE9YQp0aGlzLmI9Yn0sCnVROmZ1bmN0aW9uIHVRKCl7fSwKaEY6ZnVuY3Rpb24gaEYoKXt9LApS
-NDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIKSC55OChiKQp1LmouYShkKQppZihILm9UKGIpKXt0
-PVtjXQpDLk5tLkZWKHQsZCkKZD10fXM9dS56CnI9UC5DSChKLk0xKGQsUC53MCgpLHMpLCEwLHMpCnUu
-WS5hKGEpCnJldHVybiBQLndZKEguRWsoYSxyLG51bGwpKX0sCkRtOmZ1bmN0aW9uKGEsYixjKXt2YXIg
-dAp0cnl7aWYoT2JqZWN0LmlzRXh0ZW5zaWJsZShhKSYmIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJv
-cGVydHkuY2FsbChhLGIpKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoYSxiLHt2YWx1ZTpjfSkKcmV0dXJu
-ITB9fWNhdGNoKHQpe0guUnUodCl9cmV0dXJuITF9LApPbTpmdW5jdGlvbihhLGIpe2lmKE9iamVjdC5w
-cm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChhLGIpKXJldHVybiBhW2JdCnJldHVybiBudWxsfSwK
-d1k6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbHx8dHlwZW9mIGE9PSJzdHJpbmcifHx0eXBlb2YgYT09Im51
-bWJlciJ8fEgubChhKSlyZXR1cm4gYQppZihhIGluc3RhbmNlb2YgUC5FNClyZXR1cm4gYS5hCmlmKEgu
-UjkoYSkpcmV0dXJuIGEKaWYodS54LmIoYSkpcmV0dXJuIGEKaWYoYSBpbnN0YW5jZW9mIFAuaVApcmV0
-dXJuIEgubzIoYSkKaWYodS5ZLmIoYSkpcmV0dXJuIFAuaEUoYSwiJGRhcnRfanNGdW5jdGlvbiIsbmV3
-IFAuUEMoKSkKcmV0dXJuIFAuaEUoYSwiXyRkYXJ0X2pzT2JqZWN0IixuZXcgUC5tdCgkLmtJKCkpKX0s
-CmhFOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1QLk9tKGEsYikKaWYodD09bnVsbCl7dD1jLiQxKGEpClAu
-RG0oYSxiLHQpfXJldHVybiB0fSwKTDc6ZnVuY3Rpb24oYSl7dmFyIHQscwppZihhPT1udWxsfHx0eXBl
-b2YgYT09InN0cmluZyJ8fHR5cGVvZiBhPT0ibnVtYmVyInx8dHlwZW9mIGE9PSJib29sZWFuIilyZXR1
-cm4gYQplbHNlIGlmKGEgaW5zdGFuY2VvZiBPYmplY3QmJkguUjkoYSkpcmV0dXJuIGEKZWxzZSBpZihh
-IGluc3RhbmNlb2YgT2JqZWN0JiZ1LnguYihhKSlyZXR1cm4gYQplbHNlIGlmKGEgaW5zdGFuY2VvZiBE
-YXRlKXt0PUgudVAoYS5nZXRUaW1lKCkpCmlmKE1hdGguYWJzKHQpPD04NjRlMTMpcz0hMQplbHNlIHM9
-ITAKaWYocylILnZoKFAueFkoIkRhdGVUaW1lIGlzIG91dHNpZGUgdmFsaWQgcmFuZ2U6ICIrdCkpClAu
-VUkoITEsImlzVXRjIix1LnkpCnJldHVybiBuZXcgUC5pUCh0LCExKX1lbHNlIGlmKGEuY29uc3RydWN0
-b3I9PT0kLmtJKCkpcmV0dXJuIGEubwplbHNlIHJldHVybiBQLk5EKGEpfSwKTkQ6ZnVuY3Rpb24oYSl7
-aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIFAuaVEoYSwkLncoKSxuZXcgUC5OeigpKQppZihh
-IGluc3RhbmNlb2YgQXJyYXkpcmV0dXJuIFAuaVEoYSwkLlI4KCksbmV3IFAuUVMoKSkKcmV0dXJuIFAu
-aVEoYSwkLlI4KCksbmV3IFAubnAoKSl9LAppUTpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9UC5PbShhLGIp
-CmlmKHQ9PW51bGx8fCEoYSBpbnN0YW5jZW9mIE9iamVjdCkpe3Q9Yy4kMShhKQpQLkRtKGEsYix0KX1y
-ZXR1cm4gdH0sClBDOmZ1bmN0aW9uIFBDKCl7fSwKbXQ6ZnVuY3Rpb24gbXQoYSl7dGhpcy5hPWF9LApO
-ejpmdW5jdGlvbiBOeigpe30sClFTOmZ1bmN0aW9uIFFTKCl7fSwKbnA6ZnVuY3Rpb24gbnAoKXt9LApF
-NDpmdW5jdGlvbiBFNChhKXt0aGlzLmE9YX0sCnI3OmZ1bmN0aW9uIHI3KGEpe3RoaXMuYT1hfSwKVHo6
-ZnVuY3Rpb24gVHooYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKY286ZnVuY3Rpb24gY28oKXt9LApi
-QjpmdW5jdGlvbiBiQigpe30sCktlOmZ1bmN0aW9uIEtlKGEpe3RoaXMuYT1hfSwKZDU6ZnVuY3Rpb24g
-ZDUoKXt9LApuNjpmdW5jdGlvbiBuNigpe319LFc9ewp4MzpmdW5jdGlvbigpe3JldHVybiB3aW5kb3d9
-LApacjpmdW5jdGlvbigpe3JldHVybiBkb2N1bWVudH0sCko2OmZ1bmN0aW9uKCl7dmFyIHQ9ZG9jdW1l
-bnQuY3JlYXRlRWxlbWVudCgiYSIpCnJldHVybiB0fSwKVTk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9
-ZG9jdW1lbnQuYm9keQpzLnRvU3RyaW5nCnQ9dS5hYwp0PW5ldyBILlU1KG5ldyBXLmU3KEMuUlkucjYo
-cyxhLGIsYykpLHQuQygiYTIobEQuRSkiKS5hKG5ldyBXLkN2KCkpLHQuQygiVTU8bEQuRT4iKSkKcmV0
-dXJuIHUuaC5hKHQuZ3I4KHQpKX0sCnJTOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj0iZWxlbWVudCB0YWcg
-dW5hdmFpbGFibGUiCnRyeXt0PUouWUUoYSkKdC5nbnMoYSkKcj10LmducyhhKX1jYXRjaChzKXtILlJ1
-KHMpfXJldHVybiByfSwKcUQ6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscT1uZXcgUC52cygkLlgzLHUu
-YW8pLHA9bmV3IFAuWmYocSx1LmJqKSxvPW5ldyBYTUxIdHRwUmVxdWVzdCgpCkMuRHQuZW8obywiR0VU
-IixhLCEwKQpiLksoMCxuZXcgVy5iVShvKSkKdD11LnUKcz10LmEobmV3IFcuaEgobyxwKSkKdS5aLmEo
-bnVsbCkKcj11LkUKVy5KRShvLCJsb2FkIixzLCExLHIpClcuSkUobywiZXJyb3IiLHQuYShwLmdZSigp
+JjEwMjMpPDwxMHxqJjEwMjMKaz0yfWVsc2Ugaz0xfWVsc2Ugaz0xCmlmKHI9PW51bGwpcj1uZXcgUC5S
+bigiIikKbT1DLnhCLk5qKGEscyx0KQpyLmErPSFxP20udG9Mb3dlckNhc2UoKTptCnIuYSs9UC56WChw
+KQp0Kz1rCnM9dH19fX1pZihyPT1udWxsKXJldHVybiBDLnhCLk5qKGEsYixjKQppZihzPGMpe209Qy54
+Qi5OaihhLHMsYykKci5hKz0hcT9tLnRvTG93ZXJDYXNlKCk6bX1uPXIuYQpyZXR1cm4gbi5jaGFyQ29k
+ZUF0KDApPT0wP246bn0sClBpOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscQppZihiPT09YylyZXR1
+cm4iIgppZighUC5FdChKLnJZKGEpLlcoYSxiKSkpUC5SMyhhLGIsIlNjaGVtZSBub3Qgc3RhcnRpbmcg
+d2l0aCBhbHBoYWJldGljIGNoYXJhY3RlciIpCmZvcih0PWIscz0hMTt0PGM7Kyt0KXtyPUMueEIuVyhh
+LHQpCmlmKHI8MTI4KXtxPXI+Pj40CmlmKHE+PTgpcmV0dXJuIEguT0goQy5tSyxxKQpxPShDLm1LW3Fd
+JjE8PChyJjE1KSkhPT0wfWVsc2UgcT0hMQppZighcSlQLlIzKGEsdCwiSWxsZWdhbCBzY2hlbWUgY2hh
+cmFjdGVyIikKaWYoNjU8PXImJnI8PTkwKXM9ITB9YT1DLnhCLk5qKGEsYixjKQpyZXR1cm4gUC5ZYShz
+P2EudG9Mb3dlckNhc2UoKTphKX0sCllhOmZ1bmN0aW9uKGEpe2lmKGE9PT0iaHR0cCIpcmV0dXJuImh0
+dHAiCmlmKGE9PT0iZmlsZSIpcmV0dXJuImZpbGUiCmlmKGE9PT0iaHR0cHMiKXJldHVybiJodHRwcyIK
+aWYoYT09PSJwYWNrYWdlIilyZXR1cm4icGFja2FnZSIKcmV0dXJuIGF9LAp6UjpmdW5jdGlvbihhLGIs
+Yyl7aWYoYT09bnVsbClyZXR1cm4iIgpyZXR1cm4gUC5QSShhLGIsYyxDLnRvLCExKX0sCmthOmZ1bmN0
+aW9uKGEsYixjLGQsZSxmKXt2YXIgdCxzPWU9PT0iZmlsZSIscj1zfHxmLHE9YT09bnVsbAppZihxJiZk
+PT1udWxsKXJldHVybiBzPyIvIjoiIgpxPSFxCmlmKHEmJmQhPW51bGwpdGhyb3cgSC5iKFAueFkoIkJv
+dGggcGF0aCBhbmQgcGF0aFNlZ21lbnRzIHNwZWNpZmllZCIpKQppZihxKXQ9UC5QSShhLGIsYyxDLldk
+LCEwKQplbHNle2QudG9TdHJpbmcKcT1ILnQ2KGQpCnQ9bmV3IEguQTgoZCxxLkMoInFVKDEpIikuYihu
+ZXcgUC5SWigpKSxxLkMoIkE4PDEscVU+IikpLnpWKDAsIi8iKX1pZih0Lmxlbmd0aD09PTApe2lmKHMp
+cmV0dXJuIi8ifWVsc2UgaWYociYmIUMueEIubih0LCIvIikpdD0iLyIrdApyZXR1cm4gUC5Kcih0LGUs
+Zil9LApKcjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9Yi5sZW5ndGg9PT0wCmlmKHQmJiFjJiYhQy54Qi5u
+KGEsIi8iKSlyZXR1cm4gUC53RihhLCF0fHxjKQpyZXR1cm4gUC54ZShhKX0sCmxlOmZ1bmN0aW9uKGEs
+YixjLGQpe3ZhciB0LHM9e30KaWYoYSE9bnVsbCl7aWYoZCE9bnVsbCl0aHJvdyBILmIoUC54WSgiQm90
+aCBxdWVyeSBhbmQgcXVlcnlQYXJhbWV0ZXJzIHNwZWNpZmllZCIpKQpyZXR1cm4gUC5QSShhLGIsYyxD
+LlZDLCEwKX1pZihkPT1udWxsKXJldHVybiBudWxsCnQ9bmV3IFAuUm4oIiIpCnMuYT0iIgpkLksoMCxu
+ZXcgUC55NShuZXcgUC5NRShzLHQpKSkKcz10LmEKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9
+LAp0RzpmdW5jdGlvbihhLGIsYyl7aWYoYT09bnVsbClyZXR1cm4gbnVsbApyZXR1cm4gUC5QSShhLGIs
+YyxDLlZDLCEwKX0sCnJ2OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG89YisyCmlmKG8+PWEu
+bGVuZ3RoKXJldHVybiIlIgp0PUMueEIubShhLGIrMSkKcz1DLnhCLm0oYSxvKQpyPUgub28odCkKcT1I
+Lm9vKHMpCmlmKHI8MHx8cTwwKXJldHVybiIlIgpwPXIqMTYrcQppZihwPDEyNyl7bz1DLmpuLndHKHAs
+NCkKaWYobz49OClyZXR1cm4gSC5PSChDLkYzLG8pCm89KEMuRjNbb10mMTw8KHAmMTUpKSE9PTB9ZWxz
+ZSBvPSExCmlmKG8pcmV0dXJuIEguTHcoYyYmNjU8PXAmJjkwPj1wPyhwfDMyKT4+PjA6cCkKaWYodD49
+OTd8fHM+PTk3KXJldHVybiBDLnhCLk5qKGEsYixiKzMpLnRvVXBwZXJDYXNlKCkKcmV0dXJuIG51bGx9
+LAp6WDpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbj0iMDEyMzQ1Njc4OUFCQ0RFRiIKaWYoYTwx
+Mjgpe3Q9bmV3IEFycmF5KDMpCnQuZml4ZWQkbGVuZ3RoPUFycmF5CnM9SC5WTSh0LHUudCkKQy5ObS5Z
+KHMsMCwzNykKQy5ObS5ZKHMsMSxDLnhCLlcobixhPj4+NCkpCkMuTm0uWShzLDIsQy54Qi5XKG4sYSYx
+NSkpfWVsc2V7aWYoYT4yMDQ3KWlmKGE+NjU1MzUpe3I9MjQwCnE9NH1lbHNle3I9MjI0CnE9M31lbHNl
+e3I9MTkyCnE9Mn10PW5ldyBBcnJheSgzKnEpCnQuZml4ZWQkbGVuZ3RoPUFycmF5CnM9SC5WTSh0LHUu
+dCkKZm9yKHA9MDstLXEscT49MDtyPTEyOCl7bz1DLmpuLmJmKGEsNipxKSY2M3xyCkMuTm0uWShzLHAs
+MzcpCkMuTm0uWShzLHArMSxDLnhCLlcobixvPj4+NCkpCkMuTm0uWShzLHArMixDLnhCLlcobixvJjE1
+KSkKcCs9M319cmV0dXJuIFAuSE0ocywwLG51bGwpfSwKUEk6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIg
+dD1QLlVsKGEsYixjLGQsZSkKcmV0dXJuIHQ9PW51bGw/Qy54Qi5OaihhLGIsYyk6dH0sClVsOmZ1bmN0
+aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyLHEscCxvPW51bGwsbj0hZSxtPWIsbD1tLGs9bwp3aGlsZSgh
+MCl7aWYodHlwZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4gbS5KKCkKaWYodHlwZW9mIGMhPT0ibnVtYmVy
+IilyZXR1cm4gSC5wWShjKQppZighKG08YykpYnJlYWsKYyQwOnt0PUMueEIubShhLG0pCmlmKHQ8MTI3
+KXtzPXQ+Pj40CmlmKHM+PTgpcmV0dXJuIEguT0goZCxzKQpzPShkW3NdJjE8PCh0JjE1KSkhPT0wfWVs
+c2Ugcz0hMQppZihzKSsrbQplbHNle2lmKHQ9PT0zNyl7cj1QLnJ2KGEsbSwhMSkKaWYocj09bnVsbCl7
+bSs9MwpicmVhayBjJDB9aWYoIiUiPT09cil7cj0iJTI1IgpxPTF9ZWxzZSBxPTN9ZWxzZXtpZihuKWlm
+KHQ8PTkzKXtzPXQ+Pj40CmlmKHM+PTgpcmV0dXJuIEguT0goQy5hayxzKQpzPShDLmFrW3NdJjE8PCh0
+JjE1KSkhPT0wfWVsc2Ugcz0hMQplbHNlIHM9ITEKaWYocyl7UC5SMyhhLG0sIkludmFsaWQgY2hhcmFj
+dGVyIikKcT1vCnI9cX1lbHNle2lmKCh0JjY0NTEyKT09PTU1Mjk2KXtzPW0rMQppZihzPGMpe3A9Qy54
+Qi5tKGEscykKaWYoKHAmNjQ1MTIpPT09NTYzMjApe3Q9NjU1MzZ8KHQmMTAyMyk8PDEwfHAmMTAyMwpx
+PTJ9ZWxzZSBxPTF9ZWxzZSBxPTF9ZWxzZSBxPTEKcj1QLnpYKHQpfX1pZihrPT1udWxsKWs9bmV3IFAu
+Um4oIiIpCmsuYSs9Qy54Qi5OaihhLGwsbSkKay5hKz1ILmQocikKaWYodHlwZW9mIHEhPT0ibnVtYmVy
+IilyZXR1cm4gSC5wWShxKQptKz1xCmw9bX19fWlmKGs9PW51bGwpcmV0dXJuIG8KaWYodHlwZW9mIGwh
+PT0ibnVtYmVyIilyZXR1cm4gbC5KKCkKaWYobDxjKWsuYSs9Qy54Qi5OaihhLGwsYykKbj1rLmEKcmV0
+dXJuIG4uY2hhckNvZGVBdCgwKT09MD9uOm59LAp5QjpmdW5jdGlvbihhKXtpZihDLnhCLm4oYSwiLiIp
+KXJldHVybiEwCnJldHVybiBDLnhCLk9ZKGEsIi8uIikhPT0tMX0sCnhlOmZ1bmN0aW9uKGEpe3ZhciB0
+LHMscixxLHAsbyxuCmlmKCFQLnlCKGEpKXJldHVybiBhCnQ9SC5WTShbXSx1LnMpCmZvcihzPWEuc3Bs
+aXQoIi8iKSxyPXMubGVuZ3RoLHE9ITEscD0wO3A8cjsrK3Ape289c1twXQppZihKLlJNKG8sIi4uIikp
+e249dC5sZW5ndGgKaWYobiE9PTApe2lmKDA+PW4pcmV0dXJuIEguT0godCwtMSkKdC5wb3AoKQppZih0
+Lmxlbmd0aD09PTApQy5ObS5pKHQsIiIpfXE9ITB9ZWxzZSBpZigiLiI9PT1vKXE9ITAKZWxzZXtDLk5t
+LmkodCxvKQpxPSExfX1pZihxKUMuTm0uaSh0LCIiKQpyZXR1cm4gQy5ObS56Vih0LCIvIil9LAp3Rjpm
+dW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbwppZighUC55QihhKSlyZXR1cm4hYj9QLkMxKGEpOmEK
+dD1ILlZNKFtdLHUucykKZm9yKHM9YS5zcGxpdCgiLyIpLHI9cy5sZW5ndGgscT0hMSxwPTA7cDxyOysr
+cCl7bz1zW3BdCmlmKCIuLiI9PT1vKWlmKHQubGVuZ3RoIT09MCYmQy5ObS5ncloodCkhPT0iLi4iKXtp
+ZigwPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LC0xKQp0LnBvcCgpCnE9ITB9ZWxzZXtDLk5tLmkodCwi
+Li4iKQpxPSExfWVsc2UgaWYoIi4iPT09bylxPSEwCmVsc2V7Qy5ObS5pKHQsbykKcT0hMX19cz10Lmxl
+bmd0aAppZihzIT09MClpZihzPT09MSl7aWYoMD49cylyZXR1cm4gSC5PSCh0LDApCnM9dFswXS5sZW5n
+dGg9PT0wfWVsc2Ugcz0hMQplbHNlIHM9ITAKaWYocylyZXR1cm4iLi8iCmlmKHF8fEMuTm0uZ3JaKHQp
+PT09Ii4uIilDLk5tLmkodCwiIikKaWYoIWIpe2lmKDA+PXQubGVuZ3RoKXJldHVybiBILk9IKHQsMCkK
+Qy5ObS5ZKHQsMCxQLkMxKHRbMF0pKX1yZXR1cm4gQy5ObS56Vih0LCIvIil9LApDMTpmdW5jdGlvbihh
+KXt2YXIgdCxzLHIscT1hLmxlbmd0aAppZihxPj0yJiZQLkV0KEouUXooYSwwKSkpZm9yKHQ9MTt0PHE7
+Kyt0KXtzPUMueEIuVyhhLHQpCmlmKHM9PT01OClyZXR1cm4gQy54Qi5OaihhLDAsdCkrIiUzQSIrQy54
+Qi5HKGEsdCsxKQppZihzPD0xMjcpe3I9cz4+PjQKaWYocj49OClyZXR1cm4gSC5PSChDLm1LLHIpCnI9
+KEMubUtbcl0mMTw8KHMmMTUpKT09PTB9ZWxzZSByPSEwCmlmKHIpYnJlYWt9cmV0dXJuIGF9LAptbjpm
+dW5jdGlvbihhKXt2YXIgdCxzLHIscT1hLmdGaigpLHA9cS5sZW5ndGgKaWYocD4wJiZKLkhtKHFbMF0p
+PT09MiYmSi5hNihxWzBdLDEpPT09NTgpe2lmKDA+PXApcmV0dXJuIEguT0gocSwwKQpQLnJnKEouYTYo
+cVswXSwwKSwhMSkKUC5ITihxLCExLDEpCnQ9ITB9ZWxzZXtQLkhOKHEsITEsMCkKdD0hMX1zPWEuZ3RU
+KCkmJiF0PyJcXCI6IiIKaWYoYS5nY2ooKSl7cj1hLmdKZihhKQppZihyLmxlbmd0aCE9PTApcz1zKyJc
+XCIrcisiXFwifXM9UC52ZyhzLHEsIlxcIikKcD10JiZwPT09MT9zKyJcXCI6cwpyZXR1cm4gcC5jaGFy
+Q29kZUF0KDApPT0wP3A6cH0sCkloOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCmZvcih0PTAscz0wO3M8
+MjsrK3Mpe3I9Qy54Qi5XKGEsYitzKQppZig0ODw9ciYmcjw9NTcpdD10KjE2K3ItNDgKZWxzZXtyfD0z
+MgppZig5Nzw9ciYmcjw9MTAyKXQ9dCoxNityLTg3CmVsc2UgdGhyb3cgSC5iKFAueFkoIkludmFsaWQg
+VVJMIGVuY29kaW5nIikpfX1yZXR1cm4gdH0sCmt1OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxy
+LHEscD1KLnJZKGEpLG89Ygp3aGlsZSghMCl7aWYoIShvPGMpKXt0PSEwCmJyZWFrfXM9cC5XKGEsbykK
+aWYoczw9MTI3KWlmKHMhPT0zNylyPWUmJnM9PT00MwplbHNlIHI9ITAKZWxzZSByPSEwCmlmKHIpe3Q9
+ITEKYnJlYWt9KytvfWlmKHQpe2lmKEMueE0hPT1kKXI9ITEKZWxzZSByPSEwCmlmKHIpcmV0dXJuIHAu
+TmooYSxiLGMpCmVsc2UgcT1uZXcgSC5xaihwLk5qKGEsYixjKSl9ZWxzZXtxPUguVk0oW10sdS50KQpm
+b3Iobz1iO288YzsrK28pe3M9cC5XKGEsbykKaWYocz4xMjcpdGhyb3cgSC5iKFAueFkoIklsbGVnYWwg
+cGVyY2VudCBlbmNvZGluZyBpbiBVUkkiKSkKaWYocz09PTM3KXtpZihvKzM+YS5sZW5ndGgpdGhyb3cg
+SC5iKFAueFkoIlRydW5jYXRlZCBVUkkiKSkKQy5ObS5pKHEsUC5JaChhLG8rMSkpCm8rPTJ9ZWxzZSBp
+ZihlJiZzPT09NDMpQy5ObS5pKHEsMzIpCmVsc2UgQy5ObS5pKHEscyl9fXUuTC5iKHEpCnJldHVybiBu
+ZXcgUC5HWSghMSkuV0oocSl9LApFdDpmdW5jdGlvbihhKXt2YXIgdD1hfDMyCnJldHVybiA5Nzw9dCYm
+dDw9MTIyfSwKS0Q6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuLG0sbD0iSW52YWxpZCBN
+SU1FIHR5cGUiLGs9SC5WTShbYi0xXSx1LnQpCmZvcih0PWEubGVuZ3RoLHM9YixyPS0xLHE9bnVsbDtz
+PHQ7KytzKXtxPUMueEIuVyhhLHMpCmlmKHE9PT00NHx8cT09PTU5KWJyZWFrCmlmKHE9PT00Nyl7aWYo
+cjwwKXtyPXMKY29udGludWV9dGhyb3cgSC5iKFAucnIobCxhLHMpKX19aWYocjwwJiZzPmIpdGhyb3cg
+SC5iKFAucnIobCxhLHMpKQpmb3IoO3EhPT00NDspe0MuTm0uaShrLHMpOysrcwpmb3IocD0tMTtzPHQ7
+KytzKXtxPUMueEIuVyhhLHMpCmlmKHE9PT02MSl7aWYocDwwKXA9c31lbHNlIGlmKHE9PT01OXx8cT09
+PTQ0KWJyZWFrfWlmKHA+PTApQy5ObS5pKGsscCkKZWxzZXtvPUMuTm0uZ3JaKGspCmlmKHEhPT00NHx8
+cyE9PW8rN3x8IUMueEIuUWkoYSwiYmFzZTY0IixvKzEpKXRocm93IEguYihQLnJyKCJFeHBlY3Rpbmcg
+Jz0nIixhLHMpKQpicmVha319Qy5ObS5pKGsscykKbj1zKzEKaWYoKGsubGVuZ3RoJjEpPT09MSlhPUMu
+aDkueXIoYSxuLHQpCmVsc2V7bT1QLlVsKGEsbix0LEMuVkMsITApCmlmKG0hPW51bGwpYT1DLnhCLmk3
+KGEsbix0LG0pfXJldHVybiBuZXcgUC5QRShhLGssYyl9LAp1eDpmdW5jdGlvbigpe3ZhciB0PSIwMTIz
+NDU2Nzg5QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ei0u
+X34hJCYnKCkqKyw7PSIscz0iLiIscj0iOiIscT0iLyIscD0iPyIsbz0iIyIsbj11LmdjLG09UC5kSCgy
+MixuZXcgUC5xMygpLCEwLG4pLGw9bmV3IFAueUkobSksaz1uZXcgUC5jNigpLGo9bmV3IFAucWQoKSxp
+PW4uYihsLiQyKDAsMjI1KSkKay4kMyhpLHQsMSkKay4kMyhpLHMsMTQpCmsuJDMoaSxyLDM0KQprLiQz
+KGkscSwzKQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmIobC4kMigxNCwyMjUpKQprLiQz
+KGksdCwxKQprLiQzKGkscywxNSkKay4kMyhpLHIsMzQpCmsuJDMoaSxxLDIzNCkKay4kMyhpLHAsMTcy
+KQprLiQzKGksbywyMDUpCmk9bi5iKGwuJDIoMTUsMjI1KSkKay4kMyhpLHQsMSkKay4kMyhpLCIlIiwy
+MjUpCmsuJDMoaSxyLDM0KQprLiQzKGkscSw5KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1u
+LmIobC4kMigxLDIyNSkpCmsuJDMoaSx0LDEpCmsuJDMoaSxyLDM0KQprLiQzKGkscSwxMCkKay4kMyhp
+LHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5iKGwuJDIoMiwyMzUpKQprLiQzKGksdCwxMzkpCmsuJDMo
+aSxxLDEzMSkKay4kMyhpLHMsMTQ2KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmIobC4k
+MigzLDIzNSkpCmsuJDMoaSx0LDExKQprLiQzKGkscSw2OCkKay4kMyhpLHMsMTgpCmsuJDMoaSxwLDE3
+MikKay4kMyhpLG8sMjA1KQppPW4uYihsLiQyKDQsMjI5KSkKay4kMyhpLHQsNSkKai4kMyhpLCJBWiIs
+MjI5KQprLiQzKGksciwxMDIpCmsuJDMoaSwiQCIsNjgpCmsuJDMoaSwiWyIsMjMyKQprLiQzKGkscSwx
+MzgpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYihsLiQyKDUsMjI5KSkKay4kMyhpLHQs
+NSkKai4kMyhpLCJBWiIsMjI5KQprLiQzKGksciwxMDIpCmsuJDMoaSwiQCIsNjgpCmsuJDMoaSxxLDEz
+OCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5iKGwuJDIoNiwyMzEpKQpqLiQzKGksIjE5
+Iiw3KQprLiQzKGksIkAiLDY4KQprLiQzKGkscSwxMzgpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1
+KQppPW4uYihsLiQyKDcsMjMxKSkKai4kMyhpLCIwOSIsNykKay4kMyhpLCJAIiw2OCkKay4kMyhpLHEs
+MTM4KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKay4kMyhuLmIobC4kMig4LDgpKSwiXSIsNSkK
+aT1uLmIobC4kMig5LDIzNSkpCmsuJDMoaSx0LDExKQprLiQzKGkscywxNikKay4kMyhpLHEsMjM0KQpr
+LiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmIobC4kMigxNiwyMzUpKQprLiQzKGksdCwxMSkK
+ay4kMyhpLHMsMTcpCmsuJDMoaSxxLDIzNCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5i
+KGwuJDIoMTcsMjM1KSkKay4kMyhpLHQsMTEpCmsuJDMoaSxxLDkpCmsuJDMoaSxwLDE3MikKay4kMyhp
+LG8sMjA1KQppPW4uYihsLiQyKDEwLDIzNSkpCmsuJDMoaSx0LDExKQprLiQzKGkscywxOCkKay4kMyhp
+LHEsMjM0KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmIobC4kMigxOCwyMzUpKQprLiQz
+KGksdCwxMSkKay4kMyhpLHMsMTkpCmsuJDMoaSxxLDIzNCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywy
+MDUpCmk9bi5iKGwuJDIoMTksMjM1KSkKay4kMyhpLHQsMTEpCmsuJDMoaSxxLDIzNCkKay4kMyhpLHAs
+MTcyKQprLiQzKGksbywyMDUpCmk9bi5iKGwuJDIoMTEsMjM1KSkKay4kMyhpLHQsMTEpCmsuJDMoaSxx
+LDEwKQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmIobC4kMigxMiwyMzYpKQprLiQzKGks
+dCwxMikKay4kMyhpLHAsMTIpCmsuJDMoaSxvLDIwNSkKaT1uLmIobC4kMigxMywyMzcpKQprLiQzKGks
+dCwxMykKay4kMyhpLHAsMTMpCmouJDMobi5iKGwuJDIoMjAsMjQ1KSksImF6IiwyMSkKbD1uLmIobC4k
+MigyMSwyNDUpKQpqLiQzKGwsImF6IiwyMSkKai4kMyhsLCIwOSIsMjEpCmsuJDMobCwiKy0uIiwyMSkK
+cmV0dXJuIG19LApVQjpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscixxLHAsbz0kLnZaKCkKZm9y
+KHQ9Si5yWShhKSxzPWI7czxjOysrcyl7aWYoZDwwfHxkPj1vLmxlbmd0aClyZXR1cm4gSC5PSChvLGQp
+CnI9b1tkXQpxPXQuVyhhLHMpXjk2CmlmKHE+OTUpcT0zMQppZihxPj1yLmxlbmd0aClyZXR1cm4gSC5P
+SChyLHEpCnA9cltxXQpkPXAmMzEKQy5ObS5ZKGUscD4+PjUscyl9cmV0dXJuIGR9LApXRjpmdW5jdGlv
+biBXRihhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKYTI6ZnVuY3Rpb24gYTIoKXt9LAppUDpmdW5jdGlv
+biBpUChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQ1A6ZnVuY3Rpb24gQ1AoKXt9LApYUzpmdW5jdGlv
+biBYUygpe30sCkM2OmZ1bmN0aW9uIEM2KGEpe3RoaXMuYT1hfSwKbjpmdW5jdGlvbiBuKCl7fSwKdTpm
+dW5jdGlvbiB1KGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9LApiSjpm
+dW5jdGlvbiBiSihhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmU9YQpfLmY9YgpfLmE9YwpfLmI9ZApf
+LmM9ZQpfLmQ9Zn0sCmVZOmZ1bmN0aW9uIGVZKGEsYixjLGQsZSl7dmFyIF89dGhpcwpfLmY9YQpfLmE9
+YgpfLmI9YwpfLmM9ZApfLmQ9ZX0sCm1wOmZ1bmN0aW9uIG1wKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5h
+PWEKXy5iPWIKXy5jPWMKXy5kPWR9LAp1YjpmdW5jdGlvbiB1YihhKXt0aGlzLmE9YX0sCmRzOmZ1bmN0
+aW9uIGRzKGEpe3RoaXMuYT1hfSwKbGo6ZnVuY3Rpb24gbGooYSl7dGhpcy5hPWF9LApVVjpmdW5jdGlv
+biBVVihhKXt0aGlzLmE9YX0sCms1OmZ1bmN0aW9uIGs1KCl7fSwKS1k6ZnVuY3Rpb24gS1koKXt9LApj
+OmZ1bmN0aW9uIGMoYSl7dGhpcy5hPWF9LApDRDpmdW5jdGlvbiBDRChhKXt0aGlzLmE9YX0sCmFFOmZ1
+bmN0aW9uIGFFKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCkVIOmZ1bmN0aW9uIEVI
+KCl7fSwKS046ZnVuY3Rpb24gS04oKXt9LApjWDpmdW5jdGlvbiBjWCgpe30sCkFuOmZ1bmN0aW9uIEFu
+KCl7fSwKek06ZnVuY3Rpb24gek0oKXt9LApaMDpmdW5jdGlvbiBaMCgpe30sCk4zOmZ1bmN0aW9uIE4z
+KGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKYzg6ZnVuY3Rpb24gYzgoKXt9LApG
+SzpmdW5jdGlvbiBGSygpe30sCms6ZnVuY3Rpb24gaygpe30sCk9kOmZ1bmN0aW9uIE9kKCl7fSwKaWI6
+ZnVuY3Rpb24gaWIoKXt9LAp4dTpmdW5jdGlvbiB4dSgpe30sCkd6OmZ1bmN0aW9uIEd6KCl7fSwKcVU6
+ZnVuY3Rpb24gcVUoKXt9LApSbjpmdW5jdGlvbiBSbihhKXt0aGlzLmE9YX0sCkdEOmZ1bmN0aW9uIEdE
+KCl7fSwKbjE6ZnVuY3Rpb24gbjEoYSl7dGhpcy5hPWF9LApjUzpmdW5jdGlvbiBjUyhhKXt0aGlzLmE9
+YX0sClZDOmZ1bmN0aW9uIFZDKGEpe3RoaXMuYT1hfSwKSlQ6ZnVuY3Rpb24gSlQoYSxiKXt0aGlzLmE9
+YQp0aGlzLmI9Yn0sCkRuOmZ1bmN0aW9uIERuKGEsYixjLGQsZSxmLGcpe3ZhciBfPXRoaXMKXy5hPWEK
+Xy5iPWIKXy5jPWMKXy5kPWQKXy5lPWUKXy5mPWYKXy5yPWcKXy5RPV8uej1fLnk9Xy54PW51bGx9LApl
+MTpmdW5jdGlvbiBlMShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKTlk6ZnVuY3Rpb24gTlkoYSl7dGhp
+cy5hPWF9LApSWjpmdW5jdGlvbiBSWigpe30sCk1FOmZ1bmN0aW9uIE1FKGEsYil7dGhpcy5hPWEKdGhp
+cy5iPWJ9LAp5NTpmdW5jdGlvbiB5NShhKXt0aGlzLmE9YX0sClBFOmZ1bmN0aW9uIFBFKGEsYixjKXt0
+aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCnEzOmZ1bmN0aW9uIHEzKCl7fSwKeUk6ZnVuY3Rpb24g
+eUkoYSl7dGhpcy5hPWF9LApjNjpmdW5jdGlvbiBjNigpe30sCnFkOmZ1bmN0aW9uIHFkKCl7fSwKVWY6
+ZnVuY3Rpb24gVWYoYSxiLGMsZCxlLGYsZyxoKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8u
+ZD1kCl8uZT1lCl8uZj1mCl8ucj1nCl8ueD1oCl8ueT1udWxsfSwKcWU6ZnVuY3Rpb24gcWUoYSxiLGMs
+ZCxlLGYsZyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZQpfLmY9ZgpfLnI9
+ZwpfLlE9Xy56PV8ueT1fLng9bnVsbH0sCmlKOmZ1bmN0aW9uIGlKKCl7fSwKbFI6ZnVuY3Rpb24gbFIo
+YSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCmpnOmZ1bmN0aW9uIGpnKGEsYil7dGhpcy5hPWEKdGhpcy5i
+PWJ9LApCZjpmdW5jdGlvbiBCZihhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQXM6ZnVuY3Rpb24gQXMo
+KXt9LApHRTpmdW5jdGlvbiBHRShhKXt0aGlzLmE9YX0sCk43OmZ1bmN0aW9uIE43KGEsYil7dGhpcy5h
+PWEKdGhpcy5iPWJ9LAp1UTpmdW5jdGlvbiB1USgpe30sCmhGOmZ1bmN0aW9uIGhGKCl7fSwKUjQ6ZnVu
+Y3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyCkgueGQoYikKdS5qLmIoZCkKaWYoSC5vVChiKSl7dD1bY10K
+Qy5ObS5GVih0LGQpCmQ9dH1zPXUuegpyPVAuQ0goSi5NMShkLFAudzAoKSxzKSwhMCxzKQp1LlouYihh
+KQpyZXR1cm4gUC53WShILkVrKGEscixudWxsKSl9LApEbTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKdHJ5
+e2lmKE9iamVjdC5pc0V4dGVuc2libGUoYSkmJiFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5
+LmNhbGwoYSxiKSl7T2JqZWN0LmRlZmluZVByb3BlcnR5KGEsYix7dmFsdWU6Y30pCnJldHVybiEwfX1j
+YXRjaCh0KXtILlJ1KHQpfXJldHVybiExfSwKT206ZnVuY3Rpb24oYSxiKXtpZihPYmplY3QucHJvdG90
+eXBlLmhhc093blByb3BlcnR5LmNhbGwoYSxiKSlyZXR1cm4gYVtiXQpyZXR1cm4gbnVsbH0sCndZOmZ1
+bmN0aW9uKGEpe2lmKGE9PW51bGx8fHR5cGVvZiBhPT0ic3RyaW5nInx8dHlwZW9mIGE9PSJudW1iZXIi
+fHxILmwoYSkpcmV0dXJuIGEKaWYoYSBpbnN0YW5jZW9mIFAuRTQpcmV0dXJuIGEuYQppZihILlI5KGEp
+KXJldHVybiBhCmlmKHUudy5jKGEpKXJldHVybiBhCmlmKGEgaW5zdGFuY2VvZiBQLmlQKXJldHVybiBI
+Lm8yKGEpCmlmKHUuWi5jKGEpKXJldHVybiBQLmhFKGEsIiRkYXJ0X2pzRnVuY3Rpb24iLG5ldyBQLlBD
+KCkpCnJldHVybiBQLmhFKGEsIl8kZGFydF9qc09iamVjdCIsbmV3IFAubXQoJC5rSSgpKSl9LApoRTpm
+dW5jdGlvbihhLGIsYyl7dmFyIHQ9UC5PbShhLGIpCmlmKHQ9PW51bGwpe3Q9Yy4kMShhKQpQLkRtKGEs
+Yix0KX1yZXR1cm4gdH0sCkw3OmZ1bmN0aW9uKGEpe3ZhciB0LHMKaWYoYT09bnVsbHx8dHlwZW9mIGE9
+PSJzdHJpbmcifHx0eXBlb2YgYT09Im51bWJlciJ8fHR5cGVvZiBhPT0iYm9vbGVhbiIpcmV0dXJuIGEK
+ZWxzZSBpZihhIGluc3RhbmNlb2YgT2JqZWN0JiZILlI5KGEpKXJldHVybiBhCmVsc2UgaWYoYSBpbnN0
+YW5jZW9mIE9iamVjdCYmdS53LmMoYSkpcmV0dXJuIGEKZWxzZSBpZihhIGluc3RhbmNlb2YgRGF0ZSl7
+dD1ILlNjKGEuZ2V0VGltZSgpKQppZihNYXRoLmFicyh0KTw9ODY0ZTEzKXM9ITEKZWxzZSBzPSEwCmlm
+KHMpSC52aChQLnhZKCJEYXRlVGltZSBpcyBvdXRzaWRlIHZhbGlkIHJhbmdlOiAiK3QpKQpyZXR1cm4g
+bmV3IFAuaVAodCwhMSl9ZWxzZSBpZihhLmNvbnN0cnVjdG9yPT09JC5rSSgpKXJldHVybiBhLm8KZWxz
+ZSByZXR1cm4gUC5ORChhKX0sCk5EOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJl
+dHVybiBQLmlRKGEsJC53KCksbmV3IFAuTnooKSkKaWYoYSBpbnN0YW5jZW9mIEFycmF5KXJldHVybiBQ
+LmlRKGEsJC5SOCgpLG5ldyBQLlFTKCkpCnJldHVybiBQLmlRKGEsJC5SOCgpLG5ldyBQLm5wKCkpfSwK
+aVE6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PVAuT20oYSxiKQppZih0PT1udWxsfHwhKGEgaW5zdGFuY2Vv
+ZiBPYmplY3QpKXt0PWMuJDEoYSkKUC5EbShhLGIsdCl9cmV0dXJuIHR9LApQQzpmdW5jdGlvbiBQQygp
+e30sCm10OmZ1bmN0aW9uIG10KGEpe3RoaXMuYT1hfSwKTno6ZnVuY3Rpb24gTnooKXt9LApRUzpmdW5j
+dGlvbiBRUygpe30sCm5wOmZ1bmN0aW9uIG5wKCl7fSwKRTQ6ZnVuY3Rpb24gRTQoYSl7dGhpcy5hPWF9
+LApyNzpmdW5jdGlvbiByNyhhKXt0aGlzLmE9YX0sClR6OmZ1bmN0aW9uIFR6KGEsYil7dGhpcy5hPWEK
+dGhpcy4kdGk9Yn0sCmNvOmZ1bmN0aW9uIGNvKCl7fSwKbmQ6ZnVuY3Rpb24gbmQoKXt9LApLZTpmdW5j
+dGlvbiBLZShhKXt0aGlzLmE9YX0sCmQ1OmZ1bmN0aW9uIGQ1KCl7fSwKbjY6ZnVuY3Rpb24gbjYoKXt9
+fSxXPXsKeDM6ZnVuY3Rpb24oKXtyZXR1cm4gd2luZG93fSwKWnI6ZnVuY3Rpb24oKXtyZXR1cm4gZG9j
+dW1lbnR9LApKNjpmdW5jdGlvbigpe3ZhciB0PWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImEiKQpyZXR1
+cm4gdH0sClU5OmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1kb2N1bWVudC5ib2R5LHM9KHQmJkMuUlkpLnI2
+KHQsYSxiLGMpCnMudG9TdHJpbmcKdD11LmFjCnQ9bmV3IEguVTUobmV3IFcuZTcocyksdC5DKCJhMihs
+RC5FKSIpLmIobmV3IFcuQ3YoKSksdC5DKCJVNTxsRC5FPiIpKQpyZXR1cm4gdS5oLmIodC5ncjgodCkp
+fSwKclM6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPSJlbGVtZW50IHRhZyB1bmF2YWlsYWJsZSIKdHJ5e3Q9
+Si5SRShhKQppZih0eXBlb2YgdC5nbnMoYSk9PSJzdHJpbmciKXI9dC5nbnMoYSl9Y2F0Y2gocyl7SC5S
+dShzKX1yZXR1cm4gcn0sCnFEOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHE9bmV3IFAudnMoJC5YMyx1
+LlkpLHA9bmV3IFAuWmYocSx1LkUpLG89bmV3IFhNTEh0dHBSZXF1ZXN0KCkKQy5EdC5lbyhvLCJHRVQi
+LGEsITApCmIuSygwLG5ldyBXLmJVKG8pKQp0PXUuYW4Kcz10LmIobmV3IFcuaEgobyxwKSkKdS5NLmIo
+bnVsbCkKcj11LnAKVy5KRShvLCJsb2FkIixzLCExLHIpClcuSkUobywiZXJyb3IiLHQuYihwLmdZSigp
 KSwhMSxyKQpvLnNlbmQoKQpyZXR1cm4gcX0sCkMwOmZ1bmN0aW9uKGEsYil7YT01MzY4NzA5MTEmYSti
 CmE9NTM2ODcwOTExJmErKCg1MjQyODcmYSk8PDEwKQpyZXR1cm4gYV5hPj4+Nn0sCnJFOmZ1bmN0aW9u
 KGEsYixjLGQpe3ZhciB0PVcuQzAoVy5DMChXLkMwKFcuQzAoMCxhKSxiKSxjKSxkKSxzPTUzNjg3MDkx
@@ -1816,2368 +1758,2377 @@
 dWxsJiYhMClKLmRaKGEsYix0LCExKQpyZXR1cm4gbmV3IFcueEMoYSxiLHQsITEsZS5DKCJ4QzwwPiIp
 KX0sClR3OmZ1bmN0aW9uKGEpe3ZhciB0PVcuSjYoKSxzPXdpbmRvdy5sb2NhdGlvbgp0PW5ldyBXLkpR
 KG5ldyBXLm1rKHQscykpCnQuQ1koYSkKcmV0dXJuIHR9LAp5VzpmdW5jdGlvbihhLGIsYyxkKXt1Lmgu
-YShhKQpILmgoYikKSC5oKGMpCnUuY3IuYShkKQpyZXR1cm4hMH0sClFXOmZ1bmN0aW9uKGEsYixjLGQp
-e3ZhciB0LHMscgp1LmguYShhKQpILmgoYikKSC5oKGMpCnQ9dS5jci5hKGQpLmEKcz10LmEKcy5ocmVm
-PWMKcj1zLmhvc3RuYW1lCnQ9dC5iCmlmKCEocj09PXQuaG9zdG5hbWUmJnMucG9ydD09PXQucG9ydCYm
-cy5wcm90b2NvbD09PXQucHJvdG9jb2wpKWlmKHI9PT0iIilpZihzLnBvcnQ9PT0iIil7dD1zLnByb3Rv
-Y29sCnQ9dD09PSI6Inx8dD09PSIifWVsc2UgdD0hMQplbHNlIHQ9ITEKZWxzZSB0PSEwCnJldHVybiB0
-fSwKQmw6ZnVuY3Rpb24oKXt2YXIgdD11Lk4scz1QLnRNKEMuUXgsdCkscj11LmQwLmEobmV3IFcuSUEo
-KSkscT1ILlZNKFsiVEVNUExBVEUiXSx1LnMpCnQ9bmV3IFcuY3QocyxQLkxzKHQpLFAuTHModCksUC5M
-cyh0KSxudWxsKQp0LkNZKG51bGwsbmV3IEgubEooQy5ReCxyLHUuZmopLHEsbnVsbCkKcmV0dXJuIHR9
-LApQdjpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJldHVybiBudWxsCnJldHVybiBXLlAxKGEpfSwKcWM6
-ZnVuY3Rpb24oYSl7dmFyIHQKaWYoYT09bnVsbClyZXR1cm4gbnVsbAppZigicG9zdE1lc3NhZ2UiIGlu
-IGEpe3Q9Vy5QMShhKQppZih1LmFTLmIodCkpcmV0dXJuIHQKcmV0dXJuIG51bGx9ZWxzZSByZXR1cm4g
-dS5jaC5hKGEpfSwKUDE6ZnVuY3Rpb24oYSl7aWYoYT09PXdpbmRvdylyZXR1cm4gdS5jaS5hKGEpCmVs
-c2UgcmV0dXJuIG5ldyBXLmRXKGEpfSwKSEg6ZnVuY3Rpb24oYSl7aWYoYT09PXdpbmRvdy5sb2NhdGlv
-bilyZXR1cm4gYQplbHNlIHJldHVybiBuZXcgVy5GYigpfSwKYUY6ZnVuY3Rpb24oYSxiKXt2YXIgdD0k
-LlgzCmlmKHQ9PT1DLk5VKXJldHVybiBhCnJldHVybiB0LlB5KGEsYil9LApxRTpmdW5jdGlvbiBxRSgp
-e30sCkdoOmZ1bmN0aW9uIEdoKCl7fSwKZlk6ZnVuY3Rpb24gZlkoKXt9LApuQjpmdW5jdGlvbiBuQigp
-e30sCkF6OmZ1bmN0aW9uIEF6KCl7fSwKUVA6ZnVuY3Rpb24gUVAoKXt9LApueDpmdW5jdGlvbiBueCgp
-e30sCm9KOmZ1bmN0aW9uIG9KKCl7fSwKaWQ6ZnVuY3Rpb24gaWQoKXt9LApRRjpmdW5jdGlvbiBRRigp
-e30sCk5oOmZ1bmN0aW9uIE5oKCl7fSwKYWU6ZnVuY3Rpb24gYWUoKXt9LApJQjpmdW5jdGlvbiBJQigp
-e30sCm43OmZ1bmN0aW9uIG43KCl7fSwKd3o6ZnVuY3Rpb24gd3ooYSxiKXt0aGlzLmE9YQp0aGlzLiR0
-aT1ifSwKY3Y6ZnVuY3Rpb24gY3YoKXt9LApDdjpmdW5jdGlvbiBDdigpe30sCmVhOmZ1bmN0aW9uIGVh
-KCl7fSwKRDA6ZnVuY3Rpb24gRDAoKXt9LApUNTpmdW5jdGlvbiBUNSgpe30sCmg0OmZ1bmN0aW9uIGg0
-KCl7fSwKYnI6ZnVuY3Rpb24gYnIoKXt9LApWYjpmdW5jdGlvbiBWYigpe30sCmZKOmZ1bmN0aW9uIGZK
-KCl7fSwKYlU6ZnVuY3Rpb24gYlUoYSl7dGhpcy5hPWF9LApoSDpmdW5jdGlvbiBoSChhLGIpe3RoaXMu
-YT1hCnRoaXMuYj1ifSwKd2E6ZnVuY3Rpb24gd2EoKXt9LApTZzpmdW5jdGlvbiBTZygpe30sCnU4OmZ1
-bmN0aW9uIHU4KCl7fSwKT0s6ZnVuY3Rpb24gT0soKXt9LAplNzpmdW5jdGlvbiBlNyhhKXt0aGlzLmE9
-YX0sCnVIOmZ1bmN0aW9uIHVIKCl7fSwKQkg6ZnVuY3Rpb24gQkgoKXt9LApTTjpmdW5jdGlvbiBTTigp
-e30sCmV3OmZ1bmN0aW9uIGV3KCl7fSwKbHA6ZnVuY3Rpb24gbHAoKXt9LApUYjpmdW5jdGlvbiBUYigp
-e30sCkl2OmZ1bmN0aW9uIEl2KCl7fSwKV1A6ZnVuY3Rpb24gV1AoKXt9LAp5WTpmdW5jdGlvbiB5WSgp
-e30sCnc2OmZ1bmN0aW9uIHc2KCl7fSwKSzU6ZnVuY3Rpb24gSzUoKXt9LApDbTpmdW5jdGlvbiBDbSgp
-e30sCkNROmZ1bmN0aW9uIENRKCl7fSwKdzQ6ZnVuY3Rpb24gdzQoKXt9LApyaDpmdW5jdGlvbiByaCgp
-e30sCmNmOmZ1bmN0aW9uIGNmKCl7fSwKaTc6ZnVuY3Rpb24gaTcoYSl7dGhpcy5hPWF9LApTeTpmdW5j
-dGlvbiBTeShhKXt0aGlzLmE9YX0sCktTOmZ1bmN0aW9uIEtTKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9
-LApBMzpmdW5jdGlvbiBBMyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKSTQ6ZnVuY3Rpb24gSTQoYSl7
-dGhpcy5hPWF9LApGazpmdW5jdGlvbiBGayhhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApSTzpmdW5j
-dGlvbiBSTyhhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uJHRpPWR9LApldTpm
-dW5jdGlvbiBldShhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uJHRpPWR9LAp4
-QzpmdW5jdGlvbiB4QyhhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5iPWEKXy5jPWIKXy5kPWMKXy5lPWQK
-Xy4kdGk9ZX0sCnZOOmZ1bmN0aW9uIHZOKGEpe3RoaXMuYT1hfSwKSlE6ZnVuY3Rpb24gSlEoYSl7dGhp
-cy5hPWF9LApHbTpmdW5jdGlvbiBHbSgpe30sCnZEOmZ1bmN0aW9uIHZEKGEpe3RoaXMuYT1hfSwKVXY6
-ZnVuY3Rpb24gVXYoYSl7dGhpcy5hPWF9LApFZzpmdW5jdGlvbiBFZyhhLGIsYyl7dGhpcy5hPWEKdGhp
-cy5iPWIKdGhpcy5jPWN9LAptNjpmdW5jdGlvbiBtNigpe30sCkVvOmZ1bmN0aW9uIEVvKCl7fSwKV2s6
-ZnVuY3Rpb24gV2soKXt9LApjdDpmdW5jdGlvbiBjdChhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5lPWEK
-Xy5hPWIKXy5iPWMKXy5jPWQKXy5kPWV9LApJQTpmdW5jdGlvbiBJQSgpe30sCk93OmZ1bmN0aW9uIE93
-KCl7fSwKVzk6ZnVuY3Rpb24gVzkoYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPS0xCl8u
-ZD1udWxsCl8uJHRpPWN9LApkVzpmdW5jdGlvbiBkVyhhKXt0aGlzLmE9YX0sCkZiOmZ1bmN0aW9uIEZi
-KCl7fSwKa0Y6ZnVuY3Rpb24ga0YoKXt9LAptazpmdW5jdGlvbiBtayhhLGIpe3RoaXMuYT1hCnRoaXMu
-Yj1ifSwKS286ZnVuY3Rpb24gS28oYSl7dGhpcy5hPWEKdGhpcy5iPSExfSwKZm06ZnVuY3Rpb24gZm0o
-YSl7dGhpcy5hPWF9LApMZTpmdW5jdGlvbiBMZSgpe30sCks3OmZ1bmN0aW9uIEs3KCl7fSwKckI6ZnVu
-Y3Rpb24gckIoKXt9LApYVzpmdW5jdGlvbiBYVygpe30sCm9hOmZ1bmN0aW9uIG9hKCl7fX0sVT17Cmpm
-OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxCmlmKGE9PW51bGwpdD1udWxsCmVsc2V7dD1ILlZNKFtdLHUu
-ZDcpCmZvcihzPUouSVQodS5ULmEoYSkpO3MuRigpOyl7cj1zLmdsKCkKcT1KLlU2KHIpCkMuTm0uaSh0
-LG5ldyBVLlNlKEguaChxLnEociwiZGVzY3JpcHRpb24iKSksSC5oKHEucShyLCJocmVmIikpKSl9fXJl
-dHVybiB0fSwKTmQ6ZnVuY3Rpb24oYSl7dmFyIHQscwppZihhPT1udWxsKXQ9bnVsbAplbHNle3Q9SC5W
-TShbXSx1LmFBKQpmb3Iocz1KLklUKHUuVC5hKGEpKTtzLkYoKTspQy5ObS5pKHQsVS5OZihzLmdsKCkp
-KX1yZXR1cm4gdH0sCk5mOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbz0iZGVzY3JpcHRpb24iLG49
-Si5VNihhKSxtPUguaChuLnEoYSxvKSksbD1ILlZNKFtdLHUuYUopCmZvcihuPUouSVQodS5ULmEobi5x
-KGEsImVudHJpZXMiKSkpO24uRigpOyl7dD1uLmdsKCkKcz1KLlU2KHQpCnI9SC5oKHMucSh0LG8pKQpx
-PUguaChzLnEodCwiZnVuY3Rpb24iKSkKcz1zLnEodCwibGluayIpCmlmKHM9PW51bGwpcz1udWxsCmVs
-c2V7cD1KLlU2KHMpCnM9bmV3IFUuTWwoSC5oKHAucShzLCJocmVmIikpLEgudVAocC5xKHMsImxpbmUi
-KSksSC5oKHAucShzLCJwYXRoIikpKX1DLk5tLmkobCxuZXcgVS53YihyLHEscykpfXJldHVybiBuZXcg
-VS55RChtLGwpfSwKZDI6ZnVuY3Rpb24gZDIoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1i
-Cl8uYz1jCl8uZD1kCl8uZT1lfSwKU2U6ZnVuY3Rpb24gU2UoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0s
-Ck1sOmZ1bmN0aW9uIE1sKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCnlEOmZ1bmN0
-aW9uIHlEKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp3YjpmdW5jdGlvbiB3YihhLGIsYyl7dGhpcy5h
-PWEKdGhpcy5iPWIKdGhpcy5jPWN9fSxCPXsKWWY6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4s
-bSxsPUguaChhLnEoMCwicmVnaW9ucyIpKSxrPUguaChhLnEoMCwibmF2aWdhdGlvbkNvbnRlbnQiKSks
-aj1ILmgoYS5xKDAsInNvdXJjZUNvZGUiKSksaT1QLkZsKHUuWCx1LmRfKQpmb3IodD11LmEuYShhLnEo
-MCwiZWRpdHMiKSksdD10LmdQdSh0KSx0PXQuZ2t6KHQpLHM9dS5ULHI9dS5oNDt0LkYoKTspe3E9dC5n
-bCgpCnA9cS5hCm89SC5WTShbXSxyKQpmb3IocT1KLklUKHMuYShxLmIpKTtxLkYoKTspe249cS5nbCgp
-Cm09Si5VNihuKQpDLk5tLmkobyxuZXcgQi5qOChILnVQKG0ucShuLCJsaW5lIikpLEguaChtLnEobiwi
-ZXhwbGFuYXRpb24iKSksSC51UChtLnEobiwib2Zmc2V0IikpKSl9aS5ZKDAscCxvKX1yZXR1cm4gbmV3
-IEIucXAobCxrLGosaSl9LApqODpmdW5jdGlvbiBqOChhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhp
-cy5jPWN9LApxcDpmdW5jdGlvbiBxcChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1j
-Cl8uZD1kfSwKZnY6ZnVuY3Rpb24gZnYoKXt9LApPUzpmdW5jdGlvbihhKXt2YXIgdAppZighKGE+PTY1
-JiZhPD05MCkpdD1hPj05NyYmYTw9MTIyCmVsc2UgdD0hMApyZXR1cm4gdH0sCll1OmZ1bmN0aW9uKGEs
-Yil7dmFyIHQ9YS5sZW5ndGgscz1iKzIKaWYodDxzKXJldHVybiExCmlmKCFCLk9TKEMueEIubShhLGIp
-KSlyZXR1cm4hMQppZihDLnhCLm0oYSxiKzEpIT09NTgpcmV0dXJuITEKaWYodD09PXMpcmV0dXJuITAK
-cmV0dXJuIEMueEIubShhLHMpPT09NDd9fSxUPXttUTpmdW5jdGlvbiBtUSgpe319LEw9ewpJcTpmdW5j
-dGlvbigpe0MuQlouQihkb2N1bWVudCwiRE9NQ29udGVudExvYWRlZCIsbmV3IEwuZSgpKQpDLm9sLkIo
-d2luZG93LCJwb3BzdGF0ZSIsbmV3IEwuTCgpKX0sCmt6OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dS5nLmEo
-YS5wYXJlbnROb2RlKS5xdWVyeVNlbGVjdG9yKCI6c2NvcGUgPiB1bCIpLHI9cy5zdHlsZSxxPSIiK0Mu
-Q0QuelEocy5vZmZzZXRIZWlnaHQpKjIrInB4IgpyLm1heEhlaWdodD1xCnI9Si5xRihhKQpxPXIuJHRp
-CnQ9cS5DKCJ+KDEpPyIpLmEobmV3IEwuV3gocyxhKSkKdS5aLmEobnVsbCkKVy5KRShyLmEsci5iLHQs
-ITEscS5jKX0sCnlYOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG49InF1ZXJ5U2VsZWN0b3JB
-bGwiLG09ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihhKSxsPXUuZwptLnRvU3RyaW5nCnQ9dS5oCkguRGgo
-bCx0LCJUIixuKQpzPXUuUgpyPW5ldyBXLnd6KG0ucXVlcnlTZWxlY3RvckFsbCgiLm5hdi1saW5rIiks
-cykKci5LKHIsbmV3IEwuQU8oYikpCkguRGgobCx0LCJUIixuKQpxPW5ldyBXLnd6KG0ucXVlcnlTZWxl
-Y3RvckFsbCgiLnJlZ2lvbiIpLHMpCmlmKHEuZ0EocSkhPT0wKXtwPW0ucXVlcnlTZWxlY3RvcigidGFi
-bGVbZGF0YS1wYXRoXSIpCnAudG9TdHJpbmcKcS5LKHEsbmV3IEwuSG8ocC5nZXRBdHRyaWJ1dGUoImRh
-dGEtIituZXcgVy5TeShuZXcgVy5pNyhwKSkuTygicGF0aCIpKSkpfUguRGgobCx0LCJUIixuKQpvPW5l
-dyBXLnd6KG0ucXVlcnlTZWxlY3RvckFsbCgiLmFkZC1oaW50LWxpbmsiKSxzKQpvLksobyxuZXcgTC5J
-QygpKX0sClE2OmZ1bmN0aW9uKGEsYil7dmFyIHQ9dS5YCnJldHVybiBXLnFEKEwuUTQoYSxiKSxQLkVG
-KFsiQ29udGVudC1UeXBlIiwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD1VVEYtOCJdLHQsdCkpfSwK
-dHk6ZnVuY3Rpb24oYSl7dmFyIHQ9MCxzPVAuRlgodS5hKSxyLHEscCxvLG4sbSxsLGsKdmFyICRhc3lu
-YyR0eT1QLmx6KGZ1bmN0aW9uKGIsYyl7aWYoYj09PTEpcmV0dXJuIFAuZjMoYyxzKQp3aGlsZSh0cnVl
-KXN3aXRjaCh0KXtjYXNlIDA6bj1uZXcgUC52cygkLlgzLHUuZ1YpCm09bmV3IFAuWmYobix1LmJDKQps
-PW5ldyBYTUxIdHRwUmVxdWVzdCgpCms9dS5YCkMuRHQuZW8obCwiUE9TVCIsTC5RNChhLFAuRmwoayxr
-KSksITApCmwuc2V0UmVxdWVzdEhlYWRlcigiQ29udGVudC1UeXBlIiwiYXBwbGljYXRpb24vanNvbjsg
-Y2hhcnNldD1VVEYtOCIpCms9dS51CnE9ay5hKG5ldyBMLkwxKG0sbCkpCnUuWi5hKG51bGwpCnA9dS5F
-ClcuSkUobCwibG9hZCIscSwhMSxwKQpXLkpFKGwsImVycm9yIixrLmEobS5nWUooKSksITEscCkKbC5z
-ZW5kKCkKdD0zCnJldHVybiBQLmpRKG4sJGFzeW5jJHR5KQpjYXNlIDM6bz1DLkN0LnBXKDAsbC5yZXNw
-b25zZVRleHQsbnVsbCkKaWYobC5zdGF0dXM9PT0yMDApe3I9dS5hLmEobykKdD0xCmJyZWFrfWVsc2Ug
-dGhyb3cgSC5iKG8pCmNhc2UgMTpyZXR1cm4gUC55QyhyLHMpfX0pCnJldHVybiBQLkRJKCRhc3luYyR0
-eSxzKX0sCmFLOmZ1bmN0aW9uKGEpe3ZhciB0PVAuaEsoYSkuZ2hZKCkucSgwLCJsaW5lIikKcmV0dXJu
-IHQ9PW51bGw/bnVsbDpILkhwKHQsbnVsbCl9LApHNjpmdW5jdGlvbihhKXt2YXIgdD1QLmhLKGEpLmdo
-WSgpLnEoMCwib2Zmc2V0IikKcmV0dXJuIHQ9PW51bGw/bnVsbDpILkhwKHQsbnVsbCl9LAppNjpmdW5j
-dGlvbihhKXtyZXR1cm4gTC5uVyh1Lk8uYShhKSl9LApuVzpmdW5jdGlvbihhKXt2YXIgdD0wLHM9UC5G
-WCh1LnopLHI9MSxxLHA9W10sbyxuLG0sbCxrCnZhciAkYXN5bmMkaTY9UC5seihmdW5jdGlvbihiLGMp
-e2lmKGI9PT0xKXtxPWMKdD1yfXdoaWxlKHRydWUpc3dpdGNoKHQpe2Nhc2UgMDpsPXUuZy5hKFcucWMo
-YS5jdXJyZW50VGFyZ2V0KSkuZ2V0QXR0cmlidXRlKCJocmVmIikKYS5wcmV2ZW50RGVmYXVsdCgpCnI9
-Mwp0PTYKcmV0dXJuIFAualEoTC50eShsKSwkYXN5bmMkaTYpCmNhc2UgNjp1LmJaLmEoSi5HcihXLlB2
-KGRvY3VtZW50LmRlZmF1bHRWaWV3KSkpLnJlbG9hZCgpCnI9MQp0PTUKYnJlYWsKY2FzZSAzOnI9Mgpr
-PXEKbz1ILlJ1KGspCm49SC50cyhrKQpMLkMyKCJDb3VsZCBub3QgYWRkL3JlbW92ZSBoaW50IixvLG4p
-CnQ9NQpicmVhawpjYXNlIDI6dD0xCmJyZWFrCmNhc2UgNTpyZXR1cm4gUC55QyhudWxsLHMpCmNhc2Ug
-MTpyZXR1cm4gUC5mMyhxLHMpfX0pCnJldHVybiBQLkRJKCRhc3luYyRpNixzKX0sCkMyOmZ1bmN0aW9u
-KGEsYixjKXt2YXIgdCxzLHI9ImV4Y2VwdGlvbiIscT0ic3RhY2tUcmFjZSIscD11LmEuYihiKSYmSi5S
-TShiLnEoMCwic3VjY2VzcyIpLCExKSYmYi54NChyKSYmYi54NChxKSxvPUouaWEoYikKaWYocCl7dD1I
-Lmgoby5xKGIscikpCmM9by5xKGIscSl9ZWxzZSB0PW8udyhiKQpzPWRvY3VtZW50LnF1ZXJ5U2VsZWN0
-b3IoIi5wb3B1cC1wYW5lIikKcy5xdWVyeVNlbGVjdG9yKCJoMiIpLmlubmVyVGV4dD1hCnMucXVlcnlT
-ZWxlY3RvcigicCIpLmlubmVyVGV4dD10CnMucXVlcnlTZWxlY3RvcigicHJlIikuaW5uZXJUZXh0PUou
-aihjKQpwPXUuWAp1LmRkLmEocy5xdWVyeVNlbGVjdG9yKCJhLmJvdHRvbSIpKS5ocmVmPVAuWGQoImh0
-dHBzIiwiZ2l0aHViLmNvbSIsImRhcnQtbGFuZy9zZGsvaXNzdWVzL25ldyIsUC5FRihbInRpdGxlIiwi
-SXNzdWUgd2l0aCBOTkJEIG1pZ3JhdGlvbiB0b29sOiAiK2EsImxhYmVscyIsImFyZWEtYW5hbHl6ZXIs
-YW5hbHl6ZXItbm5iZC1taWdyYXRpb24sdHlwZS1idWciLCJib2R5IixhKyJcblxuRXJyb3I6ICIrSC5F
-aih0KSsiXG5cblBsZWFzZSBmaWxsIGluIHRoZSBmb2xsb3dpbmc6XG5cbioqTmFtZSBvZiBwYWNrYWdl
-IGJlaW5nIG1pZ3JhdGVkIChpZiBwdWJsaWMpKio6XG4qKldoYXQgSSB3YXMgZG9pbmcgd2hlbiB0aGlz
-IGlzc3VlIG9jY3VycmVkKio6XG4qKklzIGl0IHBvc3NpYmxlIHRvIHdvcmsgYXJvdW5kIHRoaXMgaXNz
-dWUqKjpcbioqSGFzIHRoaXMgaXNzdWUgaGFwcGVuZWQgYmVmb3JlLCBhbmQgaWYgc28sIGhvdyBvZnRl
-bioqOlxuKipEYXJ0IFNESyB2ZXJzaW9uKio6ICh2aXNpYmxlIGluIGxvd2VyIGxlZnQgb2YgbWlncmF0
-aW9uIHByZXZpZXcpXG4qKkFkZGl0aW9uYWwgZGV0YWlscyoqOlxuXG5UaGFua3MgZm9yIGZpbGluZyFc
-blxuU3RhY2t0cmFjZTogX2F1dG8gcG9wdWxhdGVkIGJ5IG1pZ3JhdGlvbiBwcmV2aWV3IHRvb2wuX1xu
-XG5gYGBcbiIrSC5FaihjKSsiXG5gYGBcbiJdLHAscCkpLmduRCgpCnA9cy5zdHlsZQpwLmRpc3BsYXk9
-ImluaXRpYWwiCkwucUooYSsiOiAiK0guRWooYiksYyl9LAp0MjpmdW5jdGlvbihhLGIsYyl7dmFyIHQs
-cyxyLHEscCxvLG49e30sbT11LmcuYShXLnFjKGEuY3VycmVudFRhcmdldCkpCmEucHJldmVudERlZmF1
-bHQoKQp0PW4uYT1tLmdldEF0dHJpYnV0ZSgiaHJlZiIpCmlmKEouemwodCwiPyIpKXtzPUMueEIuTmoo
-dCwwLEMueEIuT1kodCwiPyIpKQpuLmE9cwpyPXN9ZWxzZSByPXQKaWYoYyE9bnVsbCl7cT0kLm5VKCkK
-cj1uLmE9cS5vNShELm5yKHEudE0oYykscikpfXA9TC5HNih0KQpvPUwuYUsodCkKaWYocCE9bnVsbClM
-LmFmKHIscCxvLGIsbmV3IEwublQobixwLG8pKQplbHNlIEwuYWYocixudWxsLG51bGwsYixuZXcgTC5O
-WShuKSl9LAp2VTpmdW5jdGlvbigpe3ZhciB0PWRvY3VtZW50CkguRGgodS5nLHUuaCwiVCIsInF1ZXJ5
-U2VsZWN0b3JBbGwiKQp0PW5ldyBXLnd6KHQucXVlcnlTZWxlY3RvckFsbCgiLmNvZGUiKSx1LlIpCnQu
-Syh0LG5ldyBMLmVYKCkpfSwKaFg6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PXUuWApMLlE2KGEsUC5FRihb
-InJlZ2lvbiIsInJlZ2lvbiIsIm9mZnNldCIsSC5FaihiKV0sdCx0KSkuVzcobmV3IEwuRFQoYSxiLGMp
-LHUuUCkuT0EobmV3IEwuZUgoYSkpfSwKRzc6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdAppZighSi5w
-NChhLCIuZGFydCIpKXtMLkJFKGEsbmV3IEIucXAoIiIsIiIsIiIsQy5DTSksZCkKTC5CWChhLG51bGwp
-CmlmKGUhPW51bGwpZS4kMCgpCnJldHVybn10PXUuWApMLlE2KGEsUC5FRihbImlubGluZSIsInRydWUi
-XSx0LHQpKS5XNyhuZXcgTC55dShhLGQsYixjLGUpLHUuUCkuT0EobmV3IEwuekQoYSkpfSwKR2U6ZnVu
-Y3Rpb24oKXt2YXIgdD0iL19wcmV2aWV3L25hdmlnYXRpb25UcmVlLmpzb24iCkwuUTYodCxDLldPKS5X
-NyhuZXcgTC5UVygpLHUuUCkuT0EobmV3IEwueHIodCkpfSwKcUo6ZnVuY3Rpb24oYSxiKXt2YXIgdAp3
-aW5kb3cKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLmVycm9yKGEp
-CndpbmRvdwp0PUguRWooYikKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25z
-b2xlLmVycm9yKHQpfSwKcU86ZnVuY3Rpb24oYSl7dmFyIHQ9YS5nZXRCb3VuZGluZ0NsaWVudFJlY3Qo
-KSxzPUMuQ0QuelEoJC5maSgpLm9mZnNldEhlaWdodCkscj13aW5kb3cuaW5uZXJIZWlnaHQscT1DLkNE
-LnpRKCQuRFcoKS5vZmZzZXRIZWlnaHQpCmlmKHQuYm90dG9tPnItKHErMTQpKUouZGgoYSkKZWxzZSBp
-Zih0LnRvcDxzKzE0KUouZGgoYSl9LApmRzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscgppZihhIT1udWxs
-KXt0PWRvY3VtZW50CnM9dC5nZXRFbGVtZW50QnlJZCgibyIrSC5FaihhKSkKcj10LnF1ZXJ5U2VsZWN0
-b3IoIi5saW5lLSIrSC5FaihiKSkKaWYocyE9bnVsbCl7TC5xTyhzKQpKLmRSKHMpLmkoMCwidGFyZ2V0
-Iil9ZWxzZSBpZihyIT1udWxsKUwucU8oci5wYXJlbnRFbGVtZW50KQppZihyIT1udWxsKUouZFIodS5n
-LmEoci5wYXJlbnROb2RlKSkuaSgwLCJoaWdobGlnaHQiKX1lbHNlIEwucU8oJC5EOSgpKX0sCmFmOmZ1
-bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyPUwuRzYod2luZG93LmxvY2F0aW9uLmhyZWYpLHE9TC5h
-Syh3aW5kb3cubG9jYXRpb24uaHJlZikKaWYociE9bnVsbCl7dD1kb2N1bWVudC5nZXRFbGVtZW50QnlJ
-ZCgibyIrSC5FaihyKSkKaWYodCE9bnVsbClKLmRSKHQpLlIoMCwidGFyZ2V0Iil9aWYocSE9bnVsbCl7
-cz1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIubGluZS0iK0guRWoocSkpCmlmKHMhPW51bGwpSi5kUihz
-LnBhcmVudEVsZW1lbnQpLlIoMCwiaGlnaGxpZ2h0Iil9aWYoYT09PXdpbmRvdy5sb2NhdGlvbi5wYXRo
-bmFtZSl7TC5mRyhiLGMpCmUuJDAoKX1lbHNlIEwuRzcoYSxiLGMsZCxlKX0sClE0OmZ1bmN0aW9uKGEs
-Yil7dmFyIHQscyxyPVAuaEsoYSkscT11LlgKcT1QLkZsKHEscSkKZm9yKHQ9ci5naFkoKSx0PXQuZ1B1
-KHQpLHQ9dC5na3oodCk7dC5GKCk7KXtzPXQuZ2woKQpxLlkoMCxzLmEscy5iKX1mb3IodD1iLmdQdShi
-KSx0PXQuZ2t6KHQpO3QuRigpOyl7cz10LmdsKCkKcS5ZKDAscy5hLHMuYil9cS5ZKDAsImF1dGhUb2tl
-biIsJC5VRSgpKQpyZXR1cm4gci5ubSgwLHEpLmduRCgpfSwKVDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxy
-LHEscCxvLG4sbSxsLGs9JC5oTCgpCkoubDUoaywiIikKaWYoYT09bnVsbCl7dD1kb2N1bWVudC5jcmVh
-dGVFbGVtZW50KCJwIikKQy5MdC5zYTQodCwiU2VlIGRldGFpbHMgYWJvdXQgYSBwcm9wb3NlZCBlZGl0
-LiIpCkMuTHQuc1AodCxILlZNKFsicGxhY2Vob2xkZXIiXSx1LmkpKQprLmFwcGVuZENoaWxkKHQpCkMu
-THQuRkYodCkKcmV0dXJufXM9YS5kCnI9JC5uVSgpCnE9ci50TShzKQpwPWEuYgpvPWRvY3VtZW50Cm49
-ci5IUChzLEouVDAoby5xdWVyeVNlbGVjdG9yKCIucm9vdCIpLnRleHRDb250ZW50KSkKbT1hLmMKbD1v
-LmNyZWF0ZUVsZW1lbnQoInAiKQprLmFwcGVuZENoaWxkKGwpCmwuYXBwZW5kQ2hpbGQoby5jcmVhdGVU
-ZXh0Tm9kZShILkVqKHApKyIgYXQgIitILkVqKG4pKyI6IitILkVqKG0pKyIuIikpCkouZGgobCkKTC5D
-QyhhLGsscSkKTC5GeihhLGspfSwKTEg6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuLG0s
-bCxrLGosaSxoLGc9JC55UCgpCkoubDUoZywiIikKaWYoYi5nQShiKT09PTApe3Q9ZG9jdW1lbnQKcz10
-LmNyZWF0ZUVsZW1lbnQoInAiKQpnLmFwcGVuZENoaWxkKHMpCnMuYXBwZW5kQ2hpbGQodC5jcmVhdGVU
-ZXh0Tm9kZSgiTm8gcHJvcG9zZWQgZWRpdHMiKSl9ZWxzZSBmb3IoZz1iLmdQdShiKSxnPWcuZ2t6KGcp
-LHQ9dS5HLHI9dC5DKCJ+KDEpPyIpLHE9dS5aLHQ9dC5jO2cuRigpOyl7cD1nLmdsKCkKbz1kb2N1bWVu
-dApzPW8uY3JlYXRlRWxlbWVudCgicCIpCm49JC55UCgpCm4uYXBwZW5kQ2hpbGQocykKcy5hcHBlbmRD
-aGlsZChvLmNyZWF0ZVRleHROb2RlKEguRWoocC5hKSsiOiIpKQptPW8uY3JlYXRlRWxlbWVudCgidWwi
-KQpuLmFwcGVuZENoaWxkKG0pCmZvcihwPUouSVQocC5iKTtwLkYoKTspe2w9cC5nbCgpCms9by5jcmVh
-dGVFbGVtZW50KCJsaSIpCm0uYXBwZW5kQ2hpbGQoaykKSi5kUihrKS5pKDAsImVkaXQiKQpqPW8uY3Jl
-YXRlRWxlbWVudCgiYSIpCmsuYXBwZW5kQ2hpbGQoaikKai5jbGFzc0xpc3QuYWRkKCJlZGl0LWxpbmsi
-KQppPWwuYwpuPUguRWooaSkKai5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhq
-KSkuTygib2Zmc2V0IiksbikKaD1sLmEKbj1ILkVqKGgpCmouc2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3
-IFcuU3kobmV3IFcuaTcoaikpLk8oImxpbmUiKSxuKQpqLmFwcGVuZENoaWxkKG8uY3JlYXRlVGV4dE5v
-ZGUoImxpbmUgIitILkVqKGgpKSkKbj1yLmEobmV3IEwuRUUoaSxoLGEpKQpxLmEobnVsbCkKVy5KRShq
-LCJjbGljayIsbiwhMSx0KQprLmFwcGVuZENoaWxkKG8uY3JlYXRlVGV4dE5vZGUoIjogIitILkVqKGwu
-YikpKX19aWYoYylMLlQxKG51bGwpfSwKRnI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj13aW5kb3cu
-bG9jYXRpb24scT1QLmhLKChyJiZDLkV4KS5nRHIocikrSC5FaihhKSkKcj11LlgKcj1QLkZsKHIscikK
-aWYoYiE9bnVsbClyLlkoMCwib2Zmc2V0IixILkVqKGIpKQppZihjIT1udWxsKXIuWSgwLCJsaW5lIixI
-LkVqKGMpKQpyLlkoMCwiYXV0aFRva2VuIiwkLlVFKCkpCnE9cS5ubSgwLHIpCnI9d2luZG93Lmhpc3Rv
-cnkKdD11LnoKcz1xLmduRCgpCnIucHVzaFN0YXRlKG5ldyBQLkJmKFtdLFtdKS5QdihQLkZsKHQsdCkp
-LCIiLHMpfSwKRW46ZnVuY3Rpb24oYSl7dmFyIHQ9Si5iYihkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIu
-cm9vdCIpLnRleHRDb250ZW50LCIvIikKaWYoQy54Qi5uKGEsdCkpcmV0dXJuIEMueEIuRyhhLHQubGVu
-Z3RoKQplbHNlIHJldHVybiBhfSwKQlg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXt9CnMuYT1hCmE9TC5F
-bihhKQpzLmE9YQpKLmRyKCQuRDkoKSxhKQp0PWRvY3VtZW50CkguRGgodS5nLHUuaCwiVCIsInF1ZXJ5
-U2VsZWN0b3JBbGwiKQp0PW5ldyBXLnd6KHQucXVlcnlTZWxlY3RvckFsbCgiLm5hdi1wYW5lbCAubmF2
-LWxpbmsiKSx1LlIpCnQuSyh0LG5ldyBMLlZTKHMpKX0sCkJFOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD0i
-LnJlZ2lvbnMiLHM9ZG9jdW1lbnQscj1zLnF1ZXJ5U2VsZWN0b3IodCkscT1zLnF1ZXJ5U2VsZWN0b3Io
-Ii5jb2RlIikKSi50SChyLGIuYSwkLktHKCkpCkoudEgocSxiLmIsJC5LRygpKQpMLkxIKGEsYi5kLGMp
-CkwudlUoKQpMLnlYKCIuY29kZSIsITApCkwueVgodCwhMCl9LAp0WDpmdW5jdGlvbihhLGIpe3ZhciB0
-LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGc9ZG9jdW1lbnQsZj1nLmNyZWF0ZUVsZW1lbnQoInVsIikK
-YS5hcHBlbmRDaGlsZChmKQpmb3IodD1iLmxlbmd0aCxzPXUuWixyPTA7cjxiLmxlbmd0aDtiLmxlbmd0
-aD09PXR8fCgwLEgubGspKGIpLCsrcil7cT1iW3JdCnA9Zy5jcmVhdGVFbGVtZW50KCJsaSIpCmYuYXBw
-ZW5kQ2hpbGQocCkKbz1KLllFKHApCmlmKHEuYT09PUMuWTIpe28uZ1AocCkuaSgwLCJkaXIiKQpuPWcu
-Y3JlYXRlRWxlbWVudCgic3BhbiIpCnAuYXBwZW5kQ2hpbGQobikKbz1KLllFKG4pCm8uZ1AobikuaSgw
-LCJhcnJvdyIpCm8uc2hmKG4sIiYjeDI1QkM7IikKbT1nLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpwLmFw
-cGVuZENoaWxkKG0pCkoubDUobSwiJiN4MUY0QzE7IikKcC5hcHBlbmRDaGlsZChnLmNyZWF0ZVRleHRO
-b2RlKHEuYikpCkwudFgocCxxLmMpCkwua3oobil9ZWxzZXtvLnNoZihwLCImI3gxRjRDNDsiKQpsPWcu
-Y3JlYXRlRWxlbWVudCgiYSIpCnAuYXBwZW5kQ2hpbGQobCkKbz1KLllFKGwpCm8uZ1AobCkuaSgwLCJu
-YXYtbGluayIpCmwuc2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTcobCkpLk8oIm5h
-bWUiKSxxLmQpCmwuc2V0QXR0cmlidXRlKCJocmVmIixxLmUpCmwuYXBwZW5kQ2hpbGQoZy5jcmVhdGVU
-ZXh0Tm9kZShxLmIpKQpvPW8uZ1ZsKGwpCms9by4kdGkKaj1rLkMoIn4oMSk/IikuYShuZXcgTC5URCgp
-KQpzLmEobnVsbCkKVy5KRShvLmEsby5iLGosITEsay5jKQppPXEuZgppZih0eXBlb2YgaSE9PSJudW1i
-ZXIiKXJldHVybiBpLm9zKCkKaWYoaT4wKXtoPWcuY3JlYXRlRWxlbWVudCgic3BhbiIpCnAuYXBwZW5k
-Q2hpbGQoaCkKSi5kUihoKS5pKDAsImVkaXQtY291bnQiKQpvPSIiK2krIiAiCmlmKGk9PT0xKWs9ImVk
-aXQiCmVsc2Ugaz0iZWRpdHMiCmguc2V0QXR0cmlidXRlKCJ0aXRsZSIsbytrKQpoLmFwcGVuZENoaWxk
-KGcuY3JlYXRlVGV4dE5vZGUoQy5qbi53KGkpKSl9fX19LApGejpmdW5jdGlvbihhLGIpe3ZhciB0LHMs
-cixxLHAsbyxuLG0sbCxrLGo9YS5hCmlmKGohPW51bGwpe3Q9ZG9jdW1lbnQKcz10LmNyZWF0ZUVsZW1l
-bnQoInAiKQpiLmFwcGVuZENoaWxkKHMpCmZvcihyPWoubGVuZ3RoLHE9dS5pLHA9dS5RLG89MDtvPGou
-bGVuZ3RoO2oubGVuZ3RoPT09cnx8KDAsSC5saykoaiksKytvKXtuPWpbb10KbT10LmNyZWF0ZUVsZW1l
-bnQoImEiKQpzLmFwcGVuZENoaWxkKG0pCm0uYXBwZW5kQ2hpbGQodC5jcmVhdGVUZXh0Tm9kZShuLmEp
-KQptLnNldEF0dHJpYnV0ZSgiaHJlZiIsbi5iKQpsPXAuYShILlZNKFsiYWRkLWhpbnQtbGluayIsImJl
-Zm9yZS1hcHBseSIsImJ1dHRvbiJdLHEpKQprPUouZFIobSkKay5WMSgwKQprLkZWKDAsbCl9fX0sCkND
-OmZ1bmN0aW9uKGEyLGEzLGE0KXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkLGMs
-YixhLGEwLGExPW51bGwKZm9yKHQ9YTIuZSxzPXQubGVuZ3RoLHI9dS5pLHE9dS5RLHA9MDtwPHQubGVu
-Z3RoO3QubGVuZ3RoPT09c3x8KDAsSC5saykodCksKytwKXtvPXRbcF0Kbj1kb2N1bWVudAptPW4uY3Jl
-YXRlRWxlbWVudCgicCIpCmw9cS5hKEguVk0oWyJ0cmFjZSJdLHIpKQprPUouZFIobSkKay5WMSgwKQpr
-LkZWKDAsbCkKaj1hMy5hcHBlbmRDaGlsZChtKQptPW4uY3JlYXRlRWxlbWVudCgic3BhbiIpCmw9cS5h
-KEguVk0oWyJ0eXBlLWRlc2NyaXB0aW9uIl0scikpCms9Si5kUihtKQprLlYxKDApCmsuRlYoMCxsKQpt
-LmFwcGVuZENoaWxkKG4uY3JlYXRlVGV4dE5vZGUoby5hKSkKai5hcHBlbmRDaGlsZChtKQpqLmFwcGVu
-ZENoaWxkKG4uY3JlYXRlVGV4dE5vZGUoIjoiKSkKbT1uLmNyZWF0ZUVsZW1lbnQoInVsIikKbD1xLmEo
-SC5WTShbInRyYWNlIl0scikpCms9Si5kUihtKQprLlYxKDApCmsuRlYoMCxsKQppPWouYXBwZW5kQ2hp
-bGQobSkKZm9yKG09by5iLGw9bS5sZW5ndGgsaD0wO2g8bS5sZW5ndGg7bS5sZW5ndGg9PT1sfHwoMCxI
-LmxrKShtKSwrK2gpe2c9bVtoXQpmPW4uY3JlYXRlRWxlbWVudCgibGkiKQpKLmw1KGYsIiYjeDI3NEY7
-ICIpCmkuYXBwZW5kQ2hpbGQoZikKZT1uLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpkPXEuYShILlZNKFsi
-ZnVuY3Rpb24iXSxyKSkKaz1KLmRSKGUpCmsuVjEoMCkKay5GVigwLGQpCmQ9Zy5iCkwua0QoZSxkPT1u
-dWxsPyJ1bmtub3duIjpkKQpmLmFwcGVuZENoaWxkKGUpCmM9Zy5jCmlmKGMhPW51bGwpe2YuYXBwZW5k
-Q2hpbGQobi5jcmVhdGVUZXh0Tm9kZSgiICgiKSkKYj1jLmIKYT1uLmNyZWF0ZUVsZW1lbnQoImEiKQph
-LmFwcGVuZENoaWxkKG4uY3JlYXRlVGV4dE5vZGUoSC5FaihjLmMpKyI6IitILkVqKGIpKSkKYTA9Yy5h
-CmU9JC5uVSgpCmEuc2V0QXR0cmlidXRlKCJocmVmIixlLm81KGUucTcoMCxhNCxhMCxhMSxhMSxhMSxh
-MSxhMSxhMSkpKQphLmNsYXNzTGlzdC5hZGQoIm5hdi1saW5rIikKZi5hcHBlbmRDaGlsZChhKQpmLmFw
-cGVuZENoaWxkKG4uY3JlYXRlVGV4dE5vZGUoIikiKSl9Zi5hcHBlbmRDaGlsZChuLmNyZWF0ZVRleHRO
-b2RlKCI6ICIpKQplPWcuYQpMLmtEKGYsZT09bnVsbD8idW5rbm93biI6ZSl9fX0sCmtEOmZ1bmN0aW9u
-KGEsYil7dmFyIHQscyxyPUguVk0oYi5zcGxpdCgiLiIpLHUucykscT1DLk5tLmd0SChyKSxwPWRvY3Vt
-ZW50CmEuYXBwZW5kQ2hpbGQocC5jcmVhdGVUZXh0Tm9kZShxKSkKZm9yKHE9SC5xQyhyLDEsbnVsbCx1
-Lk4pLHE9bmV3IEguYTcocSxxLmdBKHEpLHEuJHRpLkMoImE3PGFMLkU+IikpLHQ9Si5ZRShhKTtxLkYo
-KTspe3M9cS5kCnQubnooYSwiYmVmb3JlZW5kIiwiJiM4MjAzOy4iLG51bGwsbnVsbCkKYS5hcHBlbmRD
-aGlsZChwLmNyZWF0ZVRleHROb2RlKHMpKX19LAplOmZ1bmN0aW9uIGUoKXt9LApWVzpmdW5jdGlvbiBW
-VyhhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApvWjpmdW5jdGlvbiBvWigpe30sCmpy
-OmZ1bmN0aW9uIGpyKCl7fSwKcWw6ZnVuY3Rpb24gcWwoKXt9LApIaTpmdW5jdGlvbiBIaSgpe30sCkJU
-OmZ1bmN0aW9uIEJUKCl7fSwKUFk6ZnVuY3Rpb24gUFkoKXt9LApMOmZ1bmN0aW9uIEwoKXt9LApXeDpm
-dW5jdGlvbiBXeChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQU86ZnVuY3Rpb24gQU8oYSl7dGhpcy5h
-PWF9LApkTjpmdW5jdGlvbiBkTihhKXt0aGlzLmE9YX0sCkhvOmZ1bmN0aW9uIEhvKGEpe3RoaXMuYT1h
-fSwKeHo6ZnVuY3Rpb24geHooYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCklDOmZ1bmN0aW9uIElDKCl7
-fSwKTDE6ZnVuY3Rpb24gTDEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCm5UOmZ1bmN0aW9uIG5UKGEs
-YixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCk5ZOmZ1bmN0aW9uIE5ZKGEpe3RoaXMuYT1h
-fSwKZVg6ZnVuY3Rpb24gZVgoKXt9LApEVDpmdW5jdGlvbiBEVChhLGIsYyl7dGhpcy5hPWEKdGhpcy5i
-PWIKdGhpcy5jPWN9LAplSDpmdW5jdGlvbiBlSChhKXt0aGlzLmE9YX0sCnl1OmZ1bmN0aW9uIHl1KGEs
-YixjLGQsZSl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZX0sCnpEOmZ1bmN0
-aW9uIHpEKGEpe3RoaXMuYT1hfSwKVFc6ZnVuY3Rpb24gVFcoKXt9LAp4cjpmdW5jdGlvbiB4cihhKXt0
-aGlzLmE9YX0sCkVFOmZ1bmN0aW9uIEVFKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30s
-ClFMOmZ1bmN0aW9uIFFMKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApWUzpmdW5jdGlvbiBWUyhhKXt0
-aGlzLmE9YX0sClREOmZ1bmN0aW9uIFREKCl7fSwKWEE6ZnVuY3Rpb24gWEEoKXt9LAptSzpmdW5jdGlv
-bihhKXt2YXIgdCxzLHIscSxwLG8sbj1ILlZNKFtdLHUuY1EpCmZvcih0PUouSVQodS5ULmEoYSkpO3Qu
-RigpOyl7cz10LmdsKCkKcj1KLlU2KHMpCnE9TC5wMihILmgoci5xKHMsInR5cGUiKSkpCnA9SC5oKHIu
-cShzLCJuYW1lIikpCm89ci5xKHMsInN1YnRyZWUiKQpvPW89PW51bGw/bnVsbDpMLm1LKG8pCkMuTm0u
-aShuLG5ldyBMLlpaKHEscCxvLEguaChyLnEocywicGF0aCIpKSxILmgoci5xKHMsImhyZWYiKSksSC51
-UChyLnEocywiZWRpdENvdW50IikpKSl9cmV0dXJuIG59LApwMjpmdW5jdGlvbihhKXtzd2l0Y2goYSl7
-Y2FzZSJkaXJlY3RvcnkiOnJldHVybiBDLlkyCmNhc2UiZmlsZSI6cmV0dXJuIEMucmYKZGVmYXVsdDp0
-aHJvdyBILmIoUC5QVigiVW5yZWNvZ25pemVkIG5hdmlnYXRpb24gdHJlZSBub2RlIHR5cGU6ICIrSC5F
-aihhKSkpfX0sClpaOmZ1bmN0aW9uIFpaKGEsYixjLGQsZSxmKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1i
-Cl8uYz1jCl8uZD1kCl8uZT1lCl8uZj1mfSwKTzk6ZnVuY3Rpb24gTzkoYSl7dGhpcy5iPWF9LApJVjpm
-dW5jdGlvbiBJVihhLGIsYyxkKXt2YXIgXz10aGlzCl8uZD1hCl8uZT1iCl8uZj1jCl8ucj1kfX0sTT17
-CllGOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG4KZm9yKHQ9Yi5sZW5ndGgscz0xO3M8dDsr
-K3Mpe2lmKGJbc109PW51bGx8fGJbcy0xXSE9bnVsbCljb250aW51ZQpmb3IoO3Q+PTE7dD1yKXtyPXQt
-MQppZihiW3JdIT1udWxsKWJyZWFrfXE9bmV3IFAuUm4oIiIpCnA9IiIrKGErIigiKQpxLmE9cApvPUgu
-cUMoYiwwLHQsSC50NihiKS5jKQpuPW8uJHRpCm49cCtuZXcgSC5sSihvLG4uQygicVUqKGFMLkUpIiku
-YShuZXcgTS5ObygpKSxuLkMoImxKPGFMLkUscVUqPiIpKS56VigwLCIsICIpCnEuYT1uCnEuYT1uKygi
-KTogcGFydCAiKyhzLTEpKyIgd2FzIG51bGwsIGJ1dCBwYXJ0ICIrcysiIHdhcyBub3QuIikKdGhyb3cg
-SC5iKFAueFkocS53KDApKSl9fSwKbEk6ZnVuY3Rpb24gbEkoYSl7dGhpcy5hPWF9LApNaTpmdW5jdGlv
-biBNaSgpe30sCnE3OmZ1bmN0aW9uIHE3KCl7fSwKTm86ZnVuY3Rpb24gTm8oKXt9fSxYPXsKQ0w6ZnVu
-Y3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG89Yi54WihhKQpiLmhLKGEpCmlmKG8hPW51bGwpYT1KLktW
-KGEsby5sZW5ndGgpCnQ9dS5pCnM9SC5WTShbXSx0KQpyPUguVk0oW10sdCkKdD1hLmxlbmd0aAppZih0
-IT09MCYmYi5yNChDLnhCLlcoYSwwKSkpe2lmKDA+PXQpcmV0dXJuIEguT0goYSwwKQpDLk5tLmkocixh
-WzBdKQpxPTF9ZWxzZXtDLk5tLmkociwiIikKcT0wfWZvcihwPXE7cDx0OysrcClpZihiLnI0KEMueEIu
-VyhhLHApKSl7Qy5ObS5pKHMsQy54Qi5OaihhLHEscCkpCkMuTm0uaShyLGFbcF0pCnE9cCsxfWlmKHE8
-dCl7Qy5ObS5pKHMsQy54Qi5HKGEscSkpCkMuTm0uaShyLCIiKX1yZXR1cm4gbmV3IFguV0QoYixvLHMs
-cil9LApXRDpmdW5jdGlvbiBXRChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uZD1jCl8u
-ZT1kfSwKcVI6ZnVuY3Rpb24gcVIoYSl7dGhpcy5hPWF9LApJNzpmdW5jdGlvbihhKXtyZXR1cm4gbmV3
-IFguZHYoYSl9LApkdjpmdW5jdGlvbiBkdihhKXt0aGlzLmE9YX19LE89ewpSaDpmdW5jdGlvbigpe3Zh
-ciB0LHM9bnVsbAppZihQLnVvKCkuZ0ZpKCkhPT0iZmlsZSIpcmV0dXJuICQuRWIoKQp0PVAudW8oKQpp
-ZighQy54Qi5UYyh0LmdJaSh0KSwiLyIpKXJldHVybiAkLkViKCkKaWYoUC5LTChzLCJhL2IiLHMscyxz
-LHMscykudDQoKT09PSJhXFxiIilyZXR1cm4gJC5LaygpCnJldHVybiAkLmJEKCl9LAp6TDpmdW5jdGlv
-biB6TCgpe319LEU9e09GOmZ1bmN0aW9uIE9GKGEsYixjKXt0aGlzLmQ9YQp0aGlzLmU9Ygp0aGlzLmY9
-Y319LEY9e3J1OmZ1bmN0aW9uIHJ1KGEsYixjLGQpe3ZhciBfPXRoaXMKXy5kPWEKXy5lPWIKXy5mPWMK
-Xy5yPWR9fSxEPXsKUlg6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9UC51bygpCmlmKHIuRE4oMCwkLkk2KSly
-ZXR1cm4gJC5GZgokLkk2PXIKaWYoJC5IaygpPT0kLkViKCkpcmV0dXJuICQuRmY9ci5aSSgiLiIpLnco
-MCkKZWxzZXt0PXIudDQoKQpzPXQubGVuZ3RoLTEKcmV0dXJuICQuRmY9cz09PTA/dDpDLnhCLk5qKHQs
-MCxzKX19LApucjpmdW5jdGlvbihhLGIpe3ZhciB0PW51bGwKcmV0dXJuICQublUoKS5xNygwLGEsYix0
-LHQsdCx0LHQsdCl9fQp2YXIgdz1bQyxILEosUCxXLFUsQixULEwsTSxYLE8sRSxGLERdCmh1bmtIZWxw
-ZXJzLnNldEZ1bmN0aW9uTmFtZXNJZk5lY2Vzc2FyeSh3KQp2YXIgJD17fQpILkZLLnByb3RvdHlwZT17
-fQpKLnZCLnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGE9PT1ifSwKZ2lPOmZ1bmN0
-aW9uKGEpe3JldHVybiBILmVRKGEpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4iSW5zdGFuY2Ugb2YgJyIr
-SC5FaihILk0oYSkpKyInIn0sCmU3OmZ1bmN0aW9uKGEsYil7dS5vLmEoYikKdGhyb3cgSC5iKFAubHIo
-YSxiLmdXYSgpLGIuZ25kKCksYi5nVm0oKSkpfX0KSi55RS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEp
-e3JldHVybiBTdHJpbmcoYSl9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIGE/NTE5MDE4OjIxODE1OX0s
-CiRpYTI6MX0KSi53ZS5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe3JldHVybiBudWxsPT1ifSwK
-dzpmdW5jdGlvbihhKXtyZXR1cm4ibnVsbCJ9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIDB9LAplNzpm
-dW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlNqKGEsdS5vLmEoYikpfSwKJGljODoxfQpKLk1GLnByb3Rv
-dHlwZT17CmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gMH0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmlu
-ZyhhKX0sCiRpdm06MX0KSi5pQy5wcm90b3R5cGU9e30KSi5rZC5wcm90b3R5cGU9e30KSi5jNS5wcm90
-b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PWFbJC53KCldCmlmKHQ9PW51bGwpcmV0dXJuIHRoaXMu
-dChhKQpyZXR1cm4iSmF2YVNjcmlwdCBmdW5jdGlvbiBmb3IgIitILkVqKEouaih0KSl9LAokUzpmdW5j
-dGlvbigpe3JldHVybntmdW5jOjEsb3B0OlssLCwsLCwsLCwsLCwsLCwsXX19LAokaUVIOjF9CkouamQu
-cHJvdG90eXBlPXsKaTpmdW5jdGlvbihhLGIpe0gudDYoYSkuYy5hKGIpCmlmKCEhYS5maXhlZCRsZW5n
-dGgpSC52aChQLkw0KCJhZGQiKSkKYS5wdXNoKGIpfSwKVzQ6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZigh
-IWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgicmVtb3ZlQXQiKSkKdD1hLmxlbmd0aAppZihiPj10KXRo
-cm93IEguYihQLk83KGIsbnVsbCkpCnJldHVybiBhLnNwbGljZShiLDEpWzBdfSwKVUc6ZnVuY3Rpb24o
-YSxiLGMpe3ZhciB0LHMscgpILnQ2KGEpLkMoImNYPDE+IikuYShjKQppZighIWEuZml4ZWQkbGVuZ3Ro
-KUgudmgoUC5MNCgiaW5zZXJ0QWxsIikpCnQ9YS5sZW5ndGgKUC53QShiLDAsdCwiaW5kZXgiKQpzPWMu
-bGVuZ3RoCnRoaXMuc0EoYSx0K3MpCnI9YitzCnRoaXMuWVcoYSxyLGEubGVuZ3RoLGEsYikKdGhpcy52
-ZyhhLGIscixjKX0sCm12OmZ1bmN0aW9uKGEpe2lmKCEhYS5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJy
-ZW1vdmVMYXN0IikpCmlmKGEubGVuZ3RoPT09MCl0aHJvdyBILmIoSC5IWShhLC0xKSkKcmV0dXJuIGEu
-cG9wKCl9LApGVjpmdW5jdGlvbihhLGIpe3ZhciB0CkgudDYoYSkuQygiY1g8MT4iKS5hKGIpCmlmKCEh
-YS5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJhZGRBbGwiKSkKZm9yKHQ9Si5JVChiKTt0LkYoKTspYS5w
-dXNoKHQuZ2woKSl9LApFMjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC50NihhKQpyZXR1cm4gbmV3IEgu
-bEooYSx0LktxKGMpLkMoIjEoMikiKS5hKGIpLHQuQygiQDwxPiIpLktxKGMpLkMoImxKPDEsMj4iKSl9
-LAp6VjpmdW5jdGlvbihhLGIpe3ZhciB0LHM9UC5POChhLmxlbmd0aCwiIiwhMSx1Lk4pCmZvcih0PTA7
-dDxhLmxlbmd0aDsrK3QpdGhpcy5ZKHMsdCxILkVqKGFbdF0pKQpyZXR1cm4gcy5qb2luKGIpfSwKTjA6
-ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyCmQuYShiKQpILnQ2KGEpLktxKGQpLkMoIjEoMSwyKSIp
-LmEoYykKdD1hLmxlbmd0aApmb3Iocz1iLHI9MDtyPHQ7KytyKXtzPWMuJDIocyxhW3JdKQppZihhLmxl
-bmd0aCE9PXQpdGhyb3cgSC5iKFAuYTQoYSkpfXJldHVybiBzfSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8
-MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguT0goYSxiKQpyZXR1cm4gYVtiXX0sCmd0SDpmdW5jdGlvbihh
-KXtpZihhLmxlbmd0aD4wKXJldHVybiBhWzBdCnRocm93IEguYihILldwKCkpfSwKZ3JaOmZ1bmN0aW9u
-KGEpe3ZhciB0PWEubGVuZ3RoCmlmKHQ+MClyZXR1cm4gYVt0LTFdCnRocm93IEguYihILldwKCkpfSwK
-WVc6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHIscQpILnQ2KGEpLkMoImNYPDE+IikuYShkKQpp
-ZighIWEuaW1tdXRhYmxlJGxpc3QpSC52aChQLkw0KCJzZXRSYW5nZSIpKQpQLmpCKGIsYyxhLmxlbmd0
-aCkKdD1jLWIKaWYodD09PTApcmV0dXJuClAuazEoZSwic2tpcENvdW50IikKcz1kCnI9Si5VNihzKQpp
-ZihlK3Q+ci5nQShzKSl0aHJvdyBILmIoSC5hcigpKQppZihlPGIpZm9yKHE9dC0xO3E+PTA7LS1xKWFb
-YitxXT1yLnEocyxlK3EpCmVsc2UgZm9yKHE9MDtxPHQ7KytxKWFbYitxXT1yLnEocyxlK3EpfSwKdmc6
-ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIHRoaXMuWVcoYSxiLGMsZCwwKX0sClZyOmZ1bmN0aW9uKGEs
-Yil7dmFyIHQscwpILnQ2KGEpLkMoImEyKDEpIikuYShiKQp0PWEubGVuZ3RoCmZvcihzPTA7czx0Oysr
-cyl7aWYoSC5vVChiLiQxKGFbc10pKSlyZXR1cm4hMAppZihhLmxlbmd0aCE9PXQpdGhyb3cgSC5iKFAu
-YTQoYSkpfXJldHVybiExfSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIgdApmb3IodD0wO3Q8YS5sZW5ndGg7
-Kyt0KWlmKEouUk0oYVt0XSxiKSlyZXR1cm4hMApyZXR1cm4hMX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJu
-IFAuV0UoYSwiWyIsIl0iKX0sCmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEoubTEoYSxhLmxlbmd0
-aCxILnQ2KGEpLkMoIm0xPDE+IikpfSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKGEpfSwKZ0E6
-ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKc0E6ZnVuY3Rpb24oYSxiKXtpZighIWEuZml4ZWQk
-bGVuZ3RoKUgudmgoUC5MNCgic2V0IGxlbmd0aCIpKQphLmxlbmd0aD1ifSwKcTpmdW5jdGlvbihhLGIp
-e0gudVAoYikKaWYoYj49YS5sZW5ndGh8fGI8MCl0aHJvdyBILmIoSC5IWShhLGIpKQpyZXR1cm4gYVti
-XX0sClk6ZnVuY3Rpb24oYSxiLGMpe0gudDYoYSkuYy5hKGMpCmlmKCEhYS5pbW11dGFibGUkbGlzdClI
-LnZoKFAuTDQoImluZGV4ZWQgc2V0IikpCmlmKGI+PWEubGVuZ3RofHxiPDApdGhyb3cgSC5iKEguSFko
-YSxiKSkKYVtiXT1jfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0KSi5Qby5wcm90b3R5cGU9e30KSi5t
-MS5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9uKCl7dmFy
-IHQscz10aGlzLHI9cy5hLHE9ci5sZW5ndGgKaWYocy5iIT09cSl0aHJvdyBILmIoSC5sayhyKSkKdD1z
-LmMKaWYodD49cSl7cy5zSChudWxsKQpyZXR1cm4hMX1zLnNIKHJbdF0pOysrcy5jCnJldHVybiEwfSwK
-c0g6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLkMoIjE/IikuYShhKX0sCiRpQW46MX0KSi5xSS5w
-cm90b3R5cGU9ewp6UTpmdW5jdGlvbihhKXtpZihhPjApe2lmKGEhPT0xLzApcmV0dXJuIE1hdGgucm91
-bmQoYSl9ZWxzZSBpZihhPi0xLzApcmV0dXJuIDAtTWF0aC5yb3VuZCgwLWEpCnRocm93IEguYihQLkw0
-KCIiK2ErIi5yb3VuZCgpIikpfSwKV1o6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscQppZihiPDJ8fGI+
-MzYpdGhyb3cgSC5iKFAuVEUoYiwyLDM2LCJyYWRpeCIsbnVsbCkpCnQ9YS50b1N0cmluZyhiKQppZihD
-LnhCLm0odCx0Lmxlbmd0aC0xKSE9PTQxKXJldHVybiB0CnM9L14oW1xkYS16XSspKD86XC4oW1xkYS16
-XSspKT9cKGVcKyhcZCspXCkkLy5leGVjKHQpCmlmKHM9PW51bGwpSC52aChQLkw0KCJVbmV4cGVjdGVk
-IHRvU3RyaW5nIHJlc3VsdDogIit0KSkKcj1zLmxlbmd0aAppZigxPj1yKXJldHVybiBILk9IKHMsMSkK
-dD1zWzFdCmlmKDM+PXIpcmV0dXJuIEguT0gocywzKQpxPStzWzNdCnI9c1syXQppZihyIT1udWxsKXt0
-Kz1yCnEtPXIubGVuZ3RofXJldHVybiB0K0MueEIuSXgoIjAiLHEpfSwKdzpmdW5jdGlvbihhKXtpZihh
-PT09MCYmMS9hPDApcmV0dXJuIi0wLjAiCmVsc2UgcmV0dXJuIiIrYX0sCmdpTzpmdW5jdGlvbihhKXt2
-YXIgdCxzLHIscSxwPWF8MAppZihhPT09cClyZXR1cm4gNTM2ODcwOTExJnAKdD1NYXRoLmFicyhhKQpz
-PU1hdGgubG9nKHQpLzAuNjkzMTQ3MTgwNTU5OTQ1M3wwCnI9TWF0aC5wb3coMixzKQpxPXQ8MT90L3I6
-ci90CnJldHVybiA1MzY4NzA5MTEmKChxKjkwMDcxOTkyNTQ3NDA5OTJ8MCkrKHEqMzU0MjI0MzE4MTE3
-NjUyMXwwKSkqNTk5MTk3K3MqMTI1OX0sCnpZOmZ1bmN0aW9uKGEsYil7dmFyIHQ9YSViCmlmKHQ9PT0w
-KXJldHVybiAwCmlmKHQ+MClyZXR1cm4gdAppZihiPDApcmV0dXJuIHQtYgplbHNlIHJldHVybiB0K2J9
-LAp3RzpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGE+MCl0PXRoaXMucDMoYSxiKQplbHNle3Q9Yj4zMT8z
-MTpiCnQ9YT4+dD4+PjB9cmV0dXJuIHR9LApiZjpmdW5jdGlvbihhLGIpe2lmKGI8MCl0aHJvdyBILmIo
-SC50TChiKSkKcmV0dXJuIHRoaXMucDMoYSxiKX0sCnAzOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGI+MzE/
-MDphPj4+Yn0sCiRpQ1A6MSwKJGlsZjoxfQpKLnVyLnByb3RvdHlwZT17JGlJZjoxfQpKLlZBLnByb3Rv
-dHlwZT17fQpKLkRyLnByb3RvdHlwZT17Cm06ZnVuY3Rpb24oYSxiKXtpZihiPDApdGhyb3cgSC5iKEgu
-SFkoYSxiKSkKaWYoYj49YS5sZW5ndGgpSC52aChILkhZKGEsYikpCnJldHVybiBhLmNoYXJDb2RlQXQo
-Yil9LApXOmZ1bmN0aW9uKGEsYil7aWYoYj49YS5sZW5ndGgpdGhyb3cgSC5iKEguSFkoYSxiKSkKcmV0
-dXJuIGEuY2hhckNvZGVBdChiKX0sCmRkOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILnVuKGIsYSww
-KX0sCmg6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYiE9InN0cmluZyIpdGhyb3cgSC5iKFAuTDMoYixu
-dWxsLG51bGwpKQpyZXR1cm4gYStifSwKVGM6ZnVuY3Rpb24oYSxiKXt2YXIgdD1iLmxlbmd0aCxzPWEu
-bGVuZ3RoCmlmKHQ+cylyZXR1cm4hMQpyZXR1cm4gYj09PXRoaXMuRyhhLHMtdCl9LAppNzpmdW5jdGlv
-bihhLGIsYyxkKXt2YXIgdD1QLmpCKGIsYyxhLmxlbmd0aCkscz1hLnN1YnN0cmluZygwLGIpLHI9YS5z
-dWJzdHJpbmcodCkKcmV0dXJuIHMrZCtyfSwKUWk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CmlmKGM8MHx8
-Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5ndGgsbnVsbCxudWxsKSkKdD1jK2IubGVu
-Z3RoCmlmKHQ+YS5sZW5ndGgpcmV0dXJuITEKcmV0dXJuIGI9PT1hLnN1YnN0cmluZyhjLHQpfSwKbjpm
-dW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlFpKGEsYiwwKX0sCk5qOmZ1bmN0aW9uKGEsYixjKXtpZihj
-PT1udWxsKWM9YS5sZW5ndGgKaWYoYjwwKXRocm93IEguYihQLk83KGIsbnVsbCkpCmlmKGI+Yyl0aHJv
-dyBILmIoUC5PNyhiLG51bGwpKQppZihjPmEubGVuZ3RoKXRocm93IEguYihQLk83KGMsbnVsbCkpCnJl
-dHVybiBhLnN1YnN0cmluZyhiLGMpfSwKRzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLk5qKGEsYixu
-dWxsKX0sCmhjOmZ1bmN0aW9uKGEpe3JldHVybiBhLnRvTG93ZXJDYXNlKCl9LApiUzpmdW5jdGlvbihh
-KXt2YXIgdCxzLHIscT1hLnRyaW0oKSxwPXEubGVuZ3RoCmlmKHA9PT0wKXJldHVybiBxCmlmKHRoaXMu
-VyhxLDApPT09MTMzKXt0PUoubW0ocSwxKQppZih0PT09cClyZXR1cm4iIn1lbHNlIHQ9MApzPXAtMQpy
-PXRoaXMubShxLHMpPT09MTMzP0ouYzEocSxzKTpwCmlmKHQ9PT0wJiZyPT09cClyZXR1cm4gcQpyZXR1
-cm4gcS5zdWJzdHJpbmcodCxyKX0sCkl4OmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZigwPj1iKXJldHVy
-biIiCmlmKGI9PT0xfHxhLmxlbmd0aD09PTApcmV0dXJuIGEKaWYoYiE9PWI+Pj4wKXRocm93IEguYihD
-LkVxKQpmb3IodD1hLHM9IiI7ITA7KXtpZigoYiYxKT09PTEpcz10K3MKYj1iPj4+MQppZihiPT09MCli
-cmVhawp0Kz10fXJldHVybiBzfSwKWFU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CmlmKGM8MHx8Yz5hLmxl
-bmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5ndGgsbnVsbCxudWxsKSkKdD1hLmluZGV4T2YoYixj
-KQpyZXR1cm4gdH0sCk9ZOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuWFUoYSxiLDApfSwKUGs6ZnVu
-Y3Rpb24oYSxiLGMpe3ZhciB0LHMKaWYoYz09bnVsbCljPWEubGVuZ3RoCmVsc2UgaWYoYzwwfHxjPmEu
-bGVuZ3RoKXRocm93IEguYihQLlRFKGMsMCxhLmxlbmd0aCxudWxsLG51bGwpKQp0PWIubGVuZ3RoCnM9
-YS5sZW5ndGgKaWYoYyt0PnMpYz1zLXQKcmV0dXJuIGEubGFzdEluZGV4T2YoYixjKX0sCmNuOmZ1bmN0
-aW9uKGEsYil7cmV0dXJuIHRoaXMuUGsoYSxiLG51bGwpfSwKSXM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
-PWEubGVuZ3RoCmlmKGM+dCl0aHJvdyBILmIoUC5URShjLDAsdCxudWxsLG51bGwpKQpyZXR1cm4gSC5t
-MihhLGIsYyl9LAp0ZzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLklzKGEsYiwwKX0sCnc6ZnVuY3Rp
-b24oYSl7cmV0dXJuIGF9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQscyxyCmZvcih0PWEubGVuZ3RoLHM9
-MCxyPTA7cjx0Oysrcil7cz01MzY4NzA5MTEmcythLmNoYXJDb2RlQXQocikKcz01MzY4NzA5MTEmcyso
-KDUyNDI4NyZzKTw8MTApCnNePXM+PjZ9cz01MzY4NzA5MTEmcysoKDY3MTA4ODYzJnMpPDwzKQpzXj1z
-Pj4xMQpyZXR1cm4gNTM2ODcwOTExJnMrKCgxNjM4MyZzKTw8MTUpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0
-dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0gudVAoYikKaWYoYj49YS5sZW5ndGh8fCExKXRo
-cm93IEguYihILkhZKGEsYikpCnJldHVybiBhW2JdfSwKJGl2WDoxLAokaXFVOjF9CkgubmQucHJvdG90
-eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdD0iTGF0ZUluaXRpYWxpemF0aW9uRXJyb3I6ICIrdGhpcy5h
-CnJldHVybiB0fX0KSC5xai5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmxl
-bmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gQy54Qi5tKHRoaXMuYSxILnVQKGIpKX19CkguYlEu
-cHJvdG90eXBlPXt9CkguYUwucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMKcmV0
-dXJuIG5ldyBILmE3KHQsdC5nQSh0KSxILkxoKHQpLkMoImE3PGFMLkU+IikpfSwKelY6ZnVuY3Rpb24o
-YSxiKXt2YXIgdCxzLHIscT10aGlzLHA9cS5nQShxKQppZihiLmxlbmd0aCE9PTApe2lmKHA9PT0wKXJl
-dHVybiIiCnQ9SC5FaihxLkUoMCwwKSkKaWYocCE9PXEuZ0EocSkpdGhyb3cgSC5iKFAuYTQocSkpCmZv
-cihzPXQscj0xO3I8cDsrK3Ipe3M9cytiK0guRWoocS5FKDAscikpCmlmKHAhPT1xLmdBKHEpKXRocm93
-IEguYihQLmE0KHEpKX1yZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c31lbHNle2ZvcihyPTAscz0i
-IjtyPHA7KytyKXtzKz1ILkVqKHEuRSgwLHIpKQppZihwIT09cS5nQShxKSl0aHJvdyBILmIoUC5hNChx
-KSl9cmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9fSwKZXY6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
-dGhpcy5HRygwLEguTGgodGhpcykuQygiYTIoYUwuRSkiKS5hKGIpKX0sCkUyOmZ1bmN0aW9uKGEsYixj
-KXt2YXIgdD1ILkxoKHRoaXMpCnJldHVybiBuZXcgSC5sSih0aGlzLHQuS3EoYykuQygiMShhTC5FKSIp
-LmEoYiksdC5DKCJAPGFMLkU+IikuS3EoYykuQygibEo8MSwyPiIpKX19CkgubkgucHJvdG90eXBlPXsK
-Z1VEOmZ1bmN0aW9uKCl7dmFyIHQ9Si5IbSh0aGlzLmEpLHM9dGhpcy5jCmlmKHM9PW51bGx8fHM+dCly
-ZXR1cm4gdApyZXR1cm4gc30sCmdBczpmdW5jdGlvbigpe3ZhciB0PUouSG0odGhpcy5hKSxzPXRoaXMu
-YgppZihzPnQpcmV0dXJuIHQKcmV0dXJuIHN9LApnQTpmdW5jdGlvbihhKXt2YXIgdCxzPUouSG0odGhp
-cy5hKSxyPXRoaXMuYgppZihyPj1zKXJldHVybiAwCnQ9dGhpcy5jCmlmKHQ9PW51bGx8fHQ+PXMpcmV0
-dXJuIHMtcgppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkhOKCkKcmV0dXJuIHQtcn0sCkU6
-ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLHM9dC5nQXMoKStiCmlmKGI8MHx8cz49dC5nVUQoKSl0aHJv
-dyBILmIoUC5DZihiLHQsImluZGV4IixudWxsLG51bGwpKQpyZXR1cm4gSi5HQSh0LmEscyl9fQpILmE3
-LnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5kCnJldHVybiB0fSwKRjpmdW5jdGlv
-bigpe3ZhciB0LHM9dGhpcyxyPXMuYSxxPUouVTYocikscD1xLmdBKHIpCmlmKHMuYiE9PXApdGhyb3cg
-SC5iKFAuYTQocikpCnQ9cy5jCmlmKHQ+PXApe3Muc0kobnVsbCkKcmV0dXJuITF9cy5zSShxLkUocix0
-KSk7KytzLmMKcmV0dXJuITB9LApzSTpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4kdGkuQygiMT8iKS5h
-KGEpfSwKJGlBbjoxfQpILmkxLnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXt2YXIgdD1ILkxoKHRo
-aXMpCnJldHVybiBuZXcgSC5NSChKLklUKHRoaXMuYSksdGhpcy5iLHQuQygiQDwxPiIpLktxKHQuUVsx
-XSkuQygiTUg8MSwyPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBKLkhtKHRoaXMuYSl9fQpILnh5
-LnByb3RvdHlwZT17JGliUToxfQpILk1ILnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgdD10aGlz
-LHM9dC5iCmlmKHMuRigpKXt0LnNJKHQuYy4kMShzLmdsKCkpKQpyZXR1cm4hMH10LnNJKG51bGwpCnJl
-dHVybiExfSwKZ2w6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmEKcmV0dXJuIHR9LApzSTpmdW5jdGlvbihh
-KXt0aGlzLmE9dGhpcy4kdGkuQygiMj8iKS5hKGEpfX0KSC5sSi5wcm90b3R5cGU9ewpnQTpmdW5jdGlv
-bihhKXtyZXR1cm4gSi5IbSh0aGlzLmEpfSwKRTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmIuJDEo
-Si5HQSh0aGlzLmEsYikpfX0KSC5VNS5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7cmV0dXJuIG5l
-dyBILlNPKEouSVQodGhpcy5hKSx0aGlzLmIsdGhpcy4kdGkuQygiU088MT4iKSl9fQpILlNPLnByb3Rv
-dHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgdCxzCmZvcih0PXRoaXMuYSxzPXRoaXMuYjt0LkYoKTspaWYo
-SC5vVChzLiQxKHQuZ2woKSkpKXJldHVybiEwCnJldHVybiExfSwKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4g
-dGhpcy5hLmdsKCl9fQpILlNVLnByb3RvdHlwZT17fQpILlJlLnByb3RvdHlwZT17Clk6ZnVuY3Rpb24o
-YSxiLGMpe0guTGgodGhpcykuQygiUmUuRSIpLmEoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2Rp
-ZnkgYW4gdW5tb2RpZmlhYmxlIGxpc3QiKSl9fQpILncyLnByb3RvdHlwZT17fQpILnd2LnByb3RvdHlw
-ZT17CmdpTzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLl9oYXNoQ29kZQppZih0IT1udWxsKXJldHVybiB0
-CnQ9NTM2ODcwOTExJjY2NDU5NypKLmhmKHRoaXMuYSkKdGhpcy5faGFzaENvZGU9dApyZXR1cm4gdH0s
-Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuJ1N5bWJvbCgiJytILkVqKHRoaXMuYSkrJyIpJ30sCkROOmZ1bmN0
+YihhKQpILnkoYikKSC55KGMpCnUuTy5iKGQpCnJldHVybiEwfSwKUVc6ZnVuY3Rpb24oYSxiLGMsZCl7
+dmFyIHQscyxyCnUuaC5iKGEpCkgueShiKQpILnkoYykKdD11Lk8uYihkKS5hCnM9dC5hCnMuaHJlZj1j
+CnI9cy5ob3N0bmFtZQp0PXQuYgppZighKHI9PXQuaG9zdG5hbWUmJnMucG9ydD09dC5wb3J0JiZzLnBy
+b3RvY29sPT10LnByb3RvY29sKSlpZihyPT09IiIpaWYocy5wb3J0PT09IiIpe3Q9cy5wcm90b2NvbAp0
+PXQ9PT0iOiJ8fHQ9PT0iIn1lbHNlIHQ9ITEKZWxzZSB0PSExCmVsc2UgdD0hMApyZXR1cm4gdH0sCkJs
+OmZ1bmN0aW9uKCl7dmFyIHQ9dS5OLHM9UC50TShDLlF4LHQpLHI9dS5kRy5iKG5ldyBXLklBKCkpLHE9
+SC5WTShbIlRFTVBMQVRFIl0sdS5zKQp0PW5ldyBXLmN0KHMsUC5Mcyh0KSxQLkxzKHQpLFAuTHModCks
+bnVsbCkKdC5DWShudWxsLG5ldyBILkE4KEMuUXgscix1LmR2KSxxLG51bGwpCnJldHVybiB0fSwKdVY6
+ZnVuY3Rpb24oYSl7aWYoYT09bnVsbClyZXR1cm4gbnVsbApyZXR1cm4gVy5QMShhKX0sCnFjOmZ1bmN0
+aW9uKGEpe3ZhciB0CmlmKGE9PW51bGwpcmV0dXJuIG51bGwKaWYoInBvc3RNZXNzYWdlIiBpbiBhKXt0
+PVcuUDEoYSkKaWYodS51LmModCkpcmV0dXJuIHQKcmV0dXJuIG51bGx9ZWxzZSByZXR1cm4gdS51LmIo
+YSl9LApQMTpmdW5jdGlvbihhKXtpZihhPT09d2luZG93KXJldHVybiB1LmNpLmIoYSkKZWxzZSByZXR1
+cm4gbmV3IFcuZFcoYSl9LApISDpmdW5jdGlvbihhKXtpZihhPT09d2luZG93LmxvY2F0aW9uKXJldHVy
+biBhCmVsc2UgcmV0dXJuIG5ldyBXLkZiKCl9LAphRjpmdW5jdGlvbihhLGIpe3ZhciB0PSQuWDMKaWYo
+dD09PUMuTlUpcmV0dXJuIGEKcmV0dXJuIHQuUHkoYSxiKX0sCnFFOmZ1bmN0aW9uIHFFKCl7fSwKR2g6
+ZnVuY3Rpb24gR2goKXt9LApmWTpmdW5jdGlvbiBmWSgpe30sCm5COmZ1bmN0aW9uIG5CKCl7fSwKQXo6
+ZnVuY3Rpb24gQXooKXt9LApRUDpmdW5jdGlvbiBRUCgpe30sCm54OmZ1bmN0aW9uIG54KCl7fSwKb0o6
+ZnVuY3Rpb24gb0ooKXt9LAppZDpmdW5jdGlvbiBpZCgpe30sClFGOmZ1bmN0aW9uIFFGKCl7fSwKTmg6
+ZnVuY3Rpb24gTmgoKXt9LApJQjpmdW5jdGlvbiBJQigpe30sCm43OmZ1bmN0aW9uIG43KCl7fSwKd3o6
+ZnVuY3Rpb24gd3ooYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKY3Y6ZnVuY3Rpb24gY3YoKXt9LApD
+djpmdW5jdGlvbiBDdigpe30sCmVhOmZ1bmN0aW9uIGVhKCl7fSwKRDA6ZnVuY3Rpb24gRDAoKXt9LApU
+NTpmdW5jdGlvbiBUNSgpe30sCmg0OmZ1bmN0aW9uIGg0KCl7fSwKYnI6ZnVuY3Rpb24gYnIoKXt9LApW
+YjpmdW5jdGlvbiBWYigpe30sCk83OmZ1bmN0aW9uIE83KCl7fSwKYlU6ZnVuY3Rpb24gYlUoYSl7dGhp
+cy5hPWF9LApoSDpmdW5jdGlvbiBoSChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKd2E6ZnVuY3Rpb24g
+d2EoKXt9LApTZzpmdW5jdGlvbiBTZygpe30sCnU4OmZ1bmN0aW9uIHU4KCl7fSwKQWo6ZnVuY3Rpb24g
+QWooKXt9LAplNzpmdW5jdGlvbiBlNyhhKXt0aGlzLmE9YX0sCnVIOmZ1bmN0aW9uIHVIKCl7fSwKQkg6
+ZnVuY3Rpb24gQkgoKXt9LApTTjpmdW5jdGlvbiBTTigpe30sCmV3OmZ1bmN0aW9uIGV3KCl7fSwKbHA6
+ZnVuY3Rpb24gbHAoKXt9LApUYjpmdW5jdGlvbiBUYigpe30sCkl2OmZ1bmN0aW9uIEl2KCl7fSwKV1A6
+ZnVuY3Rpb24gV1AoKXt9LAp5WTpmdW5jdGlvbiB5WSgpe30sCnc2OmZ1bmN0aW9uIHc2KCl7fSwKSzU6
+ZnVuY3Rpb24gSzUoKXt9LApDbTpmdW5jdGlvbiBDbSgpe30sCkNROmZ1bmN0aW9uIENRKCl7fSwKdzQ6
+ZnVuY3Rpb24gdzQoKXt9LApyaDpmdW5jdGlvbiByaCgpe30sCmNmOmZ1bmN0aW9uIGNmKCl7fSwKaTc6
+ZnVuY3Rpb24gaTcoYSl7dGhpcy5hPWF9LApTeTpmdW5jdGlvbiBTeShhKXt0aGlzLmE9YX0sCktTOmZ1
+bmN0aW9uIEtTKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApBMzpmdW5jdGlvbiBBMyhhLGIpe3RoaXMu
+YT1hCnRoaXMuYj1ifSwKSTQ6ZnVuY3Rpb24gSTQoYSl7dGhpcy5hPWF9LApGazpmdW5jdGlvbiBGayhh
+LGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApSTzpmdW5jdGlvbiBSTyhhLGIsYyxkKXt2YXIgXz10aGlz
+Cl8uYT1hCl8uYj1iCl8uYz1jCl8uJHRpPWR9LApldTpmdW5jdGlvbiBldShhLGIsYyxkKXt2YXIgXz10
+aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uJHRpPWR9LAp4QzpmdW5jdGlvbiB4QyhhLGIsYyxkLGUpe3Zh
+ciBfPXRoaXMKXy5iPWEKXy5jPWIKXy5kPWMKXy5lPWQKXy4kdGk9ZX0sCnZOOmZ1bmN0aW9uIHZOKGEp
+e3RoaXMuYT1hfSwKSlE6ZnVuY3Rpb24gSlEoYSl7dGhpcy5hPWF9LApHbTpmdW5jdGlvbiBHbSgpe30s
+CnZEOmZ1bmN0aW9uIHZEKGEpe3RoaXMuYT1hfSwKVXY6ZnVuY3Rpb24gVXYoYSl7dGhpcy5hPWF9LApF
+ZzpmdW5jdGlvbiBFZyhhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LAptNjpmdW5jdGlv
+biBtNigpe30sCkVvOmZ1bmN0aW9uIEVvKCl7fSwKV2s6ZnVuY3Rpb24gV2soKXt9LApjdDpmdW5jdGlv
+biBjdChhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5lPWEKXy5hPWIKXy5iPWMKXy5jPWQKXy5kPWV9LApJ
+QTpmdW5jdGlvbiBJQSgpe30sCk93OmZ1bmN0aW9uIE93KCl7fSwKVzk6ZnVuY3Rpb24gVzkoYSxiLGMp
+e3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPS0xCl8uZD1udWxsCl8uJHRpPWN9LApkVzpmdW5jdGlv
+biBkVyhhKXt0aGlzLmE9YX0sCkZiOmZ1bmN0aW9uIEZiKCl7fSwKa0Y6ZnVuY3Rpb24ga0YoKXt9LApt
+azpmdW5jdGlvbiBtayhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKS286ZnVuY3Rpb24gS28oYSl7dGhp
+cy5hPWF9LApmbTpmdW5jdGlvbiBmbShhKXt0aGlzLmE9YX0sCkxlOmZ1bmN0aW9uIExlKCl7fSwKSzc6
+ZnVuY3Rpb24gSzcoKXt9LApyQjpmdW5jdGlvbiByQigpe30sClhXOmZ1bmN0aW9uIFhXKCl7fSwKb2E6
+ZnVuY3Rpb24gb2EoKXt9fSxVPXsKamY6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEKaWYoYT09bnVsbCl0
+PW51bGwKZWxzZXt0PUguVk0oW10sdS5mQSkKZm9yKHM9Si5JVCh1LlIuYihhKSk7cy5GKCk7KXtyPXMu
+Z2woKQpxPUouVTYocikKQy5ObS5pKHQsbmV3IFUuU2UoSC5jMChxLnEociwiZGVzY3JpcHRpb24iKSks
+SC5jMChxLnEociwiaHJlZiIpKSkpfX1yZXR1cm4gdH0sCk5kOmZ1bmN0aW9uKGEpe3ZhciB0LHMKaWYo
+YT09bnVsbCl0PW51bGwKZWxzZXt0PUguVk0oW10sdS5oaCkKZm9yKHM9Si5JVCh1LlIuYihhKSk7cy5G
+KCk7KUMuTm0uaSh0LFUuTmYocy5nbCgpKSl9cmV0dXJuIHR9LApOZjpmdW5jdGlvbihhKXt2YXIgdCxz
+LHIscSxwLG89ImRlc2NyaXB0aW9uIixuPUouVTYoYSksbT1ILmMwKG4ucShhLG8pKSxsPUguVk0oW10s
+dS5hSikKZm9yKG49Si5JVCh1LlIuYihuLnEoYSwiZW50cmllcyIpKSk7bi5GKCk7KXt0PW4uZ2woKQpz
+PUouVTYodCkKcj1ILmMwKHMucSh0LG8pKQpxPUguYzAocy5xKHQsImZ1bmN0aW9uIikpCnM9cy5xKHQs
+ImxpbmsiKQppZihzPT1udWxsKXM9bnVsbAplbHNle3A9Si5VNihzKQpzPW5ldyBVLk1sKEguYzAocC5x
+KHMsImhyZWYiKSksSC5XWShwLnEocywibGluZSIpKSxILmMwKHAucShzLCJwYXRoIikpKX1DLk5tLmko
+bCxuZXcgVS53YihyLHEscykpfXJldHVybiBuZXcgVS55RChtLGwpfSwKZDI6ZnVuY3Rpb24gZDIoYSxi
+LGMsZCxlKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lfSwKU2U6ZnVuY3Rp
+b24gU2UoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCk1sOmZ1bmN0aW9uIE1sKGEsYixjKXt0aGlzLmE9
+YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCnlEOmZ1bmN0aW9uIHlEKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9
+LAp3YjpmdW5jdGlvbiB3YihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9fSxCPXsKWWY6
+ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsPUguYzAoYS5xKDAsInJlZ2lvbnMiKSksaz1I
+LmMwKGEucSgwLCJuYXZpZ2F0aW9uQ29udGVudCIpKSxqPUguYzAoYS5xKDAsInNvdXJjZUNvZGUiKSks
+aT1QLkZsKHUuTix1LmY0KQpmb3IodD11LlMuYShhLnEoMCwiZWRpdHMiKSksdD10LmdQdSh0KSx0PXQu
+Z2t6KHQpLHM9dS5SLHI9dS5naTt0LkYoKTspe3E9dC5nbCgpCnA9cS5hCm89SC5WTShbXSxyKQpmb3Io
+cT1KLklUKHMuYihxLmIpKTtxLkYoKTspe249cS5nbCgpCm09Si5VNihuKQpDLk5tLmkobyxuZXcgQi5q
+OChILldZKG0ucShuLCJsaW5lIikpLEguYzAobS5xKG4sImV4cGxhbmF0aW9uIikpLEguV1kobS5xKG4s
+Im9mZnNldCIpKSkpfWkuWSgwLHAsbyl9cmV0dXJuIG5ldyBCLnFwKGwsayxqLGkpfSwKajg6ZnVuY3Rp
+b24gajgoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKcXA6ZnVuY3Rpb24gcXAoYSxi
+LGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZH0sCmZ2OmZ1bmN0aW9uIGZ2KCl7
+fSwKT1M6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoIShhPj02NSYmYTw9OTApKXQ9YT49OTcmJmE8PTEyMgpl
+bHNlIHQ9ITAKcmV0dXJuIHR9LApZdTpmdW5jdGlvbihhLGIpe3ZhciB0PWEubGVuZ3RoLHM9YisyCmlm
+KHQ8cylyZXR1cm4hMQppZighQi5PUyhDLnhCLm0oYSxiKSkpcmV0dXJuITEKaWYoQy54Qi5tKGEsYisx
+KSE9PTU4KXJldHVybiExCmlmKHQ9PT1zKXJldHVybiEwCnJldHVybiBDLnhCLm0oYSxzKT09PTQ3fX0s
+VD17bVE6ZnVuY3Rpb24gbVEoKXt9fSxMPXsKSXE6ZnVuY3Rpb24oKXtDLkJaLkIoZG9jdW1lbnQsIkRP
+TUNvbnRlbnRMb2FkZWQiLG5ldyBMLmUoKSkKQy5vbC5CKHdpbmRvdywicG9wc3RhdGUiLG5ldyBMLkwo
+KSl9LAprejpmdW5jdGlvbihhKXt2YXIgdCxzPXUuaC5hKGEucGFyZW50Tm9kZSkucXVlcnlTZWxlY3Rv
+cigiOnNjb3BlID4gdWwiKSxyPXMuc3R5bGUscT0iIitDLkNELnpRKHMub2Zmc2V0SGVpZ2h0KSoyKyJw
+eCIKci5tYXhIZWlnaHQ9cQpyPUoucUYoYSkKcT1yLiR0aQp0PXEuQygifigxKSIpLmIobmV3IEwuV3go
+cyxhKSkKdS5NLmIobnVsbCkKVy5KRShyLmEsci5iLHQsITEscS5kKX0sCnlYOmZ1bmN0aW9uKGEsYil7
+dmFyIHQscyxyLHEscCxvPSJxdWVyeVNlbGVjdG9yQWxsIixuPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Io
+YSksbT11LmgKbi50b1N0cmluZwpILkRoKG0sbSwiVCIsbykKdD11LlQKcz1uZXcgVy53eihuLnF1ZXJ5
+U2VsZWN0b3JBbGwoIi5uYXYtbGluayIpLHQpCnMuSyhzLG5ldyBMLkFPKGIpKQpILkRoKG0sbSwiVCIs
+bykKcj1uZXcgVy53eihuLnF1ZXJ5U2VsZWN0b3JBbGwoIi5yZWdpb24iKSx0KQppZihyLmdBKHIpIT09
+MCl7cT1uLnF1ZXJ5U2VsZWN0b3IoInRhYmxlW2RhdGEtcGF0aF0iKQpxLnRvU3RyaW5nCnIuSyhyLG5l
+dyBMLkhvKHEuZ2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTcocSkpLk8oInBhdGgi
+KSkpKX1ILkRoKG0sbSwiVCIsbykKcD1uZXcgVy53eihuLnF1ZXJ5U2VsZWN0b3JBbGwoIi5hZGQtaGlu
+dC1saW5rIiksdCkKcC5LKHAsbmV3IEwuSUMoKSl9LApRNjpmdW5jdGlvbihhLGIpe3ZhciB0PXUuTgpy
+ZXR1cm4gVy5xRChMLlE0KGEsYiksUC5FRihbIkNvbnRlbnQtVHlwZSIsImFwcGxpY2F0aW9uL2pzb247
+IGNoYXJzZXQ9VVRGLTgiXSx0LHQpKX0sCnR5OmZ1bmN0aW9uKGEpe3ZhciB0PTAscz1QLkZYKHUuUyks
+cixxLHAsbyxuLG0sbCxrCnZhciAkYXN5bmMkdHk9UC5seihmdW5jdGlvbihiLGMpe2lmKGI9PT0xKXJl
+dHVybiBQLmYzKGMscykKd2hpbGUodHJ1ZSlzd2l0Y2godCl7Y2FzZSAwOm49bmV3IFAudnMoJC5YMyx1
+LlkpCm09bmV3IFAuWmYobix1LkUpCmw9bmV3IFhNTEh0dHBSZXF1ZXN0KCkKaz11Lk4KQy5EdC5lbyhs
+LCJQT1NUIixMLlE0KGEsUC5GbChrLGspKSwhMCkKbC5zZXRSZXF1ZXN0SGVhZGVyKCJDb250ZW50LVR5
+cGUiLCJhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PVVURi04IikKaz11LmFuCnE9ay5iKG5ldyBMLkwx
+KG0sbCkpCnUuTS5iKG51bGwpCnA9dS5wClcuSkUobCwibG9hZCIscSwhMSxwKQpXLkpFKGwsImVycm9y
+IixrLmIobS5nWUooKSksITEscCkKbC5zZW5kKCkKdD0zCnJldHVybiBQLmpRKG4sJGFzeW5jJHR5KQpj
+YXNlIDM6bz1DLkN0LnBXKDAsbC5yZXNwb25zZVRleHQsbnVsbCkKaWYobC5zdGF0dXM9PT0yMDApe3I9
+dS5TLmEobykKdD0xCmJyZWFrfWVsc2UgdGhyb3cgSC5iKG8pCmNhc2UgMTpyZXR1cm4gUC55QyhyLHMp
+fX0pCnJldHVybiBQLkRJKCRhc3luYyR0eSxzKX0sCmFLOmZ1bmN0aW9uKGEpe3ZhciB0PVAuaEsoYSku
+Z2hZKCkucSgwLCJsaW5lIikKcmV0dXJuIHQ9PW51bGw/bnVsbDpILkhwKHQsbnVsbCl9LApHNjpmdW5j
+dGlvbihhKXt2YXIgdD1QLmhLKGEpLmdoWSgpLnEoMCwib2Zmc2V0IikKcmV0dXJuIHQ9PW51bGw/bnVs
+bDpILkhwKHQsbnVsbCl9LAppNjpmdW5jdGlvbihhKXtyZXR1cm4gTC5uVyh1LlYuYihhKSl9LApuVzpm
+dW5jdGlvbihhKXt2YXIgdD0wLHM9UC5GWCh1LnopLHI9MSxxLHA9W10sbyxuLG0sbCxrCnZhciAkYXN5
+bmMkaTY9UC5seihmdW5jdGlvbihiLGMpe2lmKGI9PT0xKXtxPWMKdD1yfXdoaWxlKHRydWUpc3dpdGNo
+KHQpe2Nhc2UgMDpsPXUuaC5hKFcucWMoYS5jdXJyZW50VGFyZ2V0KSkuZ2V0QXR0cmlidXRlKCJocmVm
+IikKYS5wcmV2ZW50RGVmYXVsdCgpCnI9Mwp0PTYKcmV0dXJuIFAualEoTC50eShsKSwkYXN5bmMkaTYp
+CmNhc2UgNjp1LmFfLmEoSi5HcihXLnVWKGRvY3VtZW50LmRlZmF1bHRWaWV3KSkpLnJlbG9hZCgpCnI9
+MQp0PTUKYnJlYWsKY2FzZSAzOnI9MgprPXEKbz1ILlJ1KGspCm49SC50cyhrKQpMLkMyKCJDb3VsZCBu
+b3QgYWRkL3JlbW92ZSBoaW50IixvLG4pCnQ9NQpicmVhawpjYXNlIDI6dD0xCmJyZWFrCmNhc2UgNTpy
+ZXR1cm4gUC55QyhudWxsLHMpCmNhc2UgMTpyZXR1cm4gUC5mMyhxLHMpfX0pCnJldHVybiBQLkRJKCRh
+c3luYyRpNixzKX0sCkMyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHI9ImV4Y2VwdGlvbiIscT0ic3Rh
+Y2tUcmFjZSIscD11LlMuYyhiKSYmSi5STShiLnEoMCwic3VjY2VzcyIpLCExKSYmSC5vVChiLng0KHIp
+KSYmSC5vVChiLng0KHEpKSxvPUouaWEoYikKaWYocCl7dD1ILmMwKG8ucShiLHIpKQpjPW8ucShiLHEp
+fWVsc2UgdD1vLncoYikKcD1kb2N1bWVudApzPXAucXVlcnlTZWxlY3RvcigiLnBvcHVwLXBhbmUiKQpz
+LnF1ZXJ5U2VsZWN0b3IoImgyIikuaW5uZXJUZXh0PWEKcy5xdWVyeVNlbGVjdG9yKCJwIikuaW5uZXJU
+ZXh0PXQKcy5xdWVyeVNlbGVjdG9yKCJwcmUiKS5pbm5lclRleHQ9Si5qKGMpCm89dS5OCnUuYnEuYShz
+LnF1ZXJ5U2VsZWN0b3IoImEuYm90dG9tIikpLmhyZWY9UC5YZCgiaHR0cHMiLCJnaXRodWIuY29tIiwi
+ZGFydC1sYW5nL3Nkay9pc3N1ZXMvbmV3IixQLkVGKFsidGl0bGUiLCJJc3N1ZSB3aXRoIE5OQkQgbWln
+cmF0aW9uIHRvb2w6ICIrYSwibGFiZWxzIiwiYXJlYS1hbmFseXplcixhbmFseXplci1ubmJkLW1pZ3Jh
+dGlvbix0eXBlLWJ1ZyIsImJvZHkiLGErIlxuXG5FcnJvcjogIitILmQodCkrIlxuXG5QbGVhc2UgZmls
+bCBpbiB0aGUgZm9sbG93aW5nOlxuXG4qKk5hbWUgb2YgcGFja2FnZSBiZWluZyBtaWdyYXRlZCAoaWYg
+cHVibGljKSoqOlxuKipXaGF0IEkgd2FzIGRvaW5nIHdoZW4gdGhpcyBpc3N1ZSBvY2N1cnJlZCoqOlxu
+KipJcyBpdCBwb3NzaWJsZSB0byB3b3JrIGFyb3VuZCB0aGlzIGlzc3VlKio6XG4qKkhhcyB0aGlzIGlz
+c3VlIGhhcHBlbmVkIGJlZm9yZSwgYW5kIGlmIHNvLCBob3cgb2Z0ZW4qKjpcbioqRGFydCBTREsgdmVy
+c2lvbioqOiAiK0guZChwLmdldEVsZW1lbnRCeUlkKCJzZGstdmVyc2lvbiIpLnRleHRDb250ZW50KSsi
+XG4qKkFkZGl0aW9uYWwgZGV0YWlscyoqOlxuXG5UaGFua3MgZm9yIGZpbGluZyFcblxuU3RhY2t0cmFj
+ZTogX2F1dG8gcG9wdWxhdGVkIGJ5IG1pZ3JhdGlvbiBwcmV2aWV3IHRvb2wuX1xuXG5gYGBcbiIrSC5k
+KGMpKyJcbmBgYFxuIl0sbyxvKSkudygwKQpvPXMuc3R5bGUKby5kaXNwbGF5PSJpbml0aWFsIgpMLnFK
+KGErIjogIitILmQoYiksYyl9LAp0MjpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG49e30s
+bT11LmguYShXLnFjKGEuY3VycmVudFRhcmdldCkpCmEucHJldmVudERlZmF1bHQoKQp0PW4uYT1tLmdl
+dEF0dHJpYnV0ZSgiaHJlZiIpCmlmKEouemwodCwiPyIpKXtzPUMueEIuTmoodCwwLEMueEIuT1kodCwi
+PyIpKQpuLmE9cwpyPXN9ZWxzZSByPXQKaWYoYyE9bnVsbCl7cT0kLm5VKCkKcj1uLmE9cS5vNShELm5y
+KHEudE0oYykscikpfXA9TC5HNih0KQpvPUwuYUsodCkKaWYocCE9bnVsbClMLmFmKHIscCxvLGIsbmV3
+IEwublQobixwLG8pKQplbHNlIEwuYWYocixudWxsLG51bGwsYixuZXcgTC5CWihuKSl9LAp2VTpmdW5j
+dGlvbigpe3ZhciB0PWRvY3VtZW50LHM9dS5oCkguRGgocyxzLCJUIiwicXVlcnlTZWxlY3RvckFsbCIp
+CnQ9bmV3IFcud3oodC5xdWVyeVNlbGVjdG9yQWxsKCIuY29kZSIpLHUuVCkKdC5LKHQsbmV3IEwuR0go
+KSl9LApoWDpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9dS5OCkwuUTYoYSxQLkVGKFsicmVnaW9uIiwicmVn
+aW9uIiwib2Zmc2V0IixILmQoYildLHQsdCkpLlc3KG5ldyBMLkRUKGEsYixjKSx1LlApLk9BKG5ldyBM
+LmVIKGEpKX0sCkc3OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQKaWYoIUouaHcoYSwiLmRhcnQiKSl7
+TC5CRShhLG5ldyBCLnFwKCIiLCIiLCIiLEMuQ00pLGQpCkwuQlgoYSxudWxsKQppZihlIT1udWxsKWUu
+JDAoKQpyZXR1cm59dD11Lk4KTC5RNihhLFAuRUYoWyJpbmxpbmUiLCJ0cnVlIl0sdCx0KSkuVzcobmV3
+IEwueXUoYSxkLGIsYyxlKSx1LlApLk9BKG5ldyBMLnpEKGEpKX0sCkdlOmZ1bmN0aW9uKCl7dmFyIHQ9
+Ii9fcHJldmlldy9uYXZpZ2F0aW9uVHJlZS5qc29uIgpMLlE2KHQsQy5XTykuVzcobmV3IEwuVFcoKSx1
+LlApLk9BKG5ldyBMLnhyKHQpKX0sCnFKOmZ1bmN0aW9uKGEsYil7dmFyIHQKd2luZG93CmlmKHR5cGVv
+ZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS5lcnJvcihhKQp3aW5kb3cKdD1ILmQo
+YikKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLmVycm9yKHQpfSwK
+cU86ZnVuY3Rpb24oYSl7dmFyIHQ9YS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxzPUMuQ0QuelEoJC5m
+aSgpLm9mZnNldEhlaWdodCkscj13aW5kb3cuaW5uZXJIZWlnaHQscT1DLkNELnpRKCQuRFcoKS5vZmZz
+ZXRIZWlnaHQpCmlmKHR5cGVvZiByIT09Im51bWJlciIpcmV0dXJuIHIuSE4oKQppZih0LmJvdHRvbT5y
+LShxKzE0KSlKLmRoKGEpCmVsc2UgaWYodC50b3A8cysxNClKLmRoKGEpfSwKZkc6ZnVuY3Rpb24oYSxi
+KXt2YXIgdCxzLHIKaWYoYSE9bnVsbCl7dD1kb2N1bWVudApzPXQuZ2V0RWxlbWVudEJ5SWQoIm8iK0gu
+ZChhKSkKcj10LnF1ZXJ5U2VsZWN0b3IoIi5saW5lLSIrSC5kKGIpKQppZihzIT1udWxsKXtMLnFPKHMp
+CkouZFIocykuaSgwLCJ0YXJnZXQiKX1lbHNlIGlmKHIhPW51bGwpTC5xTyhyLnBhcmVudEVsZW1lbnQp
+CmlmKHIhPW51bGwpSi5kUih1LmguYShyLnBhcmVudE5vZGUpKS5pKDAsImhpZ2hsaWdodCIpfWVsc2Ug
+TC5xTygkLkQ5KCkpfSwKYWY6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHI9TC5HNih3aW5kb3cu
+bG9jYXRpb24uaHJlZikscT1MLmFLKHdpbmRvdy5sb2NhdGlvbi5ocmVmKQppZihyIT1udWxsKXt0PWRv
+Y3VtZW50LmdldEVsZW1lbnRCeUlkKCJvIitILmQocikpCmlmKHQhPW51bGwpSi5kUih0KS5SKDAsInRh
+cmdldCIpfWlmKHEhPW51bGwpe3M9ZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLmxpbmUtIitILmQocSkp
+CmlmKHMhPW51bGwpSi5kUihzLnBhcmVudEVsZW1lbnQpLlIoMCwiaGlnaGxpZ2h0Iil9aWYoYT09d2lu
+ZG93LmxvY2F0aW9uLnBhdGhuYW1lKXtMLmZHKGIsYykKZS4kMCgpfWVsc2UgTC5HNyhhLGIsYyxkLGUp
+fSwKUTQ6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9UC5oSyhhKSxxPXUuTgpxPVAuRmwocSxxKQpmb3Io
+dD1yLmdoWSgpLHQ9dC5nUHUodCksdD10Lmdreih0KTt0LkYoKTspe3M9dC5nbCgpCnEuWSgwLHMuYSxz
+LmIpfWZvcih0PWIuZ1B1KGIpLHQ9dC5na3oodCk7dC5GKCk7KXtzPXQuZ2woKQpxLlkoMCxzLmEscy5i
+KX1xLlkoMCwiYXV0aFRva2VuIiwkLlVFKCkpCnJldHVybiByLm5tKDAscSkudygwKX0sClQxOmZ1bmN0
+aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrPSQuaEwoKQpKLmw1KGssIiIpCmlmKGE9PW51bGwp
+e3Q9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgicCIpCnQudGV4dENvbnRlbnQ9IlNlZSBkZXRhaWxzIGFi
+b3V0IGEgcHJvcG9zZWQgZWRpdC4iCkMuTHQuc1AodCxILlZNKFsicGxhY2Vob2xkZXIiXSx1LnMpKQpr
+LmFwcGVuZENoaWxkKHQpCkMuTHQuRkYodCkKcmV0dXJufXM9YS5kCnI9JC5uVSgpCnE9ci50TShzKQpw
+PWEuYgpvPWRvY3VtZW50Cm49ci5IUChzLEouVDAoby5xdWVyeVNlbGVjdG9yKCIucm9vdCIpLnRleHRD
+b250ZW50KSkKbT1hLmMKbD1vLmNyZWF0ZUVsZW1lbnQoInAiKQprLmFwcGVuZENoaWxkKGwpCmwuYXBw
+ZW5kQ2hpbGQoby5jcmVhdGVUZXh0Tm9kZShILmQocCkrIiBhdCAiK0guZChuKSsiOiIrSC5kKG0pKyIu
+IikpCkouZGgobCkKTC5DQyhhLGsscSkKTC5GeihhLGspfSwKTEg6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
+LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGc9JC55UCgpCkoubDUoZywiIikKaWYoYi5nQShiKT09PTAp
+e3Q9ZG9jdW1lbnQKcz10LmNyZWF0ZUVsZW1lbnQoInAiKQpnLmFwcGVuZENoaWxkKHMpCnMuYXBwZW5k
+Q2hpbGQodC5jcmVhdGVUZXh0Tm9kZSgiTm8gcHJvcG9zZWQgZWRpdHMiKSl9ZWxzZSBmb3IoZz1iLmdQ
+dShiKSxnPWcuZ2t6KGcpLHQ9dS5RLHI9dC5DKCJ+KDEpIikscT11Lk0sdD10LmQ7Zy5GKCk7KXtwPWcu
+Z2woKQpvPWRvY3VtZW50CnM9by5jcmVhdGVFbGVtZW50KCJwIikKbj0kLnlQKCkKbi5hcHBlbmRDaGls
+ZChzKQpzLmFwcGVuZENoaWxkKG8uY3JlYXRlVGV4dE5vZGUoSC5kKHAuYSkrIjoiKSkKbT1vLmNyZWF0
+ZUVsZW1lbnQoInVsIikKbi5hcHBlbmRDaGlsZChtKQpmb3IocD1KLklUKHAuYik7cC5GKCk7KXtuPXAu
+Z2woKQpsPW8uY3JlYXRlRWxlbWVudCgibGkiKQptLmFwcGVuZENoaWxkKGwpCkouZFIobCkuaSgwLCJl
+ZGl0IikKaz1vLmNyZWF0ZUVsZW1lbnQoImEiKQpsLmFwcGVuZENoaWxkKGspCmsuY2xhc3NMaXN0LmFk
+ZCgiZWRpdC1saW5rIikKaj1uLmMKaT1ILmQoaikKay5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5T
+eShuZXcgVy5pNyhrKSkuTygib2Zmc2V0IiksaSkKaD1uLmEKaT1ILmQoaCkKay5zZXRBdHRyaWJ1dGUo
+ImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhrKSkuTygibGluZSIpLGkpCmsuYXBwZW5kQ2hpbGQoby5j
+cmVhdGVUZXh0Tm9kZSgibGluZSAiK0guZChoKSkpCmk9ci5iKG5ldyBMLkVFKGosaCxhKSkKcS5iKG51
+bGwpClcuSkUoaywiY2xpY2siLGksITEsdCkKbC5hcHBlbmRDaGlsZChvLmNyZWF0ZVRleHROb2RlKCI6
+ICIrSC5kKG4uYikpKX19aWYoYylMLlQxKG51bGwpfSwKRnI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMs
+cj13aW5kb3cubG9jYXRpb24scT1QLmhLKChyJiZDLkV4KS5nRHIocikrSC5kKGEpKQpyPXUuTgpyPVAu
+RmwocixyKQppZihiIT1udWxsKXIuWSgwLCJvZmZzZXQiLEguZChiKSkKaWYoYyE9bnVsbClyLlkoMCwi
+bGluZSIsSC5kKGMpKQpyLlkoMCwiYXV0aFRva2VuIiwkLlVFKCkpCnE9cS5ubSgwLHIpCnI9d2luZG93
+Lmhpc3RvcnkKdD11LnoKcz1xLncoMCkKci50b1N0cmluZwpyLnB1c2hTdGF0ZShuZXcgUC5CZihbXSxb
+XSkuUHYoUC5GbCh0LHQpKSwiIixzKX0sCkVuOmZ1bmN0aW9uKGEpe3ZhciB0PUouYmIoZG9jdW1lbnQu
+cXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVudCwiLyIpCmlmKEMueEIubihhLHQpKXJldHVy
+biBDLnhCLkcoYSx0Lmxlbmd0aCkKZWxzZSByZXR1cm4gYX0sCkJYOmZ1bmN0aW9uKGEsYil7dmFyIHQs
+cyxyPXt9CnIuYT1hCmE9TC5FbihhKQpyLmE9YQokLkQ5KCkudGV4dENvbnRlbnQ9YQp0PWRvY3VtZW50
+CnM9dS5oCkguRGgocyxzLCJUIiwicXVlcnlTZWxlY3RvckFsbCIpCnQ9bmV3IFcud3oodC5xdWVyeVNl
+bGVjdG9yQWxsKCIubmF2LXBhbmVsIC5uYXYtbGluayIpLHUuVCkKdC5LKHQsbmV3IEwuVlMocikpfSwK
+QkU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PSIucmVnaW9ucyIscz1kb2N1bWVudCxyPXMucXVlcnlTZWxl
+Y3Rvcih0KSxxPXMucXVlcnlTZWxlY3RvcigiLmNvZGUiKQpKLnRIKHIsYi5hLCQuS0coKSkKSi50SChx
+LGIuYiwkLktHKCkpCkwuTEgoYSxiLmQsYykKTC52VSgpCkwueVgoIi5jb2RlIiwhMCkKTC55WCh0LCEw
+KX0sCnRYOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZz1kb2N1bWVu
+dCxmPWcuY3JlYXRlRWxlbWVudCgidWwiKQphLmFwcGVuZENoaWxkKGYpCmZvcih0PWIubGVuZ3RoLHM9
+dS5NLHI9MDtyPGIubGVuZ3RoO2IubGVuZ3RoPT09dHx8KDAsSC5saykoYiksKytyKXtxPWJbcl0KcD1n
+LmNyZWF0ZUVsZW1lbnQoImxpIikKZi5hcHBlbmRDaGlsZChwKQpvPUouUkUocCkKaWYocS5hPT09Qy5Z
+Mil7by5nUChwKS5pKDAsImRpciIpCm49Zy5jcmVhdGVFbGVtZW50KCJzcGFuIikKcC5hcHBlbmRDaGls
+ZChuKQpvPUouUkUobikKby5nUChuKS5pKDAsImFycm93IikKby5zaGYobiwiJiN4MjVCQzsiKQptPWcu
+Y3JlYXRlRWxlbWVudCgic3BhbiIpCnAuYXBwZW5kQ2hpbGQobSkKSi5sNShtLCImI3gxRjRDMTsiKQpw
+LmFwcGVuZENoaWxkKGcuY3JlYXRlVGV4dE5vZGUocS5iKSkKTC50WChwLHEuYykKTC5reihuKX1lbHNl
+e28uc2hmKHAsIiYjeDFGNEM0OyIpCmw9Zy5jcmVhdGVFbGVtZW50KCJhIikKcC5hcHBlbmRDaGlsZChs
+KQpvPUouUkUobCkKby5nUChsKS5pKDAsIm5hdi1saW5rIikKbC5zZXRBdHRyaWJ1dGUoImRhdGEtIitu
+ZXcgVy5TeShuZXcgVy5pNyhsKSkuTygibmFtZSIpLHEuZCkKbC5zZXRBdHRyaWJ1dGUoImhyZWYiLHEu
+ZSkKbC5hcHBlbmRDaGlsZChnLmNyZWF0ZVRleHROb2RlKHEuYikpCm89by5nVmwobCkKaz1vLiR0aQpq
+PWsuQygifigxKSIpLmIobmV3IEwuVEQoKSkKcy5iKG51bGwpClcuSkUoby5hLG8uYixqLCExLGsuZCkK
+aT1xLmYKaWYodHlwZW9mIGkhPT0ibnVtYmVyIilyZXR1cm4gaS5vcygpCmlmKGk+MCl7aD1nLmNyZWF0
+ZUVsZW1lbnQoInNwYW4iKQpwLmFwcGVuZENoaWxkKGgpCkouZFIoaCkuaSgwLCJlZGl0LWNvdW50IikK
+bz0iIitpKyIgIgppZihpPT09MSlrPSJlZGl0IgplbHNlIGs9ImVkaXRzIgpoLnNldEF0dHJpYnV0ZSgi
+dGl0bGUiLG8raykKaC5hcHBlbmRDaGlsZChnLmNyZWF0ZVRleHROb2RlKEMuam4udyhpKSkpfX19fSwK
+Rno6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqPWEuYQppZihqIT1udWxsKXt0
+PWRvY3VtZW50CnM9dC5jcmVhdGVFbGVtZW50KCJwIikKYi5hcHBlbmRDaGlsZChzKQpmb3Iocj1qLmxl
+bmd0aCxxPXUucyxwPXUuWCxvPTA7bzxqLmxlbmd0aDtqLmxlbmd0aD09PXJ8fCgwLEgubGspKGopLCsr
+byl7bj1qW29dCm09dC5jcmVhdGVFbGVtZW50KCJhIikKcy5hcHBlbmRDaGlsZChtKQptLmFwcGVuZENo
+aWxkKHQuY3JlYXRlVGV4dE5vZGUobi5hKSkKbS5zZXRBdHRyaWJ1dGUoImhyZWYiLG4uYikKbD1wLmIo
+SC5WTShbImFkZC1oaW50LWxpbmsiLCJiZWZvcmUtYXBwbHkiLCJidXR0b24iXSxxKSkKaz1KLmRSKG0p
+CmsuVjEoMCkKay5GVigwLGwpfX19LApDQzpmdW5jdGlvbihhMixhMyxhNCl7dmFyIHQscyxyLHEscCxv
+LG4sbSxsLGssaixpLGgsZyxmLGUsZCxjLGIsYSxhMCxhMT1udWxsCmZvcih0PWEyLmUscz10Lmxlbmd0
+aCxyPXUucyxxPXUuWCxwPTA7cDx0Lmxlbmd0aDt0Lmxlbmd0aD09PXN8fCgwLEgubGspKHQpLCsrcCl7
+bz10W3BdCm49ZG9jdW1lbnQKbT1uLmNyZWF0ZUVsZW1lbnQoInAiKQpsPXEuYihILlZNKFsidHJhY2Ui
+XSxyKSkKaz1KLmRSKG0pCmsuVjEoMCkKay5GVigwLGwpCmo9YTMuYXBwZW5kQ2hpbGQobSkKbT1uLmNy
+ZWF0ZUVsZW1lbnQoInNwYW4iKQpsPXEuYihILlZNKFsidHlwZS1kZXNjcmlwdGlvbiJdLHIpKQprPUou
+ZFIobSkKay5WMSgwKQprLkZWKDAsbCkKbS5hcHBlbmRDaGlsZChuLmNyZWF0ZVRleHROb2RlKG8uYSkp
+CmouYXBwZW5kQ2hpbGQobSkKai5hcHBlbmRDaGlsZChuLmNyZWF0ZVRleHROb2RlKCI6IikpCm09bi5j
+cmVhdGVFbGVtZW50KCJ1bCIpCmw9cS5iKEguVk0oWyJ0cmFjZSJdLHIpKQprPUouZFIobSkKay5WMSgw
+KQprLkZWKDAsbCkKaT1qLmFwcGVuZENoaWxkKG0pCmZvcihtPW8uYixsPW0ubGVuZ3RoLGg9MDtoPG0u
+bGVuZ3RoO20ubGVuZ3RoPT09bHx8KDAsSC5saykobSksKytoKXtnPW1baF0KZj1uLmNyZWF0ZUVsZW1l
+bnQoImxpIikKSi5sNShmLCImI3gyNzRGOyAiKQppLmFwcGVuZENoaWxkKGYpCmU9bi5jcmVhdGVFbGVt
+ZW50KCJzcGFuIikKZD1xLmIoSC5WTShbImZ1bmN0aW9uIl0scikpCms9Si5kUihlKQprLlYxKDApCmsu
+RlYoMCxkKQpkPWcuYgpMLmtEKGUsZD09bnVsbD8idW5rbm93biI6ZCkKZi5hcHBlbmRDaGlsZChlKQpj
+PWcuYwppZihjIT1udWxsKXtmLmFwcGVuZENoaWxkKG4uY3JlYXRlVGV4dE5vZGUoIiAoIikpCmI9Yy5i
+CmE9bi5jcmVhdGVFbGVtZW50KCJhIikKYS5hcHBlbmRDaGlsZChuLmNyZWF0ZVRleHROb2RlKEguZChj
+LmMpKyI6IitILmQoYikpKQphMD1jLmEKZT0kLm5VKCkKYS5zZXRBdHRyaWJ1dGUoImhyZWYiLGUubzUo
+ZS5xNygwLGE0LGEwLGExLGExLGExLGExLGExLGExKSkpCmEuY2xhc3NMaXN0LmFkZCgibmF2LWxpbmsi
+KQpmLmFwcGVuZENoaWxkKGEpCmYuYXBwZW5kQ2hpbGQobi5jcmVhdGVUZXh0Tm9kZSgiKSIpKX1mLmFw
+cGVuZENoaWxkKG4uY3JlYXRlVGV4dE5vZGUoIjogIikpCmU9Zy5hCkwua0QoZixlPT1udWxsPyJ1bmtu
+b3duIjplKX19fSwKa0Q6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9SC5WTShiLnNwbGl0KCIuIiksdS5z
+KSxxPUMuTm0uZ3RIKHIpLHA9ZG9jdW1lbnQKYS5hcHBlbmRDaGlsZChwLmNyZWF0ZVRleHROb2RlKHEp
+KQpmb3IocT1ILnFDKHIsMSxudWxsLHUuTikscT1uZXcgSC5hNyhxLHEuZ0EocSkscS4kdGkuQygiYTc8
+YUwuRT4iKSksdD1KLlJFKGEpO3EuRigpOyl7cz1xLmQKdC5ueihhLCJiZWZvcmVlbmQiLCImIzgyMDM7
+LiIsbnVsbCxudWxsKQphLmFwcGVuZENoaWxkKHAuY3JlYXRlVGV4dE5vZGUocykpfX0sCmU6ZnVuY3Rp
+b24gZSgpe30sClZXOmZ1bmN0aW9uIFZXKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30s
+Cm9aOmZ1bmN0aW9uIG9aKCl7fSwKanI6ZnVuY3Rpb24ganIoKXt9LApxbDpmdW5jdGlvbiBxbCgpe30s
+Cnk4OmZ1bmN0aW9uIHk4KCl7fSwKSGk6ZnVuY3Rpb24gSGkoKXt9LApCVDpmdW5jdGlvbiBCVCgpe30s
+Ckw6ZnVuY3Rpb24gTCgpe30sCld4OmZ1bmN0aW9uIFd4KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApB
+TzpmdW5jdGlvbiBBTyhhKXt0aGlzLmE9YX0sCmROOmZ1bmN0aW9uIGROKGEpe3RoaXMuYT1hfSwKSG86
+ZnVuY3Rpb24gSG8oYSl7dGhpcy5hPWF9LAp4ejpmdW5jdGlvbiB4eihhLGIpe3RoaXMuYT1hCnRoaXMu
+Yj1ifSwKSUM6ZnVuY3Rpb24gSUMoKXt9LApMMTpmdW5jdGlvbiBMMShhLGIpe3RoaXMuYT1hCnRoaXMu
+Yj1ifSwKblQ6ZnVuY3Rpb24gblQoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKQlo6
+ZnVuY3Rpb24gQlooYSl7dGhpcy5hPWF9LApHSDpmdW5jdGlvbiBHSCgpe30sCkRUOmZ1bmN0aW9uIERU
+KGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCmVIOmZ1bmN0aW9uIGVIKGEpe3RoaXMu
+YT1hfSwKeXU6ZnVuY3Rpb24geXUoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1j
+Cl8uZD1kCl8uZT1lfSwKekQ6ZnVuY3Rpb24gekQoYSl7dGhpcy5hPWF9LApUVzpmdW5jdGlvbiBUVygp
+e30sCnhyOmZ1bmN0aW9uIHhyKGEpe3RoaXMuYT1hfSwKRUU6ZnVuY3Rpb24gRUUoYSxiLGMpe3RoaXMu
+YT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKUUw6ZnVuY3Rpb24gUUwoYSxiKXt0aGlzLmE9YQp0aGlzLmI9
+Yn0sClZTOmZ1bmN0aW9uIFZTKGEpe3RoaXMuYT1hfSwKVEQ6ZnVuY3Rpb24gVEQoKXt9LApYQTpmdW5j
+dGlvbiBYQSgpe30sCm1LOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuPUguVk0oW10sdS5maCkK
+Zm9yKHQ9Si5JVCh1LlIuYihhKSk7dC5GKCk7KXtzPXQuZ2woKQpyPUouVTYocykKcT1MLnAyKEguYzAo
+ci5xKHMsInR5cGUiKSkpCnA9SC5jMChyLnEocywibmFtZSIpKQpvPXIucShzLCJzdWJ0cmVlIikKbz1v
+PT1udWxsP251bGw6TC5tSyhvKQpDLk5tLmkobixuZXcgTC5aWihxLHAsbyxILmMwKHIucShzLCJwYXRo
+IikpLEguYzAoci5xKHMsImhyZWYiKSksSC5XWShyLnEocywiZWRpdENvdW50IikpKSl9cmV0dXJuIG59
+LApwMjpmdW5jdGlvbihhKXtzd2l0Y2goYSl7Y2FzZSJkaXJlY3RvcnkiOnJldHVybiBDLlkyCmNhc2Ui
+ZmlsZSI6cmV0dXJuIEMucmYKZGVmYXVsdDp0aHJvdyBILmIoUC5QVigiVW5yZWNvZ25pemVkIG5hdmln
+YXRpb24gdHJlZSBub2RlIHR5cGU6ICIrSC5kKGEpKSl9fSwKWlo6ZnVuY3Rpb24gWlooYSxiLGMsZCxl
+LGYpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5lPWUKXy5mPWZ9LApPOTpmdW5j
+dGlvbiBPOShhKXt0aGlzLmI9YX0sCklWOmZ1bmN0aW9uIElWKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5k
+PWEKXy5lPWIKXy5mPWMKXy5yPWR9fSxNPXsKWUY6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8s
+bgpmb3IodD1iLmxlbmd0aCxzPTE7czx0Oysrcyl7aWYoYltzXT09bnVsbHx8YltzLTFdIT1udWxsKWNv
+bnRpbnVlCmZvcig7dD49MTt0PXIpe3I9dC0xCmlmKGJbcl0hPW51bGwpYnJlYWt9cT1uZXcgUC5Sbigi
+IikKcD1hKyIoIgpxLmE9cApvPUgucUMoYiwwLHQsSC50NihiKS5kKQpuPW8uJHRpCm49cCtuZXcgSC5B
+OChvLG4uQygicVUoYUwuRSkiKS5iKG5ldyBNLk5vKCkpLG4uQygiQTg8YUwuRSxxVT4iKSkuelYoMCwi
+LCAiKQpxLmE9bgpxLmE9bisoIik6IHBhcnQgIisocy0xKSsiIHdhcyBudWxsLCBidXQgcGFydCAiK3Mr
+IiB3YXMgbm90LiIpCnRocm93IEguYihQLnhZKHEudygwKSkpfX0sCmxJOmZ1bmN0aW9uIGxJKGEpe3Ro
+aXMuYT1hfSwKTWk6ZnVuY3Rpb24gTWkoKXt9LApxNzpmdW5jdGlvbiBxNygpe30sCk5vOmZ1bmN0aW9u
+IE5vKCl7fX0sWD17CkNMOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvPWIueFooYSkKYi5oSyhh
+KQppZihvIT1udWxsKWE9Si5LVihhLG8ubGVuZ3RoKQp0PXUucwpzPUguVk0oW10sdCkKcj1ILlZNKFtd
+LHQpCnQ9YS5sZW5ndGgKaWYodCE9PTAmJmIucjQoQy54Qi5XKGEsMCkpKXtpZigwPj10KXJldHVybiBI
+Lk9IKGEsMCkKQy5ObS5pKHIsYVswXSkKcT0xfWVsc2V7Qy5ObS5pKHIsIiIpCnE9MH1mb3IocD1xO3A8
+dDsrK3ApaWYoYi5yNChDLnhCLlcoYSxwKSkpe0MuTm0uaShzLEMueEIuTmooYSxxLHApKQpDLk5tLmko
+cixhW3BdKQpxPXArMX1pZihxPHQpe0MuTm0uaShzLEMueEIuRyhhLHEpKQpDLk5tLmkociwiIil9cmV0
+dXJuIG5ldyBYLldEKGIsbyxzLHIpfSwKV0Q6ZnVuY3Rpb24gV0QoYSxiLGMsZCl7dmFyIF89dGhpcwpf
+LmE9YQpfLmI9YgpfLmQ9YwpfLmU9ZH0sCnFSOmZ1bmN0aW9uIHFSKGEpe3RoaXMuYT1hfSwKSTc6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIG5ldyBYLmR2KGEpfSwKZHY6ZnVuY3Rpb24gZHYoYSl7dGhpcy5hPWF9fSxP
+PXsKUmg6ZnVuY3Rpb24oKXt2YXIgdCxzPW51bGwKaWYoUC51bygpLmdGaSgpIT09ImZpbGUiKXJldHVy
+biAkLkViKCkKdD1QLnVvKCkKaWYoIUMueEIuVGModC5nSWkodCksIi8iKSlyZXR1cm4gJC5FYigpCmlm
+KFAuS0wocywiYS9iIixzLHMscyxzLHMpLnQ0KCk9PT0iYVxcYiIpcmV0dXJuICQuS2soKQpyZXR1cm4g
+JC5iRCgpfSwKekw6ZnVuY3Rpb24gekwoKXt9fSxFPXtPRjpmdW5jdGlvbiBPRihhLGIsYyl7dGhpcy5k
+PWEKdGhpcy5lPWIKdGhpcy5mPWN9fSxGPXtydTpmdW5jdGlvbiBydShhLGIsYyxkKXt2YXIgXz10aGlz
+Cl8uZD1hCl8uZT1iCl8uZj1jCl8ucj1kfX0sRD17ClJYOmZ1bmN0aW9uKCl7dmFyIHQscyxyPVAudW8o
+KQppZihKLlJNKHIsJC5JNikpcmV0dXJuICQuRmYKJC5JNj1yCmlmKCQuSGsoKT09JC5FYigpKXJldHVy
+biAkLkZmPXIuWkkoIi4iKS53KDApCmVsc2V7dD1yLnQ0KCkKcz10Lmxlbmd0aC0xCnJldHVybiAkLkZm
+PXM9PT0wP3Q6Qy54Qi5Oaih0LDAscyl9fSwKbnI6ZnVuY3Rpb24oYSxiKXt2YXIgdD1udWxsCnJldHVy
+biAkLm5VKCkucTcoMCxhLGIsdCx0LHQsdCx0LHQpfX0KdmFyIHc9W0MsSCxKLFAsVyxVLEIsVCxMLE0s
+WCxPLEUsRixEXQpodW5rSGVscGVycy5zZXRGdW5jdGlvbk5hbWVzSWZOZWNlc3NhcnkodykKdmFyICQ9
+e30KSC5lby5wcm90b3R5cGU9e30KSi52Qi5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe3JldHVy
+biBhPT09Yn0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gSC5lUShhKX0sCnc6ZnVuY3Rpb24oYSl7cmV0
+dXJuIkluc3RhbmNlIG9mICciK0guZChILk0oYSkpKyInIn0sCmU3OmZ1bmN0aW9uKGEsYil7dS5vLmIo
+YikKdGhyb3cgSC5iKFAubHIoYSxiLmdXYSgpLGIuZ25kKCksYi5nVm0oKSkpfX0KSi55RS5wcm90b3R5
+cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJu
+IGE/NTE5MDE4OjIxODE1OX0sCiRpYTI6MX0KSi5ZRS5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIp
+e3JldHVybiBudWxsPT1ifSwKdzpmdW5jdGlvbihhKXtyZXR1cm4ibnVsbCJ9LApnaU86ZnVuY3Rpb24o
+YSl7cmV0dXJuIDB9LAplNzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlNqKGEsdS5vLmIoYikpfSwK
+JGljODoxfQpKLk1GLnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gMH0sCnc6ZnVuY3Rp
+b24oYSl7cmV0dXJuIFN0cmluZyhhKX0sCiRpdm06MX0KSi5pQy5wcm90b3R5cGU9e30KSi5rZC5wcm90
+b3R5cGU9e30KSi5jNS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PWFbJC53KCldCmlmKHQ9
+PW51bGwpcmV0dXJuIHRoaXMudChhKQpyZXR1cm4iSmF2YVNjcmlwdCBmdW5jdGlvbiBmb3IgIitILmQo
+Si5qKHQpKX0sCiRTOmZ1bmN0aW9uKCl7cmV0dXJue2Z1bmM6MSxvcHQ6WywsLCwsLCwsLCwsLCwsLCxd
+fX0sCiRpRUg6MX0KSi5qZC5wcm90b3R5cGU9ewppOmZ1bmN0aW9uKGEsYil7SC50NihhKS5kLmIoYikK
+aWYoISFhLmZpeGVkJGxlbmd0aClILnZoKFAuTDQoImFkZCIpKQphLnB1c2goYil9LApXNDpmdW5jdGlv
+bihhLGIpe3ZhciB0CmlmKCEhYS5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJyZW1vdmVBdCIpKQp0PWEu
+bGVuZ3RoCmlmKGI+PXQpdGhyb3cgSC5iKFAueChiLG51bGwpKQpyZXR1cm4gYS5zcGxpY2UoYiwxKVsw
+XX0sClVHOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIKSC50NihhKS5DKCJjWDwxPiIpLmIoYykKaWYo
+ISFhLmZpeGVkJGxlbmd0aClILnZoKFAuTDQoImluc2VydEFsbCIpKQp0PWEubGVuZ3RoClAud0EoYiww
+LHQsImluZGV4IikKcz1jLmxlbmd0aAp0aGlzLnNBKGEsdCtzKQpyPWIrcwp0aGlzLllXKGEscixhLmxl
+bmd0aCxhLGIpCnRoaXMudmcoYSxiLHIsYyl9LAptdjpmdW5jdGlvbihhKXtpZighIWEuZml4ZWQkbGVu
+Z3RoKUgudmgoUC5MNCgicmVtb3ZlTGFzdCIpKQppZihhLmxlbmd0aD09PTApdGhyb3cgSC5iKEguSFko
+YSwtMSkpCnJldHVybiBhLnBvcCgpfSwKRlY6ZnVuY3Rpb24oYSxiKXt2YXIgdApILnQ2KGEpLkMoImNY
+PDE+IikuYihiKQppZighIWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgiYWRkQWxsIikpCmZvcih0PUou
+SVQoYik7dC5GKCk7KWEucHVzaCh0LmdsKCkpfSwKSzpmdW5jdGlvbihhLGIpe3ZhciB0LHMKSC50Nihh
+KS5DKCJ+KDEpIikuYihiKQp0PWEubGVuZ3RoCmZvcihzPTA7czx0Oysrcyl7Yi4kMShhW3NdKQppZihh
+Lmxlbmd0aCE9PXQpdGhyb3cgSC5iKFAuYTQoYSkpfX0sCkUyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1I
+LnQ2KGEpCnJldHVybiBuZXcgSC5BOChhLHQuS3EoYykuQygiMSgyKSIpLmIoYiksdC5DKCJAPDE+Iiku
+S3EoYykuQygiQTg8MSwyPiIpKX0sCnpWOmZ1bmN0aW9uKGEsYil7dmFyIHQscz1uZXcgQXJyYXkoYS5s
+ZW5ndGgpCnMuZml4ZWQkbGVuZ3RoPUFycmF5CmZvcih0PTA7dDxhLmxlbmd0aDsrK3QpdGhpcy5ZKHMs
+dCxILmQoYVt0XSkpCnJldHVybiBzLmpvaW4oYil9LApOMDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxz
+LHIKZC5iKGIpCkgudDYoYSkuS3EoZCkuQygiMSgxLDIpIikuYihjKQp0PWEubGVuZ3RoCmZvcihzPWIs
+cj0wO3I8dDsrK3Ipe3M9Yy4kMihzLGFbcl0pCmlmKGEubGVuZ3RoIT09dCl0aHJvdyBILmIoUC5hNChh
+KSl9cmV0dXJuIHN9LApFOmZ1bmN0aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxlbmd0aClyZXR1cm4gSC5P
+SChhLGIpCnJldHVybiBhW2JdfSwKRDY6ZnVuY3Rpb24oYSxiLGMpe2lmKGI8MHx8Yj5hLmxlbmd0aCl0
+aHJvdyBILmIoUC5URShiLDAsYS5sZW5ndGgsInN0YXJ0IixudWxsKSkKaWYoYzxifHxjPmEubGVuZ3Ro
+KXRocm93IEguYihQLlRFKGMsYixhLmxlbmd0aCwiZW5kIixudWxsKSkKaWYoYj09PWMpcmV0dXJuIEgu
+Vk0oW10sSC50NihhKSkKcmV0dXJuIEguVk0oYS5zbGljZShiLGMpLEgudDYoYSkpfSwKZ3RIOmZ1bmN0
+aW9uKGEpe2lmKGEubGVuZ3RoPjApcmV0dXJuIGFbMF0KdGhyb3cgSC5iKEguV3AoKSl9LApnclo6ZnVu
+Y3Rpb24oYSl7dmFyIHQ9YS5sZW5ndGgKaWYodD4wKXJldHVybiBhW3QtMV0KdGhyb3cgSC5iKEguV3Ao
+KSl9LApZVzpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscj1ILnQ2KGEpCnIuQygiY1g8MT4iKS5i
+KGQpCmlmKCEhYS5pbW11dGFibGUkbGlzdClILnZoKFAuTDQoInNldFJhbmdlIikpClAuakIoYixjLGEu
+bGVuZ3RoKQp0PWMtYgppZih0PT09MClyZXR1cm4KUC5rMShlLCJza2lwQ291bnQiKQpyLkMoInpNPDE+
+IikuYihkKQpyPUouVTYoZCkKaWYoZSt0PnIuZ0EoZCkpdGhyb3cgSC5iKEguYXIoKSkKaWYoZTxiKWZv
+cihzPXQtMTtzPj0wOy0tcylhW2Irc109ci5xKGQsZStzKQplbHNlIGZvcihzPTA7czx0OysrcylhW2Ir
+c109ci5xKGQsZStzKX0sCnZnOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiB0aGlzLllXKGEsYixjLGQs
+MCl9LApWcjpmdW5jdGlvbihhLGIpe3ZhciB0LHMKSC50NihhKS5DKCJhMigxKSIpLmIoYikKdD1hLmxl
+bmd0aApmb3Iocz0wO3M8dDsrK3Mpe2lmKEgub1QoYi4kMShhW3NdKSkpcmV0dXJuITAKaWYoYS5sZW5n
+dGghPT10KXRocm93IEguYihQLmE0KGEpKX1yZXR1cm4hMX0sCnRnOmZ1bmN0aW9uKGEsYil7dmFyIHQK
+Zm9yKHQ9MDt0PGEubGVuZ3RoOysrdClpZihKLlJNKGFbdF0sYikpcmV0dXJuITAKcmV0dXJuITF9LAp3
+OmZ1bmN0aW9uKGEpe3JldHVybiBQLldFKGEsIlsiLCJdIil9LApna3o6ZnVuY3Rpb24oYSl7cmV0dXJu
+IG5ldyBKLm0xKGEsYS5sZW5ndGgsSC50NihhKS5DKCJtMTwxPiIpKX0sCmdpTzpmdW5jdGlvbihhKXty
+ZXR1cm4gSC5lUShhKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnNBOmZ1bmN0aW9u
+KGEsYil7aWYoISFhLmZpeGVkJGxlbmd0aClILnZoKFAuTDQoInNldCBsZW5ndGgiKSkKaWYoYjwwKXRo
+cm93IEguYihQLlRFKGIsMCxudWxsLCJuZXdMZW5ndGgiLG51bGwpKQphLmxlbmd0aD1ifSwKcTpmdW5j
+dGlvbihhLGIpe0guU2MoYikKaWYoYj49YS5sZW5ndGh8fGI8MCl0aHJvdyBILmIoSC5IWShhLGIpKQpy
+ZXR1cm4gYVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe0gudDYoYSkuZC5iKGMpCmlmKCEhYS5pbW11dGFi
+bGUkbGlzdClILnZoKFAuTDQoImluZGV4ZWQgc2V0IikpCmlmKGI+PWEubGVuZ3RofHxiPDApdGhyb3cg
+SC5iKEguSFkoYSxiKSkKYVtiXT1jfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0KSi5Qby5wcm90b3R5
+cGU9e30KSi5tMS5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0
+aW9uKCl7dmFyIHQscz10aGlzLHI9cy5hLHE9ci5sZW5ndGgKaWYocy5iIT09cSl0aHJvdyBILmIoSC5s
+ayhyKSkKdD1zLmMKaWYodD49cSl7cy5zSChudWxsKQpyZXR1cm4hMX1zLnNIKHJbdF0pOysrcy5jCnJl
+dHVybiEwfSwKc0g6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLmQuYihhKX0sCiRpQW46MX0KSi5x
+SS5wcm90b3R5cGU9ewp5dTpmdW5jdGlvbihhKXt2YXIgdAppZihhPj0tMjE0NzQ4MzY0OCYmYTw9MjE0
+NzQ4MzY0NylyZXR1cm4gYXwwCmlmKGlzRmluaXRlKGEpKXt0PWE8MD9NYXRoLmNlaWwoYSk6TWF0aC5m
+bG9vcihhKQpyZXR1cm4gdCswfXRocm93IEguYihQLkw0KCIiK2ErIi50b0ludCgpIikpfSwKelE6ZnVu
+Y3Rpb24oYSl7aWYoYT4wKXtpZihhIT09MS8wKXJldHVybiBNYXRoLnJvdW5kKGEpfWVsc2UgaWYoYT4t
+MS8wKXJldHVybiAwLU1hdGgucm91bmQoMC1hKQp0aHJvdyBILmIoUC5MNCgiIithKyIucm91bmQoKSIp
+KX0sCldaOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEKaWYoYjwyfHxiPjM2KXRocm93IEguYihQLlRF
+KGIsMiwzNiwicmFkaXgiLG51bGwpKQp0PWEudG9TdHJpbmcoYikKaWYoQy54Qi5tKHQsdC5sZW5ndGgt
+MSkhPT00MSlyZXR1cm4gdApzPS9eKFtcZGEtel0rKSg/OlwuKFtcZGEtel0rKSk/XChlXCsoXGQrKVwp
+JC8uZXhlYyh0KQppZihzPT1udWxsKUgudmgoUC5MNCgiVW5leHBlY3RlZCB0b1N0cmluZyByZXN1bHQ6
+ICIrdCkpCnI9cy5sZW5ndGgKaWYoMT49cilyZXR1cm4gSC5PSChzLDEpCnQ9c1sxXQppZigzPj1yKXJl
+dHVybiBILk9IKHMsMykKcT0rc1szXQpyPXNbMl0KaWYociE9bnVsbCl7dCs9cgpxLT1yLmxlbmd0aH1y
+ZXR1cm4gdCtDLnhCLkl4KCIwIixxKX0sCnc6ZnVuY3Rpb24oYSl7aWYoYT09PTAmJjEvYTwwKXJldHVy
+biItMC4wIgplbHNlIHJldHVybiIiK2F9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscD1hfDAK
+aWYoYT09PXApcmV0dXJuIDUzNjg3MDkxMSZwCnQ9TWF0aC5hYnMoYSkKcz1NYXRoLmxvZyh0KS8wLjY5
+MzE0NzE4MDU1OTk0NTN8MApyPU1hdGgucG93KDIscykKcT10PDE/dC9yOnIvdApyZXR1cm4gNTM2ODcw
+OTExJigocSo5MDA3MTk5MjU0NzQwOTkyfDApKyhxKjM1NDIyNDMxODExNzY1MjF8MCkpKjU5OTE5Nytz
+KjEyNTl9LAp6WTpmdW5jdGlvbihhLGIpe3ZhciB0PWElYgppZih0PT09MClyZXR1cm4gMAppZih0PjAp
+cmV0dXJuIHQKaWYoYjwwKXJldHVybiB0LWIKZWxzZSByZXR1cm4gdCtifSwKd0c6ZnVuY3Rpb24oYSxi
+KXt2YXIgdAppZihhPjApdD10aGlzLnAzKGEsYikKZWxzZXt0PWI+MzE/MzE6Ygp0PWE+PnQ+Pj4wfXJl
+dHVybiB0fSwKYmY6ZnVuY3Rpb24oYSxiKXtpZihiPDApdGhyb3cgSC5iKEgudEwoYikpCnJldHVybiB0
+aGlzLnAzKGEsYil9LApwMzpmdW5jdGlvbihhLGIpe3JldHVybiBiPjMxPzA6YT4+PmJ9LAokaUNQOjEs
+CiRpRks6MX0KSi51ci5wcm90b3R5cGU9eyRpS046MX0KSi5WQS5wcm90b3R5cGU9e30KSi5Eci5wcm90
+b3R5cGU9ewptOmZ1bmN0aW9uKGEsYil7aWYoYjwwKXRocm93IEguYihILkhZKGEsYikpCmlmKGI+PWEu
+bGVuZ3RoKUgudmgoSC5IWShhLGIpKQpyZXR1cm4gYS5jaGFyQ29kZUF0KGIpfSwKVzpmdW5jdGlvbihh
+LGIpe2lmKGI+PWEubGVuZ3RoKXRocm93IEguYihILkhZKGEsYikpCnJldHVybiBhLmNoYXJDb2RlQXQo
+Yil9LApkZDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgSC51bihiLGEsMCl9LApoOmZ1bmN0aW9uKGEs
+Yil7aWYodHlwZW9mIGIhPSJzdHJpbmciKXRocm93IEguYihQLkwzKGIsbnVsbCxudWxsKSkKcmV0dXJu
+IGErYn0sClRjOmZ1bmN0aW9uKGEsYil7dmFyIHQ9Yi5sZW5ndGgscz1hLmxlbmd0aAppZih0PnMpcmV0
+dXJuITEKcmV0dXJuIGI9PT10aGlzLkcoYSxzLXQpfSwKaTc6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQs
+cwpjPVAuakIoYixjLGEubGVuZ3RoKQp0PWEuc3Vic3RyaW5nKDAsYikKcz1hLnN1YnN0cmluZyhjKQpy
+ZXR1cm4gdCtkK3N9LApRaTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKaWYoIUgub2soYykpSC52aChILnRM
+KGMpKQppZih0eXBlb2YgYyE9PSJudW1iZXIiKXJldHVybiBjLkooKQppZihjPDB8fGM+YS5sZW5ndGgp
+dGhyb3cgSC5iKFAuVEUoYywwLGEubGVuZ3RoLG51bGwsbnVsbCkpCnQ9YytiLmxlbmd0aAppZih0PmEu
+bGVuZ3RoKXJldHVybiExCnJldHVybiBiPT09YS5zdWJzdHJpbmcoYyx0KX0sCm46ZnVuY3Rpb24oYSxi
+KXtyZXR1cm4gdGhpcy5RaShhLGIsMCl9LApOajpmdW5jdGlvbihhLGIsYyl7aWYoIUgub2soYikpSC52
+aChILnRMKGIpKQppZihjPT1udWxsKWM9YS5sZW5ndGgKaWYodHlwZW9mIGIhPT0ibnVtYmVyIilyZXR1
+cm4gYi5KKCkKaWYoYjwwKXRocm93IEguYihQLngoYixudWxsKSkKaWYoYj5jKXRocm93IEguYihQLngo
+YixudWxsKSkKaWYoYz5hLmxlbmd0aCl0aHJvdyBILmIoUC54KGMsbnVsbCkpCnJldHVybiBhLnN1YnN0
+cmluZyhiLGMpfSwKRzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLk5qKGEsYixudWxsKX0sCmhjOmZ1
+bmN0aW9uKGEpe3JldHVybiBhLnRvTG93ZXJDYXNlKCl9LApiUzpmdW5jdGlvbihhKXt2YXIgdCxzLHIs
+cT1hLnRyaW0oKSxwPXEubGVuZ3RoCmlmKHA9PT0wKXJldHVybiBxCmlmKHRoaXMuVyhxLDApPT09MTMz
+KXt0PUoubW0ocSwxKQppZih0PT09cClyZXR1cm4iIn1lbHNlIHQ9MApzPXAtMQpyPXRoaXMubShxLHMp
+PT09MTMzP0ouYzEocSxzKTpwCmlmKHQ9PT0wJiZyPT09cClyZXR1cm4gcQpyZXR1cm4gcS5zdWJzdHJp
+bmcodCxyKX0sCkl4OmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZigwPj1iKXJldHVybiIiCmlmKGI9PT0x
+fHxhLmxlbmd0aD09PTApcmV0dXJuIGEKaWYoYiE9PWI+Pj4wKXRocm93IEguYihDLkVxKQpmb3IodD1h
+LHM9IiI7ITA7KXtpZigoYiYxKT09PTEpcz10K3MKYj1iPj4+MQppZihiPT09MClicmVhawp0Kz10fXJl
+dHVybiBzfSwKWFU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CmlmKGM8MHx8Yz5hLmxlbmd0aCl0aHJvdyBI
+LmIoUC5URShjLDAsYS5sZW5ndGgsbnVsbCxudWxsKSkKdD1hLmluZGV4T2YoYixjKQpyZXR1cm4gdH0s
+Ck9ZOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuWFUoYSxiLDApfSwKUGs6ZnVuY3Rpb24oYSxiLGMp
+e3ZhciB0LHMKaWYoYz09bnVsbCljPWEubGVuZ3RoCmVsc2UgaWYoYzwwfHxjPmEubGVuZ3RoKXRocm93
+IEguYihQLlRFKGMsMCxhLmxlbmd0aCxudWxsLG51bGwpKQp0PWIubGVuZ3RoCnM9YS5sZW5ndGgKaWYo
+Yyt0PnMpYz1zLXQKcmV0dXJuIGEubGFzdEluZGV4T2YoYixjKX0sCmNuOmZ1bmN0aW9uKGEsYil7cmV0
+dXJuIHRoaXMuUGsoYSxiLG51bGwpfSwKSXM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PWEubGVuZ3RoCmlm
+KGM+dCl0aHJvdyBILmIoUC5URShjLDAsdCxudWxsLG51bGwpKQpyZXR1cm4gSC5tMihhLGIsYyl9LAp0
+ZzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLklzKGEsYiwwKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJu
+IGF9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQscyxyCmZvcih0PWEubGVuZ3RoLHM9MCxyPTA7cjx0Oysr
+cil7cz01MzY4NzA5MTEmcythLmNoYXJDb2RlQXQocikKcz01MzY4NzA5MTEmcysoKDUyNDI4NyZzKTw8
+MTApCnNePXM+PjZ9cz01MzY4NzA5MTEmcysoKDY3MTA4ODYzJnMpPDwzKQpzXj1zPj4xMQpyZXR1cm4g
+NTM2ODcwOTExJnMrKCgxNjM4MyZzKTw8MTUpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3Ro
+fSwKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKaWYoYj49YS5sZW5ndGh8fCExKXRocm93IEguYihILkhZ
+KGEsYikpCnJldHVybiBhW2JdfSwKJGl2WDoxLAokaXFVOjF9CkgucWoucHJvdG90eXBlPXsKZ0E6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEMueEIu
+bSh0aGlzLmEsSC5TYyhiKSl9fQpILmJRLnByb3RvdHlwZT17fQpILmFMLnByb3RvdHlwZT17Cmdrejpm
+dW5jdGlvbihhKXt2YXIgdD10aGlzCnJldHVybiBuZXcgSC5hNyh0LHQuZ0EodCksSC5MaCh0KS5DKCJh
+NzxhTC5FPiIpKX0sCnpWOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHE9dGhpcyxwPXEuZ0EocSkKaWYo
+Yi5sZW5ndGghPT0wKXtpZihwPT09MClyZXR1cm4iIgp0PUguZChxLkUoMCwwKSkKaWYocCE9PXEuZ0Eo
+cSkpdGhyb3cgSC5iKFAuYTQocSkpCmZvcihzPXQscj0xO3I8cDsrK3Ipe3M9cytiK0guZChxLkUoMCxy
+KSkKaWYocCE9PXEuZ0EocSkpdGhyb3cgSC5iKFAuYTQocSkpfXJldHVybiBzLmNoYXJDb2RlQXQoMCk9
+PTA/czpzfWVsc2V7Zm9yKHI9MCxzPSIiO3I8cDsrK3Ipe3MrPUguZChxLkUoMCxyKSkKaWYocCE9PXEu
+Z0EocSkpdGhyb3cgSC5iKFAuYTQocSkpfXJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpzfX0sCmV2
+OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuR0coMCxILkxoKHRoaXMpLkMoImEyKGFMLkUpIikuYihi
+KSl9LApFMjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEguQTgodGhp
+cyx0LktxKGMpLkMoIjEoYUwuRSkiKS5iKGIpLHQuQygiQDxhTC5FPiIpLktxKGMpLkMoIkE4PDEsMj4i
+KSl9fQpILm5ILnByb3RvdHlwZT17CmdVRDpmdW5jdGlvbigpe3ZhciB0PUouSG0odGhpcy5hKSxzPXRo
+aXMuYwppZihzPT1udWxsfHxzPnQpcmV0dXJuIHQKcmV0dXJuIHN9LApnQXM6ZnVuY3Rpb24oKXt2YXIg
+dD1KLkhtKHRoaXMuYSkscz10aGlzLmIKaWYocz50KXJldHVybiB0CnJldHVybiBzfSwKZ0E6ZnVuY3Rp
+b24oYSl7dmFyIHQscz1KLkhtKHRoaXMuYSkscj10aGlzLmIKaWYocj49cylyZXR1cm4gMAp0PXRoaXMu
+YwppZih0PT1udWxsfHx0Pj1zKXJldHVybiBzLXIKaWYodHlwZW9mIHQhPT0ibnVtYmVyIilyZXR1cm4g
+dC5ITigpCnJldHVybiB0LXJ9LApFOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLHI9cy5nQXMoKSti
+CmlmKGI+PTApe3Q9cy5nVUQoKQppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiBILnBZKHQpCnQ9
+cj49dH1lbHNlIHQ9ITAKaWYodCl0aHJvdyBILmIoUC5DZihiLHMsImluZGV4IixudWxsLG51bGwpKQpy
+ZXR1cm4gSi5HQShzLmEscil9fQpILmE3LnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRo
+aXMuZH0sCkY6ZnVuY3Rpb24oKXt2YXIgdCxzPXRoaXMscj1zLmEscT1KLlU2KHIpLHA9cS5nQShyKQpp
+ZihzLmIhPT1wKXRocm93IEguYihQLmE0KHIpKQp0PXMuYwppZih0Pj1wKXtzLnNJKG51bGwpCnJldHVy
+biExfXMuc0kocS5FKHIsdCkpOysrcy5jCnJldHVybiEwfSwKc0k6ZnVuY3Rpb24oYSl7dGhpcy5kPXRo
+aXMuJHRpLmQuYihhKX0sCiRpQW46MX0KSC5pMS5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7dmFy
+IHQ9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEguTUgoSi5JVCh0aGlzLmEpLHRoaXMuYix0LkMoIkA8MT4i
+KS5LcSh0LmNoWzFdKS5DKCJNSDwxLDI+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIEouSG0odGhp
+cy5hKX19CkgueHkucHJvdG90eXBlPXskaWJROjF9CkguTUgucHJvdG90eXBlPXsKRjpmdW5jdGlvbigp
+e3ZhciB0PXRoaXMscz10LmIKaWYocy5GKCkpe3Quc0kodC5jLiQxKHMuZ2woKSkpCnJldHVybiEwfXQu
+c0kobnVsbCkKcmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmF9LApzSTpmdW5jdGlv
+bihhKXt0aGlzLmE9dGhpcy4kdGkuY2hbMV0uYihhKX19CkguQTgucHJvdG90eXBlPXsKZ0E6ZnVuY3Rp
+b24oYSl7cmV0dXJuIEouSG0odGhpcy5hKX0sCkU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5iLiQx
+KEouR0EodGhpcy5hLGIpKX19CkguVTUucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3JldHVybiBu
+ZXcgSC5TTyhKLklUKHRoaXMuYSksdGhpcy5iLHRoaXMuJHRpLkMoIlNPPDE+IikpfX0KSC5TTy5wcm90
+b3R5cGU9ewpGOmZ1bmN0aW9uKCl7dmFyIHQscwpmb3IodD10aGlzLmEscz10aGlzLmI7dC5GKCk7KWlm
+KEgub1Qocy4kMSh0LmdsKCkpKSlyZXR1cm4hMApyZXR1cm4hMX0sCmdsOmZ1bmN0aW9uKCl7cmV0dXJu
+IHRoaXMuYS5nbCgpfX0KSC5TVS5wcm90b3R5cGU9e30KSC5SZS5wcm90b3R5cGU9ewpZOmZ1bmN0aW9u
+KGEsYixjKXtILkxoKHRoaXMpLkMoIlJlLkUiKS5iKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgbW9k
+aWZ5IGFuIHVubW9kaWZpYWJsZSBsaXN0IikpfX0KSC5YQy5wcm90b3R5cGU9e30KSC53di5wcm90b3R5
+cGU9ewpnaU86ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5faGFzaENvZGUKaWYodCE9bnVsbClyZXR1cm4g
+dAp0PTUzNjg3MDkxMSY2NjQ1OTcqSi5oZih0aGlzLmEpCnRoaXMuX2hhc2hDb2RlPXQKcmV0dXJuIHR9
+LAp3OmZ1bmN0aW9uKGEpe3JldHVybidTeW1ib2woIicrSC5kKHRoaXMuYSkrJyIpJ30sCkROOmZ1bmN0
 aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1cm4gYiBpbnN0YW5jZW9mIEgud3YmJnRoaXMu
 YT09Yi5hfSwKJGlHRDoxfQpILlBELnByb3RvdHlwZT17fQpILldVLnByb3RvdHlwZT17Cnc6ZnVuY3Rp
 b24oYSl7cmV0dXJuIFAubk8odGhpcyl9LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILkxoKHRoaXMp
-CnQuYy5hKGIpCnQuUVsxXS5hKGMpCkguZGMoKX0sCmdQdTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5x
-NChhLEguTGgodGhpcykuQygiTjM8MSwyPiIpKX0sCnE0OmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcwpy
-ZXR1cm4gUC5sMChmdW5jdGlvbigpe3ZhciBzPWEKdmFyIHI9MCxxPTEscCxvLG4sbSxsCnJldHVybiBm
-dW5jdGlvbiAkYXN5bmMkZ1B1KGMsZCl7aWYoYz09PTEpe3A9ZApyPXF9d2hpbGUodHJ1ZSlzd2l0Y2go
-cil7Y2FzZSAwOm89dC5nVigpLG89by5na3oobyksbj1ILkxoKHQpLG49bi5DKCJAPDE+IikuS3Eobi5R
-WzFdKS5DKCJOMzwxLDI+IikKY2FzZSAyOmlmKCFvLkYoKSl7cj0zCmJyZWFrfW09by5nbCgpCmw9dC5x
-KDAsbSkKbC50b1N0cmluZwpyPTQKcmV0dXJuIG5ldyBQLk4zKG0sbCxuKQpjYXNlIDQ6cj0yCmJyZWFr
-CmNhc2UgMzpyZXR1cm4gUC5UaCgpCmNhc2UgMTpyZXR1cm4gUC5ZbShwKX19fSxiKX0sCiRpWjA6MX0K
-SC5MUC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKeDQ6ZnVuY3Rpb24o
-YSl7aWYodHlwZW9mIGEhPSJzdHJpbmciKXJldHVybiExCmlmKCJfX3Byb3RvX18iPT09YSlyZXR1cm4h
-MQpyZXR1cm4gdGhpcy5iLmhhc093blByb3BlcnR5KGEpfSwKcTpmdW5jdGlvbihhLGIpe2lmKCF0aGlz
-Lng0KGIpKXJldHVybiBudWxsCnJldHVybiB0aGlzLkQoYil9LApEOmZ1bmN0aW9uKGEpe3JldHVybiB0
-aGlzLmJbSC5oKGEpXX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwPUguTGgodGhpcykKcC5D
-KCJ+KDEsMikiKS5hKGIpCnQ9dGhpcy5jCmZvcihzPXQubGVuZ3RoLHA9cC5RWzFdLHI9MDtyPHM7Kyty
-KXtxPXRbcl0KYi4kMihxLHAuYSh0aGlzLkQocSkpKX19LApnVjpmdW5jdGlvbigpe3JldHVybiBuZXcg
-SC5YUih0aGlzLEguTGgodGhpcykuQygiWFI8MT4iKSl9fQpILlhSLnByb3RvdHlwZT17CmdrejpmdW5j
-dGlvbihhKXt2YXIgdD10aGlzLmEuYwpyZXR1cm4gbmV3IEoubTEodCx0Lmxlbmd0aCxILnQ2KHQpLkMo
-Im0xPDE+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5jLmxlbmd0aH19CkguTEkucHJv
-dG90eXBlPXsKZ1dhOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5hCnJldHVybiB0fSwKZ25kOmZ1bmN0aW9u
-KCl7dmFyIHQscyxyLHEscD10aGlzCmlmKHAuYz09PTEpcmV0dXJuIEMuZG4KdD1wLmQKcz10Lmxlbmd0
-aC1wLmUubGVuZ3RoLXAuZgppZihzPT09MClyZXR1cm4gQy5kbgpyPVtdCmZvcihxPTA7cTxzOysrcSl7
-aWYocT49dC5sZW5ndGgpcmV0dXJuIEguT0godCxxKQpyLnB1c2godFtxXSl9cmV0dXJuIEouekMocil9
-LApnVm06ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9dGhpcwppZihsLmMhPT0wKXJldHVy
-biBDLkR4CnQ9bC5lCnM9dC5sZW5ndGgKcj1sLmQKcT1yLmxlbmd0aC1zLWwuZgppZihzPT09MClyZXR1
-cm4gQy5EeApwPW5ldyBILk41KHUuZW8pCmZvcihvPTA7bzxzOysrbyl7aWYobz49dC5sZW5ndGgpcmV0
-dXJuIEguT0godCxvKQpuPXRbb10KbT1xK28KaWYobTwwfHxtPj1yLmxlbmd0aClyZXR1cm4gSC5PSChy
-LG0pCnAuWSgwLG5ldyBILnd2KG4pLHJbbV0pfXJldHVybiBuZXcgSC5QRChwLHUuZ0YpfSwKJGl2UTox
-fQpILkNqLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQKSC5oKGEpCnQ9dGhpcy5hCnQu
-Yj10LmIrIiQiK0guRWooYSkKQy5ObS5pKHRoaXMuYixhKQpDLk5tLmkodGhpcy5jLGIpOysrdC5hfSwK
-JFM6MTJ9CkguZjkucHJvdG90eXBlPXsKcVM6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPXRoaXMscT1uZXcg
-UmVnRXhwKHIuYSkuZXhlYyhhKQppZihxPT1udWxsKXJldHVybiBudWxsCnQ9T2JqZWN0LmNyZWF0ZShu
-dWxsKQpzPXIuYgppZihzIT09LTEpdC5hcmd1bWVudHM9cVtzKzFdCnM9ci5jCmlmKHMhPT0tMSl0LmFy
-Z3VtZW50c0V4cHI9cVtzKzFdCnM9ci5kCmlmKHMhPT0tMSl0LmV4cHI9cVtzKzFdCnM9ci5lCmlmKHMh
-PT0tMSl0Lm1ldGhvZD1xW3MrMV0Kcz1yLmYKaWYocyE9PS0xKXQucmVjZWl2ZXI9cVtzKzFdCnJldHVy
-biB0fX0KSC5XMC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYgppZih0PT1udWxs
-KXJldHVybiJOb1N1Y2hNZXRob2RFcnJvcjogIitILkVqKHRoaXMuYSkKcmV0dXJuIk5vU3VjaE1ldGhv
-ZEVycm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIit0KyInIG9uIG51bGwifX0KSC5hei5wcm90b3R5cGU9
-ewp3OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcyxyPSJOb1N1Y2hNZXRob2RFcnJvcjogbWV0aG9kIG5v
-dCBmb3VuZDogJyIscT1zLmIKaWYocT09bnVsbClyZXR1cm4iTm9TdWNoTWV0aG9kRXJyb3I6ICIrSC5F
-aihzLmEpCnQ9cy5jCmlmKHQ9PW51bGwpcmV0dXJuIHIrcSsiJyAoIitILkVqKHMuYSkrIikiCnJldHVy
-biByK3ErIicgb24gJyIrdCsiJyAoIitILkVqKHMuYSkrIikifX0KSC52Vi5wcm90b3R5cGU9ewp3OmZ1
-bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdC5sZW5ndGg9PT0wPyJFcnJvciI6IkVycm9yOiAi
-K3R9fQpILmJxLnByb3RvdHlwZT17fQpILkFtLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe2lmKHUu
-Vy5iKGEpKWlmKGEuJHRocm93bkpzRXJyb3I9PW51bGwpYS4kdGhyb3duSnNFcnJvcj10aGlzLmEKcmV0
-dXJuIGF9LAokUzo1fQpILlhPLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmIK
-aWYocyE9bnVsbClyZXR1cm4gcwpzPXRoaXMuYQp0PXMhPT1udWxsJiZ0eXBlb2Ygcz09PSJvYmplY3Qi
-P3Muc3RhY2s6bnVsbApyZXR1cm4gdGhpcy5iPXQ9PW51bGw/IiI6dH0sCiRpR3o6MX0KSC52LnByb3Rv
-dHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jb25zdHJ1Y3RvcixzPXQ9PW51bGw/bnVsbDp0
-Lm5hbWUKcmV0dXJuIkNsb3N1cmUgJyIrSC5OUShzPT1udWxsPyJ1bmtub3duIjpzKSsiJyJ9LAokaUVI
-OjEsCmdRbDpmdW5jdGlvbigpe3JldHVybiB0aGlzfSwKJEM6IiQxIiwKJFI6MSwKJEQ6bnVsbH0KSC5s
-Yy5wcm90b3R5cGU9e30KSC56eC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuJHN0
-YXRpY19uYW1lCmlmKHQ9PW51bGwpcmV0dXJuIkNsb3N1cmUgb2YgdW5rbm93biBzdGF0aWMgbWV0aG9k
-IgpyZXR1cm4iQ2xvc3VyZSAnIitILk5RKHQpKyInIn19CkguclQucHJvdG90eXBlPXsKRE46ZnVuY3Rp
-b24oYSxiKXt2YXIgdD10aGlzCmlmKGI9PW51bGwpcmV0dXJuITEKaWYodD09PWIpcmV0dXJuITAKaWYo
-IShiIGluc3RhbmNlb2YgSC5yVCkpcmV0dXJuITEKcmV0dXJuIHQuYT09PWIuYSYmdC5iPT09Yi5iJiZ0
-LmM9PT1iLmN9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmMKaWYocz09bnVsbCl0PUguZVEo
-dGhpcy5hKQplbHNlIHQ9dHlwZW9mIHMhPT0ib2JqZWN0Ij9KLmhmKHMpOkguZVEocykKcmV0dXJuKHRe
-SC5lUSh0aGlzLmIpKT4+PjB9LAp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwppZih0PT1udWxsKXQ9
-dGhpcy5hCnJldHVybiJDbG9zdXJlICciK0guRWoodGhpcy5kKSsiJyBvZiAiKygiSW5zdGFuY2Ugb2Yg
-JyIrSC5FaihILk0odCkpKyInIil9fQpILkVxLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJu
-IlJ1bnRpbWVFcnJvcjogIitILkVqKHRoaXMuYSl9fQpILmtZLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24o
-YSl7cmV0dXJuIkFzc2VydGlvbiBmYWlsZWQ6ICIrUC5wKHRoaXMuYSl9fQpILk41LnByb3RvdHlwZT17
-CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LApnVjpmdW5jdGlvbigpe3JldHVybiBuZXcgSC5p
-NSh0aGlzLEguTGgodGhpcykuQygiaTU8MT4iKSl9LAp4NDpmdW5jdGlvbihhKXt2YXIgdCxzCmlmKHR5
-cGVvZiBhPT0ic3RyaW5nIil7dD10aGlzLmIKaWYodD09bnVsbClyZXR1cm4hMQpyZXR1cm4gdGhpcy5Y
-dSh0LGEpfWVsc2V7cz10aGlzLkNYKGEpCnJldHVybiBzfX0sCkNYOmZ1bmN0aW9uKGEpe3ZhciB0PXRo
-aXMuZAppZih0PT1udWxsKXJldHVybiExCnJldHVybiB0aGlzLkZoKHRoaXMuQnQodCxKLmhmKGEpJjB4
-M2ZmZmZmZiksYSk+PTB9LApxOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscD10aGlzLG89bnVsbApp
-Zih0eXBlb2YgYj09InN0cmluZyIpe3Q9cC5iCmlmKHQ9PW51bGwpcmV0dXJuIG8Kcz1wLmoyKHQsYikK
-cj1zPT1udWxsP286cy5iCnJldHVybiByfWVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYweDNm
-ZmZmZmYpPT09Yil7cT1wLmMKaWYocT09bnVsbClyZXR1cm4gbwpzPXAuajIocSxiKQpyPXM9PW51bGw/
-bzpzLmIKcmV0dXJuIHJ9ZWxzZSByZXR1cm4gcC5hYShiKX0sCmFhOmZ1bmN0aW9uKGEpe3ZhciB0LHMs
-cj10aGlzLmQKaWYocj09bnVsbClyZXR1cm4gbnVsbAp0PXRoaXMuQnQocixKLmhmKGEpJjB4M2ZmZmZm
-ZikKcz10aGlzLkZoKHQsYSkKaWYoczwwKXJldHVybiBudWxsCnJldHVybiB0W3NdLmJ9LApZOmZ1bmN0
-aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbj10aGlzLG09SC5MaChuKQptLmMuYShiKQptLlFbMV0u
-YShjKQppZih0eXBlb2YgYj09InN0cmluZyIpe3Q9bi5iCm4uRUgodD09bnVsbD9uLmI9bi56SygpOnQs
-YixjKX1lbHNlIGlmKHR5cGVvZiBiPT0ibnVtYmVyIiYmKGImMHgzZmZmZmZmKT09PWIpe3M9bi5jCm4u
-RUgocz09bnVsbD9uLmM9bi56SygpOnMsYixjKX1lbHNle3I9bi5kCmlmKHI9PW51bGwpcj1uLmQ9bi56
-SygpCnE9Si5oZihiKSYweDNmZmZmZmYKcD1uLkJ0KHIscSkKaWYocD09bnVsbCluLkVJKHIscSxbbi5I
-bihiLGMpXSkKZWxzZXtvPW4uRmgocCxiKQppZihvPj0wKXBbb10uYj1jCmVsc2UgcC5wdXNoKG4uSG4o
-YixjKSl9fX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9dGhpcwpILkxoKHIpLkMoIn4oMSwyKSIp
-LmEoYikKdD1yLmUKcz1yLnIKZm9yKDt0IT1udWxsOyl7Yi4kMih0LmEsdC5iKQppZihzIT09ci5yKXRo
-cm93IEguYihQLmE0KHIpKQp0PXQuY319LApFSDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz10aGlzLHI9
-SC5MaChzKQpyLmMuYShiKQpyLlFbMV0uYShjKQp0PXMuajIoYSxiKQppZih0PT1udWxsKXMuRUkoYSxi
-LHMuSG4oYixjKSkKZWxzZSB0LmI9Y30sCmtzOmZ1bmN0aW9uKCl7dGhpcy5yPXRoaXMucisxJjY3MTA4
-ODYzfSwKSG46ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLHM9SC5MaCh0KSxyPW5ldyBILmRiKHMuYy5h
-KGEpLHMuUVsxXS5hKGIpKQppZih0LmU9PW51bGwpdC5lPXQuZj1yCmVsc2V7cz10LmYKcy50b1N0cmlu
-ZwpyLmQ9cwp0LmY9cy5jPXJ9Kyt0LmEKdC5rcygpCnJldHVybiByfSwKRmg6ZnVuY3Rpb24oYSxiKXt2
-YXIgdCxzCmlmKGE9PW51bGwpcmV0dXJuLTEKdD1hLmxlbmd0aApmb3Iocz0wO3M8dDsrK3MpaWYoSi5S
-TShhW3NdLmEsYikpcmV0dXJuIHMKcmV0dXJuLTF9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLm5PKHRo
-aXMpfSwKajI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYVtiXX0sCkJ0OmZ1bmN0aW9uKGEsYil7cmV0dXJu
-IGFbYl19LApFSTpmdW5jdGlvbihhLGIsYyl7YVtiXT1jfSwKcm46ZnVuY3Rpb24oYSxiKXtkZWxldGUg
-YVtiXX0sClh1OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuajIoYSxiKSE9bnVsbH0sCnpLOmZ1bmN0
-aW9uKCl7dmFyIHQ9Ijxub24taWRlbnRpZmllci1rZXk+IixzPU9iamVjdC5jcmVhdGUobnVsbCkKdGhp
-cy5FSShzLHQscykKdGhpcy5ybihzLHQpCnJldHVybiBzfSwKJGlGbzoxfQpILmRiLnByb3RvdHlwZT17
-fQpILmk1LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuYX0sCmdrejpmdW5j
-dGlvbihhKXt2YXIgdD10aGlzLmEscz1uZXcgSC5ONih0LHQucix0aGlzLiR0aS5DKCJONjwxPiIpKQpz
-LmM9dC5lCnJldHVybiBzfSwKdGc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hLng0KGIpfX0KSC5O
-Ni5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9uKCl7dmFy
-IHQscz10aGlzLHI9cy5hCmlmKHMuYiE9PXIucil0aHJvdyBILmIoUC5hNChyKSkKdD1zLmMKaWYodD09
-bnVsbCl7cy5zcVkobnVsbCkKcmV0dXJuITF9ZWxzZXtzLnNxWSh0LmEpCnMuYz10LmMKcmV0dXJuITB9
-fSwKc3FZOmZ1bmN0aW9uKGEpe3RoaXMuZD10aGlzLiR0aS5DKCIxPyIpLmEoYSl9LAokaUFuOjF9Ckgu
-ZEMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYShhKX0sCiRTOjV9Ckgud04u
-cHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hKGEsYil9LAokUzoyMX0KSC5W
-WC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hKEguaChhKSl9LAokUzo0N30K
-SC5WUi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJSZWdFeHAvIit0aGlzLmErIi8iK3Ro
-aXMuYi5mbGFnc30sCmdIYzpmdW5jdGlvbigpe3ZhciB0PXRoaXMscz10LmMKaWYocyE9bnVsbClyZXR1
-cm4gcwpzPXQuYgpyZXR1cm4gdC5jPUgudjQodC5hLHMubXVsdGlsaW5lLCFzLmlnbm9yZUNhc2Uscy51
-bmljb2RlLHMuZG90QWxsLCEwKX0sCmRkOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILktXKHRoaXMs
-YiwwKX0sClVaOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLmdIYygpCnMubGFzdEluZGV4PWIKdD1z
-LmV4ZWMoYSkKaWYodD09bnVsbClyZXR1cm4gbnVsbApyZXR1cm4gbmV3IEguRUsodCl9LAokaXZYOjEs
-CiRpd0w6MX0KSC5FSy5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7dmFyIHQKSC51UChiKQp0PXRo
-aXMuYgppZihiPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LGIpCnJldHVybiB0W2JdfSwKJGlPZDoxLAok
-aWliOjF9CkguS1cucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgSC5QYih0aGlz
-LmEsdGhpcy5iLHRoaXMuYyl9fQpILlBiLnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7dmFyIHQ9dGhp
-cy5kCnQudG9TdHJpbmcKcmV0dXJuIHR9LApGOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG49dGhp
-cyxtPW4uYgppZihtPT1udWxsKXJldHVybiExCnQ9bi5jCnM9bS5sZW5ndGgKaWYodDw9cyl7cj1uLmEK
-cT1yLlVaKG0sdCkKaWYocSE9bnVsbCl7bi5kPXEKdD1xLmIKcD10LmluZGV4Cm89cCt0WzBdLmxlbmd0
-aAppZihwPT09byl7aWYoci5iLnVuaWNvZGUpe3Q9bi5jCnI9dCsxCmlmKHI8cyl7dD1DLnhCLm0obSx0
-KQppZih0Pj01NTI5NiYmdDw9NTYzMTkpe3Q9Qy54Qi5tKG0scikKdD10Pj01NjMyMCYmdDw9NTczNDN9
-ZWxzZSB0PSExfWVsc2UgdD0hMX1lbHNlIHQ9ITEKbz0odD9vKzE6bykrMX1uLmM9bwpyZXR1cm4hMH19
-bi5iPW4uZD1udWxsCnJldHVybiExfSwKJGlBbjoxfQpILnRRLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24o
-YSxiKXtILnVQKGIpCmlmKGIhPT0wKUgudmgoUC5PNyhiLG51bGwpKQpyZXR1cm4gdGhpcy5jfSwKJGlP
-ZDoxfQpILnVuLnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguU2QodGhpcy5h
-LHRoaXMuYix0aGlzLmMpfX0KSC5TZC5wcm90b3R5cGU9ewpGOmZ1bmN0aW9uKCl7dmFyIHQscyxyPXRo
-aXMscT1yLmMscD1yLmIsbz1wLmxlbmd0aCxuPXIuYSxtPW4ubGVuZ3RoCmlmKHErbz5tKXtyLmQ9bnVs
-bApyZXR1cm4hMX10PW4uaW5kZXhPZihwLHEpCmlmKHQ8MCl7ci5jPW0rMQpyLmQ9bnVsbApyZXR1cm4h
-MX1zPXQrbwpyLmQ9bmV3IEgudFEodCxwKQpyLmM9cz09PXIuYz9zKzE6cwpyZXR1cm4hMH0sCmdsOmZ1
-bmN0aW9uKCl7dmFyIHQ9dGhpcy5kCnQudG9TdHJpbmcKcmV0dXJuIHR9LAokaUFuOjF9CkguRVQucHJv
-dG90eXBlPXskaUVUOjEsJGlBUzoxfQpILmIwLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVy
-biBhLmxlbmd0aH0sCiRpWGo6MX0KSC5EZy5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC51UChi
-KQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19LApZOmZ1bmN0aW9uKGEsYixjKXtILkdIKGMp
-Ckgub2QoYixhLGEubGVuZ3RoKQphW2JdPWN9LAokaWJROjEsCiRpY1g6MSwKJGl6TToxfQpILlBnLnBy
-b3RvdHlwZT17Clk6ZnVuY3Rpb24oYSxiLGMpe0gudVAoYykKSC5vZChiLGEsYS5sZW5ndGgpCmFbYl09
-Y30sCiRpYlE6MSwKJGljWDoxLAokaXpNOjF9CkgueGoucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIp
-e0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5kRS5wcm90b3R5cGU9ewpx
-OmZ1bmN0aW9uKGEsYil7SC51UChiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILlpB
-LnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1
-cm4gYVtiXX19CkguZFQucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0gudVAoYikKSC5vZChiLGEs
-YS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5QcS5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC51
-UChiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILmVFLnByb3RvdHlwZT17CmdBOmZ1
-bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCkgub2QoYixh
-LGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguVjYucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0
-dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJl
-dHVybiBhW2JdfSwKJGlWNjoxLAokaW42OjF9CkguUkcucHJvdG90eXBlPXt9CkguVlAucHJvdG90eXBl
-PXt9CkguV0IucHJvdG90eXBlPXt9CkguWkcucHJvdG90eXBlPXt9CkguSmMucHJvdG90eXBlPXsKQzpm
-dW5jdGlvbihhKXtyZXR1cm4gSC5jRSh2LnR5cGVVbml2ZXJzZSx0aGlzLGEpfSwKS3E6ZnVuY3Rpb24o
-YSl7cmV0dXJuIEgudjUodi50eXBlVW5pdmVyc2UsdGhpcyxhKX19CkguRy5wcm90b3R5cGU9e30KSC51
-OS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9fQpILmlNLnByb3RvdHlwZT17
-fQpQLnRoLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxzPXQuYQp0LmE9bnVs
-bApzLiQwKCl9LAokUzoxMX0KUC5oYS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzCnRo
-aXMuYS5hPXUuTS5hKGEpCnQ9dGhpcy5iCnM9dGhpcy5jCnQuZmlyc3RDaGlsZD90LnJlbW92ZUNoaWxk
-KHMpOnQuYXBwZW5kQ2hpbGQocyl9LAokUzozMH0KUC5Wcy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigp
-e3RoaXMuYS4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6MH0KUC5GdC5wcm90b3R5cGU9ewokMDpmdW5j
-dGlvbigpe3RoaXMuYS4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6MH0KUC5XMy5wcm90b3R5cGU9ewpD
-WTpmdW5jdGlvbihhLGIpe2lmKHNlbGYuc2V0VGltZW91dCE9bnVsbClzZWxmLnNldFRpbWVvdXQoSC50
-UihuZXcgUC55SCh0aGlzLGIpLDApLGEpCmVsc2UgdGhyb3cgSC5iKFAuTDQoImBzZXRUaW1lb3V0KClg
-IG5vdCBmb3VuZC4iKSl9fQpQLnlILnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5iLiQwKCl9
-LAokQzoiJDAiLAokUjowLAokUzoxfQpQLmloLnByb3RvdHlwZT17CmFNOmZ1bmN0aW9uKGEsYil7dmFy
-IHQscz10aGlzLHI9cy4kdGkKci5DKCIxLz8iKS5hKGIpCmlmKCFzLmIpcy5hLlhmKGIpCmVsc2V7dD1z
-LmEKaWYoci5DKCJiODwxPiIpLmIoYikpdC5jVShiKQplbHNlIHQuWDIoci5jLmEoYikpfX0sCncwOmZ1
-bmN0aW9uKGEsYil7dmFyIHQKaWYoYj09bnVsbCliPVAudjAoYSkKdD10aGlzLmEKaWYodGhpcy5iKXQu
-WkwoYSxiKQplbHNlIHQuTmsoYSxiKX19ClAuV00ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0
-dXJuIHRoaXMuYS4kMigwLGEpfSwKJFM6Mjl9ClAuU1gucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxi
-KXt0aGlzLmEuJDIoMSxuZXcgSC5icShhLHUubC5hKGIpKSl9LAokQzoiJDIiLAokUjoyLAokUzoyNn0K
-UC5Hcy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYShILnVQKGEpLGIpfSwKJFM6MzJ9
-ClAuRnkucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iSXRlcmF0aW9uTWFya2VyKCIrdGhp
-cy5iKyIsICIrSC5Faih0aGlzLmEpKyIpIn19ClAuR1YucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXt2
-YXIgdD10aGlzLmMKaWYodD09bnVsbClyZXR1cm4gdGhpcy4kdGkuYy5hKHRoaXMuYikKcmV0dXJuIHQu
-Z2woKX0sCkY6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbj10aGlzCmZvcih0PW4uJHRpLkMoIkFu
-PDE+Iik7ITA7KXtzPW4uYwppZihzIT1udWxsKWlmKHMuRigpKXJldHVybiEwCmVsc2Ugbi5zWDkobnVs
-bCkKcj1mdW5jdGlvbihhLGIsYyl7dmFyIG0sbD1iCndoaWxlKHRydWUpdHJ5e3JldHVybiBhKGwsbSl9
-Y2F0Y2goayl7bT1rCmw9Y319KG4uYSwwLDEpCmlmKHIgaW5zdGFuY2VvZiBQLkZ5KXtxPXIuYgppZihx
-PT09Mil7cD1uLmQKaWYocD09bnVsbHx8cC5sZW5ndGg9PT0wKXtuLnNFQyhudWxsKQpyZXR1cm4hMX1p
-ZigwPj1wLmxlbmd0aClyZXR1cm4gSC5PSChwLC0xKQpuLmE9cC5wb3AoKQpjb250aW51ZX1lbHNle3M9
-ci5hCmlmKHE9PT0zKXRocm93IHMKZWxzZXtvPXQuYShKLklUKHMpKQppZihvIGluc3RhbmNlb2YgUC5H
-Vil7cz1uLmQKaWYocz09bnVsbClzPW4uZD1bXQpDLk5tLmkocyxuLmEpCm4uYT1vLmEKY29udGludWV9
-ZWxzZXtuLnNYOShvKQpjb250aW51ZX19fX1lbHNle24uc0VDKHIpCnJldHVybiEwfX1yZXR1cm4hMX0s
-CnNFQzpmdW5jdGlvbihhKXt0aGlzLmI9dGhpcy4kdGkuQygiMT8iKS5hKGEpfSwKc1g5OmZ1bmN0aW9u
-KGEpe3RoaXMuYz10aGlzLiR0aS5DKCJBbjwxPj8iKS5hKGEpfSwKJGlBbjoxfQpQLnE0LnByb3RvdHlw
-ZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuR1YodGhpcy5hKCksdGhpcy4kdGkuQygiR1Y8
-MT4iKSl9fQpQLmI4LnByb3RvdHlwZT17fQpQLlBmLnByb3RvdHlwZT17CncwOmZ1bmN0aW9uKGEsYil7
-dmFyIHQKUC5VSShhLCJlcnJvciIsdS5LKQp0PXRoaXMuYQppZih0LmEhPT0wKXRocm93IEguYihQLlBW
-KCJGdXR1cmUgYWxyZWFkeSBjb21wbGV0ZWQiKSkKaWYoYj09bnVsbCliPVAudjAoYSkKdC5OayhhLGIp
-fSwKcG06ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMudzAoYSxudWxsKX19ClAuWmYucHJvdG90eXBlPXsK
-YU06ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMuJHRpCnMuQygiMS8/IikuYShiKQp0PXRoaXMuYQpp
-Zih0LmEhPT0wKXRocm93IEguYihQLlBWKCJGdXR1cmUgYWxyZWFkeSBjb21wbGV0ZWQiKSkKdC5YZihz
-LkMoIjEvIikuYShiKSl9fQpQLkZlLnByb3RvdHlwZT17CkhSOmZ1bmN0aW9uKGEpe2lmKCh0aGlzLmMm
-MTUpIT09NilyZXR1cm4hMApyZXR1cm4gdGhpcy5iLmIuYnYodS5hbC5hKHRoaXMuZCksYS5hLHUueSx1
-LkspfSwKS3c6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5lLHM9dS56LHI9dS5LLHE9dGhpcy4kdGkuQygi
-Mi8iKSxwPXRoaXMuYi5iCmlmKHUuYWcuYih0KSlyZXR1cm4gcS5hKHAucnAodCxhLmEsYS5iLHMscix1
-LmwpKQplbHNlIHJldHVybiBxLmEocC5idih1LmJJLmEodCksYS5hLHMscikpfX0KUC52cy5wcm90b3R5
-cGU9ewpTcTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHE9dGhpcy4kdGkKcS5LcShjKS5DKCIxLygy
-KSIpLmEoYSkKdD0kLlgzCmlmKHQhPT1DLk5VKXtjLkMoIkA8MC8+IikuS3EocS5jKS5DKCIxKDIpIiku
-YShhKQppZihiIT1udWxsKWI9UC5WSChiLHQpfXM9bmV3IFAudnMoJC5YMyxjLkMoInZzPDA+IikpCnI9
-Yj09bnVsbD8xOjMKdGhpcy54ZihuZXcgUC5GZShzLHIsYSxiLHEuQygiQDwxPiIpLktxKGMpLkMoIkZl
-PDEsMj4iKSkpCnJldHVybiBzfSwKVzc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5TcShhLG51bGws
-Yil9LApRZDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz10aGlzLiR0aQpzLktxKGMpLkMoIjEvKDIpIiku
-YShhKQp0PW5ldyBQLnZzKCQuWDMsYy5DKCJ2czwwPiIpKQp0aGlzLnhmKG5ldyBQLkZlKHQsMTksYSxi
+CnQuZC5iKGIpCnQuY2hbMV0uYihjKQpyZXR1cm4gSC5kYygpfSwKZ1B1OmZ1bmN0aW9uKGEpe3JldHVy
+biB0aGlzLnE0KGEsSC5MaCh0aGlzKS5DKCJOMzwxLDI+IikpfSwKcTQ6ZnVuY3Rpb24oYSxiKXt2YXIg
+dD10aGlzCnJldHVybiBQLmwwKGZ1bmN0aW9uKCl7dmFyIHM9YQp2YXIgcj0wLHE9MSxwLG8sbixtCnJl
+dHVybiBmdW5jdGlvbiAkYXN5bmMkZ1B1KGMsZCl7aWYoYz09PTEpe3A9ZApyPXF9d2hpbGUodHJ1ZSlz
+d2l0Y2gocil7Y2FzZSAwOm89dC5nVigpLG89by5na3oobyksbj1ILkxoKHQpLG49bi5DKCJAPDE+Iiku
+S3Eobi5jaFsxXSkuQygiTjM8MSwyPiIpCmNhc2UgMjppZighby5GKCkpe3I9MwpicmVha31tPW8uZ2wo
+KQpyPTQKcmV0dXJuIG5ldyBQLk4zKG0sdC5xKDAsbSksbikKY2FzZSA0OnI9MgpicmVhawpjYXNlIDM6
+cmV0dXJuIFAuVGgoKQpjYXNlIDE6cmV0dXJuIFAuWW0ocCl9fX0sYil9LAokaVowOjF9CkguTFAucHJv
+dG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYX0sCng0OmZ1bmN0aW9uKGEpe2lmKHR5
+cGVvZiBhIT0ic3RyaW5nIilyZXR1cm4hMQppZigiX19wcm90b19fIj09PWEpcmV0dXJuITEKcmV0dXJu
+IHRoaXMuYi5oYXNPd25Qcm9wZXJ0eShhKX0sCnE6ZnVuY3Rpb24oYSxiKXtpZighdGhpcy54NChiKSly
+ZXR1cm4gbnVsbApyZXR1cm4gdGhpcy5EKGIpfSwKRDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5iW0gu
+eShhKV19LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscD1ILkxoKHRoaXMpCnAuQygifigxLDIp
+IikuYihiKQp0PXRoaXMuYwpmb3Iocz10Lmxlbmd0aCxwPXAuY2hbMV0scj0wO3I8czsrK3Ipe3E9dFty
+XQpiLiQyKHEscC5iKHRoaXMuRChxKSkpfX0sCmdWOmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBILlhSKHRo
+aXMsSC5MaCh0aGlzKS5DKCJYUjwxPiIpKX19CkguWFIucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEp
+e3ZhciB0PXRoaXMuYS5jCnJldHVybiBuZXcgSi5tMSh0LHQubGVuZ3RoLEgudDYodCkuQygibTE8MT4i
+KSl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmMubGVuZ3RofX0KSC5MSS5wcm90b3R5cGU9
+ewpnV2E6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmEKcmV0dXJuIHR9LApnbmQ6ZnVuY3Rpb24oKXt2YXIg
+dCxzLHIscSxwPXRoaXMKaWYocC5jPT09MSlyZXR1cm4gQy5kbgp0PXAuZApzPXQubGVuZ3RoLXAuZS5s
+ZW5ndGgtcC5mCmlmKHM9PT0wKXJldHVybiBDLmRuCnI9W10KZm9yKHE9MDtxPHM7KytxKXtpZihxPj10
+Lmxlbmd0aClyZXR1cm4gSC5PSCh0LHEpCnIucHVzaCh0W3FdKX1yZXR1cm4gSi56QyhyKX0sCmdWbTpm
+dW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuLG0sbD10aGlzCmlmKGwuYyE9PTApcmV0dXJuIEMuRHgK
+dD1sLmUKcz10Lmxlbmd0aApyPWwuZApxPXIubGVuZ3RoLXMtbC5mCmlmKHM9PT0wKXJldHVybiBDLkR4
+CnA9bmV3IEguTjUodS5lbykKZm9yKG89MDtvPHM7KytvKXtpZihvPj10Lmxlbmd0aClyZXR1cm4gSC5P
+SCh0LG8pCm49dFtvXQptPXErbwppZihtPDB8fG0+PXIubGVuZ3RoKXJldHVybiBILk9IKHIsbSkKcC5Z
+KDAsbmV3IEgud3YobiksclttXSl9cmV0dXJuIG5ldyBILlBEKHAsdS5nRil9LAokaXZROjF9CkguQ2ou
+cHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdApILnkoYSkKdD10aGlzLmEKdC5iPXQuYisi
+JCIrSC5kKGEpCkMuTm0uaSh0aGlzLmIsYSkKQy5ObS5pKHRoaXMuYyxiKTsrK3QuYX0sCiRTOjEzfQpI
+LmY5LnByb3RvdHlwZT17CnFTOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj10aGlzLHE9bmV3IFJlZ0V4cChy
+LmEpLmV4ZWMoYSkKaWYocT09bnVsbClyZXR1cm4gbnVsbAp0PU9iamVjdC5jcmVhdGUobnVsbCkKcz1y
+LmIKaWYocyE9PS0xKXQuYXJndW1lbnRzPXFbcysxXQpzPXIuYwppZihzIT09LTEpdC5hcmd1bWVudHNF
+eHByPXFbcysxXQpzPXIuZAppZihzIT09LTEpdC5leHByPXFbcysxXQpzPXIuZQppZihzIT09LTEpdC5t
+ZXRob2Q9cVtzKzFdCnM9ci5mCmlmKHMhPT0tMSl0LnJlY2VpdmVyPXFbcysxXQpyZXR1cm4gdH19Ckgu
+VzAucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmIKaWYodD09bnVsbClyZXR1cm4i
+Tm9TdWNoTWV0aG9kRXJyb3I6ICIrSC5kKHRoaXMuYSkKcmV0dXJuIk5vU3VjaE1ldGhvZEVycm9yOiBt
+ZXRob2Qgbm90IGZvdW5kOiAnIit0KyInIG9uIG51bGwifX0KSC5hei5wcm90b3R5cGU9ewp3OmZ1bmN0
+aW9uKGEpe3ZhciB0LHM9dGhpcyxyPSJOb1N1Y2hNZXRob2RFcnJvcjogbWV0aG9kIG5vdCBmb3VuZDog
+JyIscT1zLmIKaWYocT09bnVsbClyZXR1cm4iTm9TdWNoTWV0aG9kRXJyb3I6ICIrSC5kKHMuYSkKdD1z
+LmMKaWYodD09bnVsbClyZXR1cm4gcitxKyInICgiK0guZChzLmEpKyIpIgpyZXR1cm4gcitxKyInIG9u
+ICciK3QrIicgKCIrSC5kKHMuYSkrIikifX0KSC52Vi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3Zh
+ciB0PXRoaXMuYQpyZXR1cm4gdC5sZW5ndGg9PT0wPyJFcnJvciI6IkVycm9yOiAiK3R9fQpILmJxLnBy
+b3RvdHlwZT17fQpILkFtLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe2lmKHUuYlUuYyhhKSlpZihh
+LiR0aHJvd25Kc0Vycm9yPT1udWxsKWEuJHRocm93bkpzRXJyb3I9dGhpcy5hCnJldHVybiBhfSwKJFM6
+NH0KSC5YTy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5iCmlmKHMhPW51bGwp
+cmV0dXJuIHMKcz10aGlzLmEKdD1zIT09bnVsbCYmdHlwZW9mIHM9PT0ib2JqZWN0Ij9zLnN0YWNrOm51
+bGwKcmV0dXJuIHRoaXMuYj10PT1udWxsPyIiOnR9LAokaUd6OjF9CkguVHAucHJvdG90eXBlPXsKdzpm
+dW5jdGlvbihhKXt2YXIgdD10aGlzLmNvbnN0cnVjdG9yLHM9dD09bnVsbD9udWxsOnQubmFtZQpyZXR1
+cm4iQ2xvc3VyZSAnIitILk5RKHM9PW51bGw/InVua25vd24iOnMpKyInIn0sCiRpRUg6MSwKZ1FsOmZ1
+bmN0aW9uKCl7cmV0dXJuIHRoaXN9LAokQzoiJDEiLAokUjoxLAokRDpudWxsfQpILmxjLnByb3RvdHlw
+ZT17fQpILnp4LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy4kc3RhdGljX25hbWUK
+aWYodD09bnVsbClyZXR1cm4iQ2xvc3VyZSBvZiB1bmtub3duIHN0YXRpYyBtZXRob2QiCnJldHVybiJD
+bG9zdXJlICciK0guTlEodCkrIicifX0KSC5yVC5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe3Zh
+ciB0PXRoaXMKaWYoYj09bnVsbClyZXR1cm4hMQppZih0PT09YilyZXR1cm4hMAppZighKGIgaW5zdGFu
+Y2VvZiBILnJUKSlyZXR1cm4hMQpyZXR1cm4gdC5hPT09Yi5hJiZ0LmI9PT1iLmImJnQuYz09PWIuY30s
+CmdpTzpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMuYwppZihzPT1udWxsKXQ9SC5lUSh0aGlzLmEpCmVs
+c2UgdD10eXBlb2YgcyE9PSJvYmplY3QiP0ouaGYocyk6SC5lUShzKQpyZXR1cm4odF5ILmVRKHRoaXMu
+YikpPj4+MH0sCnc6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jCmlmKHQ9PW51bGwpdD10aGlzLmEKcmV0
+dXJuIkNsb3N1cmUgJyIrSC5kKHRoaXMuZCkrIicgb2YgIisoIkluc3RhbmNlIG9mICciK0guZChILk0o
+dCkpKyInIil9fQpILkVxLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIlJ1bnRpbWVFcnJv
+cjogIitILmQodGhpcy5hKX19Ckgua1kucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iQXNz
+ZXJ0aW9uIGZhaWxlZDogIitQLnAodGhpcy5hKX19CkguTjUucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24o
+YSl7cmV0dXJuIHRoaXMuYX0sCmdWOmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBILmk1KHRoaXMsSC5MaCh0
+aGlzKS5DKCJpNTwxPiIpKX0sCng0OmZ1bmN0aW9uKGEpe3ZhciB0LHMKaWYodHlwZW9mIGE9PSJzdHJp
+bmciKXt0PXRoaXMuYgppZih0PT1udWxsKXJldHVybiExCnJldHVybiB0aGlzLlh1KHQsYSl9ZWxzZXtz
+PXRoaXMuQ1goYSkKcmV0dXJuIHN9fSwKQ1g6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5kCmlmKHQ9PW51
+bGwpcmV0dXJuITEKcmV0dXJuIHRoaXMuRmgodGhpcy5CdCh0LEouaGYoYSkmMHgzZmZmZmZmKSxhKT49
+MH0sCnE6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwPXRoaXMsbz1udWxsCmlmKHR5cGVvZiBiPT0i
+c3RyaW5nIil7dD1wLmIKaWYodD09bnVsbClyZXR1cm4gbwpzPXAuajIodCxiKQpyPXM9PW51bGw/bzpz
+LmIKcmV0dXJuIHJ9ZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciImJihiJjB4M2ZmZmZmZik9PT1iKXtx
+PXAuYwppZihxPT1udWxsKXJldHVybiBvCnM9cC5qMihxLGIpCnI9cz09bnVsbD9vOnMuYgpyZXR1cm4g
+cn1lbHNlIHJldHVybiBwLmFhKGIpfSwKYWE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPXRoaXMuZAppZihy
+PT1udWxsKXJldHVybiBudWxsCnQ9dGhpcy5CdChyLEouaGYoYSkmMHgzZmZmZmZmKQpzPXRoaXMuRmgo
+dCxhKQppZihzPDApcmV0dXJuIG51bGwKcmV0dXJuIHRbc10uYn0sClk6ZnVuY3Rpb24oYSxiLGMpe3Zh
+ciB0LHMscixxLHAsbyxuPXRoaXMsbT1ILkxoKG4pCm0uZC5iKGIpCm0uY2hbMV0uYihjKQppZih0eXBl
+b2YgYj09InN0cmluZyIpe3Q9bi5iCm4uRUgodD09bnVsbD9uLmI9bi56SygpOnQsYixjKX1lbHNlIGlm
+KHR5cGVvZiBiPT0ibnVtYmVyIiYmKGImMHgzZmZmZmZmKT09PWIpe3M9bi5jCm4uRUgocz09bnVsbD9u
+LmM9bi56SygpOnMsYixjKX1lbHNle3I9bi5kCmlmKHI9PW51bGwpcj1uLmQ9bi56SygpCnE9Si5oZihi
+KSYweDNmZmZmZmYKcD1uLkJ0KHIscSkKaWYocD09bnVsbCluLkVJKHIscSxbbi5IbihiLGMpXSkKZWxz
+ZXtvPW4uRmgocCxiKQppZihvPj0wKXBbb10uYj1jCmVsc2UgcC5wdXNoKG4uSG4oYixjKSl9fX0sCks6
+ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9dGhpcwpILkxoKHIpLkMoIn4oMSwyKSIpLmIoYikKdD1yLmUK
+cz1yLnIKZm9yKDt0IT1udWxsOyl7Yi4kMih0LmEsdC5iKQppZihzIT09ci5yKXRocm93IEguYihQLmE0
+KHIpKQp0PXQuY319LApFSDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz10aGlzLHI9SC5MaChzKQpyLmQu
+YihiKQpyLmNoWzFdLmIoYykKdD1zLmoyKGEsYikKaWYodD09bnVsbClzLkVJKGEsYixzLkhuKGIsYykp
+CmVsc2UgdC5iPWN9LAprczpmdW5jdGlvbigpe3RoaXMucj10aGlzLnIrMSY2NzEwODg2M30sCkhuOmZ1
+bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLHI9SC5MaChzKSxxPW5ldyBILmRiKHIuZC5iKGEpLHIuY2hb
+MV0uYihiKSkKaWYocy5lPT1udWxsKXMuZT1zLmY9cQplbHNle3Q9cy5mCnEuZD10CnMuZj10LmM9cX0r
+K3MuYQpzLmtzKCkKcmV0dXJuIHF9LApGaDpmdW5jdGlvbihhLGIpe3ZhciB0LHMKaWYoYT09bnVsbCly
+ZXR1cm4tMQp0PWEubGVuZ3RoCmZvcihzPTA7czx0OysrcylpZihKLlJNKGFbc10uYSxiKSlyZXR1cm4g
+cwpyZXR1cm4tMX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAubk8odGhpcyl9LApqMjpmdW5jdGlvbihh
+LGIpe3JldHVybiBhW2JdfSwKQnQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYVtiXX0sCkVJOmZ1bmN0aW9u
+KGEsYixjKXthW2JdPWN9LApybjpmdW5jdGlvbihhLGIpe2RlbGV0ZSBhW2JdfSwKWHU6ZnVuY3Rpb24o
+YSxiKXtyZXR1cm4gdGhpcy5qMihhLGIpIT1udWxsfSwKeks6ZnVuY3Rpb24oKXt2YXIgdD0iPG5vbi1p
+ZGVudGlmaWVyLWtleT4iLHM9T2JqZWN0LmNyZWF0ZShudWxsKQp0aGlzLkVJKHMsdCxzKQp0aGlzLnJu
+KHMsdCkKcmV0dXJuIHN9LAokaUZvOjF9CkguZGIucHJvdG90eXBlPXt9CkguaTUucHJvdG90eXBlPXsK
+Z0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5hfSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMu
+YSxzPW5ldyBILk42KHQsdC5yLHRoaXMuJHRpLkMoIk42PDE+IikpCnMuYz10LmUKcmV0dXJuIHN9LAp0
+ZzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEueDQoYil9fQpILk42LnByb3RvdHlwZT17CmdsOmZ1
+bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9dC5hCmlmKHQu
+YiE9PXMucil0aHJvdyBILmIoUC5hNChzKSkKZWxzZXtzPXQuYwppZihzPT1udWxsKXt0LnNxWShudWxs
+KQpyZXR1cm4hMX1lbHNle3Quc3FZKHMuYSkKdC5jPXQuYy5jCnJldHVybiEwfX19LApzcVk6ZnVuY3Rp
+b24oYSl7dGhpcy5kPXRoaXMuJHRpLmQuYihhKX0sCiRpQW46MX0KSC5kQy5wcm90b3R5cGU9ewokMTpm
+dW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hKGEpfSwKJFM6NH0KSC53Ti5wcm90b3R5cGU9ewokMjpmdW5j
+dGlvbihhLGIpe3JldHVybiB0aGlzLmEoYSxiKX0sCiRTOjQ3fQpILlZYLnByb3RvdHlwZT17CiQxOmZ1
+bmN0aW9uKGEpe3JldHVybiB0aGlzLmEoSC55KGEpKX0sCiRTOjQyfQpILlZSLnByb3RvdHlwZT17Cnc6
+ZnVuY3Rpb24oYSl7cmV0dXJuIlJlZ0V4cC8iK3RoaXMuYSsiLyIrdGhpcy5iLmZsYWdzfSwKZ0hjOmZ1
+bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQuYwppZihzIT1udWxsKXJldHVybiBzCnM9dC5iCnJldHVybiB0
+LmM9SC52NCh0LmEscy5tdWx0aWxpbmUsIXMuaWdub3JlQ2FzZSxzLnVuaWNvZGUscy5kb3RBbGwsITAp
+fSwKZGQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEguS1codGhpcyxiLDApfSwKVVo6ZnVuY3Rpb24o
+YSxiKXt2YXIgdCxzPXRoaXMuZ0hjKCkKcy5sYXN0SW5kZXg9Ygp0PXMuZXhlYyhhKQppZih0PT1udWxs
+KXJldHVybiBudWxsCnJldHVybiBuZXcgSC5FSyh0KX0sCiRpdlg6MSwKJGl3TDoxfQpILkVLLnByb3Rv
+dHlwZT17CnE6ZnVuY3Rpb24oYSxiKXt2YXIgdApILlNjKGIpCnQ9dGhpcy5iCmlmKGI+PXQubGVuZ3Ro
+KXJldHVybiBILk9IKHQsYikKcmV0dXJuIHRbYl19LAokaU9kOjEsCiRpaWI6MX0KSC5LVy5wcm90b3R5
+cGU9ewpna3o6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILlBiKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX19
+CkguUGIucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigp
+e3ZhciB0LHMscixxLHA9dGhpcyxvPXAuYgppZihvPT1udWxsKXJldHVybiExCnQ9cC5jCmlmKHQ8PW8u
+bGVuZ3RoKXtzPXAuYQpyPXMuVVoobyx0KQppZihyIT1udWxsKXtwLmQ9cgpvPXIuYgp0PW8uaW5kZXgK
+cT10K29bMF0ubGVuZ3RoCmlmKHQ9PT1xKXtpZihzLmIudW5pY29kZSl7bz1wLmMKdD1vKzEKcz1wLmIK
+aWYodDxzLmxlbmd0aCl7bz1KLnJZKHMpLm0ocyxvKQppZihvPj01NTI5NiYmbzw9NTYzMTkpe289Qy54
+Qi5tKHMsdCkKbz1vPj01NjMyMCYmbzw9NTczNDN9ZWxzZSBvPSExfWVsc2Ugbz0hMX1lbHNlIG89ITEK
+cT0obz9xKzE6cSkrMX1wLmM9cQpyZXR1cm4hMH19cC5iPXAuZD1udWxsCnJldHVybiExfSwKJGlBbjox
+fQpILnRRLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCmlmKGIhPT0wKUgudmgoUC54
+KGIsbnVsbCkpCnJldHVybiB0aGlzLmN9LAokaU9kOjF9CkgudW4ucHJvdG90eXBlPXsKZ2t6OmZ1bmN0
+aW9uKGEpe3JldHVybiBuZXcgSC5TZCh0aGlzLmEsdGhpcy5iLHRoaXMuYyl9fQpILlNkLnByb3RvdHlw
+ZT17CkY6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcyxxPXIuYyxwPXIuYixvPXAubGVuZ3RoLG49ci5h
+LG09bi5sZW5ndGgKaWYocStvPm0pe3IuZD1udWxsCnJldHVybiExfXQ9bi5pbmRleE9mKHAscSkKaWYo
+dDwwKXtyLmM9bSsxCnIuZD1udWxsCnJldHVybiExfXM9dCtvCnIuZD1uZXcgSC50USh0LHApCnIuYz1z
+PT09ci5jP3MrMTpzCnJldHVybiEwfSwKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKJGlBbjox
+fQpILkVULnByb3RvdHlwZT17JGlFVDoxLCRpQVM6MX0KSC5iMC5wcm90b3R5cGU9ewpnQTpmdW5jdGlv
+bihhKXtyZXR1cm4gYS5sZW5ndGh9LAokaVhqOjF9CkguRGcucHJvdG90eXBlPXsKcTpmdW5jdGlvbihh
+LGIpe0guU2MoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIs
+Yyl7SC5JZyhjKQpILm9kKGIsYSxhLmxlbmd0aCkKYVtiXT1jfSwKJGliUToxLAokaWNYOjEsCiRpek06
+MX0KSC5QZy5wcm90b3R5cGU9ewpZOmZ1bmN0aW9uKGEsYixjKXtILlNjKGMpCkgub2QoYixhLGEubGVu
+Z3RoKQphW2JdPWN9LAokaWJROjEsCiRpY1g6MSwKJGl6TToxfQpILnhqLnByb3RvdHlwZT17CnE6ZnVu
+Y3Rpb24oYSxiKXtILlNjKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguZEUucHJv
+dG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBh
+W2JdfX0KSC5aQS5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQpILm9kKGIsYSxhLmxl
+bmd0aCkKcmV0dXJuIGFbYl19fQpILndmLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIp
+Ckgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguUHEucHJvdG90eXBlPXsKcTpmdW5jdGlv
+bihhLGIpe0guU2MoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5lRS5wcm90b3R5
+cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC5TYyhi
+KQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILlY2LnByb3RvdHlwZT17CmdBOmZ1bmN0
+aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCkgub2QoYixhLGEu
+bGVuZ3RoKQpyZXR1cm4gYVtiXX0sCiRpVjY6MSwKJGluNjoxfQpILlJHLnByb3RvdHlwZT17fQpILlZQ
+LnByb3RvdHlwZT17fQpILldCLnByb3RvdHlwZT17fQpILlpHLnByb3RvdHlwZT17fQpILkpjLnByb3Rv
+dHlwZT17CkM6ZnVuY3Rpb24oYSl7cmV0dXJuIEguY0Uodi50eXBlVW5pdmVyc2UsdGhpcyxhKX0sCktx
+OmZ1bmN0aW9uKGEpe3JldHVybiBILnY1KHYudHlwZVVuaXZlcnNlLHRoaXMsYSl9fQpILkcucHJvdG90
+eXBlPXt9CkgudTkucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfX0KSC5oei5w
+cm90b3R5cGU9e30KSC5pTS5wcm90b3R5cGU9e30KUC50aC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihh
+KXt2YXIgdD10aGlzLmEscz10LmEKdC5hPW51bGwKcy4kMCgpfSwKJFM6MTJ9ClAuaGEucHJvdG90eXBl
+PXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscwp0aGlzLmEuYT11Lk0uYihhKQp0PXRoaXMuYgpzPXRoaXMu
+Ywp0LmZpcnN0Q2hpbGQ/dC5yZW1vdmVDaGlsZChzKTp0LmFwcGVuZENoaWxkKHMpfSwKJFM6Mzd9ClAu
+VnMucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuJDAoKX0sCiRDOiIkMCIsCiRSOjAsCiRT
+OjB9ClAuRnQucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuJDAoKX0sCiRDOiIkMCIsCiRS
+OjAsCiRTOjB9ClAuVzMucHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSxiKXtpZihzZWxmLnNldFRpbWVv
+dXQhPW51bGwpc2VsZi5zZXRUaW1lb3V0KEgudFIobmV3IFAueUgodGhpcyxiKSwwKSxhKQplbHNlIHRo
+cm93IEguYihQLkw0KCJgc2V0VGltZW91dCgpYCBub3QgZm91bmQuIikpfX0KUC55SC5wcm90b3R5cGU9
+ewokMDpmdW5jdGlvbigpe3RoaXMuYi4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6Mn0KUC5paC5wcm90
+b3R5cGU9ewphTTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj10aGlzLiR0aQpyLkMoIjEvIikuYihiKQp0
+PSF0aGlzLmJ8fHIuQygiYjg8MT4iKS5jKGIpCnM9dGhpcy5hCmlmKHQpcy5YZihiKQplbHNlIHMuWDIo
+ci5kLmIoYikpfSwKdzA6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmEKaWYodGhpcy5iKXQuWkwoYSxi
+KQplbHNlIHQuTmsoYSxiKX19ClAuV00ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRo
+aXMuYS4kMigwLGEpfSwKJFM6MjF9ClAuU1gucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlz
+LmEuJDIoMSxuZXcgSC5icShhLHUubC5iKGIpKSl9LAokQzoiJDIiLAokUjoyLAokUzoyNn0KUC5Hcy5w
+cm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYShILlNjKGEpLGIpfSwKJFM6Mjd9ClAuRnku
+cHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iSXRlcmF0aW9uTWFya2VyKCIrdGhpcy5iKyIs
+ICIrSC5kKHRoaXMuYSkrIikifX0KUC5HVi5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3ZhciB0PXRo
+aXMuYwppZih0PT1udWxsKXJldHVybiB0aGlzLmIKcmV0dXJuIHRoaXMuJHRpLmQuYih0LmdsKCkpfSwK
+RjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcwpmb3IoOyEwOyl7dD1wLmMKaWYodCE9bnVsbClp
+Zih0LkYoKSlyZXR1cm4hMAplbHNlIHAuYz1udWxsCnM9ZnVuY3Rpb24oYSxiLGMpe3ZhciBvLG49Ygp3
+aGlsZSh0cnVlKXRyeXtyZXR1cm4gYShuLG8pfWNhdGNoKG0pe289bQpuPWN9fShwLmEsMCwxKQppZihz
+IGluc3RhbmNlb2YgUC5GeSl7cj1zLmIKaWYocj09PTIpe3Q9cC5kCmlmKHQ9PW51bGx8fHQubGVuZ3Ro
+PT09MCl7cC5zRUMobnVsbCkKcmV0dXJuITF9aWYoMD49dC5sZW5ndGgpcmV0dXJuIEguT0godCwtMSkK
+cC5hPXQucG9wKCkKY29udGludWV9ZWxzZXt0PXMuYQppZihyPT09Myl0aHJvdyB0CmVsc2V7cT1KLklU
+KHQpCmlmKHEgaW5zdGFuY2VvZiBQLkdWKXt0PXAuZAppZih0PT1udWxsKXQ9cC5kPVtdCkMuTm0uaSh0
+LHAuYSkKcC5hPXEuYQpjb250aW51ZX1lbHNle3AuYz1xCmNvbnRpbnVlfX19fWVsc2V7cC5zRUMocykK
+cmV0dXJuITB9fXJldHVybiExfSwKc0VDOmZ1bmN0aW9uKGEpe3RoaXMuYj10aGlzLiR0aS5kLmIoYSl9
+LAokaUFuOjF9ClAucTQucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5HVih0
+aGlzLmEoKSx0aGlzLiR0aS5DKCJHVjwxPiIpKX19ClAuYjgucHJvdG90eXBlPXt9ClAuUGYucHJvdG90
+eXBlPXsKdzA6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihhPT1udWxsKWE9bmV3IFAubigpCnQ9dGhpcy5h
+CmlmKHQuYSE9PTApdGhyb3cgSC5iKFAuUFYoIkZ1dHVyZSBhbHJlYWR5IGNvbXBsZXRlZCIpKQp0Lk5r
+KGEsYil9LApwbTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy53MChhLG51bGwpfX0KUC5aZi5wcm90b3R5
+cGU9ewphTTpmdW5jdGlvbihhLGIpe3ZhciB0CnRoaXMuJHRpLkMoIjEvIikuYihiKQp0PXRoaXMuYQpp
+Zih0LmEhPT0wKXRocm93IEguYihQLlBWKCJGdXR1cmUgYWxyZWFkeSBjb21wbGV0ZWQiKSkKdC5YZihi
+KX19ClAuRmUucHJvdG90eXBlPXsKSFI6ZnVuY3Rpb24oYSl7aWYoKHRoaXMuYyYxNSkhPT02KXJldHVy
+biEwCnJldHVybiB0aGlzLmIuYi5idih1LmFsLmIodGhpcy5kKSxhLmEsdS5jSix1LkspfSwKS3c6ZnVu
+Y3Rpb24oYSl7dmFyIHQ9dGhpcy5lLHM9dS56LHI9dS5LLHE9dGhpcy4kdGkuQygiMi8iKSxwPXRoaXMu
+Yi5iCmlmKHUuRi5jKHQpKXJldHVybiBxLmIocC5ycCh0LGEuYSxhLmIscyxyLHUubCkpCmVsc2UgcmV0
+dXJuIHEuYihwLmJ2KHUueS5iKHQpLGEuYSxzLHIpKX19ClAudnMucHJvdG90eXBlPXsKU3E6ZnVuY3Rp
+b24oYSxiLGMpe3ZhciB0LHMscixxPXRoaXMuJHRpCnEuS3EoYykuQygiMS8oMikiKS5iKGEpCnQ9JC5Y
+MwppZih0IT09Qy5OVSl7Yy5DKCJAPDAvPiIpLktxKHEuZCkuQygiMSgyKSIpLmIoYSkKaWYoYiE9bnVs
+bCliPVAuVkgoYix0KX1zPW5ldyBQLnZzKCQuWDMsYy5DKCJ2czwwPiIpKQpyPWI9PW51bGw/MTozCnRo
+aXMueGYobmV3IFAuRmUocyxyLGEsYixxLkMoIkA8MT4iKS5LcShjKS5DKCJGZTwxLDI+IikpKQpyZXR1
+cm4gc30sClc3OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuU3EoYSxudWxsLGIpfSwKUWQ6ZnVuY3Rp
+b24oYSxiLGMpe3ZhciB0LHM9dGhpcy4kdGkKcy5LcShjKS5DKCIxLygyKSIpLmIoYSkKdD1uZXcgUC52
+cygkLlgzLGMuQygidnM8MD4iKSkKdGhpcy54ZihuZXcgUC5GZSh0LChiPT1udWxsPzE6Myl8MTYsYSxi
 LHMuQygiQDwxPiIpLktxKGMpLkMoIkZlPDEsMj4iKSkpCnJldHVybiB0fSwKT0E6ZnVuY3Rpb24oYSl7
-dmFyIHQscyxyCnUuYjcuYShudWxsKQp0PXRoaXMuJHRpCnM9JC5YMwpyPW5ldyBQLnZzKHMsdCkKaWYo
+dmFyIHQscyxyCnUuYmYuYihudWxsKQp0PXRoaXMuJHRpCnM9JC5YMwpyPW5ldyBQLnZzKHMsdCkKaWYo
 cyE9PUMuTlUpYT1QLlZIKGEscykKdGhpcy54ZihuZXcgUC5GZShyLDIsbnVsbCxhLHQuQygiQDwxPiIp
-LktxKHQuYykuQygiRmU8MSwyPiIpKSkKcmV0dXJuIHJ9LAp4ZjpmdW5jdGlvbihhKXt2YXIgdCxzPXRo
-aXMscj1zLmEKaWYocjw9MSl7YS5hPXUuRi5hKHMuYykKcy5jPWF9ZWxzZXtpZihyPT09Mil7dD11LmMu
-YShzLmMpCnI9dC5hCmlmKHI8NCl7dC54ZihhKQpyZXR1cm59cy5hPXIKcy5jPXQuY31QLlRrKG51bGws
-bnVsbCxzLmIsdS5NLmEobmV3IFAuZGEocyxhKSkpfX0sCmpROmZ1bmN0aW9uKGEpe3ZhciB0LHMscixx
-LHAsbyxuPXRoaXMsbT17fQptLmE9YQppZihhPT1udWxsKXJldHVybgp0PW4uYQppZih0PD0xKXtzPXUu
-Ri5hKG4uYykKbi5jPWEKaWYocyE9bnVsbCl7cj1hLmEKZm9yKHE9YTtyIT1udWxsO3E9cixyPXApcD1y
-LmEKcS5hPXN9fWVsc2V7aWYodD09PTIpe289dS5jLmEobi5jKQp0PW8uYQppZih0PDQpe28ualEoYSkK
-cmV0dXJufW4uYT10Cm4uYz1vLmN9bS5hPW4uTjgoYSkKUC5UayhudWxsLG51bGwsbi5iLHUuTS5hKG5l
-dyBQLm9RKG0sbikpKX19LAphaDpmdW5jdGlvbigpe3ZhciB0PXUuRi5hKHRoaXMuYykKdGhpcy5jPW51
-bGwKcmV0dXJuIHRoaXMuTjgodCl9LApOODpmdW5jdGlvbihhKXt2YXIgdCxzLHIKZm9yKHQ9YSxzPW51
-bGw7dCE9bnVsbDtzPXQsdD1yKXtyPXQuYQp0LmE9c31yZXR1cm4gc30sCkhIOmZ1bmN0aW9uKGEpe3Zh
-ciB0LHM9dGhpcyxyPXMuJHRpCnIuQygiMS8iKS5hKGEpCmlmKHIuQygiYjg8MT4iKS5iKGEpKWlmKHIu
-YihhKSlQLkE5KGEscykKZWxzZSBQLmszKGEscykKZWxzZXt0PXMuYWgoKQpyLmMuYShhKQpzLmE9NApz
-LmM9YQpQLkhaKHMsdCl9fSwKWDI6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzCnMuJHRpLmMuYShhKQp0
-PXMuYWgoKQpzLmE9NApzLmM9YQpQLkhaKHMsdCl9LApaTDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj10
-aGlzCnUubC5hKGIpCnQ9ci5haCgpCnM9UC5UbChhLGIpCnIuYT04CnIuYz1zClAuSFoocix0KX0sClhm
-OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuJHRpCnQuQygiMS8iKS5hKGEpCmlmKHQuQygiYjg8MT4iKS5i
-KGEpKXt0aGlzLmNVKGEpCnJldHVybn10aGlzLndVKHQuYy5hKGEpKX0sCndVOmZ1bmN0aW9uKGEpe3Zh
-ciB0PXRoaXMKdC4kdGkuYy5hKGEpCnQuYT0xClAuVGsobnVsbCxudWxsLHQuYix1Lk0uYShuZXcgUC5y
-dCh0LGEpKSl9LApjVTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLHM9dC4kdGkKcy5DKCJiODwxPiIpLmEo
-YSkKaWYocy5iKGEpKXtpZihhLmE9PT04KXt0LmE9MQpQLlRrKG51bGwsbnVsbCx0LmIsdS5NLmEobmV3
-IFAuS0YodCxhKSkpfWVsc2UgUC5BOShhLHQpCnJldHVybn1QLmszKGEsdCl9LApOazpmdW5jdGlvbihh
-LGIpe3RoaXMuYT0xClAuVGsobnVsbCxudWxsLHRoaXMuYix1Lk0uYShuZXcgUC5aTCh0aGlzLGEsYikp
-KX0sCiRpYjg6MX0KUC5kYS5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe1AuSFoodGhpcy5hLHRoaXMu
-Yil9LAokUzowfQpQLm9RLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7UC5IWih0aGlzLmIsdGhpcy5h
-LmEpfSwKJFM6MH0KUC5wVi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKdC5h
-PTAKdC5ISChhKX0sCiRTOjExfQpQLlU3LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dS5sLmEo
-YikKdGhpcy5hLlpMKGEsYil9LAokQzoiJDIiLAokUjoyLAokUzozOH0KUC52ci5wcm90b3R5cGU9ewok
-MDpmdW5jdGlvbigpe3RoaXMuYS5aTCh0aGlzLmIsdGhpcy5jKX0sCiRTOjB9ClAucnQucHJvdG90eXBl
-PXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuWDIodGhpcy5iKX0sCiRTOjB9ClAuS0YucHJvdG90eXBlPXsK
-JDA6ZnVuY3Rpb24oKXtQLkE5KHRoaXMuYix0aGlzLmEpfSwKJFM6MH0KUC5aTC5wcm90b3R5cGU9ewok
-MDpmdW5jdGlvbigpe3RoaXMuYS5aTCh0aGlzLmIsdGhpcy5jKX0sCiRTOjB9ClAuUlQucHJvdG90eXBl
-PXsKJDA6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbj10aGlzLG09bnVsbAp0cnl7cj1uLmEuYQpt
-PXIuYi5iLnp6KHUuZk8uYShyLmQpLHUueil9Y2F0Y2gocSl7dD1ILlJ1KHEpCnM9SC50cyhxKQppZihu
-LmMpe3I9dS5uLmEobi5iLmEuYykuYQpwPXQKcD1yPT1udWxsP3A9PW51bGw6cj09PXAKcj1wfWVsc2Ug
-cj0hMQpwPW4uYQppZihyKXAuYz11Lm4uYShuLmIuYS5jKQplbHNlIHAuYz1QLlRsKHQscykKcC5iPSEw
-CnJldHVybn1pZihtIGluc3RhbmNlb2YgUC52cyYmbS5hPj00KXtpZihtLmE9PT04KXtyPW4uYQpyLmM9
-dS5uLmEobS5jKQpyLmI9ITB9cmV0dXJufWlmKHUuZC5iKG0pKXtvPW4uYi5hCnI9bi5hCnIuYz1tLlc3
-KG5ldyBQLmpaKG8pLHUueikKci5iPSExfX0sCiRTOjF9ClAualoucHJvdG90eXBlPXsKJDE6ZnVuY3Rp
-b24oYSl7cmV0dXJuIHRoaXMuYX0sCiRTOjM5fQpQLnJxLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7
-dmFyIHQscyxyLHEscCxvLG4sbQp0cnl7cj10aGlzLmEKcT1yLmEKcD1xLiR0aQpvPXAuYwpuPW8uYSh0
-aGlzLmIpCnIuYz1xLmIuYi5idihwLkMoIjIvKDEpIikuYShxLmQpLG4scC5DKCIyLyIpLG8pfWNhdGNo
-KG0pe3Q9SC5SdShtKQpzPUgudHMobSkKcj10aGlzLmEKci5jPVAuVGwodCxzKQpyLmI9ITB9fSwKJFM6
-MX0KUC5SVy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuLG0sbD10aGlz
-CnRyeXt0PXUubi5hKGwuYS5hLmMpCnE9bC5iCmlmKEgub1QocS5hLkhSKHQpKSYmcS5hLmUhPW51bGwp
-e3EuYz1xLmEuS3codCkKcS5iPSExfX1jYXRjaChwKXtzPUguUnUocCkKcj1ILnRzKHApCnE9dS5uLmEo
-bC5hLmEuYykKbz1xLmEKbj1zCm09bC5iCmlmKG89PW51bGw/bj09bnVsbDpvPT09biltLmM9cQplbHNl
-IG0uYz1QLlRsKHMscikKbS5iPSEwfX0sCiRTOjF9ClAuT00ucHJvdG90eXBlPXt9ClAucWgucHJvdG90
-eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPXRoaXMscT17fSxwPW5ldyBQLnZzKCQuWDMsdS5m
-SikKcS5hPTAKdD1ILkxoKHIpCnM9dC5DKCJ+KDEpPyIpLmEobmV3IFAuQjUocSxyKSkKdS5aLmEobmV3
-IFAudU8ocSxwKSkKVy5KRShyLmEsci5iLHMsITEsdC5jKQpyZXR1cm4gcH19ClAuQjUucHJvdG90eXBl
-PXsKJDE6ZnVuY3Rpb24oYSl7SC5MaCh0aGlzLmIpLmMuYShhKTsrK3RoaXMuYS5hfSwKJFM6ZnVuY3Rp
-b24oKXtyZXR1cm4gSC5MaCh0aGlzLmIpLkMoImM4KDEpIil9fQpQLnVPLnByb3RvdHlwZT17CiQwOmZ1
-bmN0aW9uKCl7dGhpcy5iLkhIKHRoaXMuYS5hKX0sCiRTOjB9ClAuTU8ucHJvdG90eXBlPXt9ClAua1Qu
-cHJvdG90eXBlPXt9ClAueEkucHJvdG90eXBlPXt9ClAuQ3cucHJvdG90eXBlPXsKdzpmdW5jdGlvbihh
-KXtyZXR1cm4gSC5Faih0aGlzLmEpfSwKJGlYUzoxLApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5i
-fX0KUC5tMC5wcm90b3R5cGU9eyRpSkI6MX0KUC5wSy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3Zh
-ciB0PUguYih0aGlzLmEpCnQuc3RhY2s9Si5qKHRoaXMuYikKdGhyb3cgdH0sCiRTOjB9ClAuSmkucHJv
-dG90eXBlPXsKYkg6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9bnVsbAp1Lk0uYShhKQp0cnl7aWYoQy5O
-VT09PSQuWDMpe2EuJDAoKQpyZXR1cm59UC5UOChxLHEsdGhpcyxhLHUuSCl9Y2F0Y2gocil7dD1ILlJ1
-KHIpCnM9SC50cyhyKQpQLkwyKHEscSx0aGlzLHQsdS5sLmEocykpfX0sCkRsOmZ1bmN0aW9uKGEsYixj
-KXt2YXIgdCxzLHIscT1udWxsCmMuQygifigwKSIpLmEoYSkKYy5hKGIpCnRyeXtpZihDLk5VPT09JC5Y
-Myl7YS4kMShiKQpyZXR1cm59UC55dihxLHEsdGhpcyxhLGIsdS5ILGMpfWNhdGNoKHIpe3Q9SC5SdShy
-KQpzPUgudHMocikKUC5MMihxLHEsdGhpcyx0LHUubC5hKHMpKX19LApSVDpmdW5jdGlvbihhLGIpe3Jl
-dHVybiBuZXcgUC5oaih0aGlzLGIuQygiMCgpIikuYShhKSxiKX0sCkdZOmZ1bmN0aW9uKGEpe3JldHVy
-biBuZXcgUC5WcCh0aGlzLHUuTS5hKGEpKX0sClB5OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQLk9S
-KHRoaXMsYi5DKCJ+KDApIikuYShhKSxiKX0sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbnVsbH0sCnp6
-OmZ1bmN0aW9uKGEsYil7Yi5DKCIwKCkiKS5hKGEpCmlmKCQuWDM9PT1DLk5VKXJldHVybiBhLiQwKCkK
-cmV0dXJuIFAuVDgobnVsbCxudWxsLHRoaXMsYSxiKX0sCmJ2OmZ1bmN0aW9uKGEsYixjLGQpe2MuQygi
-QDwwPiIpLktxKGQpLkMoIjEoMikiKS5hKGEpCmQuYShiKQppZigkLlgzPT09Qy5OVSlyZXR1cm4gYS4k
-MShiKQpyZXR1cm4gUC55dihudWxsLG51bGwsdGhpcyxhLGIsYyxkKX0sCnJwOmZ1bmN0aW9uKGEsYixj
-LGQsZSxmKXtkLkMoIkA8MD4iKS5LcShlKS5LcShmKS5DKCIxKDIsMykiKS5hKGEpCmUuYShiKQpmLmEo
-YykKaWYoJC5YMz09PUMuTlUpcmV0dXJuIGEuJDIoYixjKQpyZXR1cm4gUC5ReChudWxsLG51bGwsdGhp
-cyxhLGIsYyxkLGUsZil9LApMajpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gYi5DKCJAPDA+IikuS3Eo
-YykuS3EoZCkuQygiMSgyLDMpIikuYShhKX19ClAuaGoucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXty
-ZXR1cm4gdGhpcy5hLnp6KHRoaXMuYix0aGlzLmMpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5j
-LkMoIjAoKSIpfX0KUC5WcC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuYkgo
-dGhpcy5iKX0sCiRTOjF9ClAuT1IucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5j
-CnJldHVybiB0aGlzLmEuRGwodGhpcy5iLHQuYShhKSx0KX0sCiRTOmZ1bmN0aW9uKCl7cmV0dXJuIHRo
-aXMuYy5DKCJ+KDApIil9fQpQLmI2LnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlz
-LHM9bmV3IFAubG0odCx0LnIsSC5MaCh0KS5DKCJsbTwxPiIpKQpzLmM9dC5lCnJldHVybiBzfSwKZ0E6
-ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYX0sCnRnOmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZihiIT09
-Il9fcHJvdG9fXyIpe3Q9dGhpcy5iCmlmKHQ9PW51bGwpcmV0dXJuITEKcmV0dXJuIHUuSi5hKHRbYl0p
-IT1udWxsfWVsc2V7cz10aGlzLlBSKGIpCnJldHVybiBzfX0sClBSOmZ1bmN0aW9uKGEpe3ZhciB0PXRo
-aXMuZAppZih0PT1udWxsKXJldHVybiExCnJldHVybiB0aGlzLkRGKHRbdGhpcy5OKGEpXSxhKT49MH0s
-Cmk6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9dGhpcwpILkxoKHIpLmMuYShiKQppZih0eXBlb2YgYj09
-InN0cmluZyImJmIhPT0iX19wcm90b19fIil7dD1yLmIKcmV0dXJuIHIuUyh0PT1udWxsP3IuYj1QLlQy
-KCk6dCxiKX1lbHNlIGlmKHR5cGVvZiBiPT0ibnVtYmVyIiYmKGImMTA3Mzc0MTgyMyk9PT1iKXtzPXIu
-YwpyZXR1cm4gci5TKHM9PW51bGw/ci5jPVAuVDIoKTpzLGIpfWVsc2UgcmV0dXJuIHIuQjcoYil9LApC
-NzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT10aGlzCkguTGgocSkuYy5hKGEpCnQ9cS5kCmlmKHQ9PW51
-bGwpdD1xLmQ9UC5UMigpCnM9cS5OKGEpCnI9dFtzXQppZihyPT1udWxsKXRbc109W3EueW8oYSldCmVs
-c2V7aWYocS5ERihyLGEpPj0wKXJldHVybiExCnIucHVzaChxLnlvKGEpKX1yZXR1cm4hMH0sClI6ZnVu
-Y3Rpb24oYSxiKXt2YXIgdD10aGlzCmlmKHR5cGVvZiBiPT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18i
-KXJldHVybiB0LkwodC5iLGIpCmVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYxMDczNzQxODIz
-KT09PWIpcmV0dXJuIHQuTCh0LmMsYikKZWxzZSByZXR1cm4gdC5xZyhiKX0sCnFnOmZ1bmN0aW9uKGEp
-e3ZhciB0LHMscixxLHA9dGhpcyxvPXAuZAppZihvPT1udWxsKXJldHVybiExCnQ9cC5OKGEpCnM9b1t0
-XQpyPXAuREYocyxhKQppZihyPDApcmV0dXJuITEKcT1zLnNwbGljZShyLDEpWzBdCmlmKDA9PT1zLmxl
-bmd0aClkZWxldGUgb1t0XQpwLkdTKHEpCnJldHVybiEwfSwKUzpmdW5jdGlvbihhLGIpe0guTGgodGhp
-cykuYy5hKGIpCmlmKHUuSi5hKGFbYl0pIT1udWxsKXJldHVybiExCmFbYl09dGhpcy55byhiKQpyZXR1
-cm4hMH0sCkw6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihhPT1udWxsKXJldHVybiExCnQ9dS5KLmEoYVti
-XSkKaWYodD09bnVsbClyZXR1cm4hMQp0aGlzLkdTKHQpCmRlbGV0ZSBhW2JdCnJldHVybiEwfSwKWDpm
-dW5jdGlvbigpe3RoaXMucj0xMDczNzQxODIzJnRoaXMucisxfSwKeW86ZnVuY3Rpb24oYSl7dmFyIHQs
-cz10aGlzLHI9bmV3IFAuYm4oSC5MaChzKS5jLmEoYSkpCmlmKHMuZT09bnVsbClzLmU9cy5mPXIKZWxz
-ZXt0PXMuZgp0LnRvU3RyaW5nCnIuYz10CnMuZj10LmI9cn0rK3MuYQpzLlgoKQpyZXR1cm4gcn0sCkdT
-OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz1hLmMscj1hLmIKaWYocz09bnVsbCl0LmU9cgplbHNlIHMu
-Yj1yCmlmKHI9PW51bGwpdC5mPXMKZWxzZSByLmM9czstLXQuYQp0LlgoKX0sCk46ZnVuY3Rpb24oYSl7
-cmV0dXJuIEouaGYoYSkmMTA3Mzc0MTgyM30sCkRGOmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZihhPT1u
-dWxsKXJldHVybi0xCnQ9YS5sZW5ndGgKZm9yKHM9MDtzPHQ7KytzKWlmKEouUk0oYVtzXS5hLGIpKXJl
-dHVybiBzCnJldHVybi0xfX0KUC5ibi5wcm90b3R5cGU9e30KUC5sbS5wcm90b3R5cGU9ewpnbDpmdW5j
-dGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQuYyxyPXQuYQpp
-Zih0LmIhPT1yLnIpdGhyb3cgSC5iKFAuYTQocikpCmVsc2UgaWYocz09bnVsbCl7dC5zaihudWxsKQpy
-ZXR1cm4hMX1lbHNle3Quc2oodC4kdGkuQygiMT8iKS5hKHMuYSkpCnQuYz1zLmIKcmV0dXJuITB9fSwK
-c2o6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLkMoIjE/IikuYShhKX0sCiRpQW46MX0KUC5tVy5w
-cm90b3R5cGU9e30KUC5MVS5wcm90b3R5cGU9eyRpYlE6MSwkaWNYOjEsJGl6TToxfQpQLmxELnByb3Rv
-dHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguYTcoYSx0aGlzLmdBKGEpLEgueihhKS5D
-KCJhNzxsRC5FPiIpKX0sCkU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5xKGEsYil9LApLOmZ1bmN0
-aW9uKGEsYil7dmFyIHQscwpILnooYSkuQygifihsRC5FKSIpLmEoYikKdD10aGlzLmdBKGEpCmZvcihz
-PTA7czx0Oysrcyl7Yi4kMSh0aGlzLnEoYSxzKSkKaWYodCE9PXRoaXMuZ0EoYSkpdGhyb3cgSC5iKFAu
-YTQoYSkpfX0sCkUyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILnooYSkKcmV0dXJuIG5ldyBILmxKKGEs
-dC5LcShjKS5DKCIxKGxELkUpIikuYShiKSx0LkMoIkA8bEQuRT4iKS5LcShjKS5DKCJsSjwxLDI+Iikp
-fSwKZHU6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQKSC56KGEpLkMoImxELkU/IikuYShkKQpQLmpCKGIs
-Yyx0aGlzLmdBKGEpKQpmb3IodD1iO3Q8YzsrK3QpdGhpcy5ZKGEsdCxkKX0sCnc6ZnVuY3Rpb24oYSl7
-cmV0dXJuIFAuV0UoYSwiWyIsIl0iKX19ClAuaWwucHJvdG90eXBlPXt9ClAucmEucHJvdG90eXBlPXsK
-JDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMuYQppZighcy5hKXRoaXMuYi5hKz0iLCAiCnMuYT0h
-MQpzPXRoaXMuYgp0PXMuYSs9SC5FaihhKQpzLmE9dCsiOiAiCnMuYSs9SC5FaihiKX0sCiRTOjQzfQpQ
-LllrLnByb3RvdHlwZT17Cks6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCkguTGgodGhpcykuQygifihZay5L
-LFlrLlYpIikuYShiKQpmb3IodD1KLklUKHRoaXMuZ1YoKSk7dC5GKCk7KXtzPXQuZ2woKQpiLiQyKHMs
-dGhpcy5xKDAscykpfX0sCmdQdTpmdW5jdGlvbihhKXtyZXR1cm4gSi5NMSh0aGlzLmdWKCksbmV3IFAu
-eVEodGhpcyksSC5MaCh0aGlzKS5DKCJOMzxZay5LLFlrLlY+IikpfSwKeDQ6ZnVuY3Rpb24oYSl7cmV0
-dXJuIEouemwodGhpcy5nVigpLGEpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIEouSG0odGhpcy5nVigp
-KX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAubk8odGhpcyl9LAokaVowOjF9ClAueVEucHJvdG90eXBl
-PXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hLHM9SC5MaCh0KQpzLkMoIllrLksiKS5hKGEpCnJl
-dHVybiBuZXcgUC5OMyhhLHQucSgwLGEpLHMuQygiQDxZay5LPiIpLktxKHMuQygiWWsuViIpKS5DKCJO
-MzwxLDI+IikpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm4gSC5MaCh0aGlzLmEpLkMoIk4zPFlrLkssWWsu
-Vj4oWWsuSykiKX19ClAuS1AucHJvdG90eXBlPXsKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0
-aGlzKQp0LmMuYShiKQp0LlFbMV0uYShjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSB1bm1v
-ZGlmaWFibGUgbWFwIikpfX0KUC5Qbi5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRo
-aXMuYS5xKDAsYil9LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILkxoKHRoaXMpCnRoaXMuYS5ZKDAs
-dC5jLmEoYiksdC5RWzFdLmEoYykpfSwKeDQ6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS54NChhKX0s
-Cks6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuSygwLEguTGgodGhpcykuQygifigxLDIpIikuYShiKSl9LApn
-QTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0dXJuIHQuZ0EodCl9LAp3OmZ1bmN0aW9uKGEpe3Jl
-dHVybiBKLmoodGhpcy5hKX0sCmdQdTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0dXJuIHQuZ1B1
-KHQpfSwKJGlaMDoxfQpQLkdqLnByb3RvdHlwZT17fQpQLk1hLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24o
-YSl7cmV0dXJuIFAuV0UodGhpcywieyIsIn0iKX19ClAuVmoucHJvdG90eXBlPXskaWJROjEsJGljWDox
-LCRpeHU6MX0KUC5Ydi5wcm90b3R5cGU9ewpGVjpmdW5jdGlvbihhLGIpe3ZhciB0CmZvcih0PUouSVQo
-SC5MaCh0aGlzKS5DKCJjWDwxPiIpLmEoYikpO3QuRigpOyl0aGlzLmkoMCx0LmdsKCkpfSwKdzpmdW5j
-dGlvbihhKXtyZXR1cm4gUC5XRSh0aGlzLCJ7IiwifSIpfSwKelY6ZnVuY3Rpb24oYSxiKXt2YXIgdCxz
-PVAucmoodGhpcyx0aGlzLnIsSC5MaCh0aGlzKS5jKQppZighcy5GKCkpcmV0dXJuIiIKaWYoYj09PSIi
-KXt0PSIiCmRvIHQrPUguRWoocy5kKQp3aGlsZShzLkYoKSl9ZWxzZXt0PSIiK0guRWoocy5kKQpmb3Io
-O3MuRigpOyl0PXQrYitILkVqKHMuZCl9cmV0dXJuIHQuY2hhckNvZGVBdCgwKT09MD90OnR9LAokaWJR
-OjEsCiRpY1g6MSwKJGl4dToxfQpQLm5ZLnByb3RvdHlwZT17fQpQLldZLnByb3RvdHlwZT17fQpQLlJV
-LnByb3RvdHlwZT17fQpQLnV3LnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMu
-YgppZihzPT1udWxsKXJldHVybiB0aGlzLmMucSgwLGIpCmVsc2UgaWYodHlwZW9mIGIhPSJzdHJpbmci
-KXJldHVybiBudWxsCmVsc2V7dD1zW2JdCnJldHVybiB0eXBlb2YgdD09InVuZGVmaW5lZCI/dGhpcy5m
-YihiKTp0fX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmI9PW51bGw/dGhpcy5jLmE6dGhpcy5D
-ZigpLmxlbmd0aH0sCmdWOmZ1bmN0aW9uKCl7aWYodGhpcy5iPT1udWxsKXt2YXIgdD10aGlzLmMKcmV0
-dXJuIG5ldyBILmk1KHQsSC5MaCh0KS5DKCJpNTwxPiIpKX1yZXR1cm4gbmV3IFAuaTgodGhpcyl9LApZ
-OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHI9dGhpcwppZihyLmI9PW51bGwpci5jLlkoMCxiLGMpCmVs
-c2UgaWYoci54NChiKSl7dD1yLmIKdFtiXT1jCnM9ci5hCmlmKHM9PW51bGw/dCE9bnVsbDpzIT09dClz
-W2JdPW51bGx9ZWxzZSByLlhLKCkuWSgwLGIsYyl9LAp4NDpmdW5jdGlvbihhKXtpZih0aGlzLmI9PW51
-bGwpcmV0dXJuIHRoaXMuYy54NChhKQpyZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0
-eS5jYWxsKHRoaXMuYSxhKX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwPXRoaXMKdS5jQS5h
-KGIpCmlmKHAuYj09bnVsbClyZXR1cm4gcC5jLksoMCxiKQp0PXAuQ2YoKQpmb3Iocz0wO3M8dC5sZW5n
-dGg7KytzKXtyPXRbc10KcT1wLmJbcl0KaWYodHlwZW9mIHE9PSJ1bmRlZmluZWQiKXtxPVAuUWUocC5h
-W3JdKQpwLmJbcl09cX1iLiQyKHIscSkKaWYodCE9PXAuYyl0aHJvdyBILmIoUC5hNChwKSl9fSwKQ2Y6
-ZnVuY3Rpb24oKXt2YXIgdD11LmJNLmEodGhpcy5jKQppZih0PT1udWxsKXQ9dGhpcy5jPUguVk0oT2Jq
-ZWN0LmtleXModGhpcy5hKSx1LnMpCnJldHVybiB0fSwKWEs6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxw
-LG89dGhpcwppZihvLmI9PW51bGwpcmV0dXJuIG8uYwp0PVAuRmwodS5OLHUueikKcz1vLkNmKCkKZm9y
-KHI9MDtxPXMubGVuZ3RoLHI8cTsrK3Ipe3A9c1tyXQp0LlkoMCxwLG8ucSgwLHApKX1pZihxPT09MClD
-Lk5tLmkocywiIikKZWxzZSBDLk5tLnNBKHMsMCkKby5hPW8uYj1udWxsCnJldHVybiBvLmM9dH0sCmZi
-OmZ1bmN0aW9uKGEpe3ZhciB0CmlmKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwo
-dGhpcy5hLGEpKXJldHVybiBudWxsCnQ9UC5RZSh0aGlzLmFbYV0pCnJldHVybiB0aGlzLmJbYV09dH19
-ClAuaTgucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0LmdBKHQp
-fSwKRTpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYQppZih0LmI9PW51bGwpdD10LmdWKCkuRSgwLGIp
-CmVsc2V7dD10LkNmKCkKaWYoYjwwfHxiPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LGIpCnQ9dFtiXX1y
-ZXR1cm4gdH0sCmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKaWYodC5iPT1udWxsKXt0PXQuZ1Yo
-KQp0PXQuZ2t6KHQpfWVsc2V7dD10LkNmKCkKdD1uZXcgSi5tMSh0LHQubGVuZ3RoLEgudDYodCkuQygi
-bTE8MT4iKSl9cmV0dXJuIHR9LAp0ZzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEueDQoYil9fQpQ
-LnBnLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHQscwp0cnl7dD1uZXcgVGV4dERlY29kZXIo
-InV0Zi04Iix7ZmF0YWw6dHJ1ZX0pCnJldHVybiB0fWNhdGNoKHMpe0guUnUocyl9cmV0dXJuIG51bGx9
-LAokUzo0NX0KUC5DVi5wcm90b3R5cGU9ewp5cjpmdW5jdGlvbihhLGEwLGExKXt2YXIgdCxzLHIscSxw
-LG8sbixtLGwsayxqLGksaCxnLGYsZSxkLGMsYj0iSW52YWxpZCBiYXNlNjQgZW5jb2RpbmcgbGVuZ3Ro
-ICIKYTE9UC5qQihhMCxhMSxhLmxlbmd0aCkKdD0kLlY3KCkKZm9yKHM9YTAscj1zLHE9bnVsbCxwPS0x
-LG89LTEsbj0wO3M8YTE7cz1tKXttPXMrMQpsPUMueEIuVyhhLHMpCmlmKGw9PT0zNyl7az1tKzIKaWYo
-azw9YTEpe2o9SC5vbyhDLnhCLlcoYSxtKSkKaT1ILm9vKEMueEIuVyhhLG0rMSkpCmg9aioxNitpLShp
-JjI1NikKaWYoaD09PTM3KWg9LTEKbT1rfWVsc2UgaD0tMX1lbHNlIGg9bAppZigwPD1oJiZoPD0xMjcp
-e2lmKGg8MHx8aD49dC5sZW5ndGgpcmV0dXJuIEguT0godCxoKQpnPXRbaF0KaWYoZz49MCl7aD1DLnhC
-Lm0oIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIz
-NDU2Nzg5Ky8iLGcpCmlmKGg9PT1sKWNvbnRpbnVlCmw9aH1lbHNle2lmKGc9PT0tMSl7aWYocDwwKXtm
-PXE9PW51bGw/bnVsbDpxLmEubGVuZ3RoCmlmKGY9PW51bGwpZj0wCnA9Zisocy1yKQpvPXN9KytuCmlm
-KGw9PT02MSljb250aW51ZX1sPWh9aWYoZyE9PS0yKXtpZihxPT1udWxsKXtxPW5ldyBQLlJuKCIiKQpm
-PXF9ZWxzZSBmPXEKZi5hKz1DLnhCLk5qKGEscixzKQpmLmErPUguTHcobCkKcj1tCmNvbnRpbnVlfX10
-aHJvdyBILmIoUC5ycigiSW52YWxpZCBiYXNlNjQgZGF0YSIsYSxzKSl9aWYocSE9bnVsbCl7Zj1xLmEr
-PUMueEIuTmooYSxyLGExKQplPWYubGVuZ3RoCmlmKHA+PTApUC54TShhLG8sYTEscCxuLGUpCmVsc2V7
-ZD1DLmpuLnpZKGUtMSw0KSsxCmlmKGQ9PT0xKXRocm93IEguYihQLnJyKGIsYSxhMSkpCmZvcig7ZDw0
-Oyl7Zis9Ij0iCnEuYT1mOysrZH19Zj1xLmEKcmV0dXJuIEMueEIuaTcoYSxhMCxhMSxmLmNoYXJDb2Rl
-QXQoMCk9PTA/ZjpmKX1jPWExLWEwCmlmKHA+PTApUC54TShhLG8sYTEscCxuLGMpCmVsc2V7ZD1DLmpu
-LnpZKGMsNCkKaWYoZD09PTEpdGhyb3cgSC5iKFAucnIoYixhLGExKSkKaWYoZD4xKWE9Qy54Qi5pNyhh
-LGExLGExLGQ9PT0yPyI9PSI6Ij0iKX1yZXR1cm4gYX19ClAuVTgucHJvdG90eXBlPXt9ClAuVWsucHJv
-dG90eXBlPXt9ClAud0kucHJvdG90eXBlPXt9ClAuWmkucHJvdG90eXBlPXt9ClAuYnkucHJvdG90eXBl
-PXsKcFc6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CnUuZlYuYShjKQp0PVAuQlMoYix0aGlzLmdIZSgpLmEp
-CnJldHVybiB0fSwKZ0hlOmZ1bmN0aW9uKCl7cmV0dXJuIEMuQTN9fQpQLk14LnByb3RvdHlwZT17fQpQ
-LnU1LnByb3RvdHlwZT17CmdaRTpmdW5jdGlvbigpe3JldHVybiBDLlFrfX0KUC5FMy5wcm90b3R5cGU9
-ewpXSjpmdW5jdGlvbihhKXt2YXIgdCxzLHI9UC5qQigwLG51bGwsYS5sZW5ndGgpLHE9ci0wCmlmKHE9
-PT0wKXJldHVybiBuZXcgVWludDhBcnJheSgwKQp0PW5ldyBVaW50OEFycmF5KHEqMykKcz1uZXcgUC5S
-dyh0KQppZihzLkd4KGEsMCxyKSE9PXIpcy5PNihKLmE2KGEsci0xKSwwKQpyZXR1cm4gbmV3IFVpbnQ4
-QXJyYXkodC5zdWJhcnJheSgwLEguck0oMCxzLmIsdC5sZW5ndGgpKSl9fQpQLlJ3LnByb3RvdHlwZT17
-Ck82OmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLHI9cy5jLHE9cy5iLHA9cSsxLG89ci5sZW5ndGgK
-aWYoKGImNjQ1MTIpPT09NTYzMjApe3Q9NjU1MzYrKChhJjEwMjMpPDwxMCl8YiYxMDIzCnMuYj1wCmlm
-KHE+PW8pcmV0dXJuIEguT0gocixxKQpyW3FdPTI0MHx0Pj4+MTgKcT1zLmI9cCsxCmlmKHA+PW8pcmV0
-dXJuIEguT0gocixwKQpyW3BdPTEyOHx0Pj4+MTImNjMKcD1zLmI9cSsxCmlmKHE+PW8pcmV0dXJuIEgu
-T0gocixxKQpyW3FdPTEyOHx0Pj4+NiY2MwpzLmI9cCsxCmlmKHA+PW8pcmV0dXJuIEguT0gocixwKQpy
-W3BdPTEyOHx0JjYzCnJldHVybiEwfWVsc2V7cy5iPXAKaWYocT49bylyZXR1cm4gSC5PSChyLHEpCnJb
-cV09MjI0fGE+Pj4xMgpxPXMuYj1wKzEKaWYocD49bylyZXR1cm4gSC5PSChyLHApCnJbcF09MTI4fGE+
-Pj42JjYzCnMuYj1xKzEKaWYocT49bylyZXR1cm4gSC5PSChyLHEpCnJbcV09MTI4fGEmNjMKcmV0dXJu
-ITF9fSwKR3g6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuLG09dGhpcwppZihiIT09YyYm
-KEMueEIubShhLGMtMSkmNjQ1MTIpPT09NTUyOTYpLS1jCmZvcih0PW0uYyxzPXQubGVuZ3RoLHI9Yjty
-PGM7KytyKXtxPUMueEIuVyhhLHIpCmlmKHE8PTEyNyl7cD1tLmIKaWYocD49cylicmVhawptLmI9cCsx
-CnRbcF09cX1lbHNlIGlmKChxJjY0NTEyKT09PTU1Mjk2KXtpZihtLmIrMz49cylicmVhawpvPXIrMQpp
-ZihtLk82KHEsQy54Qi5XKGEsbykpKXI9b31lbHNlIGlmKHE8PTIwNDcpe3A9bS5iCm49cCsxCmlmKG4+
-PXMpYnJlYWsKbS5iPW4KaWYocD49cylyZXR1cm4gSC5PSCh0LHApCnRbcF09MTkyfHE+Pj42Cm0uYj1u
-KzEKdFtuXT0xMjh8cSY2M31lbHNle3A9bS5iCmlmKHArMj49cylicmVhawpuPW0uYj1wKzEKaWYocD49
-cylyZXR1cm4gSC5PSCh0LHApCnRbcF09MjI0fHE+Pj4xMgpwPW0uYj1uKzEKaWYobj49cylyZXR1cm4g
-SC5PSCh0LG4pCnRbbl09MTI4fHE+Pj42JjYzCm0uYj1wKzEKaWYocD49cylyZXR1cm4gSC5PSCh0LHAp
-CnRbcF09MTI4fHEmNjN9fXJldHVybiByfX0KUC5HWS5wcm90b3R5cGU9ewpXSjpmdW5jdGlvbihhKXt2
-YXIgdCxzLHIscSxwLG8sbixtLGwKdS5MLmEoYSkKdD1QLmt5KCExLGEsMCxudWxsKQppZih0IT1udWxs
-KXJldHVybiB0CnM9UC5qQigwLG51bGwsSi5IbShhKSkKcj1QLmNQKGEsMCxzKQppZihyPjApe3E9UC5I
-TShhLDAscikKaWYocj09PXMpcmV0dXJuIHEKcD1uZXcgUC5SbihxKQpvPXIKbj0hMX1lbHNle3A9bmV3
-IFAuUm4oIiIpCm89MApuPSEwfW09bmV3IFAuYnooITEscCkKbS5jPW4KbS5NRShhLG8scykKdS5lZy5h
-KGEpCmlmKG0uZT4wKXtILnZoKFAucnIoIlVuZmluaXNoZWQgVVRGLTggb2N0ZXQgc2VxdWVuY2UiLGEs
-cykpCnAuYSs9SC5Mdyg2NTUzMykKbS5mPW0uZT1tLmQ9MH1sPXAuYQpyZXR1cm4gbC5jaGFyQ29kZUF0
-KDApPT0wP2w6bH19ClAuYnoucHJvdG90eXBlPXsKTUU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixx
-LHAsbyxuLG0sbCxrLGosaSxoPXRoaXMsZz0iQmFkIFVURi04IGVuY29kaW5nIDB4Igp1LkwuYShhKQp0
-PWguZApzPWguZQpyPWguZgpoLmY9aC5lPWguZD0wCiRsYWJlbDAkMDpmb3IocT1KLlU2KGEpLHA9aC5i
-LG89YjshMDtvPWopeyRsYWJlbDEkMTppZihzPjApe2Rve2lmKG89PT1jKWJyZWFrICRsYWJlbDAkMApu
-PXEucShhLG8pCmlmKHR5cGVvZiBuIT09Im51bWJlciIpcmV0dXJuIG4uek0oKQppZigobiYxOTIpIT09
-MTI4KXttPVAucnIoZytDLmpuLldaKG4sMTYpLGEsbykKdGhyb3cgSC5iKG0pfWVsc2V7dD0odDw8Nnxu
-JjYzKT4+PjA7LS1zOysrb319d2hpbGUocz4wKQptPXItMQppZihtPDB8fG0+PTQpcmV0dXJuIEguT0go
-Qy5HYixtKQppZih0PD1DLkdiW21dKXttPVAucnIoIk92ZXJsb25nIGVuY29kaW5nIG9mIDB4IitDLmpu
-LldaKHQsMTYpLGEsby1yLTEpCnRocm93IEguYihtKX1pZih0PjExMTQxMTEpe209UC5ycigiQ2hhcmFj
-dGVyIG91dHNpZGUgdmFsaWQgVW5pY29kZSByYW5nZTogMHgiK0Muam4uV1oodCwxNiksYSxvLXItMSkK
-dGhyb3cgSC5iKG0pfWlmKCFoLmN8fHQhPT02NTI3OSlwLmErPUguTHcodCkKaC5jPSExfWZvcihtPW88
-YzttOyl7bD1QLmNQKGEsbyxjKQppZihsPjApe2guYz0hMQprPW8rbApwLmErPVAuSE0oYSxvLGspCmlm
-KGs9PT1jKWJyZWFrfWVsc2Ugaz1vCmo9aysxCm49cS5xKGEsaykKaWYodHlwZW9mIG4hPT0ibnVtYmVy
-IilyZXR1cm4gbi5KKCkKaWYobjwwKXtpPVAucnIoIk5lZ2F0aXZlIFVURi04IGNvZGUgdW5pdDogLTB4
-IitDLmpuLldaKC1uLDE2KSxhLGotMSkKdGhyb3cgSC5iKGkpfWVsc2V7aWYoKG4mMjI0KT09PTE5Mil7
-dD1uJjMxCnM9MQpyPTEKY29udGludWUgJGxhYmVsMCQwfWlmKChuJjI0MCk9PT0yMjQpe3Q9biYxNQpz
-PTIKcj0yCmNvbnRpbnVlICRsYWJlbDAkMH1pZigobiYyNDgpPT09MjQwJiZuPDI0NSl7dD1uJjcKcz0z
-CnI9Mwpjb250aW51ZSAkbGFiZWwwJDB9aT1QLnJyKGcrQy5qbi5XWihuLDE2KSxhLGotMSkKdGhyb3cg
-SC5iKGkpfX1icmVhayAkbGFiZWwwJDB9aWYocz4wKXtoLmQ9dApoLmU9cwpoLmY9cn19fQpQLldGLnBy
-b3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCnUuZm8uYShhKQp0PXRoaXMuYgpzPXRo
-aXMuYQp0LmErPXMuYQpyPXQuYSs9SC5FaihhLmEpCnQuYT1yKyI6ICIKdC5hKz1QLnAoYikKcy5hPSIs
-ICJ9LAokUzo0Nn0KUC5hMi5wcm90b3R5cGU9e30KUC5pUC5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihh
-LGIpe2lmKGI9PW51bGwpcmV0dXJuITEKcmV0dXJuIGIgaW5zdGFuY2VvZiBQLmlQJiZ0aGlzLmE9PT1i
-LmEmJiEwfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4odF5DLmpuLndHKHQsMzAp
-KSYxMDczNzQxODIzfSwKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLHM9UC5HcShILnRKKHQpKSxyPVAu
-aDAoSC5OUyh0KSkscT1QLmgwKEguakEodCkpLHA9UC5oMChILklYKHQpKSxvPVAuaDAoSC5jaCh0KSks
-bj1QLmgwKEguSmQodCkpLG09UC5WeChILm8xKHQpKSxsPXMrIi0iK3IrIi0iK3ErIiAiK3ArIjoiK28r
-IjoiK24rIi4iK20KcmV0dXJuIGx9fQpQLkNQLnByb3RvdHlwZT17fQpQLlhTLnByb3RvdHlwZT17CmdJ
-STpmdW5jdGlvbigpe3JldHVybiBILnRzKHRoaXMuJHRocm93bkpzRXJyb3IpfX0KUC5DNi5wcm90b3R5
-cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQppZih0IT1udWxsKXJldHVybiJBc3NlcnRpb24g
-ZmFpbGVkOiAiK1AucCh0KQpyZXR1cm4iQXNzZXJ0aW9uIGZhaWxlZCJ9fQpQLm4ucHJvdG90eXBlPXsK
-dzpmdW5jdGlvbihhKXtyZXR1cm4iVGhyb3cgb2YgbnVsbC4ifX0KUC51LnByb3RvdHlwZT17CmdaOmZ1
-bmN0aW9uKCl7cmV0dXJuIkludmFsaWQgYXJndW1lbnQiKyghdGhpcy5hPyIocykiOiIiKX0sCmd1OmZ1
-bmN0aW9uKCl7cmV0dXJuIiJ9LAp3OmZ1bmN0aW9uKGEpe3ZhciB0LHMscj10aGlzLHE9ci5jLHA9cT09
-bnVsbD8iIjoiICgiK3ErIikiLG89ci5kLG49bz09bnVsbD8iIjoiOiAiK0guRWoobyksbT1yLmdaKCkr
-cCtuCmlmKCFyLmEpcmV0dXJuIG0KdD1yLmd1KCkKcz1QLnAoci5iKQpyZXR1cm4gbSt0KyI6ICIrc319
-ClAuYkoucHJvdG90eXBlPXsKZ1o6ZnVuY3Rpb24oKXtyZXR1cm4iUmFuZ2VFcnJvciJ9LApndTpmdW5j
-dGlvbigpe3ZhciB0LHM9dGhpcy5lLHI9dGhpcy5mCmlmKHM9PW51bGwpdD1yIT1udWxsPyI6IE5vdCBs
-ZXNzIHRoYW4gb3IgZXF1YWwgdG8gIitILkVqKHIpOiIiCmVsc2UgaWYocj09bnVsbCl0PSI6IE5vdCBn
-cmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gIitILkVqKHMpCmVsc2UgaWYocj5zKXQ9IjogTm90IGluIHJh
-bmdlICIrSC5FaihzKSsiLi4iK0guRWoocikrIiwgaW5jbHVzaXZlIgplbHNlIHQ9cjxzPyI6IFZhbGlk
-IHZhbHVlIHJhbmdlIGlzIGVtcHR5IjoiOiBPbmx5IHZhbGlkIHZhbHVlIGlzICIrSC5FaihzKQpyZXR1
-cm4gdH19ClAuZVkucHJvdG90eXBlPXsKZ1o6ZnVuY3Rpb24oKXtyZXR1cm4iUmFuZ2VFcnJvciJ9LApn
-dTpmdW5jdGlvbigpe3ZhciB0LHM9SC51UCh0aGlzLmIpCmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0
-dXJuIHMuSigpCmlmKHM8MClyZXR1cm4iOiBpbmRleCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSIKdD10aGlz
-LmYKaWYodD09PTApcmV0dXJuIjogbm8gaW5kaWNlcyBhcmUgdmFsaWQiCnJldHVybiI6IGluZGV4IHNo
-b3VsZCBiZSBsZXNzIHRoYW4gIit0fSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZn19ClAubXAu
-cHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9dGhpcyxrPXt9LGo9
-bmV3IFAuUm4oIiIpCmsuYT0iIgp0PWwuYwpmb3Iocz10Lmxlbmd0aCxyPTAscT0iIixwPSIiO3I8czsr
-K3IscD0iLCAiKXtvPXRbcl0Kai5hPXErcApxPWouYSs9UC5wKG8pCmsuYT0iLCAifWwuZC5LKDAsbmV3
-IFAuV0YoayxqKSkKbj1QLnAobC5hKQptPWoudygwKQpzPSJOb1N1Y2hNZXRob2RFcnJvcjogbWV0aG9k
-IG5vdCBmb3VuZDogJyIrSC5FaihsLmIuYSkrIidcblJlY2VpdmVyOiAiK24rIlxuQXJndW1lbnRzOiBb
-IittKyJdIgpyZXR1cm4gc319ClAudWIucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iVW5z
-dXBwb3J0ZWQgb3BlcmF0aW9uOiAiK3RoaXMuYX19ClAuZHMucHJvdG90eXBlPXsKdzpmdW5jdGlvbihh
-KXt2YXIgdD10aGlzLmEKcmV0dXJuIHQhPW51bGw/IlVuaW1wbGVtZW50ZWRFcnJvcjogIit0OiJVbmlt
-cGxlbWVudGVkRXJyb3IifX0KUC5sai5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJCYWQg
-c3RhdGU6ICIrdGhpcy5hfX0KUC5VVi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMu
-YQppZih0PT1udWxsKXJldHVybiJDb25jdXJyZW50IG1vZGlmaWNhdGlvbiBkdXJpbmcgaXRlcmF0aW9u
-LiIKcmV0dXJuIkNvbmN1cnJlbnQgbW9kaWZpY2F0aW9uIGR1cmluZyBpdGVyYXRpb246ICIrUC5wKHQp
-KyIuIn19ClAuazUucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iT3V0IG9mIE1lbW9yeSJ9
-LApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH0sCiRpWFM6MX0KUC5LWS5wcm90b3R5cGU9ewp3OmZ1
-bmN0aW9uKGEpe3JldHVybiJTdGFjayBPdmVyZmxvdyJ9LApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gbnVs
-bH0sCiRpWFM6MX0KUC5jLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVy
-biB0PT1udWxsPyJSZWFkaW5nIHN0YXRpYyB2YXJpYWJsZSBkdXJpbmcgaXRzIGluaXRpYWxpemF0aW9u
-IjoiUmVhZGluZyBzdGF0aWMgdmFyaWFibGUgJyIrdCsiJyBkdXJpbmcgaXRzIGluaXRpYWxpemF0aW9u
-In19ClAuQ0QucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iRXhjZXB0aW9uOiAiK3RoaXMu
-YX19ClAuYUUucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxq
-LGksaD10aGlzLmEsZz1oIT1udWxsJiYiIiE9PWg/IkZvcm1hdEV4Y2VwdGlvbjogIitILkVqKGgpOiJG
-b3JtYXRFeGNlcHRpb24iLGY9dGhpcy5jLGU9dGhpcy5iCmlmKHR5cGVvZiBlPT0ic3RyaW5nIil7aWYo
-ZiE9bnVsbCl0PWY8MHx8Zj5lLmxlbmd0aAplbHNlIHQ9ITEKaWYodClmPW51bGwKaWYoZj09bnVsbCl7
-aWYoZS5sZW5ndGg+NzgpZT1DLnhCLk5qKGUsMCw3NSkrIi4uLiIKcmV0dXJuIGcrIlxuIitlfWZvcihz
-PTEscj0wLHE9ITEscD0wO3A8ZjsrK3Ape289Qy54Qi5XKGUscCkKaWYobz09PTEwKXtpZihyIT09cHx8
-IXEpKytzCnI9cCsxCnE9ITF9ZWxzZSBpZihvPT09MTMpeysrcwpyPXArMQpxPSEwfX1nPXM+MT9nKygi
-IChhdCBsaW5lICIrcysiLCBjaGFyYWN0ZXIgIisoZi1yKzEpKyIpXG4iKTpnKygiIChhdCBjaGFyYWN0
-ZXIgIisoZisxKSsiKVxuIikKbj1lLmxlbmd0aApmb3IocD1mO3A8bjsrK3Ape289Qy54Qi5tKGUscCkK
-aWYobz09PTEwfHxvPT09MTMpe249cApicmVha319aWYobi1yPjc4KWlmKGYtcjw3NSl7bT1yKzc1Cmw9
-cgprPSIiCmo9Ii4uLiJ9ZWxzZXtpZihuLWY8NzUpe2w9bi03NQptPW4Kaj0iIn1lbHNle2w9Zi0zNgpt
-PWYrMzYKaj0iLi4uIn1rPSIuLi4ifWVsc2V7bT1uCmw9cgprPSIiCmo9IiJ9aT1DLnhCLk5qKGUsbCxt
-KQpyZXR1cm4gZytrK2kraisiXG4iK0MueEIuSXgoIiAiLGYtbCtrLmxlbmd0aCkrIl5cbiJ9ZWxzZSBy
-ZXR1cm4gZiE9bnVsbD9nKygiIChhdCBvZmZzZXQgIitILkVqKGYpKyIpIik6Z319ClAuRUgucHJvdG90
-eXBlPXt9ClAuSWYucHJvdG90eXBlPXt9ClAuY1gucHJvdG90eXBlPXsKRTI6ZnVuY3Rpb24oYSxiLGMp
-e3ZhciB0PUguTGgodGhpcykKcmV0dXJuIEguSzEodGhpcyx0LktxKGMpLkMoIjEoY1guRSkiKS5hKGIp
-LHQuQygiY1guRSIpLGMpfSwKZXY6ZnVuY3Rpb24oYSxiKXt2YXIgdD1ILkxoKHRoaXMpCnJldHVybiBu
-ZXcgSC5VNSh0aGlzLHQuQygiYTIoY1guRSkiKS5hKGIpLHQuQygiVTU8Y1guRT4iKSl9LApnQTpmdW5j
-dGlvbihhKXt2YXIgdCxzPXRoaXMuZ2t6KHRoaXMpCmZvcih0PTA7cy5GKCk7KSsrdApyZXR1cm4gdH0s
-CmdsMDpmdW5jdGlvbihhKXtyZXR1cm4hdGhpcy5na3oodGhpcykuRigpfSwKZ3I4OmZ1bmN0aW9uKGEp
-e3ZhciB0LHM9dGhpcy5na3oodGhpcykKaWYoIXMuRigpKXRocm93IEguYihILldwKCkpCnQ9cy5nbCgp
-CmlmKHMuRigpKXRocm93IEguYihILmRVKCkpCnJldHVybiB0fSwKRTpmdW5jdGlvbihhLGIpe3ZhciB0
-LHMscgpQLmsxKGIsImluZGV4IikKZm9yKHQ9dGhpcy5na3oodGhpcykscz0wO3QuRigpOyl7cj10Lmds
-KCkKaWYoYj09PXMpcmV0dXJuIHI7KytzfXRocm93IEguYihQLkNmKGIsdGhpcywiaW5kZXgiLG51bGws
-cykpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gUC5FUCh0aGlzLCIoIiwiKSIpfX0KUC5Bbi5wcm90b3R5
-cGU9e30KUC56TS5wcm90b3R5cGU9eyRpYlE6MSwkaWNYOjF9ClAuWjAucHJvdG90eXBlPXt9ClAuTjMu
-cHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iTWFwRW50cnkoIitILkVqKEouaih0aGlzLmEp
-KSsiOiAiK0guRWooSi5qKHRoaXMuYikpKyIpIn19ClAuYzgucHJvdG90eXBlPXsKZ2lPOmZ1bmN0aW9u
-KGEpe3JldHVybiBQLk1oLnByb3RvdHlwZS5naU8uY2FsbCh0aGlzLHRoaXMpfSwKdzpmdW5jdGlvbihh
-KXtyZXR1cm4ibnVsbCJ9fQpQLmxmLnByb3RvdHlwZT17fQpQLk1oLnByb3RvdHlwZT17Y29uc3RydWN0
-b3I6UC5NaCwkaU1oOjEsCkROOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXM9PT1ifSwKZ2lPOmZ1bmN0
-aW9uKGEpe3JldHVybiBILmVRKHRoaXMpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4iSW5zdGFuY2Ugb2Yg
-JyIrSC5FaihILk0odGhpcykpKyInIn0sCmU3OmZ1bmN0aW9uKGEsYil7dS5vLmEoYikKdGhyb3cgSC5i
-KFAubHIodGhpcyxiLmdXYSgpLGIuZ25kKCksYi5nVm0oKSkpfSwKdG9TdHJpbmc6ZnVuY3Rpb24oKXty
-ZXR1cm4gdGhpcy53KHRoaXMpfX0KUC5PZC5wcm90b3R5cGU9e30KUC5pYi5wcm90b3R5cGU9eyRpT2Q6
-MX0KUC54dS5wcm90b3R5cGU9e30KUC5Hei5wcm90b3R5cGU9e30KUC5aZC5wcm90b3R5cGU9ewp3OmZ1
-bmN0aW9uKGEpe3JldHVybiIifSwKJGlHejoxfQpQLnFVLnByb3RvdHlwZT17JGl2WDoxfQpQLlJuLnBy
-b3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEubGVuZ3RofSwKdzpmdW5jdGlvbihh
-KXt2YXIgdD10aGlzLmEKcmV0dXJuIHQuY2hhckNvZGVBdCgwKT09MD90OnR9LAokaUJMOjF9ClAuR0Qu
-cHJvdG90eXBlPXt9ClAubjEucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscQp1
-LmYuYShhKQpILmgoYikKdD1KLnJZKGIpLk9ZKGIsIj0iKQppZih0PT09LTEpe2lmKGIhPT0iIilhLlko
-MCxQLmt1KGIsMCxiLmxlbmd0aCx0aGlzLmEsITApLCIiKX1lbHNlIGlmKHQhPT0wKXtzPUMueEIuTmoo
-YiwwLHQpCnI9Qy54Qi5HKGIsdCsxKQpxPXRoaXMuYQphLlkoMCxQLmt1KHMsMCxzLmxlbmd0aCxxLCEw
-KSxQLmt1KHIsMCxyLmxlbmd0aCxxLCEwKSl9cmV0dXJuIGF9LAokUzoxOX0KUC5jUy5wcm90b3R5cGU9
-ewokMjpmdW5jdGlvbihhLGIpe3Rocm93IEguYihQLnJyKCJJbGxlZ2FsIElQdjQgYWRkcmVzcywgIith
-LHRoaXMuYSxiKSl9LAokUzo1MH0KUC5WQy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3Rocm93
-IEguYihQLnJyKCJJbGxlZ2FsIElQdjYgYWRkcmVzcywgIithLHRoaXMuYSxiKSl9LAokMTpmdW5jdGlv
-bihhKXtyZXR1cm4gdGhpcy4kMihhLG51bGwpfSwKJFM6NTF9ClAuSlQucHJvdG90eXBlPXsKJDI6ZnVu
-Y3Rpb24oYSxiKXt2YXIgdAppZihiLWE+NCl0aGlzLmEuJDIoImFuIElQdjYgcGFydCBjYW4gb25seSBj
-b250YWluIGEgbWF4aW11bSBvZiA0IGhleCBkaWdpdHMiLGEpCnQ9UC5RQShDLnhCLk5qKHRoaXMuYixh
-LGIpLDE2KQppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkooKQppZih0PDB8fHQ+NjU1MzUp
-dGhpcy5hLiQyKCJlYWNoIHBhcnQgbXVzdCBiZSBpbiB0aGUgcmFuZ2Ugb2YgYDB4MC4uMHhGRkZGYCIs
-YSkKcmV0dXJuIHR9LAokUzoyMH0KUC5Ebi5wcm90b3R5cGU9ewpnbkQ6ZnVuY3Rpb24oKXt2YXIgdCxz
-LHIscT10aGlzLHA9cS54CmlmKHA9PW51bGwpe3A9cS5hCnQ9cC5sZW5ndGghPT0wPyIiK3ArIjoiOiIi
-CnM9cS5jCnI9cz09bnVsbAppZighcnx8cD09PSJmaWxlIil7cD10KyIvLyIKdD1xLmIKaWYodC5sZW5n
-dGghPT0wKXA9cCt0KyJAIgppZighcilwKz1zCnQ9cS5kCmlmKHQhPW51bGwpcD1wKyI6IitILkVqKHQp
-fWVsc2UgcD10CnArPXEuZQp0PXEuZgppZih0IT1udWxsKXA9cCsiPyIrdAp0PXEucgppZih0IT1udWxs
-KXA9cCsiIyIrdApwPXAuY2hhckNvZGVBdCgwKT09MD9wOnAKaWYocS54PT1udWxsKXEueD1wCmVsc2Ug
-cD1ILnZoKEgueVIoIkZpZWxkICdfdGV4dCcgaGFzIGJlZW4gYXNzaWduZWQgZHVyaW5nIGluaXRpYWxp
-emF0aW9uLiIpKX1yZXR1cm4gcH0sCmdGajpmdW5jdGlvbigpe3ZhciB0LHM9dGhpcyxyPXMueQppZihy
-PT1udWxsKXt0PXMuZQppZih0Lmxlbmd0aCE9PTAmJkMueEIuVyh0LDApPT09NDcpdD1DLnhCLkcodCwx
-KQpyPXQubGVuZ3RoPT09MD9DLnhEOlAuQUYobmV3IEgubEooSC5WTSh0LnNwbGl0KCIvIiksdS5zKSx1
-LmRPLmEoUC5QSCgpKSx1LmRvKSx1Lk4pCmlmKHMueT09bnVsbClzLnNLcChyKQplbHNlIHI9SC52aChI
-LnlSKCJGaWVsZCAncGF0aFNlZ21lbnRzJyBoYXMgYmVlbiBhc3NpZ25lZCBkdXJpbmcgaW5pdGlhbGl6
-YXRpb24uIikpfXJldHVybiByfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz10LnoKaWYocz09
-bnVsbCl7cz1DLnhCLmdpTyh0LmduRCgpKQppZih0Lno9PW51bGwpdC56PXMKZWxzZSBzPUgudmgoSC55
-UigiRmllbGQgJ2hhc2hDb2RlJyBoYXMgYmVlbiBhc3NpZ25lZCBkdXJpbmcgaW5pdGlhbGl6YXRpb24u
-IikpfXJldHVybiBzfSwKZ2hZOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQuUQppZihzPT1udWxsKXtz
-PW5ldyBQLkdqKFAuV1godC5ndFAoKSksdS5kdykKaWYodC5RPT1udWxsKXQuc05NKHMpCmVsc2Ugcz1I
-LnZoKEgueVIoIkZpZWxkICdxdWVyeVBhcmFtZXRlcnMnIGhhcyBiZWVuIGFzc2lnbmVkIGR1cmluZyBp
-bml0aWFsaXphdGlvbi4iKSl9cmV0dXJuIHN9LApna3U6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5ifSwK
-Z0pmOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwppZih0PT1udWxsKXJldHVybiIiCmlmKEMueEIubih0
-LCJbIikpcmV0dXJuIEMueEIuTmoodCwxLHQubGVuZ3RoLTEpCnJldHVybiB0fSwKZ3RwOmZ1bmN0aW9u
-KGEpe3ZhciB0PXRoaXMuZApyZXR1cm4gdD09bnVsbD9QLndLKHRoaXMuYSk6dH0sCmd0UDpmdW5jdGlv
-bigpe3ZhciB0PXRoaXMuZgpyZXR1cm4gdD09bnVsbD8iIjp0fSwKZ0thOmZ1bmN0aW9uKCl7dmFyIHQ9
-dGhpcy5yCnJldHVybiB0PT1udWxsPyIiOnR9LApubTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAs
-byxuLG0sbCxrPXRoaXMKdS5VLmEobnVsbCkKdS5jOS5hKGIpCnQ9ay5hCnM9dD09PSJmaWxlIgpyPWsu
-YgpxPWsuZApwPWsuYwppZighKHAhPW51bGwpKXA9ci5sZW5ndGghPT0wfHxxIT1udWxsfHxzPyIiOm51
-bGwKbz1rLmUKaWYoIXMpbj1wIT1udWxsJiZvLmxlbmd0aCE9PTAKZWxzZSBuPSEwCmlmKG4mJiFDLnhC
-Lm4obywiLyIpKW89Ii8iK28KbT1vCmw9UC5sZShudWxsLDAsMCxiKQpyZXR1cm4gbmV3IFAuRG4odCxy
-LHAscSxtLGwsay5yKX0sCkpoOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvCmZvcih0PTAscz0w
-O0MueEIuUWkoYiwiLi4vIixzKTspe3MrPTM7Kyt0fXI9Qy54Qi5jbihhLCIvIikKd2hpbGUoITApe2lm
-KCEocj4wJiZ0PjApKWJyZWFrCnE9Qy54Qi5QayhhLCIvIixyLTEpCmlmKHE8MClicmVhawpwPXItcQpv
-PXAhPT0yCmlmKCFvfHxwPT09MylpZihDLnhCLm0oYSxxKzEpPT09NDYpbz0hb3x8Qy54Qi5tKGEscSsy
-KT09PTQ2CmVsc2Ugbz0hMQplbHNlIG89ITEKaWYobylicmVhazstLXQKcj1xfXJldHVybiBDLnhCLmk3
-KGEscisxLG51bGwsQy54Qi5HKGIscy0zKnQpKX0sClpJOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLm1T
-KFAuaEsoYSkpfSwKbVM6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGs9dGhpcyxqPW51
-bGwKaWYoYS5nRmkoKS5sZW5ndGghPT0wKXt0PWEuZ0ZpKCkKaWYoYS5nY2ooKSl7cz1hLmdrdSgpCnI9
-YS5nSmYoYSkKcT1hLmd4QSgpP2EuZ3RwKGEpOmp9ZWxzZXtxPWoKcj1xCnM9IiJ9cD1QLnhlKGEuZ0lp
-KGEpKQpvPWEuZ1FEKCk/YS5ndFAoKTpqfWVsc2V7dD1rLmEKaWYoYS5nY2ooKSl7cz1hLmdrdSgpCnI9
-YS5nSmYoYSkKcT1QLndCKGEuZ3hBKCk/YS5ndHAoYSk6aix0KQpwPVAueGUoYS5nSWkoYSkpCm89YS5n
-UUQoKT9hLmd0UCgpOmp9ZWxzZXtzPWsuYgpyPWsuYwpxPWsuZAppZihhLmdJaShhKT09PSIiKXtwPWsu
-ZQpvPWEuZ1FEKCk/YS5ndFAoKTprLmZ9ZWxzZXtpZihhLmd0VCgpKXA9UC54ZShhLmdJaShhKSkKZWxz
-ZXtuPWsuZQppZihuLmxlbmd0aD09PTApaWYocj09bnVsbClwPXQubGVuZ3RoPT09MD9hLmdJaShhKTpQ
-LnhlKGEuZ0lpKGEpKQplbHNlIHA9UC54ZSgiLyIrYS5nSWkoYSkpCmVsc2V7bT1rLkpoKG4sYS5nSWko
-YSkpCmw9dC5sZW5ndGg9PT0wCmlmKCFsfHxyIT1udWxsfHxDLnhCLm4obiwiLyIpKXA9UC54ZShtKQpl
-bHNlIHA9UC53RihtLCFsfHxyIT1udWxsKX19bz1hLmdRRCgpP2EuZ3RQKCk6an19fXJldHVybiBuZXcg
-UC5Ebih0LHMscixxLHAsbyxhLmdaOCgpP2EuZ0thKCk6ail9LApnY2o6ZnVuY3Rpb24oKXtyZXR1cm4g
-dGhpcy5jIT1udWxsfSwKZ3hBOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZCE9bnVsbH0sCmdRRDpmdW5j
-dGlvbigpe3JldHVybiB0aGlzLmYhPW51bGx9LApnWjg6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5yIT1u
-dWxsfSwKZ3RUOmZ1bmN0aW9uKCl7cmV0dXJuIEMueEIubih0aGlzLmUsIi8iKX0sCnQ0OmZ1bmN0aW9u
-KCl7dmFyIHQscz10aGlzLHI9cy5hCmlmKHIhPT0iIiYmciE9PSJmaWxlIil0aHJvdyBILmIoUC5MNCgi
-Q2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhICIrcisiIFVSSSIpKQppZihzLmd0UCgpIT09
-IiIpdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSBVUkkgd2l0
-aCBhIHF1ZXJ5IGNvbXBvbmVudCIpKQppZihzLmdLYSgpIT09IiIpdGhyb3cgSC5iKFAuTDQoIkNhbm5v
-dCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSBVUkkgd2l0aCBhIGZyYWdtZW50IGNvbXBvbmVudCIp
-KQpyPSQud1EoKQppZihILm9UKHIpKXI9UC5tbihzKQplbHNle2lmKHMuYyE9bnVsbCYmcy5nSmYocykh
-PT0iIilILnZoKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgbm9uLVdpbmRvd3MgZmlsZSBwYXRoIGZyb20g
-YSBmaWxlIFVSSSB3aXRoIGFuIGF1dGhvcml0eSIpKQp0PXMuZ0ZqKCkKUC5rRSh0LCExKQpyPVAudmco
-Qy54Qi5uKHMuZSwiLyIpPyIiKyIvIjoiIix0LCIvIikKcj1yLmNoYXJDb2RlQXQoMCk9PTA/cjpyfXJl
-dHVybiByfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nbkQoKX0sCkROOmZ1bmN0aW9uKGEsYil7
-dmFyIHQ9dGhpcwppZihiPT1udWxsKXJldHVybiExCmlmKHQ9PT1iKXJldHVybiEwCnJldHVybiB1LmRE
-LmIoYikmJnQuYT09PWIuZ0ZpKCkmJnQuYyE9bnVsbD09PWIuZ2NqKCkmJnQuYj09PWIuZ2t1KCkmJnQu
-Z0pmKHQpPT09Yi5nSmYoYikmJnQuZ3RwKHQpPT09Yi5ndHAoYikmJnQuZT09PWIuZ0lpKGIpJiZ0LmYh
-PW51bGw9PT1iLmdRRCgpJiZ0Lmd0UCgpPT09Yi5ndFAoKSYmdC5yIT1udWxsPT09Yi5nWjgoKSYmdC5n
-S2EoKT09PWIuZ0thKCl9LApzS3A6ZnVuY3Rpb24oYSl7dGhpcy55PXUuYmsuYShhKX0sCnNOTTpmdW5j
-dGlvbihhKXt0aGlzLlE9dS5jWi5hKGEpfSwKJGlpRDoxLApnRmk6ZnVuY3Rpb24oKXtyZXR1cm4gdGhp
-cy5hfSwKZ0lpOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmV9fQpQLlJaLnByb3RvdHlwZT17CiQxOmZ1
-bmN0aW9uKGEpe3JldHVybiBQLmVQKEMuWkosSC5oKGEpLEMueE0sITEpfSwKJFM6Nn0KUC5NRS5wcm90
-b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYixzPXRoaXMuYQp0LmErPXMuYQpzLmE9
-IiYiCnM9dC5hKz1ILkVqKFAuZVAoQy5GMyxhLEMueE0sITApKQppZihiIT1udWxsJiZiLmxlbmd0aCE9
-PTApe3QuYT1zKyI9Igp0LmErPUguRWooUC5lUChDLkYzLGIsQy54TSwhMCkpfX0sCiRTOjIyfQpQLnk1
-LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILmgoYSkKaWYoYj09bnVsbHx8dHlw
-ZW9mIGI9PSJzdHJpbmciKXRoaXMuYS4kMihhLEguayhiKSkKZWxzZSBmb3IodD1KLklUKHUubS5hKGIp
-KSxzPXRoaXMuYTt0LkYoKTspcy4kMihhLEguaCh0LmdsKCkpKX0sCiRTOjEyfQpQLlBFLnByb3RvdHlw
-ZT17CmdsUjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcyxvPW51bGwsbj1wLmMKaWYobj09bnVs
-bCl7bj1wLmIKaWYoMD49bi5sZW5ndGgpcmV0dXJuIEguT0gobiwwKQp0PXAuYQpuPW5bMF0rMQpzPUMu
-eEIuWFUodCwiPyIsbikKcj10Lmxlbmd0aAppZihzPj0wKXtxPVAuUEkodCxzKzEscixDLlZDLCExKQpy
-PXN9ZWxzZSBxPW8Kbj1wLmM9bmV3IFAucWUoImRhdGEiLCIiLG8sbyxQLlBJKHQsbixyLEMuV2QsITEp
-LHEsbyl9cmV0dXJuIG59LAp3OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5iCmlmKDA+PXMubGVuZ3Ro
-KXJldHVybiBILk9IKHMsMCkKdD10aGlzLmEKcmV0dXJuIHNbMF09PT0tMT8iZGF0YToiK3Q6dH19ClAu
-cTMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBVaW50OEFycmF5KDk2KX0sCiRT
-OjIzfQpQLnlJLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcy5hCmlmKGE+PXQu
-bGVuZ3RoKXJldHVybiBILk9IKHQsYSkKdD10W2FdCkouQ00odCwwLDk2LGIpCnJldHVybiB0fSwKJFM6
-MjR9ClAuYzYucHJvdG90eXBlPXsKJDM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxCmZvcih0PWIu
-bGVuZ3RoLHM9YS5sZW5ndGgscj0wO3I8dDsrK3Ipe3E9Qy54Qi5XKGIscileOTYKaWYocT49cylyZXR1
-cm4gSC5PSChhLHEpCmFbcV09Y319fQpQLnFkLnByb3RvdHlwZT17CiQzOmZ1bmN0aW9uKGEsYixjKXt2
-YXIgdCxzLHIscQpmb3IodD1DLnhCLlcoYiwwKSxzPUMueEIuVyhiLDEpLHI9YS5sZW5ndGg7dDw9czsr
-K3Qpe3E9KHReOTYpPj4+MAppZihxPj1yKXJldHVybiBILk9IKGEscSkKYVtxXT1jfX19ClAuVWYucHJv
-dG90eXBlPXsKZ2NqOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYz4wfSwKZ3hBOmZ1bmN0aW9uKCl7cmV0
-dXJuIHRoaXMuYz4wJiZ0aGlzLmQrMTx0aGlzLmV9LApnUUQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5m
-PHRoaXMucn0sCmdaODpmdW5jdGlvbigpe3JldHVybiB0aGlzLnI8dGhpcy5hLmxlbmd0aH0sCmdOdzpm
-dW5jdGlvbigpe3JldHVybiB0aGlzLmI9PT00JiZDLnhCLm4odGhpcy5hLCJmaWxlIil9LApndmg6ZnVu
-Y3Rpb24oKXtyZXR1cm4gdGhpcy5iPT09NCYmQy54Qi5uKHRoaXMuYSwiaHR0cCIpfSwKZ1JlOmZ1bmN0
-aW9uKCl7cmV0dXJuIHRoaXMuYj09PTUmJkMueEIubih0aGlzLmEsImh0dHBzIil9LApndFQ6ZnVuY3Rp
-b24oKXtyZXR1cm4gQy54Qi5RaSh0aGlzLmEsIi8iLHRoaXMuZSl9LApnRmk6ZnVuY3Rpb24oKXt2YXIg
-dD10aGlzLngKcmV0dXJuIHQ9PW51bGw/dGhpcy54PXRoaXMuVTIoKTp0fSwKVTI6ZnVuY3Rpb24oKXt2
-YXIgdD10aGlzLHM9dC5iCmlmKHM8PTApcmV0dXJuIiIKaWYodC5ndmgoKSlyZXR1cm4iaHR0cCIKaWYo
-dC5nUmUoKSlyZXR1cm4iaHR0cHMiCmlmKHQuZ053KCkpcmV0dXJuImZpbGUiCmlmKHM9PT03JiZDLnhC
-Lm4odC5hLCJwYWNrYWdlIikpcmV0dXJuInBhY2thZ2UiCnJldHVybiBDLnhCLk5qKHQuYSwwLHMpfSwK
-Z2t1OmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5jLHM9dGhpcy5iKzMKcmV0dXJuIHQ+cz9DLnhCLk5qKHRo
-aXMuYSxzLHQtMSk6IiJ9LApnSmY6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jCnJldHVybiB0PjA/Qy54
-Qi5Oaih0aGlzLmEsdCx0aGlzLmQpOiIifSwKZ3RwOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMKaWYodC5n
-eEEoKSlyZXR1cm4gUC5RQShDLnhCLk5qKHQuYSx0LmQrMSx0LmUpLG51bGwpCmlmKHQuZ3ZoKCkpcmV0
-dXJuIDgwCmlmKHQuZ1JlKCkpcmV0dXJuIDQ0MwpyZXR1cm4gMH0sCmdJaTpmdW5jdGlvbihhKXtyZXR1
-cm4gQy54Qi5Oaih0aGlzLmEsdGhpcy5lLHRoaXMuZil9LApndFA6ZnVuY3Rpb24oKXt2YXIgdD10aGlz
-LmYscz10aGlzLnIKcmV0dXJuIHQ8cz9DLnhCLk5qKHRoaXMuYSx0KzEscyk6IiJ9LApnS2E6ZnVuY3Rp
-b24oKXt2YXIgdD10aGlzLnIscz10aGlzLmEKcmV0dXJuIHQ8cy5sZW5ndGg/Qy54Qi5HKHMsdCsxKToi
-In0sCmdGajpmdW5jdGlvbigpe3ZhciB0LHMscj10aGlzLmUscT10aGlzLmYscD10aGlzLmEKaWYoQy54
-Qi5RaShwLCIvIixyKSkrK3IKaWYocj09PXEpcmV0dXJuIEMueEQKdD1ILlZNKFtdLHUucykKZm9yKHM9
-cjtzPHE7KytzKWlmKEMueEIubShwLHMpPT09NDcpe0MuTm0uaSh0LEMueEIuTmoocCxyLHMpKQpyPXMr
-MX1DLk5tLmkodCxDLnhCLk5qKHAscixxKSkKcmV0dXJuIFAuQUYodCx1Lk4pfSwKZ2hZOmZ1bmN0aW9u
-KCl7aWYodGhpcy5mPj10aGlzLnIpcmV0dXJuIEMuV08KcmV0dXJuIG5ldyBQLkdqKFAuV1godGhpcy5n
-dFAoKSksdS5kdyl9LAprWDpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmQrMQpyZXR1cm4gdCthLmxlbmd0
-aD09PXRoaXMuZSYmQy54Qi5RaSh0aGlzLmEsYSx0KX0sCk45OmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxz
-PXQucixyPXQuYQppZihzPj1yLmxlbmd0aClyZXR1cm4gdApyZXR1cm4gbmV3IFAuVWYoQy54Qi5Oaihy
-LDAscyksdC5iLHQuYyx0LmQsdC5lLHQuZixzLHQueCl9LApubTpmdW5jdGlvbihhLGIpe3ZhciB0LHMs
-cixxLHAsbyxuLG0sbCxrLGo9dGhpcyxpPW51bGwKdS5VLmEobnVsbCkKdS5jOS5hKGIpCnQ9ai5nRmko
-KQpzPXQ9PT0iZmlsZSIKcj1qLmMKcT1yPjA/Qy54Qi5OaihqLmEsai5iKzMscik6IiIKcD1qLmd4QSgp
-P2ouZ3RwKGopOmkKcj1qLmMKaWYocj4wKW89Qy54Qi5OaihqLmEscixqLmQpCmVsc2Ugbz1xLmxlbmd0
-aCE9PTB8fHAhPW51bGx8fHM/IiI6aQpyPWouYQpuPUMueEIuTmoocixqLmUsai5mKQppZighcyltPW8h
-PW51bGwmJm4ubGVuZ3RoIT09MAplbHNlIG09ITAKaWYobSYmIUMueEIubihuLCIvIikpbj0iLyIrbgps
-PVAubGUoaSwwLDAsYikKbT1qLnIKaz1tPHIubGVuZ3RoP0MueEIuRyhyLG0rMSk6aQpyZXR1cm4gbmV3
-IFAuRG4odCxxLG8scCxuLGwsayl9LApaSTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5tUyhQLmhLKGEp
-KX0sCm1TOmZ1bmN0aW9uKGEpe2lmKGEgaW5zdGFuY2VvZiBQLlVmKXJldHVybiB0aGlzLnUxKHRoaXMs
-YSkKcmV0dXJuIHRoaXMudnMoKS5tUyhhKX0sCnUxOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxv
-LG4sbSxsLGssaixpLGg9Yi5iCmlmKGg+MClyZXR1cm4gYgp0PWIuYwppZih0PjApe3M9YS5iCmlmKHM8
-PTApcmV0dXJuIGIKaWYoYS5nTncoKSlyPWIuZSE9PWIuZgplbHNlIGlmKGEuZ3ZoKCkpcj0hYi5rWCgi
-ODAiKQplbHNlIHI9IWEuZ1JlKCl8fCFiLmtYKCI0NDMiKQppZihyKXtxPXMrMQpyZXR1cm4gbmV3IFAu
-VWYoQy54Qi5OaihhLmEsMCxxKStDLnhCLkcoYi5hLGgrMSkscyx0K3EsYi5kK3EsYi5lK3EsYi5mK3Es
-Yi5yK3EsYS54KX1lbHNlIHJldHVybiB0aGlzLnZzKCkubVMoYil9cD1iLmUKaD1iLmYKaWYocD09PWgp
-e3Q9Yi5yCmlmKGg8dCl7cz1hLmYKcT1zLWgKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmooYS5hLDAscykr
-Qy54Qi5HKGIuYSxoKSxhLmIsYS5jLGEuZCxhLmUsaCtxLHQrcSxhLngpfWg9Yi5hCmlmKHQ8aC5sZW5n
-dGgpe3M9YS5yCnJldHVybiBuZXcgUC5VZihDLnhCLk5qKGEuYSwwLHMpK0MueEIuRyhoLHQpLGEuYixh
-LmMsYS5kLGEuZSxhLmYsdCsocy10KSxhLngpfXJldHVybiBhLk45KCl9dD1iLmEKaWYoQy54Qi5RaSh0
-LCIvIixwKSl7cz1hLmUKcT1zLXAKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmooYS5hLDAscykrQy54Qi5H
-KHQscCksYS5iLGEuYyxhLmQscyxoK3EsYi5yK3EsYS54KX1vPWEuZQpuPWEuZgppZihvPT09biYmYS5j
-PjApe2Zvcig7Qy54Qi5RaSh0LCIuLi8iLHApOylwKz0zCnE9by1wKzEKcmV0dXJuIG5ldyBQLlVmKEMu
-eEIuTmooYS5hLDAsbykrIi8iK0MueEIuRyh0LHApLGEuYixhLmMsYS5kLG8saCtxLGIucitxLGEueCl9
-bT1hLmEKZm9yKGw9bztDLnhCLlFpKG0sIi4uLyIsbCk7KWwrPTMKaz0wCndoaWxlKCEwKXtqPXArMwpp
-ZighKGo8PWgmJkMueEIuUWkodCwiLi4vIixwKSkpYnJlYWs7KytrCnA9an1mb3IoaT0iIjtuPmw7KXst
-LW4KaWYoQy54Qi5tKG0sbik9PT00Nyl7aWYoaz09PTApe2k9Ii8iCmJyZWFrfS0tawppPSIvIn19aWYo
-bj09PWwmJmEuYjw9MCYmIUMueEIuUWkobSwiLyIsbykpe3AtPWsqMwppPSIifXE9bi1wK2kubGVuZ3Ro
-CnJldHVybiBuZXcgUC5VZihDLnhCLk5qKG0sMCxuKStpK0MueEIuRyh0LHApLGEuYixhLmMsYS5kLG8s
-aCtxLGIucitxLGEueCl9LAp0NDpmdW5jdGlvbigpe3ZhciB0LHMscixxPXRoaXMKaWYocS5iPj0wJiYh
-cS5nTncoKSl0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhICIr
-cS5nRmkoKSsiIFVSSSIpKQp0PXEuZgpzPXEuYQppZih0PHMubGVuZ3RoKXtpZih0PHEucil0aHJvdyBI
-LmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhIFVSSSB3aXRoIGEgcXVlcnkg
-Y29tcG9uZW50IikpCnRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9t
-IGEgVVJJIHdpdGggYSBmcmFnbWVudCBjb21wb25lbnQiKSl9cj0kLndRKCkKaWYoSC5vVChyKSl0PVAu
-bW4ocSkKZWxzZXtpZihxLmM8cS5kKUgudmgoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBub24tV2luZG93
-cyBmaWxlIHBhdGggZnJvbSBhIGZpbGUgVVJJIHdpdGggYW4gYXV0aG9yaXR5IikpCnQ9Qy54Qi5Oaihz
-LHEuZSx0KX1yZXR1cm4gdH0sCmdpTzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLnkKcmV0dXJuIHQ9PW51
-bGw/dGhpcy55PUMueEIuZ2lPKHRoaXMuYSk6dH0sCkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbCly
-ZXR1cm4hMQppZih0aGlzPT09YilyZXR1cm4hMApyZXR1cm4gdS5kRC5iKGIpJiZ0aGlzLmE9PT1iLnco
-MCl9LAp2czpmdW5jdGlvbigpe3ZhciB0PXRoaXMscz1udWxsLHI9dC5nRmkoKSxxPXQuZ2t1KCkscD10
-LmM+MD90LmdKZih0KTpzLG89dC5neEEoKT90Lmd0cCh0KTpzLG49dC5hLG09dC5mLGw9Qy54Qi5Oaihu
-LHQuZSxtKSxrPXQucgptPW08az90Lmd0UCgpOnMKcmV0dXJuIG5ldyBQLkRuKHIscSxwLG8sbCxtLGs8
-bi5sZW5ndGg/dC5nS2EoKTpzKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYX0sCiRpaUQ6MX0K
-UC5xZS5wcm90b3R5cGU9e30KVy5xRS5wcm90b3R5cGU9e30KVy5HaC5wcm90b3R5cGU9ewp3OmZ1bmN0
-aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9LAokaUdoOjF9ClcuZlkucHJvdG90eXBlPXsKdzpmdW5jdGlv
-bihhKXtyZXR1cm4gU3RyaW5nKGEpfX0KVy5uQi5wcm90b3R5cGU9eyRpbkI6MX0KVy5Bei5wcm90b3R5
-cGU9eyRpQXo6MX0KVy5RUC5wcm90b3R5cGU9eyRpUVA6MX0KVy5ueC5wcm90b3R5cGU9ewpnQTpmdW5j
-dGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLm9KLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBhLmxlbmd0aH19ClcuaWQucHJvdG90eXBlPXt9ClcuUUYucHJvdG90eXBlPXt9ClcuTmgucHJv
-dG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEpfX0KVy5hZS5wcm90b3R5cGU9ewpE
-YzpmdW5jdGlvbihhLGIpe3JldHVybiBhLmNyZWF0ZUhUTUxEb2N1bWVudChiKX19ClcuSUIucHJvdG90
-eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iUmVjdGFuZ2xlICgiK0guRWooYS5sZWZ0KSsiLCAiK0gu
-RWooYS50b3ApKyIpICIrSC5FaihhLndpZHRoKSsiIHggIitILkVqKGEuaGVpZ2h0KX0sCkROOmZ1bmN0
-aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1cm4gdS5xLmIoYikmJmEubGVmdD09PWIubGVm
-dCYmYS50b3A9PT1iLnRvcCYmYS53aWR0aD09PWIud2lkdGgmJmEuaGVpZ2h0PT09Yi5oZWlnaHR9LApn
-aU86ZnVuY3Rpb24oYSl7cmV0dXJuIFcuckUoQy5DRC5naU8oYS5sZWZ0KSxDLkNELmdpTyhhLnRvcCks
-Qy5DRC5naU8oYS53aWR0aCksQy5DRC5naU8oYS5oZWlnaHQpKX0sCiRpdG46MX0KVy5uNy5wcm90b3R5
-cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLnd6LnByb3RvdHlwZT17CmdBOmZ1
-bmN0aW9uKGEpe3JldHVybiB0aGlzLmEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe3ZhciB0CkgudVAo
-YikKdD10aGlzLmEKaWYoYjwwfHxiPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LGIpCnJldHVybiB0aGlz
-LiR0aS5jLmEodFtiXSl9LApZOmZ1bmN0aW9uKGEsYixjKXt0aGlzLiR0aS5jLmEoYykKdGhyb3cgSC5i
-KFAuTDQoIkNhbm5vdCBtb2RpZnkgbGlzdCIpKX19ClcuY3YucHJvdG90eXBlPXsKZ1FnOmZ1bmN0aW9u
-KGEpe3JldHVybiBuZXcgVy5pNyhhKX0sCmdQOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5JNChhKX0s
-CnNQOmZ1bmN0aW9uKGEsYil7dmFyIHQKdS5RLmEoYikKdD10aGlzLmdQKGEpCnQuVjEoMCkKdC5GVigw
-LGIpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gYS5sb2NhbE5hbWV9LApGRjpmdW5jdGlvbihhKXt2YXIg
-dD0hIWEuc2Nyb2xsSW50b1ZpZXdJZk5lZWRlZAppZih0KWEuc2Nyb2xsSW50b1ZpZXdJZk5lZWRlZCgp
-CmVsc2UgYS5zY3JvbGxJbnRvVmlldygpfSwKbno6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzPXRo
-aXMucjYoYSxjLGQsZSkKc3dpdGNoKGIudG9Mb3dlckNhc2UoKSl7Y2FzZSJiZWZvcmViZWdpbiI6dD1h
-LnBhcmVudE5vZGUKdC50b1N0cmluZwpKLkVoKHQscyxhKQpicmVhawpjYXNlImFmdGVyYmVnaW4iOnQ9
-YS5jaGlsZE5vZGVzCnRoaXMubUsoYSxzLHQubGVuZ3RoPjA/dFswXTpudWxsKQpicmVhawpjYXNlImJl
-Zm9yZWVuZCI6YS5hcHBlbmRDaGlsZChzKQpicmVhawpjYXNlImFmdGVyZW5kIjp0PWEucGFyZW50Tm9k
-ZQp0LnRvU3RyaW5nCkouRWgodCxzLGEubmV4dFNpYmxpbmcpCmJyZWFrCmRlZmF1bHQ6SC52aChQLnhZ
-KCJJbnZhbGlkIHBvc2l0aW9uICIrYikpfX0sCnI2OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscixx
-CmlmKGM9PW51bGwpe2lmKGQ9PW51bGwpe3Q9JC5sdAppZih0PT1udWxsKXt0PUguVk0oW10sdS5wKQpz
-PW5ldyBXLnZEKHQpCkMuTm0uaSh0LFcuVHcobnVsbCkpCkMuTm0uaSh0LFcuQmwoKSkKJC5sdD1zCmQ9
-c31lbHNlIGQ9dH10PSQuRVUKaWYodD09bnVsbCl7dD1uZXcgVy5LbyhkKQokLkVVPXQKYz10fWVsc2V7
-dC5hPWQKYz10fX1lbHNlIGlmKGQhPW51bGwpdGhyb3cgSC5iKFAueFkoInZhbGlkYXRvciBjYW4gb25s
-eSBiZSBwYXNzZWQgaWYgdHJlZVNhbml0aXplciBpcyBudWxsIikpCmlmKCQueG89PW51bGwpe3Q9ZG9j
-dW1lbnQKcz1DLm1ILkRjKHQuaW1wbGVtZW50YXRpb24sIiIpCiQueG89cwokLkJPPXMuY3JlYXRlUmFu
-Z2UoKQpzPSQueG8uY3JlYXRlRWxlbWVudCgiYmFzZSIpCnUuY1IuYShzKQpzLmhyZWY9dC5iYXNlVVJJ
-CiQueG8uaGVhZC5hcHBlbmRDaGlsZChzKX10PSQueG8KaWYodC5ib2R5PT1udWxsKXtzPXQuY3JlYXRl
-RWxlbWVudCgiYm9keSIpCkMuQlouc1hHKHQsdS5rLmEocykpfXQ9JC54bwppZih1LmsuYihhKSl7dD10
-LmJvZHkKdC50b1N0cmluZwpyPXR9ZWxzZXt0LnRvU3RyaW5nCnI9dC5jcmVhdGVFbGVtZW50KGEudGFn
-TmFtZSkKJC54by5ib2R5LmFwcGVuZENoaWxkKHIpfWlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQi
-IGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUmJiFDLk5tLnRnKEMuU3EsYS50YWdOYW1lKSl7JC5CTy5z
-ZWxlY3ROb2RlQ29udGVudHMocikKcT0kLkJPLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudChiKX1lbHNl
-e0oud2YocixiKQpxPSQueG8uY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCmZvcig7dD1yLmZpcnN0Q2hp
-bGQsdCE9bnVsbDspcS5hcHBlbmRDaGlsZCh0KX1pZihyIT09JC54by5ib2R5KUouTHQocikKYy5Qbihx
-KQpkb2N1bWVudC5hZG9wdE5vZGUocSkKcmV0dXJuIHF9LApBSDpmdW5jdGlvbihhLGIsYyl7cmV0dXJu
-IHRoaXMucjYoYSxiLGMsbnVsbCl9LApzaGY6ZnVuY3Rpb24oYSxiKXt0aGlzLllDKGEsYil9LApwazpm
-dW5jdGlvbihhLGIsYyl7dGhpcy5zYTQoYSxudWxsKQpiLnRvU3RyaW5nCmEuYXBwZW5kQ2hpbGQodGhp
-cy5yNihhLGIsbnVsbCxjKSl9LApZQzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLnBrKGEsYixudWxs
-KX0sCnNSTjpmdW5jdGlvbihhLGIpe2EuaW5uZXJIVE1MPWJ9LApnbnM6ZnVuY3Rpb24oYSl7cmV0dXJu
-IGEudGFnTmFtZX0sCmdWbDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuZXUoYSwiY2xpY2siLCExLHUu
-Ryl9LAokaWN2OjF9ClcuQ3YucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHUuaC5iKHUu
-QS5hKGEpKX0sCiRTOjI1fQpXLmVhLnByb3RvdHlwZT17JGllYToxfQpXLkQwLnByb3RvdHlwZT17Ck9u
-OmZ1bmN0aW9uKGEsYixjLGQpe3UuYncuYShjKQppZihjIT1udWxsKXRoaXMudihhLGIsYyxkKX0sCkI6
-ZnVuY3Rpb24oYSxiLGMpe3JldHVybiB0aGlzLk9uKGEsYixjLG51bGwpfSwKdjpmdW5jdGlvbihhLGIs
-YyxkKXtyZXR1cm4gYS5hZGRFdmVudExpc3RlbmVyKGIsSC50Uih1LmJ3LmEoYyksMSksZCl9LAokaUQw
-OjF9ClcuVDUucHJvdG90eXBlPXskaVQ1OjF9ClcuaDQucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7
-cmV0dXJuIGEubGVuZ3RofX0KVy5ici5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5s
-ZW5ndGh9fQpXLlZiLnByb3RvdHlwZT17CnNYRzpmdW5jdGlvbihhLGIpe2EuYm9keT1ifX0KVy5mSi5w
-cm90b3R5cGU9ewplbzpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gYS5vcGVuKGIsYywhMCl9LAokaWZK
-OjF9ClcuYlUucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuc2V0UmVxdWVzdEhlYWRl
-cihILmgoYSksSC5oKGIpKX0sCiRTOjd9ClcuaEgucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
-IHQscyxyLHEscAp1LmdaLmEoYSkKdD10aGlzLmEKcz10LnN0YXR1cwpyPXM+PTIwMCYmczwzMDAKcT1z
-PjMwNyYmczw0MDAKcz1yfHxzPT09MHx8cz09PTMwNHx8cQpwPXRoaXMuYgppZihzKXAuYU0oMCx0KQpl
-bHNlIHAucG0oYSl9LAokUzoyN30KVy53YS5wcm90b3R5cGU9e30KVy5TZy5wcm90b3R5cGU9eyRpU2c6
-MX0KVy51OC5wcm90b3R5cGU9ewpnRHI6ZnVuY3Rpb24oYSl7aWYoIm9yaWdpbiIgaW4gYSlyZXR1cm4g
-YS5vcmlnaW4KcmV0dXJuIGEucHJvdG9jb2wrIi8vIithLmhvc3R9LAp3OmZ1bmN0aW9uKGEpe3JldHVy
-biBTdHJpbmcoYSl9LAokaXU4OjF9ClcuT0sucHJvdG90eXBlPXskaU9LOjF9ClcuZTcucHJvdG90eXBl
-PXsKZ3I4OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxzPXQuY2hpbGROb2Rlcy5sZW5ndGgKaWYocz09
-PTApdGhyb3cgSC5iKFAuUFYoIk5vIGVsZW1lbnRzIikpCmlmKHM+MSl0aHJvdyBILmIoUC5QVigiTW9y
-ZSB0aGFuIG9uZSBlbGVtZW50IikpCnQ9dC5maXJzdENoaWxkCnQudG9TdHJpbmcKcmV0dXJuIHR9LApG
-VjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAKdS5laC5hKGIpCnQ9Yi5hCnM9dGhpcy5hCmlmKHQh
-PT1zKWZvcihyPXQuY2hpbGROb2Rlcy5sZW5ndGgscT0wO3E8cjsrK3Epe3A9dC5maXJzdENoaWxkCnAu
-dG9TdHJpbmcKcy5hcHBlbmRDaGlsZChwKX1yZXR1cm59LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxz
-CnUuQS5hKGMpCnQ9dGhpcy5hCnM9dC5jaGlsZE5vZGVzCmlmKGI8MHx8Yj49cy5sZW5ndGgpcmV0dXJu
-IEguT0gocyxiKQp0LnJlcGxhY2VDaGlsZChjLHNbYl0pfSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRo
-aXMuYS5jaGlsZE5vZGVzCnJldHVybiBuZXcgVy5XOSh0LHQubGVuZ3RoLEgueih0KS5DKCJXOTxHbS5F
-PiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuY2hpbGROb2Rlcy5sZW5ndGh9LApxOmZ1
-bmN0aW9uKGEsYil7dmFyIHQKSC51UChiKQp0PXRoaXMuYS5jaGlsZE5vZGVzCmlmKGI8MHx8Yj49dC5s
-ZW5ndGgpcmV0dXJuIEguT0godCxiKQpyZXR1cm4gdFtiXX19ClcudUgucHJvdG90eXBlPXsKd2c6ZnVu
-Y3Rpb24oYSl7dmFyIHQ9YS5wYXJlbnROb2RlCmlmKHQhPW51bGwpdC5yZW1vdmVDaGlsZChhKX0sCkQ0
-OmZ1bmN0aW9uKGEpe3ZhciB0CmZvcig7dD1hLmZpcnN0Q2hpbGQsdCE9bnVsbDspYS5yZW1vdmVDaGls
-ZCh0KX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHQ9YS5ub2RlVmFsdWUKcmV0dXJuIHQ9PW51bGw/dGhpcy5V
-KGEpOnR9LApzYTQ6ZnVuY3Rpb24oYSxiKXthLnRleHRDb250ZW50PWJ9LAptSzpmdW5jdGlvbihhLGIs
-Yyl7cmV0dXJuIGEuaW5zZXJ0QmVmb3JlKGIsYyl9LAokaXVIOjF9ClcuQkgucHJvdG90eXBlPXsKZ0E6
-ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0gudVAoYikKaWYoYj4+
-PjAhPT1ifHxiPj1hLmxlbmd0aCl0aHJvdyBILmIoUC5DZihiLGEsbnVsbCxudWxsLG51bGwpKQpyZXR1
-cm4gYVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe3UuQS5hKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3Qg
-YXNzaWduIGVsZW1lbnQgb2YgaW1tdXRhYmxlIExpc3QuIikpfSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8
-MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguT0goYSxiKQpyZXR1cm4gYVtiXX0sCiRpYlE6MSwKJGlYajox
-LAokaWNYOjEsCiRpek06MX0KVy5TTi5wcm90b3R5cGU9e30KVy5ldy5wcm90b3R5cGU9eyRpZXc6MX0K
-Vy5scC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLlRiLnByb3Rv
-dHlwZT17CnI2OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMKaWYoImNyZWF0ZUNvbnRleHR1YWxGcmFn
-bWVudCIgaW4gd2luZG93LlJhbmdlLnByb3RvdHlwZSlyZXR1cm4gdGhpcy5EVyhhLGIsYyxkKQp0PVcu
-VTkoIjx0YWJsZT4iK0guRWooYikrIjwvdGFibGU+IixjLGQpCnM9ZG9jdW1lbnQuY3JlYXRlRG9jdW1l
-bnRGcmFnbWVudCgpCnQudG9TdHJpbmcKbmV3IFcuZTcocykuRlYoMCxuZXcgVy5lNyh0KSkKcmV0dXJu
-IHN9fQpXLkl2LnByb3RvdHlwZT17CnI2OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscixxCmlmKCJj
-cmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUpcmV0dXJuIHRo
-aXMuRFcoYSxiLGMsZCkKdD1kb2N1bWVudApzPXQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCnQ9bmV3
-IFcuZTcoQy5JZS5yNih0LmNyZWF0ZUVsZW1lbnQoInRhYmxlIiksYixjLGQpKQpyPXQuZ3I4KHQpCnIu
-dG9TdHJpbmcKdD1uZXcgVy5lNyhyKQpxPXQuZ3I4KHQpCnEudG9TdHJpbmcKbmV3IFcuZTcocykuRlYo
-MCxuZXcgVy5lNyhxKSkKcmV0dXJuIHN9fQpXLldQLnByb3RvdHlwZT17CnI2OmZ1bmN0aW9uKGEsYixj
-LGQpe3ZhciB0LHMscgppZigiY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50IiBpbiB3aW5kb3cuUmFuZ2Uu
-cHJvdG90eXBlKXJldHVybiB0aGlzLkRXKGEsYixjLGQpCnQ9ZG9jdW1lbnQKcz10LmNyZWF0ZURvY3Vt
-ZW50RnJhZ21lbnQoKQp0PW5ldyBXLmU3KEMuSWUucjYodC5jcmVhdGVFbGVtZW50KCJ0YWJsZSIpLGIs
-YyxkKSkKcj10LmdyOCh0KQpyLnRvU3RyaW5nCm5ldyBXLmU3KHMpLkZWKDAsbmV3IFcuZTcocikpCnJl
-dHVybiBzfX0KVy55WS5wcm90b3R5cGU9ewpwazpmdW5jdGlvbihhLGIsYyl7dmFyIHQKdGhpcy5zYTQo
-YSxudWxsKQpKLmJUKGEuY29udGVudCkKYi50b1N0cmluZwp0PXRoaXMucjYoYSxiLG51bGwsYykKYS5j
-b250ZW50LmFwcGVuZENoaWxkKHQpfSwKWUM6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5wayhhLGIs
-bnVsbCl9LAokaXlZOjF9ClcudzYucHJvdG90eXBlPXt9ClcuSzUucHJvdG90eXBlPXsKUG86ZnVuY3Rp
-b24oYSxiLGMpe3ZhciB0PVcuUDEoYS5vcGVuKGIsYykpCnJldHVybiB0fSwKZ21XOmZ1bmN0aW9uKGEp
-e3JldHVybiBhLmxvY2F0aW9ufSwKVXg6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYS5hbGVydChiKX0sCnVz
-OmZ1bmN0aW9uKGEsYil7cmV0dXJuIGEuY29uZmlybShiKX0sCiRpSzU6MSwKJGl2NjoxfQpXLkNtLnBy
-b3RvdHlwZT17JGlDbToxfQpXLkNRLnByb3RvdHlwZT17JGlDUToxfQpXLnc0LnByb3RvdHlwZT17Cnc6
-ZnVuY3Rpb24oYSl7cmV0dXJuIlJlY3RhbmdsZSAoIitILkVqKGEubGVmdCkrIiwgIitILkVqKGEudG9w
-KSsiKSAiK0guRWooYS53aWR0aCkrIiB4ICIrSC5FaihhLmhlaWdodCl9LApETjpmdW5jdGlvbihhLGIp
-e2lmKGI9PW51bGwpcmV0dXJuITEKcmV0dXJuIHUucS5iKGIpJiZhLmxlZnQ9PT1iLmxlZnQmJmEudG9w
+LktxKHQuZCkuQygiRmU8MSwyPiIpKSkKcmV0dXJuIHJ9LAp4ZjpmdW5jdGlvbihhKXt2YXIgdCxzPXRo
+aXMscj1zLmEKaWYocjw9MSl7YS5hPXUueC5iKHMuYykKcy5jPWF9ZWxzZXtpZihyPT09Mil7dD11Ll8u
+YihzLmMpCnI9dC5hCmlmKHI8NCl7dC54ZihhKQpyZXR1cm59cy5hPXIKcy5jPXQuY31QLlRrKG51bGws
+bnVsbCxzLmIsdS5NLmIobmV3IFAuZGEocyxhKSkpfX0sCmpROmZ1bmN0aW9uKGEpe3ZhciB0LHMscixx
+LHAsbz10aGlzLG49e30Kbi5hPWEKaWYoYT09bnVsbClyZXR1cm4KdD1vLmEKaWYodDw9MSl7cz11Lngu
+YihvLmMpCnI9by5jPWEKaWYocyE9bnVsbCl7Zm9yKDtxPXIuYSxxIT1udWxsO3I9cSk7ci5hPXN9fWVs
+c2V7aWYodD09PTIpe3A9dS5fLmIoby5jKQp0PXAuYQppZih0PDQpe3AualEoYSkKcmV0dXJufW8uYT10
+Cm8uYz1wLmN9bi5hPW8uTjgoYSkKUC5UayhudWxsLG51bGwsby5iLHUuTS5iKG5ldyBQLm9RKG4sbykp
+KX19LAphaDpmdW5jdGlvbigpe3ZhciB0PXUueC5iKHRoaXMuYykKdGhpcy5jPW51bGwKcmV0dXJuIHRo
+aXMuTjgodCl9LApOODpmdW5jdGlvbihhKXt2YXIgdCxzLHIKZm9yKHQ9YSxzPW51bGw7dCE9bnVsbDtz
+PXQsdD1yKXtyPXQuYQp0LmE9c31yZXR1cm4gc30sCkhIOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcyxy
+PXMuJHRpCnIuQygiMS8iKS5iKGEpCmlmKHIuQygiYjg8MT4iKS5jKGEpKWlmKHIuYyhhKSlQLkE5KGEs
+cykKZWxzZSBQLmszKGEscykKZWxzZXt0PXMuYWgoKQpyLmQuYihhKQpzLmE9NApzLmM9YQpQLkhaKHMs
+dCl9fSwKWDI6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzCnMuJHRpLmQuYihhKQp0PXMuYWgoKQpzLmE9
+NApzLmM9YQpQLkhaKHMsdCl9LApaTDpmdW5jdGlvbihhLGIpe3ZhciB0LHM9dGhpcwp1LmwuYihiKQp0
+PXMuYWgoKQpzLmE9OApzLmM9bmV3IFAuQ3coYSxiKQpQLkhaKHMsdCl9LApYZjpmdW5jdGlvbihhKXt2
+YXIgdD10aGlzLHM9dC4kdGkKcy5DKCIxLyIpLmIoYSkKaWYocy5DKCJiODwxPiIpLmMoYSkpe3QuY1Uo
+YSkKcmV0dXJufXQuYT0xClAuVGsobnVsbCxudWxsLHQuYix1Lk0uYihuZXcgUC5ySCh0LGEpKSl9LApj
+VTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLHM9dC4kdGkKcy5DKCJiODwxPiIpLmIoYSkKaWYocy5jKGEp
+KXtpZihhLmE9PT04KXt0LmE9MQpQLlRrKG51bGwsbnVsbCx0LmIsdS5NLmIobmV3IFAuS0YodCxhKSkp
+fWVsc2UgUC5BOShhLHQpCnJldHVybn1QLmszKGEsdCl9LApOazpmdW5jdGlvbihhLGIpe3RoaXMuYT0x
+ClAuVGsobnVsbCxudWxsLHRoaXMuYix1Lk0uYihuZXcgUC5aTCh0aGlzLGEsYikpKX0sCiRpYjg6MX0K
+UC5kYS5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe1AuSFoodGhpcy5hLHRoaXMuYil9LAokUzowfQpQ
+Lm9RLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7UC5IWih0aGlzLmIsdGhpcy5hLmEpfSwKJFM6MH0K
+UC5wVi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKdC5hPTAKdC5ISChhKX0s
+CiRTOjEyfQpQLlU3LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dS5sLmIoYikKdGhpcy5hLlpM
+KGEsYil9LAokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy4kMihhLG51bGwpfSwKJEM6IiQyIiwKJEQ6
+ZnVuY3Rpb24oKXtyZXR1cm5bbnVsbF19LAokUzozMH0KUC52ci5wcm90b3R5cGU9ewokMDpmdW5jdGlv
+bigpe3RoaXMuYS5aTCh0aGlzLmIsdGhpcy5jKX0sCiRTOjB9ClAuckgucHJvdG90eXBlPXsKJDA6ZnVu
+Y3Rpb24oKXt2YXIgdD10aGlzLmEKdC5YMih0LiR0aS5kLmIodGhpcy5iKSl9LAokUzowfQpQLktGLnBy
+b3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7UC5BOSh0aGlzLmIsdGhpcy5hKX0sCiRTOjB9ClAuWkwucHJv
+dG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuWkwodGhpcy5iLHRoaXMuYyl9LAokUzowfQpQLlJU
+LnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG49dGhpcyxtPW51bGwKdHJ5
+e3I9bi5jCm09ci5iLmIuenoodS5mTy5iKHIuZCksdS56KX1jYXRjaChxKXt0PUguUnUocSkKcz1ILnRz
+KHEpCmlmKG4uZCl7cj11Lm4uYihuLmEuYS5jKS5hCnA9dApwPXI9PW51bGw/cD09bnVsbDpyPT09cApy
+PXB9ZWxzZSByPSExCnA9bi5iCmlmKHIpcC5iPXUubi5iKG4uYS5hLmMpCmVsc2UgcC5iPW5ldyBQLkN3
+KHQscykKcC5hPSEwCnJldHVybn1pZih1LmMuYyhtKSl7aWYobSBpbnN0YW5jZW9mIFAudnMmJm0uYT49
+NCl7aWYobS5hPT09OCl7cj1uLmIKci5iPXUubi5iKG0uYykKci5hPSEwfXJldHVybn1vPW4uYS5hCnI9
+bi5iCnIuYj1tLlc3KG5ldyBQLmpaKG8pLHUueikKci5hPSExfX0sCiRTOjJ9ClAualoucHJvdG90eXBl
+PXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYX0sCiRTOjMzfQpQLnJxLnByb3RvdHlwZT17CiQw
+OmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG4sbT10aGlzCnRyeXtyPW0uYgpxPXIuJHRpCnA9cS5k
+Cm89cC5iKG0uYykKbS5hLmI9ci5iLmIuYnYocS5DKCIyLygxKSIpLmIoci5kKSxvLHEuQygiMi8iKSxw
+KX1jYXRjaChuKXt0PUguUnUobikKcz1ILnRzKG4pCnI9bS5hCnIuYj1uZXcgUC5Ddyh0LHMpCnIuYT0h
+MH19LAokUzoyfQpQLlJXLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG4s
+bSxsPXRoaXMKdHJ5e3Q9dS5uLmIobC5hLmEuYykKcT1sLmMKaWYoSC5vVChxLkhSKHQpKSYmcS5lIT1u
+dWxsKXtwPWwuYgpwLmI9cS5Ldyh0KQpwLmE9ITF9fWNhdGNoKG8pe3M9SC5SdShvKQpyPUgudHMobykK
+cT11Lm4uYihsLmEuYS5jKQpwPXEuYQpuPXMKbT1sLmIKaWYocD09bnVsbD9uPT1udWxsOnA9PT1uKW0u
+Yj1xCmVsc2UgbS5iPW5ldyBQLkN3KHMscikKbS5hPSEwfX0sCiRTOjJ9ClAuT00ucHJvdG90eXBlPXt9
+ClAucWgucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPXRoaXMscT17fSxwPW5ldyBQ
+LnZzKCQuWDMsdS5mSikKcS5hPTAKdD1ILkxoKHIpCnM9dC5DKCJ+KDEpIikuYihuZXcgUC5CNShxLHIp
+KQp1Lk0uYihuZXcgUC51TyhxLHApKQpXLkpFKHIuYSxyLmIscywhMSx0LmQpCnJldHVybiBwfX0KUC5C
+NS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtILkxoKHRoaXMuYikuZC5iKGEpOysrdGhpcy5hLmF9
+LAokUzpmdW5jdGlvbigpe3JldHVybiBILkxoKHRoaXMuYikuQygiYzgoMSkiKX19ClAudU8ucHJvdG90
+eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmIuSEgodGhpcy5hLmEpfSwKJFM6MH0KUC5NTy5wcm90b3R5
+cGU9e30KUC5rVC5wcm90b3R5cGU9e30KUC54SS5wcm90b3R5cGU9e30KUC5Ddy5wcm90b3R5cGU9ewp3
+OmZ1bmN0aW9uKGEpe3JldHVybiBILmQodGhpcy5hKX0sCiRpWFM6MX0KUC5tMC5wcm90b3R5cGU9eyRp
+SkI6MX0KUC5wSy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3ZhciB0LHM9dGhpcy5hLHI9cy5hCnM9
+cj09bnVsbD9zLmE9bmV3IFAubigpOnIKcj10aGlzLmIKaWYocj09bnVsbCl0aHJvdyBILmIocykKdD1I
+LmIocykKdC5zdGFjaz1yLncoMCkKdGhyb3cgdH0sCiRTOjB9ClAuSmkucHJvdG90eXBlPXsKYkg6ZnVu
+Y3Rpb24oYSl7dmFyIHQscyxyLHE9bnVsbAp1Lk0uYihhKQp0cnl7aWYoQy5OVT09PSQuWDMpe2EuJDAo
+KQpyZXR1cm59UC5UOChxLHEsdGhpcyxhLHUuSCl9Y2F0Y2gocil7dD1ILlJ1KHIpCnM9SC50cyhyKQpQ
+LkwyKHEscSx0aGlzLHQsdS5sLmIocykpfX0sCkRsOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscT1u
+dWxsCmMuQygifigwKSIpLmIoYSkKYy5iKGIpCnRyeXtpZihDLk5VPT09JC5YMyl7YS4kMShiKQpyZXR1
+cm59UC55dihxLHEsdGhpcyxhLGIsdS5ILGMpfWNhdGNoKHIpe3Q9SC5SdShyKQpzPUgudHMocikKUC5M
+MihxLHEsdGhpcyx0LHUubC5iKHMpKX19LApSVDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgUC5oaih0
+aGlzLGIuQygiMCgpIikuYihhKSxiKX0sCkdZOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5WcCh0aGlz
+LHUuTS5iKGEpKX0sClB5OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQLk9SKHRoaXMsYi5DKCJ+KDAp
+IikuYihhKSxiKX0sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbnVsbH0sCnp6OmZ1bmN0aW9uKGEsYil7
+Yi5DKCIwKCkiKS5iKGEpCmlmKCQuWDM9PT1DLk5VKXJldHVybiBhLiQwKCkKcmV0dXJuIFAuVDgobnVs
+bCxudWxsLHRoaXMsYSxiKX0sCmJ2OmZ1bmN0aW9uKGEsYixjLGQpe2MuQygiQDwwPiIpLktxKGQpLkMo
+IjEoMikiKS5iKGEpCmQuYihiKQppZigkLlgzPT09Qy5OVSlyZXR1cm4gYS4kMShiKQpyZXR1cm4gUC55
+dihudWxsLG51bGwsdGhpcyxhLGIsYyxkKX0sCnJwOmZ1bmN0aW9uKGEsYixjLGQsZSxmKXtkLkMoIkA8
+MD4iKS5LcShlKS5LcShmKS5DKCIxKDIsMykiKS5iKGEpCmUuYihiKQpmLmIoYykKaWYoJC5YMz09PUMu
+TlUpcmV0dXJuIGEuJDIoYixjKQpyZXR1cm4gUC5ReChudWxsLG51bGwsdGhpcyxhLGIsYyxkLGUsZil9
+LApMajpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gYi5DKCJAPDA+IikuS3EoYykuS3EoZCkuQygiMSgy
+LDMpIikuYihhKX19ClAuaGoucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5hLnp6
+KHRoaXMuYix0aGlzLmMpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jLkMoIjAoKSIpfX0KUC5W
+cC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuYkgodGhpcy5iKX0sCiRTOjJ9
+ClAuT1IucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jCnJldHVybiB0aGlzLmEu
+RGwodGhpcy5iLHQuYihhKSx0KX0sCiRTOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYy5DKCJ+KDApIil9
+fQpQLmI2LnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzLHM9bmV3IFAubG0odCx0
+LnIsSC5MaCh0KS5DKCJsbTwxPiIpKQpzLmM9dC5lCnJldHVybiBzfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0
+dXJuIHRoaXMuYX0sCnRnOmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZih0eXBlb2YgYj09InN0cmluZyIm
+JmIhPT0iX19wcm90b19fIil7dD10aGlzLmIKaWYodD09bnVsbClyZXR1cm4hMQpyZXR1cm4gdS5KLmIo
+dFtiXSkhPW51bGx9ZWxzZXtzPXRoaXMuUFIoYikKcmV0dXJuIHN9fSwKUFI6ZnVuY3Rpb24oYSl7dmFy
+IHQ9dGhpcy5kCmlmKHQ9PW51bGwpcmV0dXJuITEKcmV0dXJuIHRoaXMuREYodFt0aGlzLk4oYSldLGEp
+Pj0wfSwKaTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj10aGlzCkguTGgocikuZC5iKGIpCmlmKHR5cGVv
+ZiBiPT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18iKXt0PXIuYgpyZXR1cm4gci5TKHQ9PW51bGw/ci5i
+PVAuVDIoKTp0LGIpfWVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYxMDczNzQxODIzKT09PWIp
+e3M9ci5jCnJldHVybiByLlMocz09bnVsbD9yLmM9UC5UMigpOnMsYil9ZWxzZSByZXR1cm4gci5CNyhi
+KX0sCkI3OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPXRoaXMKSC5MaChxKS5kLmIoYSkKdD1xLmQKaWYo
+dD09bnVsbCl0PXEuZD1QLlQyKCkKcz1xLk4oYSkKcj10W3NdCmlmKHI9PW51bGwpdFtzXT1bcS55byhh
+KV0KZWxzZXtpZihxLkRGKHIsYSk+PTApcmV0dXJuITEKci5wdXNoKHEueW8oYSkpfXJldHVybiEwfSwK
+UjpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMKaWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09Il9fcHJv
+dG9fXyIpcmV0dXJuIHQuTCh0LmIsYikKZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciImJihiJjEwNzM3
+NDE4MjMpPT09YilyZXR1cm4gdC5MKHQuYyxiKQplbHNlIHJldHVybiB0LnFnKGIpfSwKcWc6ZnVuY3Rp
+b24oYSl7dmFyIHQscyxyLHEscD10aGlzLG89cC5kCmlmKG89PW51bGwpcmV0dXJuITEKdD1wLk4oYSkK
+cz1vW3RdCnI9cC5ERihzLGEpCmlmKHI8MClyZXR1cm4hMQpxPXMuc3BsaWNlKHIsMSlbMF0KaWYoMD09
+PXMubGVuZ3RoKWRlbGV0ZSBvW3RdCnAuR1MocSkKcmV0dXJuITB9LApTOmZ1bmN0aW9uKGEsYil7SC5M
+aCh0aGlzKS5kLmIoYikKaWYodS5KLmIoYVtiXSkhPW51bGwpcmV0dXJuITEKYVtiXT10aGlzLnlvKGIp
+CnJldHVybiEwfSwKTDpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGE9PW51bGwpcmV0dXJuITEKdD11Lkou
+YihhW2JdKQppZih0PT1udWxsKXJldHVybiExCnRoaXMuR1ModCkKZGVsZXRlIGFbYl0KcmV0dXJuITB9
+LApYOmZ1bmN0aW9uKCl7dGhpcy5yPTEwNzM3NDE4MjMmdGhpcy5yKzF9LAp5bzpmdW5jdGlvbihhKXt2
+YXIgdCxzPXRoaXMscj1uZXcgUC5ibihILkxoKHMpLmQuYihhKSkKaWYocy5lPT1udWxsKXMuZT1zLmY9
+cgplbHNle3Q9cy5mCnIuYz10CnMuZj10LmI9cn0rK3MuYQpzLlgoKQpyZXR1cm4gcn0sCkdTOmZ1bmN0
+aW9uKGEpe3ZhciB0PXRoaXMscz1hLmMscj1hLmIKaWYocz09bnVsbCl0LmU9cgplbHNlIHMuYj1yCmlm
+KHI9PW51bGwpdC5mPXMKZWxzZSByLmM9czstLXQuYQp0LlgoKX0sCk46ZnVuY3Rpb24oYSl7cmV0dXJu
+IEouaGYoYSkmMTA3Mzc0MTgyM30sCkRGOmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZihhPT1udWxsKXJl
+dHVybi0xCnQ9YS5sZW5ndGgKZm9yKHM9MDtzPHQ7KytzKWlmKEouUk0oYVtzXS5hLGIpKXJldHVybiBz
+CnJldHVybi0xfX0KUC5ibi5wcm90b3R5cGU9e30KUC5sbS5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigp
+e3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQuYQppZih0LmIhPT1zLnIp
+dGhyb3cgSC5iKFAuYTQocykpCmVsc2V7cz10LmMKaWYocz09bnVsbCl7dC5zaihudWxsKQpyZXR1cm4h
+MX1lbHNle3Quc2oodC4kdGkuZC5iKHMuYSkpCnQuYz10LmMuYgpyZXR1cm4hMH19fSwKc2o6ZnVuY3Rp
+b24oYSl7dGhpcy5kPXRoaXMuJHRpLmQuYihhKX0sCiRpQW46MX0KUC5tVy5wcm90b3R5cGU9e30KUC5M
+VS5wcm90b3R5cGU9eyRpYlE6MSwkaWNYOjEsJGl6TToxfQpQLmxELnByb3RvdHlwZT17CmdrejpmdW5j
+dGlvbihhKXtyZXR1cm4gbmV3IEguYTcoYSx0aGlzLmdBKGEpLEgueksoYSkuQygiYTc8bEQuRT4iKSl9
+LApFOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMucShhLGIpfSwKSzpmdW5jdGlvbihhLGIpe3ZhciB0
+LHMKSC56SyhhKS5DKCJ+KGxELkUpIikuYihiKQp0PXRoaXMuZ0EoYSkKZm9yKHM9MDtzPHQ7KytzKXti
+LiQxKHRoaXMucShhLHMpKQppZih0IT09dGhpcy5nQShhKSl0aHJvdyBILmIoUC5hNChhKSl9fSwKRTI6
+ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUgueksoYSkKcmV0dXJuIG5ldyBILkE4KGEsdC5LcShjKS5DKCIx
+KGxELkUpIikuYihiKSx0LkMoIkA8bEQuRT4iKS5LcShjKS5DKCJBODwxLDI+IikpfSwKZHU6ZnVuY3Rp
+b24oYSxiLGMsZCl7dmFyIHQKSC56SyhhKS5DKCJsRC5FIikuYihkKQpQLmpCKGIsYyx0aGlzLmdBKGEp
+KQpmb3IodD1iO3Q8YzsrK3QpdGhpcy5ZKGEsdCxkKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuV0Uo
+YSwiWyIsIl0iKX19ClAuaWwucHJvdG90eXBlPXt9ClAucmEucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24o
+YSxiKXt2YXIgdCxzPXRoaXMuYQppZighcy5hKXRoaXMuYi5hKz0iLCAiCnMuYT0hMQpzPXRoaXMuYgp0
+PXMuYSs9SC5kKGEpCnMuYT10KyI6ICIKcy5hKz1ILmQoYil9LAokUzoxfQpQLllrLnByb3RvdHlwZT17
+Cks6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCkguTGgodGhpcykuQygifihZay5LLFlrLlYpIikuYihiKQpm
+b3IodD1KLklUKHRoaXMuZ1YoKSk7dC5GKCk7KXtzPXQuZ2woKQpiLiQyKHMsdGhpcy5xKDAscykpfX0s
+CmdQdTpmdW5jdGlvbihhKXtyZXR1cm4gSi5NMSh0aGlzLmdWKCksbmV3IFAueVEodGhpcyksSC5MaCh0
+aGlzKS5DKCJOMzxZay5LLFlrLlY+IikpfSwKeDQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEouemwodGhpcy5n
+VigpLGEpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIEouSG0odGhpcy5nVigpKX0sCnc6ZnVuY3Rpb24o
+YSl7cmV0dXJuIFAubk8odGhpcyl9LAokaVowOjF9ClAueVEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
+YSl7dmFyIHQ9dGhpcy5hLHM9SC5MaCh0KQpzLkMoIllrLksiKS5iKGEpCnJldHVybiBuZXcgUC5OMyhh
+LHQucSgwLGEpLHMuQygiQDxZay5LPiIpLktxKHMuQygiWWsuViIpKS5DKCJOMzwxLDI+IikpfSwKJFM6
+ZnVuY3Rpb24oKXtyZXR1cm4gSC5MaCh0aGlzLmEpLkMoIk4zPFlrLkssWWsuVj4oWWsuSykiKX19ClAu
+S1AucHJvdG90eXBlPXsKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQp0LmQuYihiKQp0
+LmNoWzFdLmIoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgdW5tb2RpZmlhYmxlIG1hcCIp
+KX19ClAuUG4ucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEucSgwLGIpfSwK
+WTpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQp0aGlzLmEuWSgwLHQuZC5iKGIpLHQuY2hb
+MV0uYihjKSl9LAp4NDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLng0KGEpfSwKSzpmdW5jdGlvbihh
+LGIpe3RoaXMuYS5LKDAsSC5MaCh0aGlzKS5DKCJ+KDEsMikiKS5iKGIpKX0sCmdBOmZ1bmN0aW9uKGEp
+e3ZhciB0PXRoaXMuYQpyZXR1cm4gdC5nQSh0KX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIEouaih0aGlz
+LmEpfSwKZ1B1OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdC5nUHUodCl9LAokaVowOjF9
+ClAuR2oucHJvdG90eXBlPXt9ClAubGYucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gUC5X
+RSh0aGlzLCJ7IiwifSIpfX0KUC5Wai5wcm90b3R5cGU9eyRpYlE6MSwkaWNYOjEsJGl4dToxfQpQLlh2
+LnByb3RvdHlwZT17CkZWOmZ1bmN0aW9uKGEsYil7dmFyIHQKZm9yKHQ9Si5JVChILkxoKHRoaXMpLkMo
+ImNYPDE+IikuYihiKSk7dC5GKCk7KXRoaXMuaSgwLHQuZ2woKSl9LAp3OmZ1bmN0aW9uKGEpe3JldHVy
+biBQLldFKHRoaXMsInsiLCJ9Iil9LAp6VjpmdW5jdGlvbihhLGIpe3ZhciB0LHM9UC5yaih0aGlzLHRo
+aXMucixILkxoKHRoaXMpLmQpCmlmKCFzLkYoKSlyZXR1cm4iIgppZihiPT09IiIpe3Q9IiIKZG8gdCs9
+SC5kKHMuZCkKd2hpbGUocy5GKCkpfWVsc2V7dD1ILmQocy5kKQpmb3IoO3MuRigpOyl0PXQrYitILmQo
+cy5kKX1yZXR1cm4gdC5jaGFyQ29kZUF0KDApPT0wP3Q6dH0sCiRpYlE6MSwKJGljWDoxLAokaXh1OjF9
+ClAublkucHJvdG90eXBlPXt9ClAuVEMucHJvdG90eXBlPXt9ClAuUlUucHJvdG90eXBlPXt9ClAudXcu
+cHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3ZhciB0LHM9dGhpcy5iCmlmKHM9PW51bGwpcmV0dXJu
+IHRoaXMuYy5xKDAsYikKZWxzZSBpZih0eXBlb2YgYiE9InN0cmluZyIpcmV0dXJuIG51bGwKZWxzZXt0
+PXNbYl0KcmV0dXJuIHR5cGVvZiB0PT0idW5kZWZpbmVkIj90aGlzLmZiKGIpOnR9fSwKZ0E6ZnVuY3Rp
+b24oYSl7cmV0dXJuIHRoaXMuYj09bnVsbD90aGlzLmMuYTp0aGlzLkNmKCkubGVuZ3RofSwKZ1Y6ZnVu
+Y3Rpb24oKXtpZih0aGlzLmI9PW51bGwpe3ZhciB0PXRoaXMuYwpyZXR1cm4gbmV3IEguaTUodCxILkxo
+KHQpLkMoImk1PDE+IikpfXJldHVybiBuZXcgUC5pOCh0aGlzKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3Zh
+ciB0LHMscj10aGlzCmlmKHIuYj09bnVsbClyLmMuWSgwLGIsYykKZWxzZSBpZihyLng0KGIpKXt0PXIu
+Ygp0W2JdPWMKcz1yLmEKaWYocz09bnVsbD90IT1udWxsOnMhPT10KXNbYl09bnVsbH1lbHNlIHIuWEso
+KS5ZKDAsYixjKX0sCng0OmZ1bmN0aW9uKGEpe2lmKHRoaXMuYj09bnVsbClyZXR1cm4gdGhpcy5jLng0
+KGEpCnJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5hLGEpfSwK
+SzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHA9dGhpcwp1LmNBLmIoYikKaWYocC5iPT1udWxsKXJl
+dHVybiBwLmMuSygwLGIpCnQ9cC5DZigpCmZvcihzPTA7czx0Lmxlbmd0aDsrK3Mpe3I9dFtzXQpxPXAu
+YltyXQppZih0eXBlb2YgcT09InVuZGVmaW5lZCIpe3E9UC5RZShwLmFbcl0pCnAuYltyXT1xfWIuJDIo
+cixxKQppZih0IT09cC5jKXRocm93IEguYihQLmE0KHApKX19LApDZjpmdW5jdGlvbigpe3ZhciB0PXUu
+ai5iKHRoaXMuYykKaWYodD09bnVsbCl0PXRoaXMuYz1ILlZNKE9iamVjdC5rZXlzKHRoaXMuYSksdS5z
+KQpyZXR1cm4gdH0sClhLOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvPXRoaXMKaWYoby5iPT1udWxs
+KXJldHVybiBvLmMKdD1QLkZsKHUuTix1LnopCnM9by5DZigpCmZvcihyPTA7cT1zLmxlbmd0aCxyPHE7
+KytyKXtwPXNbcl0KdC5ZKDAscCxvLnEoMCxwKSl9aWYocT09PTApQy5ObS5pKHMsbnVsbCkKZWxzZSBD
+Lk5tLnNBKHMsMCkKby5hPW8uYj1udWxsCnJldHVybiBvLmM9dH0sCmZiOmZ1bmN0aW9uKGEpe3ZhciB0
+CmlmKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5hLGEpKXJldHVybiBu
+dWxsCnQ9UC5RZSh0aGlzLmFbYV0pCnJldHVybiB0aGlzLmJbYV09dH19ClAuaTgucHJvdG90eXBlPXsK
+Z0E6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0LmdBKHQpfSwKRTpmdW5jdGlvbihhLGIp
+e3ZhciB0PXRoaXMuYQppZih0LmI9PW51bGwpdD10LmdWKCkuRSgwLGIpCmVsc2V7dD10LkNmKCkKaWYo
+YjwwfHxiPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LGIpCnQ9dFtiXX1yZXR1cm4gdH0sCmdrejpmdW5j
+dGlvbihhKXt2YXIgdD10aGlzLmEKaWYodC5iPT1udWxsKXt0PXQuZ1YoKQp0PXQuZ2t6KHQpfWVsc2V7
+dD10LkNmKCkKdD1uZXcgSi5tMSh0LHQubGVuZ3RoLEgudDYodCkuQygibTE8MT4iKSl9cmV0dXJuIHR9
+LAp0ZzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEueDQoYil9fQpQLkNWLnByb3RvdHlwZT17Cnly
+OmZ1bmN0aW9uKGEsYTAsYTEpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQsYyxi
+PSJJbnZhbGlkIGJhc2U2NCBlbmNvZGluZyBsZW5ndGggIgphMT1QLmpCKGEwLGExLGEubGVuZ3RoKQp0
+PSQuVjcoKQpmb3Iocz1hMCxyPXMscT1udWxsLHA9LTEsbz0tMSxuPTA7czxhMTtzPW0pe209cysxCmw9
+Qy54Qi5XKGEscykKaWYobD09PTM3KXtrPW0rMgppZihrPD1hMSl7aj1ILm9vKEMueEIuVyhhLG0pKQpp
+PUgub28oQy54Qi5XKGEsbSsxKSkKaD1qKjE2K2ktKGkmMjU2KQppZihoPT09MzcpaD0tMQptPWt9ZWxz
+ZSBoPS0xfWVsc2UgaD1sCmlmKDA8PWgmJmg8PTEyNyl7aWYoaDwwfHxoPj10Lmxlbmd0aClyZXR1cm4g
+SC5PSCh0LGgpCmc9dFtoXQppZihnPj0wKXtoPUMueEIubSgiQUJDREVGR0hJSktMTU5PUFFSU1RVVldY
+WVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyIsZykKaWYoaD09PWwpY29udGlu
+dWUKbD1ofWVsc2V7aWYoZz09PS0xKXtpZihwPDApe2Y9cT09bnVsbD9udWxsOnEuYS5sZW5ndGgKaWYo
+Zj09bnVsbClmPTAKcD1mKyhzLXIpCm89c30rK24KaWYobD09PTYxKWNvbnRpbnVlfWw9aH1pZihnIT09
+LTIpe2lmKHE9PW51bGwpcT1uZXcgUC5SbigiIikKcS5hKz1DLnhCLk5qKGEscixzKQpxLmErPUguTHco
+bCkKcj1tCmNvbnRpbnVlfX10aHJvdyBILmIoUC5ycigiSW52YWxpZCBiYXNlNjQgZGF0YSIsYSxzKSl9
+aWYocSE9bnVsbCl7Zj1xLmErPUMueEIuTmooYSxyLGExKQplPWYubGVuZ3RoCmlmKHA+PTApUC54TShh
+LG8sYTEscCxuLGUpCmVsc2V7ZD1DLmpuLnpZKGUtMSw0KSsxCmlmKGQ9PT0xKXRocm93IEguYihQLnJy
+KGIsYSxhMSkpCmZvcig7ZDw0Oyl7Zis9Ij0iCnEuYT1mOysrZH19Zj1xLmEKcmV0dXJuIEMueEIuaTco
+YSxhMCxhMSxmLmNoYXJDb2RlQXQoMCk9PTA/ZjpmKX1jPWExLWEwCmlmKHA+PTApUC54TShhLG8sYTEs
+cCxuLGMpCmVsc2V7ZD1DLmpuLnpZKGMsNCkKaWYoZD09PTEpdGhyb3cgSC5iKFAucnIoYixhLGExKSkK
+aWYoZD4xKWE9Qy54Qi5pNyhhLGExLGExLGQ9PT0yPyI9PSI6Ij0iKX1yZXR1cm4gYX19ClAuVTgucHJv
+dG90eXBlPXt9ClAuVWsucHJvdG90eXBlPXt9ClAud0kucHJvdG90eXBlPXt9ClAuWmkucHJvdG90eXBl
+PXt9ClAuYnkucHJvdG90eXBlPXsKcFc6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CnUuZXAuYihjKQp0PVAu
+QlMoYix0aGlzLmdIZSgpLmEpCnJldHVybiB0fSwKZ0hlOmZ1bmN0aW9uKCl7cmV0dXJuIEMuQTN9fQpQ
+Lk14LnByb3RvdHlwZT17fQpQLnU1LnByb3RvdHlwZT17CmdaRTpmdW5jdGlvbigpe3JldHVybiBDLlFr
+fX0KUC5FMy5wcm90b3R5cGU9ewpXSjpmdW5jdGlvbihhKXt2YXIgdCxzLHI9UC5qQigwLG51bGwsYS5s
+ZW5ndGgpLHE9ci0wCmlmKHE9PT0wKXJldHVybiBuZXcgVWludDhBcnJheSgwKQp0PW5ldyBVaW50OEFy
+cmF5KHEqMykKcz1uZXcgUC5Sdyh0KQppZihzLkd4KGEsMCxyKSE9PXIpcy5PNihKLmE2KGEsci0xKSww
+KQpyZXR1cm4gbmV3IFVpbnQ4QXJyYXkodC5zdWJhcnJheSgwLEguck0oMCxzLmIsdC5sZW5ndGgpKSl9
+fQpQLlJ3LnByb3RvdHlwZT17Ck82OmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLHI9cy5jLHE9cy5i
+LHA9cSsxLG89ci5sZW5ndGgKaWYoKGImNjQ1MTIpPT09NTYzMjApe3Q9NjU1MzYrKChhJjEwMjMpPDwx
+MCl8YiYxMDIzCnMuYj1wCmlmKHE+PW8pcmV0dXJuIEguT0gocixxKQpyW3FdPTI0MHx0Pj4+MTgKcT1z
+LmI9cCsxCmlmKHA+PW8pcmV0dXJuIEguT0gocixwKQpyW3BdPTEyOHx0Pj4+MTImNjMKcD1zLmI9cSsx
+CmlmKHE+PW8pcmV0dXJuIEguT0gocixxKQpyW3FdPTEyOHx0Pj4+NiY2MwpzLmI9cCsxCmlmKHA+PW8p
+cmV0dXJuIEguT0gocixwKQpyW3BdPTEyOHx0JjYzCnJldHVybiEwfWVsc2V7cy5iPXAKaWYocT49byly
+ZXR1cm4gSC5PSChyLHEpCnJbcV09MjI0fGE+Pj4xMgpxPXMuYj1wKzEKaWYocD49bylyZXR1cm4gSC5P
+SChyLHApCnJbcF09MTI4fGE+Pj42JjYzCnMuYj1xKzEKaWYocT49bylyZXR1cm4gSC5PSChyLHEpCnJb
+cV09MTI4fGEmNjMKcmV0dXJuITF9fSwKR3g6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxu
+LG09dGhpcwppZihiIT09YyYmKEMueEIubShhLGMtMSkmNjQ1MTIpPT09NTUyOTYpLS1jCmZvcih0PW0u
+YyxzPXQubGVuZ3RoLHI9YjtyPGM7KytyKXtxPUMueEIuVyhhLHIpCmlmKHE8PTEyNyl7cD1tLmIKaWYo
+cD49cylicmVhawptLmI9cCsxCnRbcF09cX1lbHNlIGlmKChxJjY0NTEyKT09PTU1Mjk2KXtpZihtLmIr
+Mz49cylicmVhawpvPXIrMQppZihtLk82KHEsQy54Qi5XKGEsbykpKXI9b31lbHNlIGlmKHE8PTIwNDcp
+e3A9bS5iCm49cCsxCmlmKG4+PXMpYnJlYWsKbS5iPW4KaWYocD49cylyZXR1cm4gSC5PSCh0LHApCnRb
+cF09MTkyfHE+Pj42Cm0uYj1uKzEKdFtuXT0xMjh8cSY2M31lbHNle3A9bS5iCmlmKHArMj49cylicmVh
+awpuPW0uYj1wKzEKaWYocD49cylyZXR1cm4gSC5PSCh0LHApCnRbcF09MjI0fHE+Pj4xMgpwPW0uYj1u
+KzEKaWYobj49cylyZXR1cm4gSC5PSCh0LG4pCnRbbl09MTI4fHE+Pj42JjYzCm0uYj1wKzEKaWYocD49
+cylyZXR1cm4gSC5PSCh0LHApCnRbcF09MTI4fHEmNjN9fXJldHVybiByfX0KUC5HWS5wcm90b3R5cGU9
+ewpXSjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwKdS5MLmIoYSkKdD1QLmt5KCExLGEs
+MCxudWxsKQppZih0IT1udWxsKXJldHVybiB0CnM9UC5qQigwLG51bGwsSi5IbShhKSkKcj1QLmNQKGEs
+MCxzKQppZihyPjApe3E9UC5ITShhLDAscikKaWYocj09PXMpcmV0dXJuIHEKcD1uZXcgUC5SbihxKQpv
+PXIKbj0hMX1lbHNle289MApwPW51bGwKbj0hMH1pZihwPT1udWxsKXA9bmV3IFAuUm4oIiIpCm09bmV3
+IFAuYnooITEscCkKbS5jPW4KbS5NRShhLG8scykKaWYobS5lPjApe0gudmgoUC5ycigiVW5maW5pc2hl
+ZCBVVEYtOCBvY3RldCBzZXF1ZW5jZSIsYSxzKSkKcC5hKz1ILkx3KDY1NTMzKQptLmY9bS5lPW0uZD0w
+fWw9cC5hCnJldHVybiBsLmNoYXJDb2RlQXQoMCk9PTA/bDpsfX0KUC5iei5wcm90b3R5cGU9ewpNRTpm
+dW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGg9dGhpcyxnPSJCYWQgVVRG
+LTggZW5jb2RpbmcgMHgiCnUuTC5iKGEpCnQ9aC5kCnM9aC5lCnI9aC5mCmguZj1oLmU9aC5kPTAKJGxh
+YmVsMCQwOmZvcihxPUouVTYoYSkscD1oLmIsbz1iOyEwO289ail7JGxhYmVsMSQxOmlmKHM+MCl7ZG97
+aWYobz09PWMpYnJlYWsgJGxhYmVsMCQwCm49cS5xKGEsbykKaWYodHlwZW9mIG4hPT0ibnVtYmVyIily
+ZXR1cm4gbi56TSgpCmlmKChuJjE5MikhPT0xMjgpe209UC5ycihnK0Muam4uV1oobiwxNiksYSxvKQp0
+aHJvdyBILmIobSl9ZWxzZXt0PSh0PDw2fG4mNjMpPj4+MDstLXM7KytvfX13aGlsZShzPjApCm09ci0x
+CmlmKG08MHx8bT49NClyZXR1cm4gSC5PSChDLkdiLG0pCmlmKHQ8PUMuR2JbbV0pe209UC5ycigiT3Zl
+cmxvbmcgZW5jb2Rpbmcgb2YgMHgiK0Muam4uV1oodCwxNiksYSxvLXItMSkKdGhyb3cgSC5iKG0pfWlm
+KHQ+MTExNDExMSl7bT1QLnJyKCJDaGFyYWN0ZXIgb3V0c2lkZSB2YWxpZCBVbmljb2RlIHJhbmdlOiAw
+eCIrQy5qbi5XWih0LDE2KSxhLG8tci0xKQp0aHJvdyBILmIobSl9aWYoIWguY3x8dCE9PTY1Mjc5KXAu
+YSs9SC5Mdyh0KQpoLmM9ITF9Zm9yKG09bzxjO207KXtsPVAuY1AoYSxvLGMpCmlmKGw+MCl7aC5jPSEx
+Cms9bytsCnAuYSs9UC5ITShhLG8saykKaWYoaz09PWMpYnJlYWt9ZWxzZSBrPW8Kaj1rKzEKbj1xLnEo
+YSxrKQppZih0eXBlb2YgbiE9PSJudW1iZXIiKXJldHVybiBuLkooKQppZihuPDApe2k9UC5ycigiTmVn
+YXRpdmUgVVRGLTggY29kZSB1bml0OiAtMHgiK0Muam4uV1ooLW4sMTYpLGEsai0xKQp0aHJvdyBILmIo
+aSl9ZWxzZXtpZigobiYyMjQpPT09MTkyKXt0PW4mMzEKcz0xCnI9MQpjb250aW51ZSAkbGFiZWwwJDB9
+aWYoKG4mMjQwKT09PTIyNCl7dD1uJjE1CnM9MgpyPTIKY29udGludWUgJGxhYmVsMCQwfWlmKChuJjI0
+OCk9PT0yNDAmJm48MjQ1KXt0PW4mNwpzPTMKcj0zCmNvbnRpbnVlICRsYWJlbDAkMH1pPVAucnIoZytD
+LmpuLldaKG4sMTYpLGEsai0xKQp0aHJvdyBILmIoaSl9fWJyZWFrICRsYWJlbDAkMH1pZihzPjApe2gu
+ZD10CmguZT1zCmguZj1yfX19ClAuV0YucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxz
+LHIKdS5mby5iKGEpCnQ9dGhpcy5iCnM9dGhpcy5hCnQuYSs9cy5hCnI9dC5hKz1ILmQoYS5hKQp0LmE9
+cisiOiAiCnQuYSs9UC5wKGIpCnMuYT0iLCAifSwKJFM6Mzh9ClAuYTIucHJvdG90eXBlPXt9ClAuaVAu
+cHJvdG90eXBlPXsKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiExCnJldHVybiBiIGlu
+c3RhbmNlb2YgUC5pUCYmdGhpcy5hPT09Yi5hJiYhMH0sCmdpTzpmdW5jdGlvbihhKXt2YXIgdD10aGlz
+LmEKcmV0dXJuKHReQy5qbi53Ryh0LDMwKSkmMTA3Mzc0MTgyM30sCnc6ZnVuY3Rpb24oYSl7dmFyIHQ9
+dGhpcyxzPVAuR3EoSC50Sih0KSkscj1QLmgwKEguTlModCkpLHE9UC5oMChILmpBKHQpKSxwPVAuaDAo
+SC5JWCh0KSksbz1QLmgwKEguY2godCkpLG49UC5oMChILkpkKHQpKSxtPVAuVngoSC5vMSh0KSksbD1z
+KyItIityKyItIitxKyIgIitwKyI6IitvKyI6IituKyIuIittCnJldHVybiBsfX0KUC5DUC5wcm90b3R5
+cGU9e30KUC5YUy5wcm90b3R5cGU9e30KUC5DNi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0
+PXRoaXMuYQppZih0IT1udWxsKXJldHVybiJBc3NlcnRpb24gZmFpbGVkOiAiK1AucCh0KQpyZXR1cm4i
+QXNzZXJ0aW9uIGZhaWxlZCJ9fQpQLm4ucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iVGhy
+b3cgb2YgbnVsbC4ifX0KUC51LnByb3RvdHlwZT17CmdaOmZ1bmN0aW9uKCl7cmV0dXJuIkludmFsaWQg
+YXJndW1lbnQiKyghdGhpcy5hPyIocykiOiIiKX0sCmd1OmZ1bmN0aW9uKCl7cmV0dXJuIiJ9LAp3OmZ1
+bmN0aW9uKGEpe3ZhciB0LHMscixxLHA9dGhpcyxvPXAuYyxuPW8hPW51bGw/IiAoIitvKyIpIjoiIgpv
+PXAuZAp0PW89PW51bGw/IiI6IjogIitILmQobykKcz1wLmdaKCkrbit0CmlmKCFwLmEpcmV0dXJuIHMK
+cj1wLmd1KCkKcT1QLnAocC5iKQpyZXR1cm4gcytyKyI6ICIrcX19ClAuYkoucHJvdG90eXBlPXsKZ1o6
+ZnVuY3Rpb24oKXtyZXR1cm4iUmFuZ2VFcnJvciJ9LApndTpmdW5jdGlvbigpe3ZhciB0LHMscj10aGlz
+LmUKaWYocj09bnVsbCl7cj10aGlzLmYKdD1yIT1udWxsPyI6IE5vdCBsZXNzIHRoYW4gb3IgZXF1YWwg
+dG8gIitILmQocik6IiJ9ZWxzZXtzPXRoaXMuZgppZihzPT1udWxsKXQ9IjogTm90IGdyZWF0ZXIgdGhh
+biBvciBlcXVhbCB0byAiK0guZChyKQplbHNlIGlmKHM+cil0PSI6IE5vdCBpbiByYW5nZSAiK0guZChy
+KSsiLi4iK0guZChzKSsiLCBpbmNsdXNpdmUiCmVsc2UgdD1zPHI/IjogVmFsaWQgdmFsdWUgcmFuZ2Ug
+aXMgZW1wdHkiOiI6IE9ubHkgdmFsaWQgdmFsdWUgaXMgIitILmQocil9cmV0dXJuIHR9fQpQLmVZLnBy
+b3RvdHlwZT17CmdaOmZ1bmN0aW9uKCl7cmV0dXJuIlJhbmdlRXJyb3IifSwKZ3U6ZnVuY3Rpb24oKXt2
+YXIgdCxzPUguU2ModGhpcy5iKQppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLkooKQppZihz
+PDApcmV0dXJuIjogaW5kZXggbXVzdCBub3QgYmUgbmVnYXRpdmUiCnQ9dGhpcy5mCmlmKHQ9PT0wKXJl
+dHVybiI6IG5vIGluZGljZXMgYXJlIHZhbGlkIgpyZXR1cm4iOiBpbmRleCBzaG91bGQgYmUgbGVzcyB0
+aGFuICIrSC5kKHQpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZn19ClAubXAucHJvdG90eXBl
+PXsKdzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9dGhpcyxrPXt9LGo9bmV3IFAuUm4o
+IiIpCmsuYT0iIgpmb3IodD1sLmMscz10Lmxlbmd0aCxyPTAscT0iIixwPSIiO3I8czsrK3IscD0iLCAi
+KXtvPXRbcl0Kai5hPXErcApxPWouYSs9UC5wKG8pCmsuYT0iLCAifWwuZC5LKDAsbmV3IFAuV0Yoayxq
+KSkKbj1QLnAobC5hKQptPWoudygwKQp0PSJOb1N1Y2hNZXRob2RFcnJvcjogbWV0aG9kIG5vdCBmb3Vu
+ZDogJyIrSC5kKGwuYi5hKSsiJ1xuUmVjZWl2ZXI6ICIrbisiXG5Bcmd1bWVudHM6IFsiK20rIl0iCnJl
+dHVybiB0fX0KUC51Yi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJVbnN1cHBvcnRlZCBv
+cGVyYXRpb246ICIrdGhpcy5hfX0KUC5kcy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRo
+aXMuYQpyZXR1cm4gdCE9bnVsbD8iVW5pbXBsZW1lbnRlZEVycm9yOiAiK3Q6IlVuaW1wbGVtZW50ZWRF
+cnJvciJ9fQpQLmxqLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIkJhZCBzdGF0ZTogIit0
+aGlzLmF9fQpQLlVWLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCmlmKHQ9PW51
+bGwpcmV0dXJuIkNvbmN1cnJlbnQgbW9kaWZpY2F0aW9uIGR1cmluZyBpdGVyYXRpb24uIgpyZXR1cm4i
+Q29uY3VycmVudCBtb2RpZmljYXRpb24gZHVyaW5nIGl0ZXJhdGlvbjogIitQLnAodCkrIi4ifX0KUC5r
+NS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJPdXQgb2YgTWVtb3J5In0sCiRpWFM6MX0K
+UC5LWS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJTdGFjayBPdmVyZmxvdyJ9LAokaVhT
+OjF9ClAuYy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdD09bnVs
+bD8iUmVhZGluZyBzdGF0aWMgdmFyaWFibGUgZHVyaW5nIGl0cyBpbml0aWFsaXphdGlvbiI6IlJlYWRp
+bmcgc3RhdGljIHZhcmlhYmxlICciK3QrIicgZHVyaW5nIGl0cyBpbml0aWFsaXphdGlvbiJ9fQpQLkNE
+LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIkV4Y2VwdGlvbjogIit0aGlzLmF9fQpQLmFF
+LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGg9dGhp
+cy5hLGc9aCE9bnVsbCYmIiIhPT1oPyJGb3JtYXRFeGNlcHRpb246ICIrSC5kKGgpOiJGb3JtYXRFeGNl
+cHRpb24iLGY9dGhpcy5jLGU9dGhpcy5iCmlmKHR5cGVvZiBlPT0ic3RyaW5nIil7aWYoZiE9bnVsbClo
+PWY8MHx8Zj5lLmxlbmd0aAplbHNlIGg9ITEKaWYoaClmPW51bGwKaWYoZj09bnVsbCl7dD1lLmxlbmd0
+aD43OD9DLnhCLk5qKGUsMCw3NSkrIi4uLiI6ZQpyZXR1cm4gZysiXG4iK3R9Zm9yKHM9MSxyPTAscT0h
+MSxwPTA7cDxmOysrcCl7bz1DLnhCLlcoZSxwKQppZihvPT09MTApe2lmKHIhPT1wfHwhcSkrK3MKcj1w
+KzEKcT0hMX1lbHNlIGlmKG89PT0xMyl7KytzCnI9cCsxCnE9ITB9fWc9cz4xP2crKCIgKGF0IGxpbmUg
+IitzKyIsIGNoYXJhY3RlciAiKyhmLXIrMSkrIilcbiIpOmcrKCIgKGF0IGNoYXJhY3RlciAiKyhmKzEp
+KyIpXG4iKQpuPWUubGVuZ3RoCmZvcihwPWY7cDxuOysrcCl7bz1DLnhCLm0oZSxwKQppZihvPT09MTB8
+fG89PT0xMyl7bj1wCmJyZWFrfX1pZihuLXI+NzgpaWYoZi1yPDc1KXttPXIrNzUKbD1yCms9IiIKaj0i
+Li4uIn1lbHNle2lmKG4tZjw3NSl7bD1uLTc1Cm09bgpqPSIifWVsc2V7bD1mLTM2Cm09ZiszNgpqPSIu
+Li4ifWs9Ii4uLiJ9ZWxzZXttPW4KbD1yCms9IiIKaj0iIn1pPUMueEIuTmooZSxsLG0pCnJldHVybiBn
+K2sraStqKyJcbiIrQy54Qi5JeCgiICIsZi1sK2subGVuZ3RoKSsiXlxuIn1lbHNlIHJldHVybiBmIT1u
+dWxsP2crKCIgKGF0IG9mZnNldCAiK0guZChmKSsiKSIpOmd9fQpQLkVILnByb3RvdHlwZT17fQpQLktO
+LnByb3RvdHlwZT17fQpQLmNYLnByb3RvdHlwZT17CkUyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILkxo
+KHRoaXMpCnJldHVybiBILksxKHRoaXMsdC5LcShjKS5DKCIxKGNYLkUpIikuYihiKSx0LkMoImNYLkUi
+KSxjKX0sCmV2OmZ1bmN0aW9uKGEsYil7dmFyIHQ9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEguVTUodGhp
+cyx0LkMoImEyKGNYLkUpIikuYihiKSx0LkMoIlU1PGNYLkU+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7dmFy
+IHQscz10aGlzLmdreih0aGlzKQpmb3IodD0wO3MuRigpOykrK3QKcmV0dXJuIHR9LApnbDA6ZnVuY3Rp
+b24oYSl7cmV0dXJuIXRoaXMuZ2t6KHRoaXMpLkYoKX0sCmdyODpmdW5jdGlvbihhKXt2YXIgdCxzPXRo
+aXMuZ2t6KHRoaXMpCmlmKCFzLkYoKSl0aHJvdyBILmIoSC5XcCgpKQp0PXMuZ2woKQppZihzLkYoKSl0
+aHJvdyBILmIoSC5kVSgpKQpyZXR1cm4gdH0sCkU6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIKUC5rMShi
+LCJpbmRleCIpCmZvcih0PXRoaXMuZ2t6KHRoaXMpLHM9MDt0LkYoKTspe3I9dC5nbCgpCmlmKGI9PT1z
+KXJldHVybiByOysrc310aHJvdyBILmIoUC5DZihiLHRoaXMsImluZGV4IixudWxsLHMpKX0sCnc6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIFAuRVAodGhpcywiKCIsIikiKX19ClAuQW4ucHJvdG90eXBlPXt9ClAuek0u
+cHJvdG90eXBlPXskaWJROjEsJGljWDoxfQpQLlowLnByb3RvdHlwZT17fQpQLk4zLnByb3RvdHlwZT17
+Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIk1hcEVudHJ5KCIrSC5kKHRoaXMuYSkrIjogIitILmQodGhpcy5i
+KSsiKSJ9fQpQLmM4LnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gUC5rLnByb3RvdHlw
+ZS5naU8uY2FsbCh0aGlzLHRoaXMpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4ibnVsbCJ9fQpQLkZLLnBy
+b3RvdHlwZT17fQpQLmsucHJvdG90eXBlPXtjb25zdHJ1Y3RvcjpQLmssJGlrOjEsCkROOmZ1bmN0aW9u
+KGEsYil7cmV0dXJuIHRoaXM9PT1ifSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKHRoaXMpfSwK
+dzpmdW5jdGlvbihhKXtyZXR1cm4iSW5zdGFuY2Ugb2YgJyIrSC5kKEguTSh0aGlzKSkrIicifSwKZTc6
+ZnVuY3Rpb24oYSxiKXt1Lm8uYihiKQp0aHJvdyBILmIoUC5scih0aGlzLGIuZ1dhKCksYi5nbmQoKSxi
+LmdWbSgpKSl9LAp0b1N0cmluZzpmdW5jdGlvbigpe3JldHVybiB0aGlzLncodGhpcyl9fQpQLk9kLnBy
+b3RvdHlwZT17fQpQLmliLnByb3RvdHlwZT17JGlPZDoxfQpQLnh1LnByb3RvdHlwZT17fQpQLkd6LnBy
+b3RvdHlwZT17fQpQLnFVLnByb3RvdHlwZT17JGl2WDoxfQpQLlJuLnByb3RvdHlwZT17CmdBOmZ1bmN0
+aW9uKGEpe3JldHVybiB0aGlzLmEubGVuZ3RofSwKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0
+dXJuIHQuY2hhckNvZGVBdCgwKT09MD90OnR9LAokaUJMOjF9ClAuR0QucHJvdG90eXBlPXt9ClAubjEu
+cHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscQp1LmYuYihhKQpILnkoYikKdD1K
+LnJZKGIpLk9ZKGIsIj0iKQppZih0PT09LTEpe2lmKGIhPT0iIilhLlkoMCxQLmt1KGIsMCxiLmxlbmd0
+aCx0aGlzLmEsITApLCIiKX1lbHNlIGlmKHQhPT0wKXtzPUMueEIuTmooYiwwLHQpCnI9Qy54Qi5HKGIs
+dCsxKQpxPXRoaXMuYQphLlkoMCxQLmt1KHMsMCxzLmxlbmd0aCxxLCEwKSxQLmt1KHIsMCxyLmxlbmd0
+aCxxLCEwKSl9cmV0dXJuIGF9LAokUzoyMH0KUC5jUy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIp
+e3Rocm93IEguYihQLnJyKCJJbGxlZ2FsIElQdjQgYWRkcmVzcywgIithLHRoaXMuYSxiKSl9LAokUzo0
+M30KUC5WQy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3Rocm93IEguYihQLnJyKCJJbGxlZ2Fs
+IElQdjYgYWRkcmVzcywgIithLHRoaXMuYSxiKSl9LAokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy4k
+MihhLG51bGwpfSwKJFM6NDR9ClAuSlQucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdApp
+ZihiLWE+NCl0aGlzLmEuJDIoImFuIElQdjYgcGFydCBjYW4gb25seSBjb250YWluIGEgbWF4aW11bSBv
+ZiA0IGhleCBkaWdpdHMiLGEpCnQ9UC5RQShDLnhCLk5qKHRoaXMuYixhLGIpLG51bGwsMTYpCmlmKHR5
+cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuSigpCmlmKHQ8MHx8dD42NTUzNSl0aGlzLmEuJDIoImVh
+Y2ggcGFydCBtdXN0IGJlIGluIHRoZSByYW5nZSBvZiBgMHgwLi4weEZGRkZgIixhKQpyZXR1cm4gdH0s
+CiRTOjQ2fQpQLkRuLnByb3RvdHlwZT17CmdrdTpmdW5jdGlvbigpe3JldHVybiB0aGlzLmJ9LApnSmY6
+ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jCmlmKHQ9PW51bGwpcmV0dXJuIiIKaWYoQy54Qi5uKHQsIlsi
+KSlyZXR1cm4gQy54Qi5Oaih0LDEsdC5sZW5ndGgtMSkKcmV0dXJuIHR9LApndHA6ZnVuY3Rpb24oYSl7
+dmFyIHQ9dGhpcy5kCmlmKHQ9PW51bGwpcmV0dXJuIFAud0sodGhpcy5hKQpyZXR1cm4gdH0sCmd0UDpm
+dW5jdGlvbigpe3ZhciB0PXRoaXMuZgpyZXR1cm4gdD09bnVsbD8iIjp0fSwKZ0thOmZ1bmN0aW9uKCl7
+dmFyIHQ9dGhpcy5yCnJldHVybiB0PT1udWxsPyIiOnR9LApubTpmdW5jdGlvbihhLGIpe3ZhciB0LHMs
+cixxLHAsbyxuLG0sbD10aGlzCnUuWC5iKG51bGwpCnUuYi5iKGIpCnQ9bC5hCnM9dD09PSJmaWxlIgpy
+PWwuYgpxPWwuZApwPWwuYwppZighKHAhPW51bGwpKXA9ci5sZW5ndGghPT0wfHxxIT1udWxsfHxzPyIi
+Om51bGwKbz1sLmUKaWYoIXMpbj1wIT1udWxsJiZvLmxlbmd0aCE9PTAKZWxzZSBuPSEwCmlmKG4mJiFD
+LnhCLm4obywiLyIpKW89Ii8iK28KbT1QLmxlKG51bGwsMCwwLGIpCnJldHVybiBuZXcgUC5Ebih0LHIs
+cCxxLG8sbSxsLnIpfSwKZ0ZqOmZ1bmN0aW9uKCl7dmFyIHQscz10aGlzLngKaWYocyE9bnVsbClyZXR1
+cm4gcwp0PXRoaXMuZQppZih0Lmxlbmd0aCE9PTAmJkMueEIuVyh0LDApPT09NDcpdD1DLnhCLkcodCwx
+KQpzPXQ9PT0iIj9DLnhEOlAuQUYobmV3IEguQTgoSC5WTSh0LnNwbGl0KCIvIiksdS5zKSx1LmRPLmIo
+UC5QSCgpKSx1LmRvKSx1Lk4pCnRoaXMuc282KHMpCnJldHVybiBzfSwKZ2hZOmZ1bmN0aW9uKCl7dmFy
+IHQscz10aGlzCmlmKHMuUT09bnVsbCl7dD1zLmYKcy5zUkgobmV3IFAuR2ooUC5XWCh0PT1udWxsPyIi
+OnQpLHUuVykpfXJldHVybiBzLlF9LApKaDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbwpmb3Io
+dD0wLHM9MDtDLnhCLlFpKGIsIi4uLyIscyk7KXtzKz0zOysrdH1yPUMueEIuY24oYSwiLyIpCndoaWxl
+KCEwKXtpZighKHI+MCYmdD4wKSlicmVhawpxPUMueEIuUGsoYSwiLyIsci0xKQppZihxPDApYnJlYWsK
+cD1yLXEKbz1wIT09MgppZighb3x8cD09PTMpaWYoQy54Qi5tKGEscSsxKT09PTQ2KW89IW98fEMueEIu
+bShhLHErMik9PT00NgplbHNlIG89ITEKZWxzZSBvPSExCmlmKG8pYnJlYWs7LS10CnI9cX1yZXR1cm4g
+Qy54Qi5pNyhhLHIrMSxudWxsLEMueEIuRyhiLHMtMyp0KSl9LApaSTpmdW5jdGlvbihhKXtyZXR1cm4g
+dGhpcy5tUyhQLmhLKGEpKX0sCm1TOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrPXRo
+aXMsaj1udWxsCmlmKGEuZ0ZpKCkubGVuZ3RoIT09MCl7dD1hLmdGaSgpCmlmKGEuZ2NqKCkpe3M9YS5n
+a3UoKQpyPWEuZ0pmKGEpCnE9YS5neEEoKT9hLmd0cChhKTpqfWVsc2V7cT1qCnI9cQpzPSIifXA9UC54
+ZShhLmdJaShhKSkKbz1hLmdRRCgpP2EuZ3RQKCk6an1lbHNle3Q9ay5hCmlmKGEuZ2NqKCkpe3M9YS5n
+a3UoKQpyPWEuZ0pmKGEpCnE9UC53QihhLmd4QSgpP2EuZ3RwKGEpOmosdCkKcD1QLnhlKGEuZ0lpKGEp
+KQpvPWEuZ1FEKCk/YS5ndFAoKTpqfWVsc2V7cz1rLmIKcj1rLmMKcT1rLmQKaWYoYS5nSWkoYSk9PT0i
+Iil7cD1rLmUKbz1hLmdRRCgpP2EuZ3RQKCk6ay5mfWVsc2V7aWYoYS5ndFQoKSlwPVAueGUoYS5nSWko
+YSkpCmVsc2V7bj1rLmUKaWYobi5sZW5ndGg9PT0wKWlmKHI9PW51bGwpcD10Lmxlbmd0aD09PTA/YS5n
+SWkoYSk6UC54ZShhLmdJaShhKSkKZWxzZSBwPVAueGUoIi8iK2EuZ0lpKGEpKQplbHNle209ay5KaChu
+LGEuZ0lpKGEpKQpsPXQubGVuZ3RoPT09MAppZighbHx8ciE9bnVsbHx8Qy54Qi5uKG4sIi8iKSlwPVAu
+eGUobSkKZWxzZSBwPVAud0YobSwhbHx8ciE9bnVsbCl9fW89YS5nUUQoKT9hLmd0UCgpOmp9fX1yZXR1
+cm4gbmV3IFAuRG4odCxzLHIscSxwLG8sYS5nWjgoKT9hLmdLYSgpOmopfSwKZ2NqOmZ1bmN0aW9uKCl7
+cmV0dXJuIHRoaXMuYyE9bnVsbH0sCmd4QTpmdW5jdGlvbigpe3JldHVybiB0aGlzLmQhPW51bGx9LApn
+UUQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5mIT1udWxsfSwKZ1o4OmZ1bmN0aW9uKCl7cmV0dXJuIHRo
+aXMuciE9bnVsbH0sCmd0VDpmdW5jdGlvbigpe3JldHVybiBDLnhCLm4odGhpcy5lLCIvIil9LAp0NDpm
+dW5jdGlvbigpe3ZhciB0LHMscj10aGlzLHE9ci5hCmlmKHEhPT0iIiYmcSE9PSJmaWxlIil0aHJvdyBI
+LmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhICIrSC5kKHEpKyIgVVJJIikp
+CnE9ci5mCmlmKChxPT1udWxsPyIiOnEpIT09IiIpdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0
+IGEgZmlsZSBwYXRoIGZyb20gYSBVUkkgd2l0aCBhIHF1ZXJ5IGNvbXBvbmVudCIpKQpxPXIucgppZigo
+cT09bnVsbD8iIjpxKSE9PSIiKXRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0
+aCBmcm9tIGEgVVJJIHdpdGggYSBmcmFnbWVudCBjb21wb25lbnQiKSkKdD0kLndRKCkKaWYoSC5vVCh0
+KSlxPVAubW4ocikKZWxzZXtpZihyLmMhPW51bGwmJnIuZ0pmKHIpIT09IiIpSC52aChQLkw0KCJDYW5u
+b3QgZXh0cmFjdCBhIG5vbi1XaW5kb3dzIGZpbGUgcGF0aCBmcm9tIGEgZmlsZSBVUkkgd2l0aCBhbiBh
+dXRob3JpdHkiKSkKcz1yLmdGaigpClAua0UocywhMSkKcT1QLnZnKEMueEIubihyLmUsIi8iKT8iLyI6
+IiIscywiLyIpCnE9cS5jaGFyQ29kZUF0KDApPT0wP3E6cX1yZXR1cm4gcX0sCnc6ZnVuY3Rpb24oYSl7
+dmFyIHQscyxyLHE9dGhpcyxwPXEueQppZihwPT1udWxsKXtwPXEuYQp0PXAubGVuZ3RoIT09MD9wKyI6
+IjoiIgpzPXEuYwpyPXM9PW51bGwKaWYoIXJ8fHA9PT0iZmlsZSIpe3A9dCsiLy8iCnQ9cS5iCmlmKHQu
+bGVuZ3RoIT09MClwPXArdCsiQCIKaWYoIXIpcCs9cwp0PXEuZAppZih0IT1udWxsKXA9cCsiOiIrSC5k
+KHQpfWVsc2UgcD10CnArPXEuZQp0PXEuZgppZih0IT1udWxsKXA9cCsiPyIrdAp0PXEucgppZih0IT1u
+dWxsKXA9cCsiIyIrdApwPXEueT1wLmNoYXJDb2RlQXQoMCk9PTA/cDpwfXJldHVybiBwfSwKRE46ZnVu
+Y3Rpb24oYSxiKXt2YXIgdCxzLHI9dGhpcwppZihiPT1udWxsKXJldHVybiExCmlmKHI9PT1iKXJldHVy
+biEwCmlmKHUuRC5jKGIpKWlmKHIuYT09Yi5nRmkoKSlpZihyLmMhPW51bGw9PT1iLmdjaigpKWlmKHIu
+Yj09Yi5na3UoKSlpZihyLmdKZihyKT09Yi5nSmYoYikpaWYoci5ndHAocik9PWIuZ3RwKGIpKWlmKHIu
+ZT09PWIuZ0lpKGIpKXt0PXIuZgpzPXQ9PW51bGwKaWYoIXM9PT1iLmdRRCgpKXtpZihzKXQ9IiIKaWYo
+dD09PWIuZ3RQKCkpe3Q9ci5yCnM9dD09bnVsbAppZighcz09PWIuZ1o4KCkpe2lmKHMpdD0iIgp0PXQ9
+PT1iLmdLYSgpfWVsc2UgdD0hMX1lbHNlIHQ9ITF9ZWxzZSB0PSExfWVsc2UgdD0hMQplbHNlIHQ9ITEK
+ZWxzZSB0PSExCmVsc2UgdD0hMQplbHNlIHQ9ITEKZWxzZSB0PSExCmVsc2UgdD0hMQpyZXR1cm4gdH0s
+CmdpTzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLnoKcmV0dXJuIHQ9PW51bGw/dGhpcy56PUMueEIuZ2lP
+KHRoaXMudygwKSk6dH0sCnNvNjpmdW5jdGlvbihhKXt0aGlzLng9dS5hLmIoYSl9LApzUkg6ZnVuY3Rp
+b24oYSl7dGhpcy5RPXUuZi5iKGEpfSwKJGlpRDoxLApnRmk6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5h
+fSwKZ0lpOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmV9fQpQLmUxLnByb3RvdHlwZT17CiQxOmZ1bmN0
+aW9uKGEpe3Rocm93IEguYihQLnJyKCJJbnZhbGlkIHBvcnQiLHRoaXMuYSx0aGlzLmIrMSkpfSwKJFM6
+MTR9ClAuTlkucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9IklsbGVnYWwgcGF0aCBjaGFy
+YWN0ZXIgIgpILnkoYSkKaWYoSi56bChhLCIvIikpaWYodGhpcy5hKXRocm93IEguYihQLnhZKHQrYSkp
+CmVsc2UgdGhyb3cgSC5iKFAuTDQodCthKSl9LAokUzoxNH0KUC5SWi5wcm90b3R5cGU9ewokMTpmdW5j
+dGlvbihhKXtyZXR1cm4gUC5lUChDLlpKLEgueShhKSxDLnhNLCExKX0sCiRTOjV9ClAuTUUucHJvdG90
+eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmIscz10aGlzLmEKdC5hKz1zLmEKcy5hPSIm
+IgpzPXQuYSs9SC5kKFAuZVAoQy5GMyxhLEMueE0sITApKQppZihiIT1udWxsJiZiLmxlbmd0aCE9PTAp
+e3QuYT1zKyI9Igp0LmErPUguZChQLmVQKEMuRjMsYixDLnhNLCEwKSl9fSwKJFM6MjJ9ClAueTUucHJv
+dG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCkgueShhKQppZihiPT1udWxsfHx0eXBlb2Yg
+Yj09InN0cmluZyIpdGhpcy5hLiQyKGEsSC55KGIpKQplbHNlIGZvcih0PUouSVQodS5SLmIoYikpLHM9
+dGhpcy5hO3QuRigpOylzLiQyKGEsSC55KHQuZ2woKSkpfSwKJFM6MTN9ClAuUEUucHJvdG90eXBlPXsK
+Z2xSOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD10aGlzLG89bnVsbCxuPXAuYwppZihuIT1udWxsKXJl
+dHVybiBuCm49cC5iCmlmKDA+PW4ubGVuZ3RoKXJldHVybiBILk9IKG4sMCkKdD1wLmEKbj1uWzBdKzEK
+cz1DLnhCLlhVKHQsIj8iLG4pCnI9dC5sZW5ndGgKaWYocz49MCl7cT1QLlBJKHQscysxLHIsQy5WQywh
+MSkKcj1zfWVsc2UgcT1vCnJldHVybiBwLmM9bmV3IFAucWUoImRhdGEiLG8sbyxvLFAuUEkodCxuLHIs
+Qy5XZCwhMSkscSxvKX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmIKaWYoMD49cy5sZW5ndGgp
+cmV0dXJuIEguT0gocywwKQp0PXRoaXMuYQpyZXR1cm4gc1swXT09PS0xPyJkYXRhOiIrdDp0fX0KUC5x
+My5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoOTYpfSwKJFM6
+MjN9ClAueUkucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmEKaWYoYT49dC5s
+ZW5ndGgpcmV0dXJuIEguT0godCxhKQp0PXRbYV0KSi5DTSh0LDAsOTYsYikKcmV0dXJuIHR9LAokUzoy
+NH0KUC5jNi5wcm90b3R5cGU9ewokMzpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEKZm9yKHQ9Yi5s
+ZW5ndGgscz1hLmxlbmd0aCxyPTA7cjx0Oysrcil7cT1DLnhCLlcoYixyKV45NgppZihxPj1zKXJldHVy
+biBILk9IKGEscSkKYVtxXT1jfX19ClAucWQucHJvdG90eXBlPXsKJDM6ZnVuY3Rpb24oYSxiLGMpe3Zh
+ciB0LHMscixxCmZvcih0PUMueEIuVyhiLDApLHM9Qy54Qi5XKGIsMSkscj1hLmxlbmd0aDt0PD1zOysr
+dCl7cT0odF45Nik+Pj4wCmlmKHE+PXIpcmV0dXJuIEguT0goYSxxKQphW3FdPWN9fX0KUC5VZi5wcm90
+b3R5cGU9ewpnY2o6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jPjB9LApneEE6ZnVuY3Rpb24oKXt2YXIg
+dCxzCmlmKHRoaXMuYz4wKXt0PXRoaXMuZAppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0Lmgo
+KQpzPXRoaXMuZQppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBILnBZKHMpCnM9dCsxPHMKdD1z
+fWVsc2UgdD0hMQpyZXR1cm4gdH0sCmdRRDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuZgppZih0eXBlb2Yg
+dCE9PSJudW1iZXIiKXJldHVybiB0LkooKQpyZXR1cm4gdDx0aGlzLnJ9LApnWjg6ZnVuY3Rpb24oKXty
+ZXR1cm4gdGhpcy5yPHRoaXMuYS5sZW5ndGh9LApnTnc6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5iPT09
+NCYmQy54Qi5uKHRoaXMuYSwiZmlsZSIpfSwKZ3ZoOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYj09PTQm
+JkMueEIubih0aGlzLmEsImh0dHAiKX0sCmdSZTpmdW5jdGlvbigpe3JldHVybiB0aGlzLmI9PT01JiZD
+LnhCLm4odGhpcy5hLCJodHRwcyIpfSwKZ3RUOmZ1bmN0aW9uKCl7cmV0dXJuIEMueEIuUWkodGhpcy5h
+LCIvIix0aGlzLmUpfSwKZ0ZpOmZ1bmN0aW9uKCl7dmFyIHQscz10aGlzLHI9InBhY2thZ2UiLHE9cy5i
+CmlmKHE8PTApcmV0dXJuIiIKdD1zLngKaWYodCE9bnVsbClyZXR1cm4gdAppZihzLmd2aCgpKXE9cy54
+PSJodHRwIgplbHNlIGlmKHMuZ1JlKCkpe3MueD0iaHR0cHMiCnE9Imh0dHBzIn1lbHNlIGlmKHMuZ053
+KCkpe3MueD0iZmlsZSIKcT0iZmlsZSJ9ZWxzZSBpZihxPT09NyYmQy54Qi5uKHMuYSxyKSl7cy54PXIK
+cT1yfWVsc2V7cT1DLnhCLk5qKHMuYSwwLHEpCnMueD1xfXJldHVybiBxfSwKZ2t1OmZ1bmN0aW9uKCl7
+dmFyIHQ9dGhpcy5jLHM9dGhpcy5iKzMKcmV0dXJuIHQ+cz9DLnhCLk5qKHRoaXMuYSxzLHQtMSk6IiJ9
+LApnSmY6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jCnJldHVybiB0PjA/Qy54Qi5Oaih0aGlzLmEsdCx0
+aGlzLmQpOiIifSwKZ3RwOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcwppZihzLmd4QSgpKXt0PXMuZApp
+Zih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LmgoKQpyZXR1cm4gUC5RQShDLnhCLk5qKHMuYSx0
+KzEscy5lKSxudWxsLG51bGwpfWlmKHMuZ3ZoKCkpcmV0dXJuIDgwCmlmKHMuZ1JlKCkpcmV0dXJuIDQ0
+MwpyZXR1cm4gMH0sCmdJaTpmdW5jdGlvbihhKXtyZXR1cm4gQy54Qi5Oaih0aGlzLmEsdGhpcy5lLHRo
+aXMuZil9LApndFA6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmYscz10aGlzLnIKaWYodHlwZW9mIHQhPT0i
+bnVtYmVyIilyZXR1cm4gdC5KKCkKcmV0dXJuIHQ8cz9DLnhCLk5qKHRoaXMuYSx0KzEscyk6IiJ9LApn
+S2E6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLnIscz10aGlzLmEKcmV0dXJuIHQ8cy5sZW5ndGg/Qy54Qi5H
+KHMsdCsxKToiIn0sCmdGajpmdW5jdGlvbigpe3ZhciB0LHMscj10aGlzLmUscT10aGlzLmYscD10aGlz
+LmEKaWYoQy54Qi5RaShwLCIvIixyKSl7aWYodHlwZW9mIHIhPT0ibnVtYmVyIilyZXR1cm4gci5oKCk7
+KytyfWlmKHI9PXEpcmV0dXJuIEMueEQKdD1ILlZNKFtdLHUucykKcz1yCndoaWxlKCEwKXtpZih0eXBl
+b2YgcyE9PSJudW1iZXIiKXJldHVybiBzLkooKQppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBI
+LnBZKHEpCmlmKCEoczxxKSlicmVhawppZihDLnhCLm0ocCxzKT09PTQ3KXtDLk5tLmkodCxDLnhCLk5q
+KHAscixzKSkKcj1zKzF9KytzfUMuTm0uaSh0LEMueEIuTmoocCxyLHEpKQpyZXR1cm4gUC5BRih0LHUu
+Til9LApnaFk6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmYKaWYodHlwZW9mIHQhPT0ibnVtYmVyIilyZXR1
+cm4gdC5KKCkKaWYodD49dGhpcy5yKXJldHVybiBDLldPCnJldHVybiBuZXcgUC5HaihQLldYKHRoaXMu
+Z3RQKCkpLHUuVyl9LAprWDpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMuZAppZih0eXBlb2YgcyE9PSJu
+dW1iZXIiKXJldHVybiBzLmgoKQp0PXMrMQpyZXR1cm4gdCthLmxlbmd0aD09PXRoaXMuZSYmQy54Qi5R
+aSh0aGlzLmEsYSx0KX0sCk45OmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQucixyPXQuYQppZihzPj1y
+Lmxlbmd0aClyZXR1cm4gdApyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihyLDAscyksdC5iLHQuYyx0LmQs
+dC5lLHQuZixzLHQueCl9LApubTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGo9
+dGhpcyxpPW51bGwKdS5YLmIobnVsbCkKdS5iLmIoYikKdD1qLmdGaSgpCnM9dD09PSJmaWxlIgpyPWou
+YwpxPXI+MD9DLnhCLk5qKGouYSxqLmIrMyxyKToiIgpwPWouZ3hBKCk/ai5ndHAoaik6aQpyPWouYwpp
+ZihyPjApbz1DLnhCLk5qKGouYSxyLGouZCkKZWxzZSBvPXEubGVuZ3RoIT09MHx8cCE9bnVsbHx8cz8i
+IjppCnI9ai5hCm49Qy54Qi5OaihyLGouZSxqLmYpCmlmKCFzKW09byE9bnVsbCYmbi5sZW5ndGghPT0w
+CmVsc2UgbT0hMAppZihtJiYhQy54Qi5uKG4sIi8iKSluPSIvIituCmw9UC5sZShpLDAsMCxiKQptPWou
+cgprPW08ci5sZW5ndGg/Qy54Qi5HKHIsbSsxKTppCnJldHVybiBuZXcgUC5Ebih0LHEsbyxwLG4sbCxr
+KX0sClpJOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLm1TKFAuaEsoYSkpfSwKbVM6ZnVuY3Rpb24oYSl7
+aWYoYSBpbnN0YW5jZW9mIFAuVWYpcmV0dXJuIHRoaXMudTEodGhpcyxhKQpyZXR1cm4gdGhpcy52cygp
+Lm1TKGEpfSwKdTE6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYs
+ZT1iLmIKaWYoZT4wKXJldHVybiBiCnQ9Yi5jCmlmKHQ+MCl7cz1hLmIKaWYoczw9MClyZXR1cm4gYgpp
+ZihhLmdOdygpKXI9Yi5lIT1iLmYKZWxzZSBpZihhLmd2aCgpKXI9IWIua1goIjgwIikKZWxzZSByPSFh
+LmdSZSgpfHwhYi5rWCgiNDQzIikKaWYocil7cT1zKzEKcD1DLnhCLk5qKGEuYSwwLHEpK0MueEIuRyhi
+LmEsZSsxKQplPWIuZAppZih0eXBlb2YgZSE9PSJudW1iZXIiKXJldHVybiBlLmgoKQpvPWIuZQppZih0
+eXBlb2YgbyE9PSJudW1iZXIiKXJldHVybiBvLmgoKQpuPWIuZgppZih0eXBlb2YgbiE9PSJudW1iZXIi
+KXJldHVybiBuLmgoKQpyZXR1cm4gbmV3IFAuVWYocCxzLHQrcSxlK3EsbytxLG4rcSxiLnIrcSxhLngp
+fWVsc2UgcmV0dXJuIHRoaXMudnMoKS5tUyhiKX1tPWIuZQplPWIuZgppZihtPT1lKXt0PWIucgppZih0
+eXBlb2YgZSE9PSJudW1iZXIiKXJldHVybiBlLkooKQppZihlPHQpe3M9YS5mCmlmKHR5cGVvZiBzIT09
+Im51bWJlciIpcmV0dXJuIHMuSE4oKQpxPXMtZQpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxz
+KStDLnhCLkcoYi5hLGUpLGEuYixhLmMsYS5kLGEuZSxlK3EsdCtxLGEueCl9ZT1iLmEKaWYodDxlLmxl
+bmd0aCl7cz1hLnIKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmooYS5hLDAscykrQy54Qi5HKGUsdCksYS5i
+LGEuYyxhLmQsYS5lLGEuZix0KyhzLXQpLGEueCl9cmV0dXJuIGEuTjkoKX10PWIuYQppZihDLnhCLlFp
+KHQsIi8iLG0pKXtzPWEuZQppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLkhOKCkKaWYodHlw
+ZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4gSC5wWShtKQpxPXMtbQpwPUMueEIuTmooYS5hLDAscykrQy54
+Qi5HKHQsbSkKaWYodHlwZW9mIGUhPT0ibnVtYmVyIilyZXR1cm4gZS5oKCkKcmV0dXJuIG5ldyBQLlVm
+KHAsYS5iLGEuYyxhLmQscyxlK3EsYi5yK3EsYS54KX1sPWEuZQprPWEuZgppZihsPT1rJiZhLmM+MCl7
+Zm9yKDtDLnhCLlFpKHQsIi4uLyIsbSk7KXtpZih0eXBlb2YgbSE9PSJudW1iZXIiKXJldHVybiBtLmgo
+KQptKz0zfWlmKHR5cGVvZiBsIT09Im51bWJlciIpcmV0dXJuIGwuSE4oKQppZih0eXBlb2YgbSE9PSJu
+dW1iZXIiKXJldHVybiBILnBZKG0pCnE9bC1tKzEKcD1DLnhCLk5qKGEuYSwwLGwpKyIvIitDLnhCLkco
+dCxtKQppZih0eXBlb2YgZSE9PSJudW1iZXIiKXJldHVybiBlLmgoKQpyZXR1cm4gbmV3IFAuVWYocCxh
+LmIsYS5jLGEuZCxsLGUrcSxiLnIrcSxhLngpfWo9YS5hCmZvcihpPWw7Qy54Qi5RaShqLCIuLi8iLGkp
+Oyl7aWYodHlwZW9mIGkhPT0ibnVtYmVyIilyZXR1cm4gaS5oKCkKaSs9M31oPTAKd2hpbGUoITApe2lm
+KHR5cGVvZiBtIT09Im51bWJlciIpcmV0dXJuIG0uaCgpCmc9bSszCmlmKHR5cGVvZiBlIT09Im51bWJl
+ciIpcmV0dXJuIEgucFkoZSkKaWYoIShnPD1lJiZDLnhCLlFpKHQsIi4uLyIsbSkpKWJyZWFrOysraApt
+PWd9Zj0iIgp3aGlsZSghMCl7aWYodHlwZW9mIGshPT0ibnVtYmVyIilyZXR1cm4gay5vcygpCmlmKHR5
+cGVvZiBpIT09Im51bWJlciIpcmV0dXJuIEgucFkoaSkKaWYoIShrPmkpKWJyZWFrOy0tawppZihDLnhC
+Lm0oaixrKT09PTQ3KXtpZihoPT09MCl7Zj0iLyIKYnJlYWt9LS1oCmY9Ii8ifX1pZihrPT09aSYmYS5i
+PD0wJiYhQy54Qi5RaShqLCIvIixsKSl7bS09aCozCmY9IiJ9cT1rLW0rZi5sZW5ndGgKcmV0dXJuIG5l
+dyBQLlVmKEMueEIuTmooaiwwLGspK2YrQy54Qi5HKHQsbSksYS5iLGEuYyxhLmQsbCxlK3EsYi5yK3Es
+YS54KX0sCnQ0OmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD10aGlzCmlmKHAuYj49MCYmIXAuZ053KCkp
+dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSAiK0guZChwLmdG
+aSgpKSsiIFVSSSIpKQp0PXAuZgpzPXAuYQppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0Lkoo
+KQppZih0PHMubGVuZ3RoKXtpZih0PHAucil0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBm
+aWxlIHBhdGggZnJvbSBhIFVSSSB3aXRoIGEgcXVlcnkgY29tcG9uZW50IikpCnRocm93IEguYihQLkw0
+KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgVVJJIHdpdGggYSBmcmFnbWVudCBjb21w
+b25lbnQiKSl9cj0kLndRKCkKaWYoSC5vVChyKSl0PVAubW4ocCkKZWxzZXtxPXAuZAppZih0eXBlb2Yg
+cSE9PSJudW1iZXIiKXJldHVybiBILnBZKHEpCmlmKHAuYzxxKUgudmgoUC5MNCgiQ2Fubm90IGV4dHJh
+Y3QgYSBub24tV2luZG93cyBmaWxlIHBhdGggZnJvbSBhIGZpbGUgVVJJIHdpdGggYW4gYXV0aG9yaXR5
+IikpCnQ9Qy54Qi5OaihzLHAuZSx0KX1yZXR1cm4gdH0sCmdpTzpmdW5jdGlvbihhKXt2YXIgdD10aGlz
+LnkKcmV0dXJuIHQ9PW51bGw/dGhpcy55PUMueEIuZ2lPKHRoaXMuYSk6dH0sCkROOmZ1bmN0aW9uKGEs
+Yil7aWYoYj09bnVsbClyZXR1cm4hMQppZih0aGlzPT09YilyZXR1cm4hMApyZXR1cm4gdS5ELmMoYikm
+JnRoaXMuYT09PWIudygwKX0sCnZzOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPW51bGwscj10LmdGaSgp
+LHE9dC5na3UoKSxwPXQuYz4wP3QuZ0pmKHQpOnMsbz10Lmd4QSgpP3QuZ3RwKHQpOnMsbj10LmEsbT10
+LmYsbD1DLnhCLk5qKG4sdC5lLG0pLGs9dC5yCmlmKHR5cGVvZiBtIT09Im51bWJlciIpcmV0dXJuIG0u
+SigpCm09bTxrP3QuZ3RQKCk6cwpyZXR1cm4gbmV3IFAuRG4ocixxLHAsbyxsLG0sazxuLmxlbmd0aD90
+LmdLYSgpOnMpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKJGlpRDoxfQpQLnFlLnByb3Rv
+dHlwZT17fQpXLnFFLnByb3RvdHlwZT17fQpXLkdoLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0
+dXJuIFN0cmluZyhhKX0sCiRpR2g6MX0KVy5mWS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVy
+biBTdHJpbmcoYSl9fQpXLm5CLnByb3RvdHlwZT17JGluQjoxfQpXLkF6LnByb3RvdHlwZT17JGlBejox
+fQpXLlFQLnByb3RvdHlwZT17JGlRUDoxfQpXLm54LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3Jl
+dHVybiBhLmxlbmd0aH19Clcub0oucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVu
+Z3RofX0KVy5pZC5wcm90b3R5cGU9e30KVy5RRi5wcm90b3R5cGU9e30KVy5OaC5wcm90b3R5cGU9ewp3
+OmZ1bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9fQpXLklCLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24o
+YSl7cmV0dXJuIlJlY3RhbmdsZSAoIitILmQoYS5sZWZ0KSsiLCAiK0guZChhLnRvcCkrIikgIitILmQo
+YS53aWR0aCkrIiB4ICIrSC5kKGEuaGVpZ2h0KX0sCkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbCly
+ZXR1cm4hMQpyZXR1cm4gdS5xLmMoYikmJmEubGVmdD09PWIubGVmdCYmYS50b3A9PT1iLnRvcCYmYS53
+aWR0aD09PWIud2lkdGgmJmEuaGVpZ2h0PT09Yi5oZWlnaHR9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJu
+IFcuckUoQy5DRC5naU8oYS5sZWZ0KSxDLkNELmdpTyhhLnRvcCksQy5DRC5naU8oYS53aWR0aCksQy5D
+RC5naU8oYS5oZWlnaHQpKX0sCiRpdG46MX0KVy5uNy5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXty
+ZXR1cm4gYS5sZW5ndGh9fQpXLnd6LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlz
+LmEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe3ZhciB0CkguU2MoYikKdD10aGlzLmEKaWYoYjwwfHxi
+Pj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LGIpCnJldHVybiB0aGlzLiR0aS5kLmIodFtiXSl9LApZOmZ1
+bmN0aW9uKGEsYixjKXt0aGlzLiR0aS5kLmIoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkg
+bGlzdCIpKX19ClcuY3YucHJvdG90eXBlPXsKZ1FnOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5pNyhh
+KX0sCmdQOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5JNChhKX0sCnNQOmZ1bmN0aW9uKGEsYil7dmFy
+IHQKdS5YLmIoYikKdD10aGlzLmdQKGEpCnQuVjEoMCkKdC5GVigwLGIpfSwKdzpmdW5jdGlvbihhKXty
+ZXR1cm4gYS5sb2NhbE5hbWV9LApGRjpmdW5jdGlvbihhKXt2YXIgdD0hIWEuc2Nyb2xsSW50b1ZpZXdJ
+Zk5lZWRlZAppZih0KWEuc2Nyb2xsSW50b1ZpZXdJZk5lZWRlZCgpCmVsc2UgYS5zY3JvbGxJbnRvVmll
+dygpfSwKbno6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzPXRoaXMucjYoYSxjLGQsZSkKc3dpdGNo
+KGIudG9Mb3dlckNhc2UoKSl7Y2FzZSJiZWZvcmViZWdpbiI6YS5wYXJlbnROb2RlLmluc2VydEJlZm9y
+ZShzLGEpCmJyZWFrCmNhc2UiYWZ0ZXJiZWdpbiI6dD1hLmNoaWxkTm9kZXMKYS5pbnNlcnRCZWZvcmUo
+cyx0Lmxlbmd0aD4wP3RbMF06bnVsbCkKYnJlYWsKY2FzZSJiZWZvcmVlbmQiOmEuYXBwZW5kQ2hpbGQo
+cykKYnJlYWsKY2FzZSJhZnRlcmVuZCI6YS5wYXJlbnROb2RlLmluc2VydEJlZm9yZShzLGEubmV4dFNp
+YmxpbmcpCmJyZWFrCmRlZmF1bHQ6SC52aChQLnhZKCJJbnZhbGlkIHBvc2l0aW9uICIrYikpfX0sCnI2
+OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscixxCmlmKGM9PW51bGwpe2lmKGQ9PW51bGwpe3Q9JC5s
+dAppZih0PT1udWxsKXt0PUguVk0oW10sdS5rKQpzPW5ldyBXLnZEKHQpCkMuTm0uaSh0LFcuVHcobnVs
+bCkpCkMuTm0uaSh0LFcuQmwoKSkKJC5sdD1zCmQ9c31lbHNlIGQ9dH10PSQuRVUKaWYodD09bnVsbCl7
+dD1uZXcgVy5LbyhkKQokLkVVPXQKYz10fWVsc2V7dC5hPWQKYz10fX1lbHNlIGlmKGQhPW51bGwpdGhy
+b3cgSC5iKFAueFkoInZhbGlkYXRvciBjYW4gb25seSBiZSBwYXNzZWQgaWYgdHJlZVNhbml0aXplciBp
+cyBudWxsIikpCmlmKCQueG89PW51bGwpe3Q9ZG9jdW1lbnQKcz10LmltcGxlbWVudGF0aW9uLmNyZWF0
+ZUhUTUxEb2N1bWVudCgiIikKJC54bz1zCiQuQk89cy5jcmVhdGVSYW5nZSgpCnM9JC54by5jcmVhdGVF
+bGVtZW50KCJiYXNlIikKdS5jUi5iKHMpCnMuaHJlZj10LmJhc2VVUkkKJC54by5oZWFkLmFwcGVuZENo
+aWxkKHMpfXQ9JC54bwppZih0LmJvZHk9PW51bGwpe3M9dC5jcmVhdGVFbGVtZW50KCJib2R5IikKdC5i
+b2R5PXUuaS5iKHMpfXQ9JC54bwppZih1LmkuYyhhKSlyPXQuYm9keQplbHNle3I9dC5jcmVhdGVFbGVt
+ZW50KGEudGFnTmFtZSkKJC54by5ib2R5LmFwcGVuZENoaWxkKHIpfWlmKCJjcmVhdGVDb250ZXh0dWFs
+RnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUmJiFDLk5tLnRnKEMuU3EsYS50YWdOYW1l
+KSl7JC5CTy5zZWxlY3ROb2RlQ29udGVudHMocikKcT0kLkJPLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVu
+dChiKX1lbHNle3IuaW5uZXJIVE1MPWIKcT0kLnhvLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpmb3Io
+O3Q9ci5maXJzdENoaWxkLHQhPW51bGw7KXEuYXBwZW5kQ2hpbGQodCl9dD0kLnhvLmJvZHkKaWYocj09
+bnVsbD90IT1udWxsOnIhPT10KUouTHQocikKYy5QbihxKQpkb2N1bWVudC5hZG9wdE5vZGUocSkKcmV0
+dXJuIHF9LApBSDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIHRoaXMucjYoYSxiLGMsbnVsbCl9LApzaGY6
+ZnVuY3Rpb24oYSxiKXt0aGlzLllDKGEsYil9LApwazpmdW5jdGlvbihhLGIsYyl7YS50ZXh0Q29udGVu
+dD1udWxsCmEuYXBwZW5kQ2hpbGQodGhpcy5yNihhLGIsbnVsbCxjKSl9LApZQzpmdW5jdGlvbihhLGIp
+e3JldHVybiB0aGlzLnBrKGEsYixudWxsKX0sCmdWbDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuZXUo
+YSwiY2xpY2siLCExLHUuUSl9LAokaWN2OjEsCmduczpmdW5jdGlvbihhKXtyZXR1cm4gYS50YWdOYW1l
+fX0KVy5Ddi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5oLmModS5BLmIoYSkpfSwK
+JFM6MjV9ClcuZWEucHJvdG90eXBlPXskaWVhOjF9ClcuRDAucHJvdG90eXBlPXsKT246ZnVuY3Rpb24o
+YSxiLGMsZCl7dS5VLmIoYykKaWYoYyE9bnVsbCl0aGlzLnYoYSxiLGMsZCl9LApCOmZ1bmN0aW9uKGEs
+YixjKXtyZXR1cm4gdGhpcy5PbihhLGIsYyxudWxsKX0sCnY6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJu
+IGEuYWRkRXZlbnRMaXN0ZW5lcihiLEgudFIodS5VLmIoYyksMSksZCl9LAokaUQwOjF9ClcuVDUucHJv
+dG90eXBlPXskaVQ1OjF9ClcuaDQucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVu
+Z3RofX0KVy5ici5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLlZi
+LnByb3RvdHlwZT17fQpXLk83LnByb3RvdHlwZT17CmVvOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBh
+Lm9wZW4oYixjLCEwKX0sCiRpTzc6MX0KVy5iVS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3Ro
+aXMuYS5zZXRSZXF1ZXN0SGVhZGVyKEgueShhKSxILnkoYikpfSwKJFM6OH0KVy5oSC5wcm90b3R5cGU9
+ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwCnUucC5iKGEpCnQ9dGhpcy5hCnM9dC5zdGF0dXMK
+aWYodHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4gcy50QigpCnI9cz49MjAwJiZzPDMwMApxPXM+MzA3
+JiZzPDQwMApzPXJ8fHM9PT0wfHxzPT09MzA0fHxxCnA9dGhpcy5iCmlmKHMpcC5hTSgwLHQpCmVsc2Ug
+cC5wbShhKX0sCiRTOjE1fQpXLndhLnByb3RvdHlwZT17fQpXLlNnLnByb3RvdHlwZT17JGlTZzoxfQpX
+LnU4LnByb3RvdHlwZT17CmdEcjpmdW5jdGlvbihhKXtpZigib3JpZ2luIiBpbiBhKXJldHVybiBhLm9y
+aWdpbgpyZXR1cm4gSC5kKGEucHJvdG9jb2wpKyIvLyIrSC5kKGEuaG9zdCl9LAp3OmZ1bmN0aW9uKGEp
+e3JldHVybiBTdHJpbmcoYSl9LAokaXU4OjF9ClcuQWoucHJvdG90eXBlPXskaUFqOjF9ClcuZTcucHJv
+dG90eXBlPXsKZ3I4OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxzPXQuY2hpbGROb2Rlcy5sZW5ndGgK
+aWYocz09PTApdGhyb3cgSC5iKFAuUFYoIk5vIGVsZW1lbnRzIikpCmlmKHM+MSl0aHJvdyBILmIoUC5Q
+VigiTW9yZSB0aGFuIG9uZSBlbGVtZW50IikpCnJldHVybiB0LmZpcnN0Q2hpbGR9LApGVjpmdW5jdGlv
+bihhLGIpe3ZhciB0LHMscixxCnUuZWguYihiKQp0PWIuYQpzPXRoaXMuYQppZih0IT09cylmb3Iocj10
+LmNoaWxkTm9kZXMubGVuZ3RoLHE9MDtxPHI7KytxKXMuYXBwZW5kQ2hpbGQodC5maXJzdENoaWxkKQpy
+ZXR1cm59LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzCnUuQS5iKGMpCnQ9dGhpcy5hCnM9dC5jaGls
+ZE5vZGVzCmlmKGI8MHx8Yj49cy5sZW5ndGgpcmV0dXJuIEguT0gocyxiKQp0LnJlcGxhY2VDaGlsZChj
+LHNbYl0pfSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYS5jaGlsZE5vZGVzCnJldHVybiBuZXcg
+Vy5XOSh0LHQubGVuZ3RoLEgueksodCkuQygiVzk8R20uRT4iKSl9LApnQTpmdW5jdGlvbihhKXtyZXR1
+cm4gdGhpcy5hLmNoaWxkTm9kZXMubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe3ZhciB0CkguU2MoYikK
+dD10aGlzLmEuY2hpbGROb2RlcwppZihiPDB8fGI+PXQubGVuZ3RoKXJldHVybiBILk9IKHQsYikKcmV0
+dXJuIHRbYl19fQpXLnVILnByb3RvdHlwZT17CndnOmZ1bmN0aW9uKGEpe3ZhciB0PWEucGFyZW50Tm9k
+ZQppZih0IT1udWxsKXQucmVtb3ZlQ2hpbGQoYSl9LApENDpmdW5jdGlvbihhKXt2YXIgdApmb3IoO3Q9
+YS5maXJzdENoaWxkLHQhPW51bGw7KWEucmVtb3ZlQ2hpbGQodCl9LAp3OmZ1bmN0aW9uKGEpe3ZhciB0
+PWEubm9kZVZhbHVlCnJldHVybiB0PT1udWxsP3RoaXMuVShhKTp0fSwKJGl1SDoxfQpXLkJILnByb3Rv
+dHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILlNj
+KGIpCmlmKGI+Pj4wIT09Ynx8Yj49YS5sZW5ndGgpdGhyb3cgSC5iKFAuQ2YoYixhLG51bGwsbnVsbCxu
+dWxsKSkKcmV0dXJuIGFbYl19LApZOmZ1bmN0aW9uKGEsYixjKXt1LkEuYihjKQp0aHJvdyBILmIoUC5M
+NCgiQ2Fubm90IGFzc2lnbiBlbGVtZW50IG9mIGltbXV0YWJsZSBMaXN0LiIpKX0sCkU6ZnVuY3Rpb24o
+YSxiKXtpZihiPDB8fGI+PWEubGVuZ3RoKXJldHVybiBILk9IKGEsYikKcmV0dXJuIGFbYl19LAokaWJR
+OjEsCiRpWGo6MSwKJGljWDoxLAokaXpNOjF9ClcuU04ucHJvdG90eXBlPXt9ClcuZXcucHJvdG90eXBl
+PXskaWV3OjF9ClcubHAucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofX0K
+Vy5UYi5wcm90b3R5cGU9ewpyNjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzCmlmKCJjcmVhdGVDb250
+ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUpcmV0dXJuIHRoaXMuRFcoYSxi
+LGMsZCkKdD1XLlU5KCI8dGFibGU+IitILmQoYikrIjwvdGFibGU+IixjLGQpCnM9ZG9jdW1lbnQuY3Jl
+YXRlRG9jdW1lbnRGcmFnbWVudCgpCnMudG9TdHJpbmcKdC50b1N0cmluZwpuZXcgVy5lNyhzKS5GVigw
+LG5ldyBXLmU3KHQpKQpyZXR1cm4gc319ClcuSXYucHJvdG90eXBlPXsKcjY6ZnVuY3Rpb24oYSxiLGMs
+ZCl7dmFyIHQscyxyLHEKaWYoImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCIgaW4gd2luZG93LlJhbmdl
+LnByb3RvdHlwZSlyZXR1cm4gdGhpcy5EVyhhLGIsYyxkKQp0PWRvY3VtZW50CnM9dC5jcmVhdGVEb2N1
+bWVudEZyYWdtZW50KCkKdD1DLkllLnI2KHQuY3JlYXRlRWxlbWVudCgidGFibGUiKSxiLGMsZCkKdC50
+b1N0cmluZwp0PW5ldyBXLmU3KHQpCnI9dC5ncjgodCkKci50b1N0cmluZwp0PW5ldyBXLmU3KHIpCnE9
+dC5ncjgodCkKcy50b1N0cmluZwpxLnRvU3RyaW5nCm5ldyBXLmU3KHMpLkZWKDAsbmV3IFcuZTcocSkp
+CnJldHVybiBzfX0KVy5XUC5wcm90b3R5cGU9ewpyNjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIK
+aWYoImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCIgaW4gd2luZG93LlJhbmdlLnByb3RvdHlwZSlyZXR1
+cm4gdGhpcy5EVyhhLGIsYyxkKQp0PWRvY3VtZW50CnM9dC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkK
+dD1DLkllLnI2KHQuY3JlYXRlRWxlbWVudCgidGFibGUiKSxiLGMsZCkKdC50b1N0cmluZwp0PW5ldyBX
+LmU3KHQpCnI9dC5ncjgodCkKcy50b1N0cmluZwpyLnRvU3RyaW5nCm5ldyBXLmU3KHMpLkZWKDAsbmV3
+IFcuZTcocikpCnJldHVybiBzfX0KVy55WS5wcm90b3R5cGU9ewpwazpmdW5jdGlvbihhLGIsYyl7dmFy
+IHQscwphLnRleHRDb250ZW50PW51bGwKdD1hLmNvbnRlbnQKdC50b1N0cmluZwpKLmJUKHQpCnM9dGhp
+cy5yNihhLGIsbnVsbCxjKQphLmNvbnRlbnQuYXBwZW5kQ2hpbGQocyl9LApZQzpmdW5jdGlvbihhLGIp
+e3JldHVybiB0aGlzLnBrKGEsYixudWxsKX0sCiRpeVk6MX0KVy53Ni5wcm90b3R5cGU9e30KVy5LNS5w
+cm90b3R5cGU9ewpQbzpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9Vy5QMShhLm9wZW4oYixjKSkKcmV0dXJu
+IHR9LApnbVc6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubG9jYXRpb259LAokaUs1OjEsCiRpdjY6MX0KVy5D
+bS5wcm90b3R5cGU9eyRpQ206MX0KVy5DUS5wcm90b3R5cGU9eyRpQ1E6MX0KVy53NC5wcm90b3R5cGU9
+ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJSZWN0YW5nbGUgKCIrSC5kKGEubGVmdCkrIiwgIitILmQoYS50
+b3ApKyIpICIrSC5kKGEud2lkdGgpKyIgeCAiK0guZChhLmhlaWdodCl9LApETjpmdW5jdGlvbihhLGIp
+e2lmKGI9PW51bGwpcmV0dXJuITEKcmV0dXJuIHUucS5jKGIpJiZhLmxlZnQ9PT1iLmxlZnQmJmEudG9w
 PT09Yi50b3AmJmEud2lkdGg9PT1iLndpZHRoJiZhLmhlaWdodD09PWIuaGVpZ2h0fSwKZ2lPOmZ1bmN0
 aW9uKGEpe3JldHVybiBXLnJFKEMuQ0QuZ2lPKGEubGVmdCksQy5DRC5naU8oYS50b3ApLEMuQ0QuZ2lP
 KGEud2lkdGgpLEMuQ0QuZ2lPKGEuaGVpZ2h0KSl9fQpXLnJoLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9u
-KGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCmlmKGI+Pj4wIT09Ynx8
+KGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCmlmKGI+Pj4wIT09Ynx8
 Yj49YS5sZW5ndGgpdGhyb3cgSC5iKFAuQ2YoYixhLG51bGwsbnVsbCxudWxsKSkKcmV0dXJuIGFbYl19
-LApZOmZ1bmN0aW9uKGEsYixjKXt1LkEuYShjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGFzc2lnbiBl
+LApZOmZ1bmN0aW9uKGEsYixjKXt1LkEuYihjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGFzc2lnbiBl
 bGVtZW50IG9mIGltbXV0YWJsZSBMaXN0LiIpKX0sCkU6ZnVuY3Rpb24oYSxiKXtpZihiPDB8fGI+PWEu
 bGVuZ3RoKXJldHVybiBILk9IKGEsYikKcmV0dXJuIGFbYl19LAokaWJROjEsCiRpWGo6MSwKJGljWDox
 LAokaXpNOjF9ClcuY2YucHJvdG90eXBlPXsKSzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAKdS5l
-QS5hKGIpCmZvcih0PXRoaXMuZ1YoKSxzPXQubGVuZ3RoLHI9dGhpcy5hLHE9MDtxPHQubGVuZ3RoO3Qu
+QS5iKGIpCmZvcih0PXRoaXMuZ1YoKSxzPXQubGVuZ3RoLHI9dGhpcy5hLHE9MDtxPHQubGVuZ3RoO3Qu
 bGVuZ3RoPT09c3x8KDAsSC5saykodCksKytxKXtwPXRbcV0KYi4kMihwLHIuZ2V0QXR0cmlidXRlKHAp
 KX19LApnVjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcy5hLmF0dHJpYnV0ZXMsbz1ILlZNKFtd
 LHUucykKZm9yKHQ9cC5sZW5ndGgscz11Lmg5LHI9MDtyPHQ7KytyKXtpZihyPj1wLmxlbmd0aClyZXR1
-cm4gSC5PSChwLHIpCnE9cy5hKHBbcl0pCmlmKHEubmFtZXNwYWNlVVJJPT1udWxsKUMuTm0uaShvLHEu
-bmFtZSl9cmV0dXJuIG99fQpXLmk3LnByb3RvdHlwZT17Cng0OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMu
-YS5oYXNBdHRyaWJ1dGUoYSkKcmV0dXJuIHR9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS5n
-ZXRBdHRyaWJ1dGUoSC5oKGIpKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3RoaXMuYS5zZXRBdHRyaWJ1dGUo
-YixjKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmdWKCkubGVuZ3RofX0KVy5TeS5wcm90b3R5
-cGU9ewp4NDpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEuYS5oYXNBdHRyaWJ1dGUoImRhdGEtIit0aGlz
-Lk8oYSkpCnJldHVybiB0fSwKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEuYS5nZXRBdHRyaWJ1
-dGUoImRhdGEtIit0aGlzLk8oSC5oKGIpKSl9LApZOmZ1bmN0aW9uKGEsYixjKXt0aGlzLmEuYS5zZXRB
-dHRyaWJ1dGUoImRhdGEtIit0aGlzLk8oYiksYyl9LApLOmZ1bmN0aW9uKGEsYil7dGhpcy5hLksoMCxu
-ZXcgVy5LUyh0aGlzLHUuZUEuYShiKSkpfSwKZ1Y6ZnVuY3Rpb24oKXt2YXIgdD1ILlZNKFtdLHUucykK
-dGhpcy5hLksoMCxuZXcgVy5BMyh0aGlzLHQpKQpyZXR1cm4gdH0sCmdBOmZ1bmN0aW9uKGEpe3JldHVy
-biB0aGlzLmdWKCkubGVuZ3RofSwKazpmdW5jdGlvbihhKXt2YXIgdCxzLHI9SC5WTShhLnNwbGl0KCIt
-IiksdS5zKQpmb3IodD0xO3Q8ci5sZW5ndGg7Kyt0KXtzPXJbdF0KaWYocy5sZW5ndGg+MClDLk5tLlko
-cix0LHNbMF0udG9VcHBlckNhc2UoKStKLktWKHMsMSkpfXJldHVybiBDLk5tLnpWKHIsIiIpfSwKTzpm
-dW5jdGlvbihhKXt2YXIgdCxzLHIscSxwCmZvcih0PWEubGVuZ3RoLHM9MCxyPSIiO3M8dDsrK3Mpe3E9
-YVtzXQpwPXEudG9Mb3dlckNhc2UoKQpyPShxIT09cCYmcz4wP3IrIi0iOnIpK3B9cmV0dXJuIHIuY2hh
-ckNvZGVBdCgwKT09MD9yOnJ9fQpXLktTLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7aWYoSi5y
-WShhKS5uKGEsImRhdGEtIikpdGhpcy5iLiQyKHRoaXMuYS5rKEMueEIuRyhhLDUpKSxiKX0sCiRTOjd9
-ClcuQTMucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtpZihKLnJZKGEpLm4oYSwiZGF0YS0iKSlD
-Lk5tLmkodGhpcy5iLHRoaXMuYS5rKEMueEIuRyhhLDUpKSl9LAokUzo3fQpXLkk0LnByb3RvdHlwZT17
-CkRHOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD1QLkxzKHUuTikKZm9yKHQ9dGhpcy5hLmNsYXNzTmFt
-ZS5zcGxpdCgiICIpLHM9dC5sZW5ndGgscj0wO3I8czsrK3Ipe3E9Si5UMCh0W3JdKQppZihxLmxlbmd0
-aCE9PTApcC5pKDAscSl9cmV0dXJuIHB9LApwOmZ1bmN0aW9uKGEpe3RoaXMuYS5jbGFzc05hbWU9dS5D
-LmEoYSkuelYoMCwiICIpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5jbGFzc0xpc3QubGVu
-Z3RofSwKVjE6ZnVuY3Rpb24oYSl7dGhpcy5hLmNsYXNzTmFtZT0iIn0sCnRnOmZ1bmN0aW9uKGEsYil7
-dmFyIHQ9dGhpcy5hLmNsYXNzTGlzdC5jb250YWlucyhiKQpyZXR1cm4gdH0sCmk6ZnVuY3Rpb24oYSxi
-KXt2YXIgdD10aGlzLmEuY2xhc3NMaXN0LHM9dC5jb250YWlucyhiKQp0LmFkZChiKQpyZXR1cm4hc30s
-ClI6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmEuY2xhc3NMaXN0LHM9dC5jb250YWlucyhiKQp0LnJl
-bW92ZShiKQpyZXR1cm4gc30sCkZWOmZ1bmN0aW9uKGEsYil7Vy5UTih0aGlzLmEsdS5RLmEoYikpfX0K
-Vy5Gay5wcm90b3R5cGU9e30KVy5STy5wcm90b3R5cGU9e30KVy5ldS5wcm90b3R5cGU9e30KVy54Qy5w
-cm90b3R5cGU9e30KVy52Ti5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLiQx
-KHUuQi5hKGEpKX0sCiRTOjI4fQpXLkpRLnByb3RvdHlwZT17CkNZOmZ1bmN0aW9uKGEpe3ZhciB0Cmlm
-KCQub3IuYT09PTApe2Zvcih0PTA7dDwyNjI7Kyt0KSQub3IuWSgwLEMuY21bdF0sVy5wUygpKQpmb3Io
-dD0wO3Q8MTI7Kyt0KSQub3IuWSgwLEMuQklbdF0sVy5WNCgpKX19LAppMDpmdW5jdGlvbihhKXtyZXR1
-cm4gJC5BTigpLnRnKDAsVy5yUyhhKSl9LApFYjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9JC5vci5xKDAs
-Vy5yUyhhKSsiOjoiK2IpCmlmKHQ9PW51bGwpdD0kLm9yLnEoMCwiKjo6IitiKQppZih0PT1udWxsKXJl
-dHVybiExCnJldHVybiBILnk4KHQuJDQoYSxiLGMsdGhpcykpfSwKJGlrRjoxfQpXLkdtLnByb3RvdHlw
-ZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuVzkoYSx0aGlzLmdBKGEpLEgueihhKS5DKCJX
-OTxHbS5FPiIpKX19ClcudkQucHJvdG90eXBlPXsKaTA6ZnVuY3Rpb24oYSl7cmV0dXJuIEMuTm0uVnIo
-dGhpcy5hLG5ldyBXLlV2KGEpKX0sCkViOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gQy5ObS5Wcih0aGlz
-LmEsbmV3IFcuRWcoYSxiLGMpKX0sCiRpa0Y6MX0KVy5Vdi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihh
-KXtyZXR1cm4gdS5lLmEoYSkuaTAodGhpcy5hKX0sCiRTOjEzfQpXLkVnLnByb3RvdHlwZT17CiQxOmZ1
-bmN0aW9uKGEpe3JldHVybiB1LmUuYShhKS5FYih0aGlzLmEsdGhpcy5iLHRoaXMuYyl9LAokUzoxM30K
-Vy5tNi5wcm90b3R5cGU9ewpDWTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIKdGhpcy5hLkZWKDAs
-YykKdD1iLmV2KDAsbmV3IFcuRW8oKSkKcz1iLmV2KDAsbmV3IFcuV2soKSkKdGhpcy5iLkZWKDAsdCkK
-cj10aGlzLmMKci5GVigwLEMueEQpCnIuRlYoMCxzKX0sCmkwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlz
-LmEudGcoMCxXLnJTKGEpKX0sCkViOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD10aGlzLHM9Vy5yUyhhKSxy
-PXQuYwppZihyLnRnKDAscysiOjoiK2IpKXJldHVybiB0LmQuRHQoYykKZWxzZSBpZihyLnRnKDAsIio6
-OiIrYikpcmV0dXJuIHQuZC5EdChjKQplbHNle3I9dC5iCmlmKHIudGcoMCxzKyI6OiIrYikpcmV0dXJu
-ITAKZWxzZSBpZihyLnRnKDAsIio6OiIrYikpcmV0dXJuITAKZWxzZSBpZihyLnRnKDAscysiOjoqIikp
-cmV0dXJuITAKZWxzZSBpZihyLnRnKDAsIio6OioiKSlyZXR1cm4hMH1yZXR1cm4hMX0sCiRpa0Y6MX0K
-Vy5Fby5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4hQy5ObS50ZyhDLkJJLEguaChhKSl9
-LAokUzoxNH0KVy5Xay5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gQy5ObS50ZyhDLkJJ
-LEguaChhKSl9LAokUzoxNH0KVy5jdC5wcm90b3R5cGU9ewpFYjpmdW5jdGlvbihhLGIsYyl7aWYodGhp
-cy5qRihhLGIsYykpcmV0dXJuITAKaWYoYj09PSJ0ZW1wbGF0ZSImJmM9PT0iIilyZXR1cm4hMAppZihh
-LmdldEF0dHJpYnV0ZSgidGVtcGxhdGUiKT09PSIiKXJldHVybiB0aGlzLmUudGcoMCxiKQpyZXR1cm4h
-MX19ClcuSUEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIlRFTVBMQVRFOjoiK0guRWoo
-SC5oKGEpKX0sCiRTOjZ9ClcuT3cucHJvdG90eXBlPXsKaTA6ZnVuY3Rpb24oYSl7dmFyIHQKaWYodS5l
-dy5iKGEpKXJldHVybiExCnQ9dS5nNy5iKGEpCmlmKHQmJlcuclMoYSk9PT0iZm9yZWlnbk9iamVjdCIp
-cmV0dXJuITEKaWYodClyZXR1cm4hMApyZXR1cm4hMX0sCkViOmZ1bmN0aW9uKGEsYixjKXtpZihiPT09
-ImlzInx8Qy54Qi5uKGIsIm9uIikpcmV0dXJuITEKcmV0dXJuIHRoaXMuaTAoYSl9LAokaWtGOjF9Clcu
-VzkucHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3ZhciB0PXRoaXMscz10LmMrMSxyPXQuYgppZihzPHIp
-e3Quc00oSi54OSh0LmEscykpCnQuYz1zCnJldHVybiEwfXQuc00obnVsbCkKdC5jPXIKcmV0dXJuITF9
-LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApzTTpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4k
-dGkuQygiMT8iKS5hKGEpfSwKJGlBbjoxfQpXLmRXLnByb3RvdHlwZT17CmdtVzpmdW5jdGlvbihhKXty
-ZXR1cm4gVy5ISCh0aGlzLmEubG9jYXRpb24pfSwKJGlEMDoxLAokaXY2OjF9ClcuRmIucHJvdG90eXBl
-PXt9Clcua0YucHJvdG90eXBlPXt9ClcubWsucHJvdG90eXBlPXskaXkwOjF9ClcuS28ucHJvdG90eXBl
-PXsKUG46ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcyxzPW5ldyBXLmZtKHQpCnQuYj0hMQpzLiQyKGEsbnVs
-bCkKZm9yKDt0LmI7KXt0LmI9ITEKcy4kMihhLG51bGwpfX0sCkVQOmZ1bmN0aW9uKGEsYil7dmFyIHQ9
-dGhpcy5iPSEwCmlmKGIhPW51bGw/YiE9PWEucGFyZW50Tm9kZTp0KUouTHQoYSkKZWxzZSBiLnJlbW92
-ZUNoaWxkKGEpfSwKSTQ6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG89ITAsbj1udWxsLG09bnVs
-bAp0cnl7bj1KLmlnKGEpCm09bi5hLmdldEF0dHJpYnV0ZSgiaXMiKQp1LmguYShhKQp0PWZ1bmN0aW9u
-KGMpe2lmKCEoYy5hdHRyaWJ1dGVzIGluc3RhbmNlb2YgTmFtZWROb2RlTWFwKSlyZXR1cm4gdHJ1ZQpp
-ZihjLmlkPT0nbGFzdENoaWxkJ3x8Yy5uYW1lPT0nbGFzdENoaWxkJ3x8Yy5pZD09J3ByZXZpb3VzU2li
-bGluZyd8fGMubmFtZT09J3ByZXZpb3VzU2libGluZyd8fGMuaWQ9PSdjaGlsZHJlbid8fGMubmFtZT09
-J2NoaWxkcmVuJylyZXR1cm4gdHJ1ZQp2YXIgbD1jLmNoaWxkTm9kZXMKaWYoYy5sYXN0Q2hpbGQmJmMu
-bGFzdENoaWxkIT09bFtsLmxlbmd0aC0xXSlyZXR1cm4gdHJ1ZQppZihjLmNoaWxkcmVuKWlmKCEoYy5j
-aGlsZHJlbiBpbnN0YW5jZW9mIEhUTUxDb2xsZWN0aW9ufHxjLmNoaWxkcmVuIGluc3RhbmNlb2YgTm9k
-ZUxpc3QpKXJldHVybiB0cnVlCnZhciBrPTAKaWYoYy5jaGlsZHJlbilrPWMuY2hpbGRyZW4ubGVuZ3Ro
-CmZvcih2YXIgaj0wO2o8aztqKyspe3ZhciBpPWMuY2hpbGRyZW5bal0KaWYoaS5pZD09J2F0dHJpYnV0
-ZXMnfHxpLm5hbWU9PSdhdHRyaWJ1dGVzJ3x8aS5pZD09J2xhc3RDaGlsZCd8fGkubmFtZT09J2xhc3RD
-aGlsZCd8fGkuaWQ9PSdwcmV2aW91c1NpYmxpbmcnfHxpLm5hbWU9PSdwcmV2aW91c1NpYmxpbmcnfHxp
-LmlkPT0nY2hpbGRyZW4nfHxpLm5hbWU9PSdjaGlsZHJlbicpcmV0dXJuIHRydWV9cmV0dXJuIGZhbHNl
-fShhKQpvPUgub1QodCk/ITA6IShhLmF0dHJpYnV0ZXMgaW5zdGFuY2VvZiBOYW1lZE5vZGVNYXApfWNh
-dGNoKHEpe0guUnUocSl9cz0iZWxlbWVudCB1bnByaW50YWJsZSIKdHJ5e3M9Si5qKGEpfWNhdGNoKHEp
-e0guUnUocSl9dHJ5e3I9Vy5yUyhhKQp0aGlzLmtSKHUuaC5hKGEpLGIsbyxzLHIsdS52LmEobiksSC5r
-KG0pKX1jYXRjaChxKXtpZihILlJ1KHEpIGluc3RhbmNlb2YgUC51KXRocm93IHEKZWxzZXt0aGlzLkVQ
-KGEsYikKd2luZG93CnA9IlJlbW92aW5nIGNvcnJ1cHRlZCBlbGVtZW50ICIrSC5FaihzKQppZih0eXBl
-b2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2FybihwKX19fSwKa1I6ZnVuY3Rp
-b24oYSxiLGMsZCxlLGYsZyl7dmFyIHQscyxyLHEscCxvLG49dGhpcwppZihjKXtuLkVQKGEsYikKd2lu
-ZG93CnQ9IlJlbW92aW5nIGVsZW1lbnQgZHVlIHRvIGNvcnJ1cHRlZCBhdHRyaWJ1dGVzIG9uIDwiK2Qr
-Ij4iCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHQpCnJl
-dHVybn1pZighbi5hLmkwKGEpKXtuLkVQKGEsYikKd2luZG93CnQ9IlJlbW92aW5nIGRpc2FsbG93ZWQg
-ZWxlbWVudCA8IitlKyI+IGZyb20gIitILkVqKGIpCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVk
-Iil3aW5kb3cuY29uc29sZS53YXJuKHQpCnJldHVybn1pZihnIT1udWxsKWlmKCFuLmEuRWIoYSwiaXMi
-LGcpKXtuLkVQKGEsYikKd2luZG93CnQ9IlJlbW92aW5nIGRpc2FsbG93ZWQgdHlwZSBleHRlbnNpb24g
-PCIrZSsnIGlzPSInK2crJyI+JwppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNv
-bnNvbGUud2Fybih0KQpyZXR1cm59dD1mLmdWKCkKcz1ILlZNKHQuc2xpY2UoMCksSC50Nih0KS5DKCJq
-ZDwxPiIpKQpmb3Iocj1mLmdWKCkubGVuZ3RoLTEsdD1mLmE7cj49MDstLXIpe2lmKHI+PXMubGVuZ3Ro
-KXJldHVybiBILk9IKHMscikKcT1zW3JdCnA9bi5hCm89Si5jSChxKQpILmgocSkKaWYoIXAuRWIoYSxv
-LHQuZ2V0QXR0cmlidXRlKHEpKSl7d2luZG93CnA9IlJlbW92aW5nIGRpc2FsbG93ZWQgYXR0cmlidXRl
-IDwiK2UrIiAiK3ErJz0iJytILkVqKHQuZ2V0QXR0cmlidXRlKHEpKSsnIj4nCmlmKHR5cGVvZiBjb25z
-b2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHApCnQucmVtb3ZlQXR0cmlidXRlKHEp
-fX1pZih1LmFXLmIoYSkpbi5QbihhLmNvbnRlbnQpfSwKJGlvbjoxfQpXLmZtLnByb3RvdHlwZT17CiQy
-OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG49dGhpcy5hCnN3aXRjaChhLm5vZGVUeXBlKXtj
-YXNlIDE6bi5JNChhLGIpCmJyZWFrCmNhc2UgODpjYXNlIDExOmNhc2UgMzpjYXNlIDQ6YnJlYWsKZGVm
-YXVsdDpuLkVQKGEsYil9dD1hLmxhc3RDaGlsZApmb3Iocj11LkE7bnVsbCE9dDspe3M9bnVsbAp0cnl7
-cz10LnByZXZpb3VzU2libGluZwppZihzIT1udWxsKXtxPXMubmV4dFNpYmxpbmcKcD10CnA9cT09bnVs
-bD9wIT1udWxsOnEhPT1wCnE9cH1lbHNlIHE9ITEKaWYocSl7cT1QLlBWKCJDb3JydXB0IEhUTUwiKQp0
-aHJvdyBILmIocSl9fWNhdGNoKG8pe0guUnUobykKcT1yLmEodCkKbi5iPSEwCmlmKGEhPT1xLnBhcmVu
-dE5vZGUpe3A9cS5wYXJlbnROb2RlCmlmKHAhPW51bGwpcC5yZW1vdmVDaGlsZChxKX1lbHNlIGEucmVt
-b3ZlQ2hpbGQocSkKdD1udWxsCnM9YS5sYXN0Q2hpbGR9aWYodCE9bnVsbCl0aGlzLiQyKHQsYSkKdD1z
-fX0sCiRTOjMxfQpXLkxlLnByb3RvdHlwZT17fQpXLks3LnByb3RvdHlwZT17fQpXLnJCLnByb3RvdHlw
-ZT17fQpXLlhXLnByb3RvdHlwZT17fQpXLm9hLnByb3RvdHlwZT17fQpQLmlKLnByb3RvdHlwZT17ClZI
-OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5hLHI9cy5sZW5ndGgKZm9yKHQ9MDt0PHI7Kyt0KWlmKHNb
-dF09PT1hKXJldHVybiB0CkMuTm0uaShzLGEpCkMuTm0uaSh0aGlzLmIsbnVsbCkKcmV0dXJuIHJ9LApQ
-djpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT10aGlzLHA9e30KaWYoYT09bnVsbClyZXR1cm4gYQppZihI
-LmwoYSkpcmV0dXJuIGEKaWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBhCmlmKHR5cGVvZiBhPT0i
-c3RyaW5nIilyZXR1cm4gYQppZihhIGluc3RhbmNlb2YgUC5pUClyZXR1cm4gbmV3IERhdGUoYS5hKQpp
-Zih1LmZ2LmIoYSkpdGhyb3cgSC5iKFAuU1koInN0cnVjdHVyZWQgY2xvbmUgb2YgUmVnRXhwIikpCmlm
-KHUuYzguYihhKSlyZXR1cm4gYQppZih1LncuYihhKSlyZXR1cm4gYQppZih1LkkuYihhKSlyZXR1cm4g
-YQp0PXUuZEUuYihhKXx8ITEKaWYodClyZXR1cm4gYQppZih1LnYuYihhKSl7cz1xLlZIKGEpCnQ9cS5i
-CmlmKHM+PXQubGVuZ3RoKXJldHVybiBILk9IKHQscykKcj1wLmE9dFtzXQppZihyIT1udWxsKXJldHVy
-biByCnI9e30KcC5hPXIKQy5ObS5ZKHQscyxyKQphLksoMCxuZXcgUC5qZyhwLHEpKQpyZXR1cm4gcC5h
-fWlmKHUuai5iKGEpKXtzPXEuVkgoYSkKcD1xLmIKaWYocz49cC5sZW5ndGgpcmV0dXJuIEguT0gocCxz
-KQpyPXBbc10KaWYociE9bnVsbClyZXR1cm4gcgpyZXR1cm4gcS5layhhLHMpfWlmKHUuZUguYihhKSl7
-cz1xLlZIKGEpCnQ9cS5iCmlmKHM+PXQubGVuZ3RoKXJldHVybiBILk9IKHQscykKcj1wLmI9dFtzXQpp
-ZihyIT1udWxsKXJldHVybiByCnI9e30KcC5iPXIKQy5ObS5ZKHQscyxyKQpxLmltKGEsbmV3IFAuVGEo
-cCxxKSkKcmV0dXJuIHAuYn10aHJvdyBILmIoUC5TWSgic3RydWN0dXJlZCBjbG9uZSBvZiBvdGhlciB0
-eXBlIikpfSwKZWs6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPUouVTYoYSkscj1zLmdBKGEpLHE9bmV3IEFy
-cmF5KHIpCkMuTm0uWSh0aGlzLmIsYixxKQpmb3IodD0wO3Q8cjsrK3QpQy5ObS5ZKHEsdCx0aGlzLlB2
-KHMucShhLHQpKSkKcmV0dXJuIHF9fQpQLmpnLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhp
-cy5hLmFbYV09dGhpcy5iLlB2KGIpfSwKJFM6Mn0KUC5UYS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihh
-LGIpe3RoaXMuYS5iW2FdPXRoaXMuYi5QdihiKX0sCiRTOjJ9ClAuQmYucHJvdG90eXBlPXsKaW06ZnVu
-Y3Rpb24oYSxiKXt2YXIgdCxzLHIscQp1LmI4LmEoYikKZm9yKHQ9T2JqZWN0LmtleXMoYSkscz10Lmxl
-bmd0aCxyPTA7cjxzOysrcil7cT10W3JdCmIuJDIocSxhW3FdKX19fQpQLkFzLnByb3RvdHlwZT17ClQ6
-ZnVuY3Rpb24oYSl7dmFyIHQKSC5oKGEpCnQ9JC5oRygpLmIKaWYodHlwZW9mIGEhPSJzdHJpbmciKUgu
-dmgoSC50TChhKSkKaWYodC50ZXN0KGEpKXJldHVybiBhCnRocm93IEguYihQLkwzKGEsInZhbHVlIiwi
-Tm90IGEgdmFsaWQgY2xhc3MgdG9rZW4iKSl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLkRHKCku
-elYoMCwiICIpfSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuREcoKQpyZXR1cm4gUC5yaih0LHQu
-cixILkxoKHQpLmMpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuREcoKS5hfSwKdGc6ZnVuY3Rp
-b24oYSxiKXt0aGlzLlQoYikKcmV0dXJuIHRoaXMuREcoKS50ZygwLGIpfSwKaTpmdW5jdGlvbihhLGIp
-e3ZhciB0CnRoaXMuVChiKQp0PXRoaXMuT1MobmV3IFAuR0UoYikpCnJldHVybiBILnk4KHQ9PW51bGw/
-ITE6dCl9LApSOmZ1bmN0aW9uKGEsYil7dmFyIHQscwp0aGlzLlQoYikKdD10aGlzLkRHKCkKcz10LlIo
-MCxiKQp0aGlzLnAodCkKcmV0dXJuIHN9LApGVjpmdW5jdGlvbihhLGIpe3RoaXMuT1MobmV3IFAuTjco
-dGhpcyx1LlEuYShiKSkpfSwKVjE6ZnVuY3Rpb24oYSl7dGhpcy5PUyhuZXcgUC51USgpKX0sCk9TOmZ1
-bmN0aW9uKGEpe3ZhciB0LHMKdS5iVS5hKGEpCnQ9dGhpcy5ERygpCnM9YS4kMSh0KQp0aGlzLnAodCkK
-cmV0dXJuIHN9fQpQLkdFLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB1LkMuYShhKS5p
-KDAsdGhpcy5hKX0sCiRTOjMzfQpQLk43LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PXRo
-aXMuYixzPUgudDYodCkKcmV0dXJuIHUuQy5hKGEpLkZWKDAsbmV3IEgubEoodCxzLkMoInFVKDEpIiku
-YSh0aGlzLmEuZ3VNKCkpLHMuQygibEo8MSxxVT4iKSkpfSwKJFM6MTV9ClAudVEucHJvdG90eXBlPXsK
-JDE6ZnVuY3Rpb24oYSl7dS5DLmEoYSkKaWYoYS5hPjApe2EuYj1hLmM9YS5kPWEuZT1hLmY9bnVsbAph
-LmE9MAphLlgoKX1yZXR1cm4gbnVsbH0sCiRTOjE1fQpQLmhGLnByb3RvdHlwZT17JGloRjoxfQpQLlBD
-LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0CnUuWS5hKGEpCnQ9ZnVuY3Rpb24oYixjLGQp
-e3JldHVybiBmdW5jdGlvbigpe3JldHVybiBiKGMsZCx0aGlzLEFycmF5LnByb3RvdHlwZS5zbGljZS5h
-cHBseShhcmd1bWVudHMpKX19KFAuUjQsYSwhMSkKUC5EbSh0LCQudygpLGEpCnJldHVybiB0fSwKJFM6
-NX0KUC5tdC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IHRoaXMuYShhKX0sCiRT
-OjV9ClAuTnoucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnI3KGEpfSwKJFM6
-NTN9ClAuUVMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLlR6KGEsdS5hbSl9
-LAokUzozNn0KUC5ucC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuRTQoYSl9
-LAokUzozN30KUC5FNC5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGIhPSJzdHJp
-bmciJiZ0eXBlb2YgYiE9Im51bWJlciIpdGhyb3cgSC5iKFAueFkoInByb3BlcnR5IGlzIG5vdCBhIFN0
-cmluZyBvciBudW0iKSkKcmV0dXJuIFAuTDcodGhpcy5hW2JdKX0sClk6ZnVuY3Rpb24oYSxiLGMpe2lm
-KHR5cGVvZiBiIT0ic3RyaW5nIiYmdHlwZW9mIGIhPSJudW1iZXIiKXRocm93IEguYihQLnhZKCJwcm9w
-ZXJ0eSBpcyBub3QgYSBTdHJpbmcgb3IgbnVtIikpCnRoaXMuYVtiXT1QLndZKGMpfSwKRE46ZnVuY3Rp
-b24oYSxiKXtpZihiPT1udWxsKXJldHVybiExCnJldHVybiBiIGluc3RhbmNlb2YgUC5FNCYmdGhpcy5h
-PT09Yi5hfSwKdzpmdW5jdGlvbihhKXt2YXIgdCxzCnRyeXt0PVN0cmluZyh0aGlzLmEpCnJldHVybiB0
-fWNhdGNoKHMpe0guUnUocykKdD10aGlzLnhiKDApCnJldHVybiB0fX0sClY3OmZ1bmN0aW9uKGEsYil7
-dmFyIHQscz10aGlzLmEKaWYoYj09bnVsbCl0PW51bGwKZWxzZXt0PUgudDYoYikKdD1QLkNIKG5ldyBI
-LmxKKGIsdC5DKCJAKDEpIikuYShQLmlHKCkpLHQuQygibEo8MSxAPiIpKSwhMCx1LnopfXJldHVybiBQ
-Lkw3KHNbYV0uYXBwbHkocyx0KSl9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIDB9fQpQLnI3LnByb3Rv
-dHlwZT17fQpQLlR6LnByb3RvdHlwZT17CmNQOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz1hPDB8fGE+
-PXQuZ0EodCkKaWYocyl0aHJvdyBILmIoUC5URShhLDAsdC5nQSh0KSxudWxsLG51bGwpKX0sCnE6ZnVu
-Y3Rpb24oYSxiKXtpZihILm9rKGIpKXRoaXMuY1AoYikKcmV0dXJuIHRoaXMuJHRpLmMuYSh0aGlzLlVy
-KDAsYikpfSwKWTpmdW5jdGlvbihhLGIsYyl7dGhpcy5jUChiKQp0aGlzLmU0KDAsYixjKX0sCmdBOmZ1
-bmN0aW9uKGEpe3ZhciB0PXRoaXMuYS5sZW5ndGgKaWYodHlwZW9mIHQ9PT0ibnVtYmVyIiYmdD4+PjA9
-PT10KXJldHVybiB0CnRocm93IEguYihQLlBWKCJCYWQgSnNBcnJheSBsZW5ndGgiKSl9LAokaWJROjEs
-CiRpY1g6MSwKJGl6TToxfQpQLmNvLnByb3RvdHlwZT17fQpQLmJCLnByb3RvdHlwZT17JGliQjoxfQpQ
-LktlLnByb3RvdHlwZT17CkRHOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD10aGlzLmEuZ2V0QXR0cmli
-dXRlKCJjbGFzcyIpLG89UC5Mcyh1Lk4pCmlmKHA9PW51bGwpcmV0dXJuIG8KZm9yKHQ9cC5zcGxpdCgi
-ICIpLHM9dC5sZW5ndGgscj0wO3I8czsrK3Ipe3E9Si5UMCh0W3JdKQppZihxLmxlbmd0aCE9PTApby5p
-KDAscSl9cmV0dXJuIG99LApwOmZ1bmN0aW9uKGEpe3RoaXMuYS5zZXRBdHRyaWJ1dGUoImNsYXNzIixh
-LnpWKDAsIiAiKSl9fQpQLmQ1LnByb3RvdHlwZT17CmdQOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5L
-ZShhKX0sCnNoZjpmdW5jdGlvbihhLGIpe3RoaXMuWUMoYSxiKX0sCnI2OmZ1bmN0aW9uKGEsYixjLGQp
-e3ZhciB0LHMscixxLHAsbwppZihkPT1udWxsKXt0PUguVk0oW10sdS5wKQpkPW5ldyBXLnZEKHQpCkMu
-Tm0uaSh0LFcuVHcobnVsbCkpCkMuTm0uaSh0LFcuQmwoKSkKQy5ObS5pKHQsbmV3IFcuT3coKSl9Yz1u
-ZXcgVy5LbyhkKQpzPSc8c3ZnIHZlcnNpb249IjEuMSI+JytILkVqKGIpKyI8L3N2Zz4iCnQ9ZG9jdW1l
-bnQKcj10LmJvZHkKci50b1N0cmluZwpxPUMuUlkuQUgocixzLGMpCnA9dC5jcmVhdGVEb2N1bWVudEZy
-YWdtZW50KCkKdD1uZXcgVy5lNyhxKQpvPXQuZ3I4KHQpCmZvcig7dD1vLmZpcnN0Q2hpbGQsdCE9bnVs
-bDspcC5hcHBlbmRDaGlsZCh0KQpyZXR1cm4gcH0sCm56OmZ1bmN0aW9uKGEsYixjLGQsZSl7dGhyb3cg
-SC5iKFAuTDQoIkNhbm5vdCBpbnZva2UgaW5zZXJ0QWRqYWNlbnRIdG1sIG9uIFNWRy4iKSl9LApnVmw6
-ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBXLmV1KGEsImNsaWNrIiwhMSx1LkcpfSwKJGlkNToxfQpQLm42
-LnByb3RvdHlwZT17JGliUToxLCRpY1g6MSwkaXpNOjEsJGlBUzoxfQpVLmQyLnByb3RvdHlwZT17fQpV
-LlNlLnByb3RvdHlwZT17fQpVLk1sLnByb3RvdHlwZT17fQpVLnlELnByb3RvdHlwZT17fQpVLndiLnBy
-b3RvdHlwZT17fQpCLmo4LnByb3RvdHlwZT17fQpCLnFwLnByb3RvdHlwZT17fQpULm1RLnByb3RvdHlw
-ZT17fQpMLmUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4KdS5hTC5h
-KGEpCnQ9d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lCnM9TC5HNih3aW5kb3cubG9jYXRpb24uaHJlZikK
-cj1MLmFLKHdpbmRvdy5sb2NhdGlvbi5ocmVmKQpMLkdlKCkKaWYodCE9PSIvIiYmdCE9PUouVDAoZG9j
-dW1lbnQucXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVudCkpTC5HNyh0LHMsciwhMCxuZXcg
-TC5WVyh0LHMscikpCnE9ZG9jdW1lbnQKcD1KLnFGKHEucXVlcnlTZWxlY3RvcigiLmFwcGx5LW1pZ3Jh
-dGlvbiIpKQpvPXAuJHRpCm49by5DKCJ+KDEpPyIpLmEobmV3IEwub1ooKSkKdS5aLmEobnVsbCkKVy5K
-RShwLmEscC5iLG4sITEsby5jKQpvPUoucUYocS5xdWVyeVNlbGVjdG9yKCIucmVydW4tbWlncmF0aW9u
-IikpCm49by4kdGkKVy5KRShvLmEsby5iLG4uQygifigxKT8iKS5hKG5ldyBMLkhpKCkpLCExLG4uYykK
-bj1KLnFGKHEucXVlcnlTZWxlY3RvcigiLnJlcG9ydC1wcm9ibGVtIikpCm89bi4kdGkKVy5KRShuLmEs
-bi5iLG8uQygifigxKT8iKS5hKG5ldyBMLkJUKCkpLCExLG8uYykKcT1KLnFGKHEucXVlcnlTZWxlY3Rv
-cigiLnBvcHVwLXBhbmUgLmNsb3NlIikpCm89cS4kdGkKVy5KRShxLmEscS5iLG8uQygifigxKT8iKS5h
-KG5ldyBMLlBZKCkpLCExLG8uYyl9LAokUzoxNn0KTC5WVy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigp
-e0wuRnIodGhpcy5hLHRoaXMuYix0aGlzLmMpfSwKJFM6MH0KTC5vWi5wcm90b3R5cGU9ewokMTpmdW5j
-dGlvbihhKXt1Lk8uYShhKQppZihDLm9sLnVzKHdpbmRvdywiVGhpcyB3aWxsIGFwcGx5IHRoZSBjaGFu
-Z2VzIHlvdSd2ZSBwcmV2aWV3ZWQgdG8geW91ciB3b3JraW5nIGRpcmVjdG9yeS4gSXQgaXMgcmVjb21t
-ZW5kZWQgeW91IGNvbW1pdCBhbnkgY2hhbmdlcyB5b3UgbWFkZSBiZWZvcmUgZG9pbmcgdGhpcy4iKSlM
-LnR5KCIvYXBwbHktbWlncmF0aW9uIikuVzcobmV3IEwuanIoKSx1LlApLk9BKG5ldyBMLnFsKCkpfSwK
-JFM6M30KTC5qci5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1LmEuYShhKQp0PWRvY3Vt
-ZW50LmJvZHkKdC5jbGFzc0xpc3QucmVtb3ZlKCJwcm9wb3NlZCIpCnQuY2xhc3NMaXN0LmFkZCgiYXBw
-bGllZCIpfSwKJFM6NDB9CkwucWwucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtMLkMyKCJDb3Vs
-ZCBub3QgYXBwbHkgbWlncmF0aW9uIixhLGIpfSwKJEM6IiQyIiwKJFI6MiwKJFM6Mn0KTC5IaS5wcm90
-b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy54bih1Lk8uYShhKSl9LAp4bjpmdW5jdGlv
-bihhKXt2YXIgdD0wLHM9UC5GWCh1LlApLHI9MSxxLHA9W10sbyxuLG0sbAp2YXIgJGFzeW5jJCQxPVAu
-bHooZnVuY3Rpb24oYixjKXtpZihiPT09MSl7cT1jCnQ9cn13aGlsZSh0cnVlKXN3aXRjaCh0KXtjYXNl
-IDA6cj0zCmRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgicmVydW5uaW5nIikKdD02CnJldHVybiBQ
-LmpRKEwudHkoIi9yZXJ1bi1taWdyYXRpb24iKSwkYXN5bmMkJDEpCmNhc2UgNjp3aW5kb3cubG9jYXRp
-b24ucmVsb2FkKCkKcC5wdXNoKDUpCnQ9NApicmVhawpjYXNlIDM6cj0yCmw9cQpvPUguUnUobCkKbj1I
-LnRzKGwpCkwuQzIoIkZhaWxlZCB0byByZXJ1biBtaWdyYXRpb24iLG8sbikKcC5wdXNoKDUpCnQ9NApi
-cmVhawpjYXNlIDI6cD1bMV0KY2FzZSA0OnI9MQpkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUo
-InJlcnVubmluZyIpCnQ9cC5wb3AoKQpicmVhawpjYXNlIDU6cmV0dXJuIFAueUMobnVsbCxzKQpjYXNl
-IDE6cmV0dXJuIFAuZjMocSxzKX19KQpyZXR1cm4gUC5ESSgkYXN5bmMkJDEscyl9LAokUzo0MX0KTC5C
-VC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt1Lk8uYShhKQpDLm9sLlBvKHdpbmRvdywiaHR0cHM6
-Ly9nb28uZ2xlL2RhcnQtbnVsbC1zYWZldHktbWlncmF0aW9uLXRvb2wtaXNzdWUiLCJyZXBvcnQtcHJv
-YmxlbSIpfSwKJFM6M30KTC5QWS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1Lk8uYShh
-KQp0PWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5wb3B1cC1wYW5lIikuc3R5bGUKdC5kaXNwbGF5PSJu
-b25lIgpyZXR1cm4ibm9uZSJ9LAokUzo0Mn0KTC5MLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3Zh
-ciB0LHMscgp1LmFMLmEoYSkKdD13aW5kb3cubG9jYXRpb24ucGF0aG5hbWUKcz1MLkc2KHdpbmRvdy5s
-b2NhdGlvbi5ocmVmKQpyPUwuYUsod2luZG93LmxvY2F0aW9uLmhyZWYpCmlmKHQubGVuZ3RoPjEpTC5H
-Nyh0LHMsciwhMSxudWxsKQplbHNle0wuQkUodCxuZXcgQi5xcCgiIiwiIiwiIixDLkNNKSwhMCkKTC5C
-WCgiJm5ic3A7IixudWxsKX19LAokUzoxNn0KTC5XeC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2
-YXIgdCxzLHIscT0iY29sbGFwc2VkIgp1Lk8uYShhKQp0PXRoaXMuYQpzPUouWUUodCkKcj10aGlzLmIK
-aWYoIXMuZ1AodCkudGcoMCxxKSl7cy5nUCh0KS5pKDAscSkKSi5kUihyKS5pKDAscSl9ZWxzZXtzLmdQ
-KHQpLlIoMCxxKQpKLmRSKHIpLlIoMCxxKX19LAokUzozfQpMLkFPLnByb3RvdHlwZT17CiQxOmZ1bmN0
-aW9uKGEpe3ZhciB0PUoucUYodS5nLmEoYSkpLHM9dC4kdGkscj1zLkMoIn4oMSk/IikuYShuZXcgTC5k
-Tih0aGlzLmEpKQp1LlouYShudWxsKQpXLkpFKHQuYSx0LmIsciwhMSxzLmMpfSwKJFM6NH0KTC5kTi5w
-cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1Lk8uYShhKQp0PWRvY3VtZW50LnF1ZXJ5U2Vs
-ZWN0b3IoInRhYmxlW2RhdGEtcGF0aF0iKQp0LnRvU3RyaW5nCkwudDIoYSx0aGlzLmEsdC5nZXRBdHRy
-aWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyh0KSkuTygicGF0aCIpKSl9LAokUzozfQpMLkhv
-LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMscgp1LmcuYShhKQp0PUoucUYoYSkKcz10
-LiR0aQpyPXMuQygifigxKT8iKS5hKG5ldyBMLnh6KGEsdGhpcy5hKSkKdS5aLmEobnVsbCkKVy5KRSh0
-LmEsdC5iLHIsITEscy5jKX0sCiRTOjR9CkwueHoucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
-IHQKdS5PLmEoYSkKdD10aGlzLmEKTC5oWCh0aGlzLmIsUC5RQSh0LmdldEF0dHJpYnV0ZSgiZGF0YS0i
-K25ldyBXLlN5KG5ldyBXLmk3KHQpKS5PKCJvZmZzZXQiKSksbnVsbCksUC5RQSh0LmdldEF0dHJpYnV0
-ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KHQpKS5PKCJsaW5lIikpLG51bGwpKX0sCiRTOjN9Ckwu
-SUMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9Si5xRih1LmcuYShhKSkscz10LiR0aQpz
-LkMoIn4oMSk/IikuYShMLmlTKCkpCnUuWi5hKG51bGwpClcuSkUodC5hLHQuYixMLmlTKCksITEscy5j
-KX0sCiRTOjR9CkwuTDEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dS5FLmEoYSkKdGhpcy5hLmFN
-KDAsdGhpcy5iKX0sCiRTOjQ0fQpMLm5ULnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlz
-LmEuYSx0aGlzLmIsdGhpcy5jKX0sCiRTOjB9CkwuTlkucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtM
-LkZyKHRoaXMuYS5hLG51bGwsbnVsbCl9LAokUzowfQpMLmVYLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9u
-KGEpe3UuZy5hKGEpCiQuekIoKS50b1N0cmluZwp1LmRILmEoJC5vdygpLnEoMCwiaGxqcyIpKS5WNygi
-aGlnaGxpZ2h0QmxvY2siLFthXSl9LAokUzo0fQpMLkRULnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEp
-e3ZhciB0LHMKdS5ELmEoYSkKdD1hLnN0YXR1cwppZih0PT09MjAwKXt0PUMuQ3QucFcoMCxhLnJlc3Bv
-bnNlVGV4dCxudWxsKQpzPUouVTYodCkKTC5UMShuZXcgVS5kMihVLmpmKHMucSh0LCJlZGl0cyIpKSxI
-Lmgocy5xKHQsImV4cGxhbmF0aW9uIikpLEgudVAocy5xKHQsImxpbmUiKSksSC5oKHMucSh0LCJwYXRo
-IikpLFUuTmQocy5xKHQsInRyYWNlcyIpKSkpCkwuRnIodGhpcy5hLHRoaXMuYix0aGlzLmMpCkwueVgo
-Ii5lZGl0LXBhbmVsIC5wYW5lbC1jb250ZW50IiwhMSl9ZWxzZSBDLm9sLlV4KHdpbmRvdywiUmVxdWVz
-dCBmYWlsZWQ7IHN0YXR1cyBvZiAiK3QpfSwKJFM6OH0KTC5lSC5wcm90b3R5cGU9ewokMjpmdW5jdGlv
-bihhLGIpe0wucUooImxvYWRSZWdpb25FeHBsYW5hdGlvbjogIitILkVqKGEpLGIpCkMub2wuVXgod2lu
-ZG93LCJDb3VsZCBub3QgbG9hZCAiK0guRWoodGhpcy5hKSsiICgiK0guRWooYSkrIikuIil9LAokQzoi
-JDIiLAokUjoyLAokUzoyfQpMLnl1LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj10
-aGlzCnUuRC5hKGEpCnQ9YS5zdGF0dXMKaWYodD09PTIwMCl7cz1yLmEKTC5CRShzLEIuWWYodS5iby5h
-KEMuQ3QucFcoMCxhLnJlc3BvbnNlVGV4dCxudWxsKSkpLHIuYikKdD1yLmMKTC5mRyh0LHIuZCkKTC5C
-WChDLnhCLnRnKHMsIj8iKT9DLnhCLk5qKHMsMCxDLnhCLk9ZKHMsIj8iKSk6cyx0KQp0PXIuZQppZih0
-IT1udWxsKXQuJDAoKX1lbHNlIEMub2wuVXgod2luZG93LCJSZXF1ZXN0IGZhaWxlZDsgc3RhdHVzIG9m
-ICIrdCl9LAokUzo4fQpMLnpELnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7TC5xSigibG9hZEZp
-bGU6ICIrSC5FaihhKSxiKQpDLm9sLlV4KHdpbmRvdywiQ291bGQgbm90IGxvYWQgIit0aGlzLmErIiAo
-IitILkVqKGEpKyIpLiIpfSwKJEM6IiQyIiwKJFI6MiwKJFM6Mn0KTC5UVy5wcm90b3R5cGU9ewokMTpm
-dW5jdGlvbihhKXt2YXIgdCxzLHIKdS5ELmEoYSkKdD1hLnN0YXR1cwppZih0PT09MjAwKXtzPUMuQ3Qu
-cFcoMCxhLnJlc3BvbnNlVGV4dCxudWxsKQpyPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5uYXYtdHJl
-ZSIpCkoubDUociwiIikKTC50WChyLEwubUsocykpfWVsc2UgQy5vbC5VeCh3aW5kb3csIlJlcXVlc3Qg
-ZmFpbGVkOyBzdGF0dXMgb2YgIit0KX0sCiRTOjh9CkwueHIucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24o
-YSxiKXtMLnFKKCJsb2FkTmF2aWdhdGlvblRyZWU6ICIrSC5FaihhKSxiKQpDLm9sLlV4KHdpbmRvdywi
-Q291bGQgbm90IGxvYWQgIit0aGlzLmErIiAoIitILkVqKGEpKyIpLiIpfSwKJEM6IiQyIiwKJFI6MiwK
-JFM6Mn0KTC5FRS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzCnUuTy5hKGEpCnQ9dGhp
-cy5hCnM9dGhpcy5iCkwuYWYod2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLHQscywhMCxuZXcgTC5RTCh0
-LHMpKQpMLmhYKHRoaXMuYyx0LHMpfSwKJFM6M30KTC5RTC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigp
-e0wuRnIod2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLHRoaXMuYSx0aGlzLmIpfSwKJFM6MH0KTC5WUy5w
-cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzPSJzZWxlY3RlZC1maWxlIgp1LmcuYShhKQph
-LnRvU3RyaW5nCnQ9Si5ZRShhKQppZihhLmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBX
-Lmk3KGEpKS5PKCJuYW1lIikpPT09dGhpcy5hLmEpdC5nUChhKS5pKDAscykKZWxzZSB0LmdQKGEpLlIo
-MCxzKX0sCiRTOjR9CkwuVEQucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEwudDIodS5P
-LmEoYSksITAsbnVsbCl9LAokUzoxN30KTC5YQS5wcm90b3R5cGU9ewpFYjpmdW5jdGlvbihhLGIsYyl7
-cmV0dXJuITB9LAppMDpmdW5jdGlvbihhKXtyZXR1cm4hMH0sCiRpa0Y6MX0KTC5aWi5wcm90b3R5cGU9
-e30KTC5POS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmJ9fQpNLmxJLnByb3Rv
-dHlwZT17CldPOmZ1bmN0aW9uKGEsYil7dmFyIHQscz1udWxsCk0uWUYoImFic29sdXRlIixILlZNKFti
-LG51bGwsbnVsbCxudWxsLG51bGwsbnVsbCxudWxsXSx1LmkpKQp0PXRoaXMuYQp0PXQuWXIoYik+MCYm
-IXQuaEsoYikKaWYodClyZXR1cm4gYgp0PUQuUlgoKQpyZXR1cm4gdGhpcy5xNygwLHQsYixzLHMscyxz
-LHMscyl9LAp0TTpmdW5jdGlvbihhKXt2YXIgdCxzLHI9WC5DTChhLHRoaXMuYSkKci5JVigpCnQ9ci5k
-CnM9dC5sZW5ndGgKaWYocz09PTApe3Q9ci5iCnJldHVybiB0PT1udWxsPyIuIjp0fWlmKHM9PT0xKXt0
-PXIuYgpyZXR1cm4gdD09bnVsbD8iLiI6dH1pZigwPj1zKXJldHVybiBILk9IKHQsLTEpCnQucG9wKCkK
-Qy5ObS5tdihyLmUpCnIuSVYoKQpyZXR1cm4gci53KDApfSwKcTc6ZnVuY3Rpb24oYSxiLGMsZCxlLGYs
-ZyxoLGkpe3ZhciB0PUguVk0oW2IsYyxkLGUsZixnLGgsaV0sdS5pKQpNLllGKCJqb2luIix0KQpyZXR1
-cm4gdGhpcy5JUChuZXcgSC5VNSh0LHUuZ2YuYShuZXcgTS5NaSgpKSx1LmZpKSl9LApJUDpmdW5jdGlv
-bihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwKdS5lUy5hKGEpCmZvcih0PWEuJHRpLHM9dC5DKCJhMihj
-WC5FKSIpLmEobmV3IE0ucTcoKSkscj1hLmdreihhKSx0PW5ldyBILlNPKHIscyx0LkMoIlNPPGNYLkU+
-IikpLHM9dGhpcy5hLHE9ITEscD0hMSxvPSIiO3QuRigpOyl7bj1ILmgoci5nbCgpKQppZihzLmhLKG4p
-JiZwKXttPVguQ0wobixzKQpsPW8uY2hhckNvZGVBdCgwKT09MD9vOm8Kbz1DLnhCLk5qKGwsMCxzLlNw
-KGwsITApKQptLmI9bwppZihzLmRzKG8pKUMuTm0uWShtLmUsMCxzLmdtSSgpKQpvPSIiK20udygwKX1l
-bHNlIGlmKHMuWXIobik+MCl7cD0hcy5oSyhuKQpvPSIiK0guRWoobil9ZWxzZXtpZighKG4ubGVuZ3Ro
-PjAmJnMuVWQoblswXSkpKWlmKHEpbys9cy5nbUkoKQpvKz1ufXE9cy5kcyhuKX1yZXR1cm4gby5jaGFy
-Q29kZUF0KDApPT0wP286b30sCm81OmZ1bmN0aW9uKGEpe3ZhciB0CmlmKCF0aGlzLnkzKGEpKXJldHVy
-biBhCnQ9WC5DTChhLHRoaXMuYSkKdC5yUigpCnJldHVybiB0LncoMCl9LAp5MzpmdW5jdGlvbihhKXt2
-YXIgdCxzLHIscSxwLG8sbixtLGwsawphLnRvU3RyaW5nCnQ9dGhpcy5hCnM9dC5ZcihhKQppZihzIT09
-MCl7aWYodD09PSQuS2soKSlmb3Iocj0wO3I8czsrK3IpaWYoQy54Qi5XKGEscik9PT00NylyZXR1cm4h
-MApxPXMKcD00N31lbHNle3E9MApwPW51bGx9Zm9yKG89bmV3IEgucWooYSkuYSxuPW8ubGVuZ3RoLHI9
-cSxtPW51bGw7cjxuOysrcixtPXAscD1sKXtsPUMueEIubShvLHIpCmlmKHQucjQobCkpe2lmKHQ9PT0k
-LktrKCkmJmw9PT00NylyZXR1cm4hMAppZihwIT1udWxsJiZ0LnI0KHApKXJldHVybiEwCmlmKHA9PT00
-NilrPW09PW51bGx8fG09PT00Nnx8dC5yNChtKQplbHNlIGs9ITEKaWYoaylyZXR1cm4hMH19aWYocD09
-bnVsbClyZXR1cm4hMAppZih0LnI0KHApKXJldHVybiEwCmlmKHA9PT00Nil0PW09PW51bGx8fHQucjQo
-bSl8fG09PT00NgplbHNlIHQ9ITEKaWYodClyZXR1cm4hMApyZXR1cm4hMX0sCkhQOmZ1bmN0aW9uKGEs
-Yil7dmFyIHQscyxyLHEscCxvPXRoaXMsbj0nVW5hYmxlIHRvIGZpbmQgYSBwYXRoIHRvICInCmI9by5X
-TygwLGIpCnQ9by5hCmlmKHQuWXIoYik8PTAmJnQuWXIoYSk+MClyZXR1cm4gby5vNShhKQppZih0Llly
-KGEpPD0wfHx0LmhLKGEpKWE9by5XTygwLGEpCmlmKHQuWXIoYSk8PTAmJnQuWXIoYik+MCl0aHJvdyBI
-LmIoWC5JNyhuK0guRWooYSkrJyIgZnJvbSAiJytILkVqKGIpKyciLicpKQpzPVguQ0woYix0KQpzLnJS
-KCkKcj1YLkNMKGEsdCkKci5yUigpCnE9cy5kCmlmKHEubGVuZ3RoPjAmJkouUk0ocVswXSwiLiIpKXJl
-dHVybiByLncoMCkKcT1zLmIKcD1yLmIKaWYocSE9cClxPXE9PW51bGx8fHA9PW51bGx8fCF0Lk5jKHEs
-cCkKZWxzZSBxPSExCmlmKHEpcmV0dXJuIHIudygwKQp3aGlsZSghMCl7cT1zLmQKaWYocS5sZW5ndGg+
-MCl7cD1yLmQKcT1wLmxlbmd0aD4wJiZ0Lk5jKHFbMF0scFswXSl9ZWxzZSBxPSExCmlmKCFxKWJyZWFr
-CkMuTm0uVzQocy5kLDApCkMuTm0uVzQocy5lLDEpCkMuTm0uVzQoci5kLDApCkMuTm0uVzQoci5lLDEp
-fXE9cy5kCmlmKHEubGVuZ3RoPjAmJkouUk0ocVswXSwiLi4iKSl0aHJvdyBILmIoWC5JNyhuK0guRWoo
-YSkrJyIgZnJvbSAiJytILkVqKGIpKyciLicpKQpxPXUuWApDLk5tLlVHKHIuZCwwLFAuTzgocy5kLmxl
-bmd0aCwiLi4iLCExLHEpKQpDLk5tLlkoci5lLDAsIiIpCkMuTm0uVUcoci5lLDEsUC5POChzLmQubGVu
-Z3RoLHQuZ21JKCksITEscSkpCnQ9ci5kCnE9dC5sZW5ndGgKaWYocT09PTApcmV0dXJuIi4iCmlmKHE+
-MSYmSi5STShDLk5tLmdyWih0KSwiLiIpKXt0PXIuZAppZigwPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0
-LC0xKQp0LnBvcCgpCnQ9ci5lCkMuTm0ubXYodCkKQy5ObS5tdih0KQpDLk5tLmkodCwiIil9ci5iPSIi
-CnIuSVYoKQpyZXR1cm4gci53KDApfX0KTS5NaS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1
-cm4gSC5oKGEpIT1udWxsfSwKJFM6MTh9Ck0ucTcucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0
-dXJuIEguaChhKSE9PSIifSwKJFM6MTh9Ck0uTm8ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7SC5o
-KGEpCnJldHVybiBhPT1udWxsPyJudWxsIjonIicrYSsnIid9LAokUzo0OH0KQi5mdi5wcm90b3R5cGU9
-ewp4WjpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMuWXIoYSkKaWYocz4wKXJldHVybiBKLmxkKGEsMCxz
-KQppZih0aGlzLmhLKGEpKXtpZigwPj1hLmxlbmd0aClyZXR1cm4gSC5PSChhLDApCnQ9YVswXX1lbHNl
-IHQ9bnVsbApyZXR1cm4gdH0sCk5jOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGE9PWJ9fQpYLldELnByb3Rv
-dHlwZT17CklWOmZ1bmN0aW9uKCl7dmFyIHQscyxyPXRoaXMKd2hpbGUoITApe3Q9ci5kCmlmKCEodC5s
-ZW5ndGghPT0wJiZKLlJNKEMuTm0uZ3JaKHQpLCIiKSkpYnJlYWsKdD1yLmQKaWYoMD49dC5sZW5ndGgp
-cmV0dXJuIEguT0godCwtMSkKdC5wb3AoKQpDLk5tLm12KHIuZSl9dD1yLmUKcz10Lmxlbmd0aAppZihz
-PjApQy5ObS5ZKHQscy0xLCIiKX0sCnJSOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG4sbT10aGlz
-LGw9SC5WTShbXSx1LmkpCmZvcih0PW0uZCxzPXQubGVuZ3RoLHI9MCxxPTA7cTx0Lmxlbmd0aDt0Lmxl
-bmd0aD09PXN8fCgwLEgubGspKHQpLCsrcSl7cD10W3FdCm89Si5pYShwKQppZighKG8uRE4ocCwiLiIp
-fHxvLkROKHAsIiIpKSlpZihvLkROKHAsIi4uIikpaWYobC5sZW5ndGg+MClsLnBvcCgpCmVsc2UgKyty
-CmVsc2UgQy5ObS5pKGwscCl9aWYobS5iPT1udWxsKUMuTm0uVUcobCwwLFAuTzgociwiLi4iLCExLHUu
-WCkpCmlmKGwubGVuZ3RoPT09MCYmbS5iPT1udWxsKUMuTm0uaShsLCIuIikKbj1QLmRIKGwubGVuZ3Ro
-LG5ldyBYLnFSKG0pLCEwLHUuWCkKdD1tLmIKdD10IT1udWxsJiZsLmxlbmd0aD4wJiZtLmEuZHModCk/
-bS5hLmdtSSgpOiIiCkgudDYobikuYy5hKHQpCmlmKCEhbi5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJp
-bnNlcnQiKSkKbi5zcGxpY2UoMCwwLHQpCm0uc25KKGwpCm0uc1BoKG4pCnQ9bS5iCmlmKHQhPW51bGwm
-Jm0uYT09PSQuS2soKSl7dC50b1N0cmluZwptLmI9SC55cyh0LCIvIiwiXFwiKX1tLklWKCl9LAp3OmZ1
-bmN0aW9uKGEpe3ZhciB0LHMscj10aGlzLHE9ci5iCnE9cSE9bnVsbD8iIitxOiIiCmZvcih0PTA7dDxy
-LmQubGVuZ3RoOysrdCl7cz1yLmUKaWYodD49cy5sZW5ndGgpcmV0dXJuIEguT0gocyx0KQpzPXErSC5F
-aihzW3RdKQpxPXIuZAppZih0Pj1xLmxlbmd0aClyZXR1cm4gSC5PSChxLHQpCnE9cytILkVqKHFbdF0p
-fXErPUguRWooQy5ObS5nclooci5lKSkKcmV0dXJuIHEuY2hhckNvZGVBdCgwKT09MD9xOnF9LApzbko6
-ZnVuY3Rpb24oYSl7dGhpcy5kPXUuZUcuYShhKX0sCnNQaDpmdW5jdGlvbihhKXt0aGlzLmU9dS5lRy5h
-KGEpfX0KWC5xUi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmEuZ21JKCl9
-LAokUzo0OX0KWC5kdi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJQYXRoRXhjZXB0aW9u
-OiAiK3RoaXMuYX19Ck8uekwucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nb2Mo
-dGhpcyl9fQpFLk9GLnByb3RvdHlwZT17ClVkOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLnRnKGEsIi8i
-KX0sCnI0OmZ1bmN0aW9uKGEpe3JldHVybiBhPT09NDd9LApkczpmdW5jdGlvbihhKXt2YXIgdD1hLmxl
-bmd0aApyZXR1cm4gdCE9PTAmJkMueEIubShhLHQtMSkhPT00N30sClNwOmZ1bmN0aW9uKGEsYil7aWYo
-YS5sZW5ndGghPT0wJiZDLnhCLlcoYSwwKT09PTQ3KXJldHVybiAxCnJldHVybiAwfSwKWXI6ZnVuY3Rp
-b24oYSl7cmV0dXJuIHRoaXMuU3AoYSwhMSl9LApoSzpmdW5jdGlvbihhKXtyZXR1cm4hMX0sCmdvYzpm
-dW5jdGlvbigpe3JldHVybiJwb3NpeCJ9LApnbUk6ZnVuY3Rpb24oKXtyZXR1cm4iLyJ9fQpGLnJ1LnBy
-b3RvdHlwZT17ClVkOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLnRnKGEsIi8iKX0sCnI0OmZ1bmN0aW9u
-KGEpe3JldHVybiBhPT09NDd9LApkczpmdW5jdGlvbihhKXt2YXIgdD1hLmxlbmd0aAppZih0PT09MCly
-ZXR1cm4hMQppZihDLnhCLm0oYSx0LTEpIT09NDcpcmV0dXJuITAKcmV0dXJuIEMueEIuVGMoYSwiOi8v
-IikmJnRoaXMuWXIoYSk9PT10fSwKU3A6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwPWEubGVuZ3Ro
-CmlmKHA9PT0wKXJldHVybiAwCmlmKEMueEIuVyhhLDApPT09NDcpcmV0dXJuIDEKZm9yKHQ9MDt0PHA7
-Kyt0KXtzPUMueEIuVyhhLHQpCmlmKHM9PT00NylyZXR1cm4gMAppZihzPT09NTgpe2lmKHQ9PT0wKXJl
-dHVybiAwCnI9Qy54Qi5YVShhLCIvIixDLnhCLlFpKGEsIi8vIix0KzEpP3QrMzp0KQppZihyPD0wKXJl
-dHVybiBwCmlmKCFifHxwPHIrMylyZXR1cm4gcgppZighQy54Qi5uKGEsImZpbGU6Ly8iKSlyZXR1cm4g
-cgppZighQi5ZdShhLHIrMSkpcmV0dXJuIHIKcT1yKzMKcmV0dXJuIHA9PT1xP3E6cis0fX1yZXR1cm4g
-MH0sCllyOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLlNwKGEsITEpfSwKaEs6ZnVuY3Rpb24oYSl7cmV0
-dXJuIGEubGVuZ3RoIT09MCYmQy54Qi5XKGEsMCk9PT00N30sCmdvYzpmdW5jdGlvbigpe3JldHVybiJ1
-cmwifSwKZ21JOmZ1bmN0aW9uKCl7cmV0dXJuIi8ifX0KTC5JVi5wcm90b3R5cGU9ewpVZDpmdW5jdGlv
-bihhKXtyZXR1cm4gQy54Qi50ZyhhLCIvIil9LApyNDpmdW5jdGlvbihhKXtyZXR1cm4gYT09PTQ3fHxh
-PT09OTJ9LApkczpmdW5jdGlvbihhKXt2YXIgdD1hLmxlbmd0aAppZih0PT09MClyZXR1cm4hMQp0PUMu
-eEIubShhLHQtMSkKcmV0dXJuISh0PT09NDd8fHQ9PT05Mil9LApTcDpmdW5jdGlvbihhLGIpe3ZhciB0
-LHMscj1hLmxlbmd0aAppZihyPT09MClyZXR1cm4gMAp0PUMueEIuVyhhLDApCmlmKHQ9PT00NylyZXR1
-cm4gMQppZih0PT09OTIpe2lmKHI8Mnx8Qy54Qi5XKGEsMSkhPT05MilyZXR1cm4gMQpzPUMueEIuWFUo
-YSwiXFwiLDIpCmlmKHM+MCl7cz1DLnhCLlhVKGEsIlxcIixzKzEpCmlmKHM+MClyZXR1cm4gc31yZXR1
-cm4gcn1pZihyPDMpcmV0dXJuIDAKaWYoIUIuT1ModCkpcmV0dXJuIDAKaWYoQy54Qi5XKGEsMSkhPT01
-OClyZXR1cm4gMApyPUMueEIuVyhhLDIpCmlmKCEocj09PTQ3fHxyPT09OTIpKXJldHVybiAwCnJldHVy
-biAzfSwKWXI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuU3AoYSwhMSl9LApoSzpmdW5jdGlvbihhKXty
-ZXR1cm4gdGhpcy5ZcihhKT09PTF9LApPdDpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGE9PT1iKXJldHVy
-biEwCmlmKGE9PT00NylyZXR1cm4gYj09PTkyCmlmKGE9PT05MilyZXR1cm4gYj09PTQ3CmlmKChhXmIp
-IT09MzIpcmV0dXJuITEKdD1hfDMyCnJldHVybiB0Pj05NyYmdDw9MTIyfSwKTmM6ZnVuY3Rpb24oYSxi
-KXt2YXIgdCxzLHIKaWYoYT09YilyZXR1cm4hMAp0PWEubGVuZ3RoCmlmKHQhPT1iLmxlbmd0aClyZXR1
-cm4hMQpmb3Iocz1KLnJZKGIpLHI9MDtyPHQ7KytyKWlmKCF0aGlzLk90KEMueEIuVyhhLHIpLHMuVyhi
-LHIpKSlyZXR1cm4hMQpyZXR1cm4hMH0sCmdvYzpmdW5jdGlvbigpe3JldHVybiJ3aW5kb3dzIn0sCmdt
-STpmdW5jdGlvbigpe3JldHVybiJcXCJ9fTsoZnVuY3Rpb24gYWxpYXNlcygpe3ZhciB0PUoudkIucHJv
-dG90eXBlCnQuVT10LncKdC5Taj10LmU3CnQ9Si5NRi5wcm90b3R5cGUKdC50PXQudwp0PVAuY1gucHJv
-dG90eXBlCnQuR0c9dC5ldgp0PVAuTWgucHJvdG90eXBlCnQueGI9dC53CnQ9Vy5jdi5wcm90b3R5cGUK
-dC5EVz10LnI2CnQ9Vy5tNi5wcm90b3R5cGUKdC5qRj10LkViCnQ9UC5FNC5wcm90b3R5cGUKdC5Vcj10
-LnEKdC5lND10Lll9KSgpOyhmdW5jdGlvbiBpbnN0YWxsVGVhck9mZnMoKXt2YXIgdD1odW5rSGVscGVy
-cy5fc3RhdGljXzEscz1odW5rSGVscGVycy5fc3RhdGljXzAscj1odW5rSGVscGVycy5pbnN0YWxsSW5z
-dGFuY2VUZWFyT2ZmLHE9aHVua0hlbHBlcnMuaW5zdGFsbFN0YXRpY1RlYXJPZmYscD1odW5rSGVscGVy
-cy5faW5zdGFuY2VfMXUKdChQLCJFWCIsIlpWIiw5KQp0KFAsInl0Iiwib0EiLDkpCnQoUCwicVciLCJC
-eiIsOSkKcyhQLCJWOSIsImVOIiwxKQpyKFAuUGYucHJvdG90eXBlLCJnWUoiLDAsMSxudWxsLFsiJDIi
-LCIkMSJdLFsidzAiLCJwbSJdLDM0LDApCnQoUCwiUEgiLCJNdCIsNikKcShXLCJwUyIsNCxudWxsLFsi
-JDQiXSxbInlXIl0sMTAsMCkKcShXLCJWNCIsNCxudWxsLFsiJDQiXSxbIlFXIl0sMTAsMCkKcChQLkFz
-LnByb3RvdHlwZSwiZ3VNIiwiVCIsNikKdChQLCJpRyIsIndZIiw1MikKdChQLCJ3MCIsIkw3IiwzNSkK
-dChMLCJpUyIsImk2IiwxNyl9KSgpOyhmdW5jdGlvbiBpbmhlcml0YW5jZSgpe3ZhciB0PWh1bmtIZWxw
-ZXJzLm1peGluLHM9aHVua0hlbHBlcnMuaW5oZXJpdCxyPWh1bmtIZWxwZXJzLmluaGVyaXRNYW55CnMo
-UC5NaCxudWxsKQpyKFAuTWgsW0guRkssSi52QixKLm0xLFAuWFMsUC5uWSxQLmNYLEguYTcsUC5BbixI
-LlNVLEguUmUsSC53dixQLlBuLEguV1UsSC5MSSxILnYsSC5mOSxILmJxLEguWE8sUC5ZayxILmRiLEgu
-TjYsSC5WUixILkVLLEguUGIsSC50USxILlNkLEguSmMsSC5HLFAuVzMsUC5paCxQLkZ5LFAuR1YsUC5i
-OCxQLlBmLFAuRmUsUC52cyxQLk9NLFAucWgsUC5NTyxQLmtULFAueEksUC5DdyxQLm0wLFAuWHYsUC5i
-bixQLmxtLFAubEQsUC5LUCxQLk1hLFAuV1ksUC5VayxQLlJ3LFAuYnosUC5hMixQLmlQLFAubGYsUC5r
-NSxQLktZLFAuQ0QsUC5hRSxQLkVILFAuek0sUC5aMCxQLk4zLFAuYzgsUC5PZCxQLmliLFAuR3osUC5a
-ZCxQLnFVLFAuUm4sUC5HRCxQLkRuLFAuUEUsUC5VZixXLmlkLFcuRmssVy5KUSxXLkdtLFcudkQsVy5t
-NixXLk93LFcuVzksVy5kVyxXLkZiLFcua0YsVy5tayxXLktvLFAuaUosUC5FNCxQLm42LFUuZDIsVS5T
-ZSxVLk1sLFUueUQsVS53YixCLmo4LEIucXAsVC5tUSxMLlhBLEwuWlosTC5POSxNLmxJLE8uekwsWC5X
-RCxYLmR2XSkKcihKLnZCLFtKLnlFLEoud2UsSi5NRixKLmpkLEoucUksSi5EcixILkVULFcuRDAsVy5B
-eixXLkxlLFcuTmgsVy5hZSxXLklCLFcubjcsVy5lYSxXLmJyLFcuU2csVy51OCxXLks3LFcuWFcsUC5o
-Rl0pCnIoSi5NRixbSi5pQyxKLmtkLEouYzVdKQpzKEouUG8sSi5qZCkKcihKLnFJLFtKLnVyLEouVkFd
-KQpyKFAuWFMsW0gubmQsSC5XMCxILmF6LEgudlYsSC5FcSxQLkM2LEgudTksUC5uLFAudSxQLm1wLFAu
-dWIsUC5kcyxQLmxqLFAuVVYsUC5jXSkKcyhQLkxVLFAublkpCnIoUC5MVSxbSC53MixXLnd6LFcuZTdd
-KQpzKEgucWosSC53MikKcihQLmNYLFtILmJRLEguaTEsSC5VNSxILlhSLFAubVcsSC51bl0pCnIoSC5i
-USxbSC5hTCxILmk1LFAueHVdKQpyKEguYUwsW0gubkgsSC5sSixQLmk4XSkKcyhILnh5LEguaTEpCnIo
-UC5BbixbSC5NSCxILlNPXSkKcyhQLlJVLFAuUG4pCnMoUC5HaixQLlJVKQpzKEguUEQsUC5HaikKcyhI
-LkxQLEguV1UpCnIoSC52LFtILkNqLEguQW0sSC5sYyxILmRDLEgud04sSC5WWCxQLnRoLFAuaGEsUC5W
-cyxQLkZ0LFAueUgsUC5XTSxQLlNYLFAuR3MsUC5kYSxQLm9RLFAucFYsUC5VNyxQLnZyLFAucnQsUC5L
-RixQLlpMLFAuUlQsUC5qWixQLnJxLFAuUlcsUC5CNSxQLnVPLFAucEssUC5oaixQLlZwLFAuT1IsUC5y
-YSxQLnlRLFAucGcsUC5XRixQLm4xLFAuY1MsUC5WQyxQLkpULFAuUlosUC5NRSxQLnk1LFAucTMsUC55
-SSxQLmM2LFAucWQsVy5DdixXLmJVLFcuaEgsVy5LUyxXLkEzLFcudk4sVy5VdixXLkVnLFcuRW8sVy5X
-ayxXLklBLFcuZm0sUC5qZyxQLlRhLFAuR0UsUC5ONyxQLnVRLFAuUEMsUC5tdCxQLk56LFAuUVMsUC5u
-cCxMLmUsTC5WVyxMLm9aLEwuanIsTC5xbCxMLkhpLEwuQlQsTC5QWSxMLkwsTC5XeCxMLkFPLEwuZE4s
-TC5IbyxMLnh6LEwuSUMsTC5MMSxMLm5ULEwuTlksTC5lWCxMLkRULEwuZUgsTC55dSxMLnpELEwuVFcs
-TC54cixMLkVFLEwuUUwsTC5WUyxMLlRELE0uTWksTS5xNyxNLk5vLFgucVJdKQpyKEgubGMsW0guengs
+cm4gSC5PSChwLHIpCnE9cy5iKHBbcl0pCmlmKHEubmFtZXNwYWNlVVJJPT1udWxsKUMuTm0uaShvLHEu
+bmFtZSl9cmV0dXJuIG99fQpXLmk3LnByb3RvdHlwZT17Cng0OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlz
+LmEuaGFzQXR0cmlidXRlKGEpfSwKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEuZ2V0QXR0cmli
+dXRlKEgueShiKSl9LApZOmZ1bmN0aW9uKGEsYixjKXt0aGlzLmEuc2V0QXR0cmlidXRlKGIsYyl9LApn
+QTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nVigpLmxlbmd0aH19ClcuU3kucHJvdG90eXBlPXsKeDQ6
+ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5hLmhhc0F0dHJpYnV0ZSgiZGF0YS0iK3RoaXMuTyhhKSl9
+LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS5hLmdldEF0dHJpYnV0ZSgiZGF0YS0iK3RoaXMu
+TyhILnkoYikpKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3RoaXMuYS5hLnNldEF0dHJpYnV0ZSgiZGF0YS0i
+K3RoaXMuTyhiKSxjKX0sCks6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuSygwLG5ldyBXLktTKHRoaXMsdS5l
+QS5iKGIpKSl9LApnVjpmdW5jdGlvbigpe3ZhciB0PUguVk0oW10sdS5zKQp0aGlzLmEuSygwLG5ldyBX
+LkEzKHRoaXMsdCkpCnJldHVybiB0fSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ1YoKS5sZW5n
+dGh9LAprOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj1ILlZNKGEuc3BsaXQoIi0iKSx1LnMpCmZvcih0PTE7
+dDxyLmxlbmd0aDsrK3Qpe3M9clt0XQppZihzLmxlbmd0aD4wKUMuTm0uWShyLHQsc1swXS50b1VwcGVy
+Q2FzZSgpK0ouS1YocywxKSl9cmV0dXJuIEMuTm0uelYociwiIil9LApPOmZ1bmN0aW9uKGEpe3ZhciB0
+LHMscixxLHAKZm9yKHQ9YS5sZW5ndGgscz0wLHI9IiI7czx0Oysrcyl7cT1hW3NdCnA9cS50b0xvd2Vy
+Q2FzZSgpCnI9KHEhPT1wJiZzPjA/cisiLSI6cikrcH1yZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6
+cn19ClcuS1MucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtpZihKLnJZKGEpLm4oYSwiZGF0YS0i
+KSl0aGlzLmIuJDIodGhpcy5hLmsoQy54Qi5HKGEsNSkpLGIpfSwKJFM6OH0KVy5BMy5wcm90b3R5cGU9
+ewokMjpmdW5jdGlvbihhLGIpe2lmKEouclkoYSkubihhLCJkYXRhLSIpKUMuTm0uaSh0aGlzLmIsdGhp
+cy5hLmsoQy54Qi5HKGEsNSkpKX0sCiRTOjh9ClcuSTQucHJvdG90eXBlPXsKREc6ZnVuY3Rpb24oKXt2
+YXIgdCxzLHIscSxwPVAuTHModS5OKQpmb3IodD10aGlzLmEuY2xhc3NOYW1lLnNwbGl0KCIgIikscz10
+Lmxlbmd0aCxyPTA7cjxzOysrcil7cT1KLlQwKHRbcl0pCmlmKHEubGVuZ3RoIT09MClwLmkoMCxxKX1y
+ZXR1cm4gcH0sCnA6ZnVuY3Rpb24oYSl7dGhpcy5hLmNsYXNzTmFtZT11LkMuYihhKS56VigwLCIgIil9
+LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmNsYXNzTGlzdC5sZW5ndGh9LApWMTpmdW5jdGlv
+bihhKXt0aGlzLmEuY2xhc3NOYW1lPSIifSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmEuY2xh
+c3NMaXN0LmNvbnRhaW5zKGIpCnJldHVybiB0fSwKaTpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYS5j
+bGFzc0xpc3Qscz10LmNvbnRhaW5zKGIpCnQuYWRkKGIpCnJldHVybiFzfSwKUjpmdW5jdGlvbihhLGIp
+e3ZhciB0PXRoaXMuYS5jbGFzc0xpc3Qscz10LmNvbnRhaW5zKGIpCnQucmVtb3ZlKGIpCnJldHVybiBz
+fSwKRlY6ZnVuY3Rpb24oYSxiKXtXLlROKHRoaXMuYSx1LlguYihiKSl9fQpXLkZrLnByb3RvdHlwZT17
+fQpXLlJPLnByb3RvdHlwZT17fQpXLmV1LnByb3RvdHlwZT17fQpXLnhDLnByb3RvdHlwZT17fQpXLnZO
+LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuJDEodS5CLmIoYSkpfSwKJFM6
+Mjh9ClcuSlEucHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoJC5vci5hPT09MCl7Zm9y
+KHQ9MDt0PDI2MjsrK3QpJC5vci5ZKDAsQy5jbVt0XSxXLnBTKCkpCmZvcih0PTA7dDwxMjsrK3QpJC5v
+ci5ZKDAsQy5CSVt0XSxXLlY0KCkpfX0sCmkwOmZ1bmN0aW9uKGEpe3JldHVybiAkLkFOKCkudGcoMCxX
+LnJTKGEpKX0sCkViOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD0kLm9yLnEoMCxILmQoVy5yUyhhKSkrIjo6
+IitiKQppZih0PT1udWxsKXQ9JC5vci5xKDAsIio6OiIrYikKaWYodD09bnVsbClyZXR1cm4hMQpyZXR1
+cm4gSC54ZCh0LiQ0KGEsYixjLHRoaXMpKX0sCiRpa0Y6MX0KVy5HbS5wcm90b3R5cGU9ewpna3o6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIG5ldyBXLlc5KGEsdGhpcy5nQShhKSxILnpLKGEpLkMoIlc5PEdtLkU+Iikp
+fX0KVy52RC5wcm90b3R5cGU9ewppMDpmdW5jdGlvbihhKXtyZXR1cm4gQy5ObS5Wcih0aGlzLmEsbmV3
+IFcuVXYoYSkpfSwKRWI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBDLk5tLlZyKHRoaXMuYSxuZXcgVy5F
+ZyhhLGIsYykpfSwKJGlrRjoxfQpXLlV2LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB1
+LmUuYihhKS5pMCh0aGlzLmEpfSwKJFM6MTZ9ClcuRWcucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7
+cmV0dXJuIHUuZS5iKGEpLkViKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX0sCiRTOjE2fQpXLm02LnByb3Rv
+dHlwZT17CkNZOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscgp0aGlzLmEuRlYoMCxjKQp0PWIuZXYo
+MCxuZXcgVy5FbygpKQpzPWIuZXYoMCxuZXcgVy5XaygpKQp0aGlzLmIuRlYoMCx0KQpyPXRoaXMuYwpy
+LkZWKDAsQy54RCkKci5GVigwLHMpfSwKaTA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS50ZygwLFcu
+clMoYSkpfSwKRWI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PXRoaXMscz1XLnJTKGEpLHI9dC5jCmlmKHIu
+dGcoMCxILmQocykrIjo6IitiKSlyZXR1cm4gdC5kLkR0KGMpCmVsc2UgaWYoci50ZygwLCIqOjoiK2Ip
+KXJldHVybiB0LmQuRHQoYykKZWxzZXtyPXQuYgppZihyLnRnKDAsSC5kKHMpKyI6OiIrYikpcmV0dXJu
+ITAKZWxzZSBpZihyLnRnKDAsIio6OiIrYikpcmV0dXJuITAKZWxzZSBpZihyLnRnKDAsSC5kKHMpKyI6
+OioiKSlyZXR1cm4hMAplbHNlIGlmKHIudGcoMCwiKjo6KiIpKXJldHVybiEwfXJldHVybiExfSwKJGlr
+RjoxfQpXLkVvLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiFDLk5tLnRnKEMuQkksSC55
+KGEpKX0sCiRTOjd9ClcuV2sucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEMuTm0udGco
+Qy5CSSxILnkoYSkpfSwKJFM6N30KVy5jdC5wcm90b3R5cGU9ewpFYjpmdW5jdGlvbihhLGIsYyl7aWYo
+dGhpcy5qRihhLGIsYykpcmV0dXJuITAKaWYoYj09PSJ0ZW1wbGF0ZSImJmM9PT0iIilyZXR1cm4hMApp
+ZihhLmdldEF0dHJpYnV0ZSgidGVtcGxhdGUiKT09PSIiKXJldHVybiB0aGlzLmUudGcoMCxiKQpyZXR1
+cm4hMX19ClcuSUEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIlRFTVBMQVRFOjoiK0gu
+ZChILnkoYSkpfSwKJFM6NX0KVy5Pdy5wcm90b3R5cGU9ewppMDpmdW5jdGlvbihhKXt2YXIgdAppZih1
+LmV3LmMoYSkpcmV0dXJuITEKdD11Lmc3LmMoYSkKaWYodCYmVy5yUyhhKT09PSJmb3JlaWduT2JqZWN0
+IilyZXR1cm4hMQppZih0KXJldHVybiEwCnJldHVybiExfSwKRWI6ZnVuY3Rpb24oYSxiLGMpe2lmKGI9
+PT0iaXMifHxDLnhCLm4oYiwib24iKSlyZXR1cm4hMQpyZXR1cm4gdGhpcy5pMChhKX0sCiRpa0Y6MX0K
+Vy5XOS5wcm90b3R5cGU9ewpGOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQuYysxLHI9dC5iCmlmKHM8
+cil7dC5zTShKLncyKHQuYSxzKSkKdC5jPXMKcmV0dXJuITB9dC5zTShudWxsKQp0LmM9cgpyZXR1cm4h
+MX0sCmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCnNNOmZ1bmN0aW9uKGEpe3RoaXMuZD10aGlz
+LiR0aS5kLmIoYSl9LAokaUFuOjF9ClcuZFcucHJvdG90eXBlPXsKZ21XOmZ1bmN0aW9uKGEpe3JldHVy
+biBXLkhIKHRoaXMuYS5sb2NhdGlvbil9LAokaUQwOjEsCiRpdjY6MX0KVy5GYi5wcm90b3R5cGU9e30K
+Vy5rRi5wcm90b3R5cGU9e30KVy5tay5wcm90b3R5cGU9eyRpeTA6MX0KVy5Lby5wcm90b3R5cGU9ewpQ
+bjpmdW5jdGlvbihhKXtuZXcgVy5mbSh0aGlzKS4kMihhLG51bGwpfSwKRVA6ZnVuY3Rpb24oYSxiKXtp
+ZihiPT1udWxsKUouTHQoYSkKZWxzZSBiLnJlbW92ZUNoaWxkKGEpfSwKSTQ6ZnVuY3Rpb24oYSxiKXt2
+YXIgdCxzLHIscSxwLG89ITAsbj1udWxsLG09bnVsbAp0cnl7bj1KLmlnKGEpCm09bi5hLmdldEF0dHJp
+YnV0ZSgiaXMiKQp1LmguYihhKQp0PWZ1bmN0aW9uKGMpe2lmKCEoYy5hdHRyaWJ1dGVzIGluc3RhbmNl
+b2YgTmFtZWROb2RlTWFwKSlyZXR1cm4gdHJ1ZQp2YXIgbD1jLmNoaWxkTm9kZXMKaWYoYy5sYXN0Q2hp
+bGQmJmMubGFzdENoaWxkIT09bFtsLmxlbmd0aC0xXSlyZXR1cm4gdHJ1ZQppZihjLmNoaWxkcmVuKWlm
+KCEoYy5jaGlsZHJlbiBpbnN0YW5jZW9mIEhUTUxDb2xsZWN0aW9ufHxjLmNoaWxkcmVuIGluc3RhbmNl
+b2YgTm9kZUxpc3QpKXJldHVybiB0cnVlCnZhciBrPTAKaWYoYy5jaGlsZHJlbilrPWMuY2hpbGRyZW4u
+bGVuZ3RoCmZvcih2YXIgaj0wO2o8aztqKyspe3ZhciBpPWMuY2hpbGRyZW5bal0KaWYoaS5pZD09J2F0
+dHJpYnV0ZXMnfHxpLm5hbWU9PSdhdHRyaWJ1dGVzJ3x8aS5pZD09J2xhc3RDaGlsZCd8fGkubmFtZT09
+J2xhc3RDaGlsZCd8fGkuaWQ9PSdjaGlsZHJlbid8fGkubmFtZT09J2NoaWxkcmVuJylyZXR1cm4gdHJ1
+ZX1yZXR1cm4gZmFsc2V9KGEpCm89SC5vVCh0KT8hMDohKGEuYXR0cmlidXRlcyBpbnN0YW5jZW9mIE5h
+bWVkTm9kZU1hcCl9Y2F0Y2gocSl7SC5SdShxKX1zPSJlbGVtZW50IHVucHJpbnRhYmxlIgp0cnl7cz1K
+LmooYSl9Y2F0Y2gocSl7SC5SdShxKX10cnl7cj1XLnJTKGEpCnRoaXMua1IodS5oLmIoYSksYixvLHMs
+cix1LkcuYihuKSxILnkobSkpfWNhdGNoKHEpe2lmKEguUnUocSkgaW5zdGFuY2VvZiBQLnUpdGhyb3cg
+cQplbHNle3RoaXMuRVAoYSxiKQp3aW5kb3cKcD0iUmVtb3ZpbmcgY29ycnVwdGVkIGVsZW1lbnQgIitI
+LmQocykKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4ocCl9
+fX0sCmtSOmZ1bmN0aW9uKGEsYixjLGQsZSxmLGcpe3ZhciB0LHMscixxLHAsbyxuPXRoaXMKaWYoYyl7
+bi5FUChhLGIpCndpbmRvdwp0PSJSZW1vdmluZyBlbGVtZW50IGR1ZSB0byBjb3JydXB0ZWQgYXR0cmli
+dXRlcyBvbiA8IitkKyI+IgppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNv
+bGUud2Fybih0KQpyZXR1cm59aWYoIW4uYS5pMChhKSl7bi5FUChhLGIpCndpbmRvdwp0PSJSZW1vdmlu
+ZyBkaXNhbGxvd2VkIGVsZW1lbnQgPCIrSC5kKGUpKyI+IGZyb20gIitILmQoYikKaWYodHlwZW9mIGNv
+bnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4odCkKcmV0dXJufWlmKGchPW51bGwp
+aWYoIW4uYS5FYihhLCJpcyIsZykpe24uRVAoYSxiKQp3aW5kb3cKdD0iUmVtb3ZpbmcgZGlzYWxsb3dl
+ZCB0eXBlIGV4dGVuc2lvbiA8IitILmQoZSkrJyBpcz0iJytnKyciPicKaWYodHlwZW9mIGNvbnNvbGUh
+PSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4odCkKcmV0dXJufXQ9Zi5nVigpCnM9SC5WTSh0
+LnNsaWNlKDApLEgudDYodCkuQygiamQ8MT4iKSkKZm9yKHI9Zi5nVigpLmxlbmd0aC0xLHQ9Zi5hO3I+
+PTA7LS1yKXtpZihyPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLHIpCnE9c1tyXQpwPW4uYQpvPUouY0go
+cSkKSC55KHEpCmlmKCFwLkViKGEsbyx0LmdldEF0dHJpYnV0ZShxKSkpe3dpbmRvdwpwPSJSZW1vdmlu
+ZyBkaXNhbGxvd2VkIGF0dHJpYnV0ZSA8IitILmQoZSkrIiAiK3ErJz0iJytILmQodC5nZXRBdHRyaWJ1
+dGUocSkpKyciPicKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndh
+cm4ocCkKdC5yZW1vdmVBdHRyaWJ1dGUocSl9fWlmKHUuYVcuYyhhKSluLlBuKGEuY29udGVudCl9LAok
+aW9uOjF9ClcuZm0ucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwPXRoaXMu
+YQpzd2l0Y2goYS5ub2RlVHlwZSl7Y2FzZSAxOnAuSTQoYSxiKQpicmVhawpjYXNlIDg6Y2FzZSAxMTpj
+YXNlIDM6Y2FzZSA0OmJyZWFrCmRlZmF1bHQ6cC5FUChhLGIpfXQ9YS5sYXN0Q2hpbGQKZm9yKHA9dS5B
+O251bGwhPXQ7KXtzPW51bGwKdHJ5e3M9dC5wcmV2aW91c1NpYmxpbmd9Y2F0Y2gocil7SC5SdShyKQpx
+PXAuYih0KQphLnJlbW92ZUNoaWxkKHEpCnQ9bnVsbApzPWEubGFzdENoaWxkfWlmKHQhPW51bGwpdGhp
+cy4kMih0LGEpCnQ9cC5iKHMpfX0sCiRTOjMxfQpXLkxlLnByb3RvdHlwZT17fQpXLks3LnByb3RvdHlw
+ZT17fQpXLnJCLnByb3RvdHlwZT17fQpXLlhXLnByb3RvdHlwZT17fQpXLm9hLnByb3RvdHlwZT17fQpQ
+LmlKLnByb3RvdHlwZT17ClZIOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5hLHI9cy5sZW5ndGgKZm9y
+KHQ9MDt0PHI7Kyt0KWlmKHNbdF09PT1hKXJldHVybiB0CkMuTm0uaShzLGEpCkMuTm0uaSh0aGlzLmIs
+bnVsbCkKcmV0dXJuIHJ9LApQdjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT10aGlzLHA9e30KaWYoYT09
+bnVsbClyZXR1cm4gYQppZihILmwoYSkpcmV0dXJuIGEKaWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVy
+biBhCmlmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gYQppZihhIGluc3RhbmNlb2YgUC5pUClyZXR1
+cm4gbmV3IERhdGUoYS5hKQppZih1LmZ2LmMoYSkpdGhyb3cgSC5iKFAuU1koInN0cnVjdHVyZWQgY2xv
+bmUgb2YgUmVnRXhwIikpCmlmKHUuYzguYyhhKSlyZXR1cm4gYQppZih1LmQuYyhhKSlyZXR1cm4gYQpp
+Zih1LkkuYyhhKSlyZXR1cm4gYQp0PXUuZEQuYyhhKXx8ITEKaWYodClyZXR1cm4gYQppZih1LkcuYyhh
+KSl7cz1xLlZIKGEpCnQ9cS5iCmlmKHM+PXQubGVuZ3RoKXJldHVybiBILk9IKHQscykKcj1wLmE9dFtz
+XQppZihyIT1udWxsKXJldHVybiByCnI9e30KcC5hPXIKQy5ObS5ZKHQscyxyKQphLksoMCxuZXcgUC5s
+UihwLHEpKQpyZXR1cm4gcC5hfWlmKHUuai5jKGEpKXtzPXEuVkgoYSkKcD1xLmIKaWYocz49cC5sZW5n
+dGgpcmV0dXJuIEguT0gocCxzKQpyPXBbc10KaWYociE9bnVsbClyZXR1cm4gcgpyZXR1cm4gcS5layhh
+LHMpfWlmKHUuZUguYyhhKSl7cz1xLlZIKGEpCnQ9cS5iCmlmKHM+PXQubGVuZ3RoKXJldHVybiBILk9I
+KHQscykKcj1wLmI9dFtzXQppZihyIT1udWxsKXJldHVybiByCnI9e30KcC5iPXIKQy5ObS5ZKHQscyxy
+KQpxLmltKGEsbmV3IFAuamcocCxxKSkKcmV0dXJuIHAuYn10aHJvdyBILmIoUC5TWSgic3RydWN0dXJl
+ZCBjbG9uZSBvZiBvdGhlciB0eXBlIikpfSwKZWs6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPUouVTYoYSks
+cj1zLmdBKGEpLHE9bmV3IEFycmF5KHIpCkMuTm0uWSh0aGlzLmIsYixxKQpmb3IodD0wO3Q8cjsrK3Qp
+Qy5ObS5ZKHEsdCx0aGlzLlB2KHMucShhLHQpKSkKcmV0dXJuIHF9fQpQLmxSLnByb3RvdHlwZT17CiQy
+OmZ1bmN0aW9uKGEsYil7dGhpcy5hLmFbYV09dGhpcy5iLlB2KGIpfSwKJFM6MX0KUC5qZy5wcm90b3R5
+cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYS5iW2FdPXRoaXMuYi5QdihiKX0sCiRTOjF9ClAuQmYu
+cHJvdG90eXBlPXsKaW06ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscQp1LmI4LmIoYikKZm9yKHQ9T2Jq
+ZWN0LmtleXMoYSkscz10Lmxlbmd0aCxyPTA7cjxzOysrcil7cT10W3JdCmIuJDIocSxhW3FdKX19fQpQ
+LkFzLnByb3RvdHlwZT17ClQ6ZnVuY3Rpb24oYSl7dmFyIHQKSC55KGEpCnQ9JC5oRygpLmIKaWYodHlw
+ZW9mIGEhPSJzdHJpbmciKUgudmgoSC50TChhKSkKaWYodC50ZXN0KGEpKXJldHVybiBhCnRocm93IEgu
+YihQLkwzKGEsInZhbHVlIiwiTm90IGEgdmFsaWQgY2xhc3MgdG9rZW4iKSl9LAp3OmZ1bmN0aW9uKGEp
+e3JldHVybiB0aGlzLkRHKCkuelYoMCwiICIpfSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuREco
+KQpyZXR1cm4gUC5yaih0LHQucixILkxoKHQpLmQpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
+REcoKS5hfSwKdGc6ZnVuY3Rpb24oYSxiKXt0aGlzLlQoYikKcmV0dXJuIHRoaXMuREcoKS50ZygwLGIp
+fSwKaTpmdW5jdGlvbihhLGIpe3RoaXMuVChiKQpyZXR1cm4gSC54ZCh0aGlzLk9TKG5ldyBQLkdFKGIp
+KSl9LApSOmZ1bmN0aW9uKGEsYil7dmFyIHQscwp0aGlzLlQoYikKdD10aGlzLkRHKCkKcz10LlIoMCxi
+KQp0aGlzLnAodCkKcmV0dXJuIHN9LApGVjpmdW5jdGlvbihhLGIpe3RoaXMuT1MobmV3IFAuTjcodGhp
+cyx1LlguYihiKSkpfSwKVjE6ZnVuY3Rpb24oYSl7dGhpcy5PUyhuZXcgUC51USgpKX0sCk9TOmZ1bmN0
+aW9uKGEpe3ZhciB0LHMKdS5jaC5iKGEpCnQ9dGhpcy5ERygpCnM9YS4kMSh0KQp0aGlzLnAodCkKcmV0
+dXJuIHN9fQpQLkdFLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB1LkMuYihhKS5pKDAs
+dGhpcy5hKX0sCiRTOjQ4fQpQLk43LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMu
+YixzPUgudDYodCkKcmV0dXJuIHUuQy5iKGEpLkZWKDAsbmV3IEguQTgodCxzLkMoInFVKDEpIikuYih0
+aGlzLmEuZ3VNKCkpLHMuQygiQTg8MSxxVT4iKSkpfSwKJFM6MTd9ClAudVEucHJvdG90eXBlPXsKJDE6
+ZnVuY3Rpb24oYSl7dS5DLmIoYSkKaWYoYS5hPjApe2EuYj1hLmM9YS5kPWEuZT1hLmY9bnVsbAphLmE9
+MAphLlgoKX1yZXR1cm4gbnVsbH0sCiRTOjE3fQpQLmhGLnByb3RvdHlwZT17JGloRjoxfQpQLlBDLnBy
+b3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0CnUuWi5iKGEpCnQ9ZnVuY3Rpb24oYixjLGQpe3Jl
+dHVybiBmdW5jdGlvbigpe3JldHVybiBiKGMsZCx0aGlzLEFycmF5LnByb3RvdHlwZS5zbGljZS5hcHBs
+eShhcmd1bWVudHMpKX19KFAuUjQsYSwhMSkKUC5EbSh0LCQudygpLGEpCnJldHVybiB0fSwKJFM6NH0K
+UC5tdC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IHRoaXMuYShhKX0sCiRTOjR9
+ClAuTnoucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnI3KGEpfSwKJFM6MzR9
+ClAuUVMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLlR6KGEsdS5hbSl9LAok
+UzozNX0KUC5ucC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuRTQoYSl9LAok
+UzozNn0KUC5FNC5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGIhPSJzdHJpbmci
+JiZ0eXBlb2YgYiE9Im51bWJlciIpdGhyb3cgSC5iKFAueFkoInByb3BlcnR5IGlzIG5vdCBhIFN0cmlu
+ZyBvciBudW0iKSkKcmV0dXJuIFAuTDcodGhpcy5hW2JdKX0sClk6ZnVuY3Rpb24oYSxiLGMpe2lmKHR5
+cGVvZiBiIT0ic3RyaW5nIiYmdHlwZW9mIGIhPSJudW1iZXIiKXRocm93IEguYihQLnhZKCJwcm9wZXJ0
+eSBpcyBub3QgYSBTdHJpbmcgb3IgbnVtIikpCnRoaXMuYVtiXT1QLndZKGMpfSwKRE46ZnVuY3Rpb24o
+YSxiKXtpZihiPT1udWxsKXJldHVybiExCnJldHVybiBiIGluc3RhbmNlb2YgUC5FNCYmdGhpcy5hPT09
+Yi5hfSwKdzpmdW5jdGlvbihhKXt2YXIgdCxzCnRyeXt0PVN0cmluZyh0aGlzLmEpCnJldHVybiB0fWNh
+dGNoKHMpe0guUnUocykKdD10aGlzLnhiKDApCnJldHVybiB0fX0sClY3OmZ1bmN0aW9uKGEsYil7dmFy
+IHQscz10aGlzLmEKaWYoYj09bnVsbCl0PW51bGwKZWxzZXt0PUgudDYoYikKdD1QLkNIKG5ldyBILkE4
+KGIsdC5DKCJAKDEpIikuYihQLmlHKCkpLHQuQygiQTg8MSxAPiIpKSwhMCx1LnopfXJldHVybiBQLkw3
+KHNbYV0uYXBwbHkocyx0KSl9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIDB9fQpQLnI3LnByb3RvdHlw
+ZT17fQpQLlR6LnByb3RvdHlwZT17CmNQOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz1hPDB8fGE+PXQu
+Z0EodCkKaWYocyl0aHJvdyBILmIoUC5URShhLDAsdC5nQSh0KSxudWxsLG51bGwpKX0sCnE6ZnVuY3Rp
+b24oYSxiKXtpZih0eXBlb2YgYj09Im51bWJlciImJmI9PT1DLmpuLnl1KGIpKXRoaXMuY1AoSC5TYyhi
+KSkKcmV0dXJuIHRoaXMuJHRpLmQuYih0aGlzLlVyKDAsYikpfSwKWTpmdW5jdGlvbihhLGIsYyl7dmFy
+IHQKdGhpcy4kdGkuZC5iKGMpCnQ9Qy5qbi55dShiKQppZihiPT09dCl0aGlzLmNQKGIpCnRoaXMuZTQo
+MCxiLGMpfSwKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hLmxlbmd0aAppZih0eXBlb2YgdD09PSJu
+dW1iZXIiJiZ0Pj4+MD09PXQpcmV0dXJuIHQKdGhyb3cgSC5iKFAuUFYoIkJhZCBKc0FycmF5IGxlbmd0
+aCIpKX0sCiRpYlE6MSwKJGljWDoxLAokaXpNOjF9ClAuY28ucHJvdG90eXBlPXt9ClAubmQucHJvdG90
+eXBlPXskaW5kOjF9ClAuS2UucHJvdG90eXBlPXsKREc6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwPXRo
+aXMuYS5nZXRBdHRyaWJ1dGUoImNsYXNzIiksbz1QLkxzKHUuTikKaWYocD09bnVsbClyZXR1cm4gbwpm
+b3IodD1wLnNwbGl0KCIgIikscz10Lmxlbmd0aCxyPTA7cjxzOysrcil7cT1KLlQwKHRbcl0pCmlmKHEu
+bGVuZ3RoIT09MClvLmkoMCxxKX1yZXR1cm4gb30sCnA6ZnVuY3Rpb24oYSl7dGhpcy5hLnNldEF0dHJp
+YnV0ZSgiY2xhc3MiLGEuelYoMCwiICIpKX19ClAuZDUucHJvdG90eXBlPXsKZ1A6ZnVuY3Rpb24oYSl7
+cmV0dXJuIG5ldyBQLktlKGEpfSwKc2hmOmZ1bmN0aW9uKGEsYil7dGhpcy5ZQyhhLGIpfSwKcjY6ZnVu
+Y3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscCxvCmlmKGQ9PW51bGwpe3Q9SC5WTShbXSx1LmspCmQ9
+bmV3IFcudkQodCkKQy5ObS5pKHQsVy5UdyhudWxsKSkKQy5ObS5pKHQsVy5CbCgpKQpDLk5tLmkodCxu
+ZXcgVy5PdygpKX1jPW5ldyBXLktvKGQpCnM9JzxzdmcgdmVyc2lvbj0iMS4xIj4nK0guZChiKSsiPC9z
+dmc+Igp0PWRvY3VtZW50CnI9dC5ib2R5CnE9KHImJkMuUlkpLkFIKHIscyxjKQpwPXQuY3JlYXRlRG9j
+dW1lbnRGcmFnbWVudCgpCnEudG9TdHJpbmcKdD1uZXcgVy5lNyhxKQpvPXQuZ3I4KHQpCmZvcig7dD1v
+LmZpcnN0Q2hpbGQsdCE9bnVsbDspcC5hcHBlbmRDaGlsZCh0KQpyZXR1cm4gcH0sCm56OmZ1bmN0aW9u
+KGEsYixjLGQsZSl7dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBpbnZva2UgaW5zZXJ0QWRqYWNlbnRIdG1s
+IG9uIFNWRy4iKSl9LApnVmw6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBXLmV1KGEsImNsaWNrIiwhMSx1
+LlEpfSwKJGlkNToxfQpQLm42LnByb3RvdHlwZT17JGliUToxLCRpY1g6MSwkaXpNOjEsJGlBUzoxfQpV
+LmQyLnByb3RvdHlwZT17fQpVLlNlLnByb3RvdHlwZT17fQpVLk1sLnByb3RvdHlwZT17fQpVLnlELnBy
+b3RvdHlwZT17fQpVLndiLnByb3RvdHlwZT17fQpCLmo4LnByb3RvdHlwZT17fQpCLnFwLnByb3RvdHlw
+ZT17fQpULm1RLnByb3RvdHlwZT17fQpMLmUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQs
+cyxyLHEscCxvLG4KdS5CLmIoYSkKdD13aW5kb3cubG9jYXRpb24ucGF0aG5hbWUKcz1MLkc2KHdpbmRv
+dy5sb2NhdGlvbi5ocmVmKQpyPUwuYUsod2luZG93LmxvY2F0aW9uLmhyZWYpCkwuR2UoKQppZih0IT09
+Ii8iJiZ0IT09Si5UMChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIucm9vdCIpLnRleHRDb250ZW50KSlM
+Lkc3KHQscyxyLCEwLG5ldyBMLlZXKHQscyxyKSkKcT1kb2N1bWVudApwPUoucUYocS5xdWVyeVNlbGVj
+dG9yKCIuYXBwbHktbWlncmF0aW9uIikpCm89cC4kdGkKbj1vLkMoIn4oMSkiKS5iKG5ldyBMLm9aKCkp
+CnUuTS5iKG51bGwpClcuSkUocC5hLHAuYixuLCExLG8uZCkKbz1KLnFGKHEucXVlcnlTZWxlY3Rvcigi
+LnJlcnVuLW1pZ3JhdGlvbiIpKQpuPW8uJHRpClcuSkUoby5hLG8uYixuLkMoIn4oMSkiKS5iKG5ldyBM
+Lnk4KCkpLCExLG4uZCkKbj1KLnFGKHEucXVlcnlTZWxlY3RvcigiLnJlcG9ydC1wcm9ibGVtIikpCm89
+bi4kdGkKVy5KRShuLmEsbi5iLG8uQygifigxKSIpLmIobmV3IEwuSGkoKSksITEsby5kKQpxPUoucUYo
+cS5xdWVyeVNlbGVjdG9yKCIucG9wdXAtcGFuZSAuY2xvc2UiKSkKbz1xLiR0aQpXLkpFKHEuYSxxLmIs
+by5DKCJ+KDEpIikuYihuZXcgTC5CVCgpKSwhMSxvLmQpfSwKJFM6MTh9CkwuVlcucHJvdG90eXBlPXsK
+JDA6ZnVuY3Rpb24oKXtMLkZyKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX0sCiRTOjB9Ckwub1oucHJvdG90
+eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dS5WLmIoYSkKaWYoSC5vVCh3aW5kb3cuY29uZmlybSgiVGhpcyB3
+aWxsIGFwcGx5IHRoZSBjaGFuZ2VzIHlvdSd2ZSBwcmV2aWV3ZWQgdG8geW91ciB3b3JraW5nIGRpcmVj
+dG9yeS4gSXQgaXMgcmVjb21tZW5kZWQgeW91IGNvbW1pdCBhbnkgY2hhbmdlcyB5b3UgbWFkZSBiZWZv
+cmUgZG9pbmcgdGhpcy4iKSkpTC50eSgiL2FwcGx5LW1pZ3JhdGlvbiIpLlc3KG5ldyBMLmpyKCksdS5Q
+KS5PQShuZXcgTC5xbCgpKX0sCiRTOjN9CkwuanIucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
+IHQKdS5TLmIoYSkKdD1kb2N1bWVudC5ib2R5CnQuY2xhc3NMaXN0LnJlbW92ZSgicHJvcG9zZWQiKQp0
+LmNsYXNzTGlzdC5hZGQoImFwcGxpZWQiKX0sCiRTOjM5fQpMLnFsLnByb3RvdHlwZT17CiQyOmZ1bmN0
+aW9uKGEsYil7TC5DMigiQ291bGQgbm90IGFwcGx5IG1pZ3JhdGlvbiIsYSxiKX0sCiRDOiIkMiIsCiRS
+OjIsCiRTOjF9CkwueTgucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMueG4odS5W
+LmIoYSkpfSwKeG46ZnVuY3Rpb24oYSl7dmFyIHQ9MCxzPVAuRlgodS5QKSxyPTEscSxwPVtdLG8sbixt
+LGwKdmFyICRhc3luYyQkMT1QLmx6KGZ1bmN0aW9uKGIsYyl7aWYoYj09PTEpe3E9Ywp0PXJ9d2hpbGUo
+dHJ1ZSlzd2l0Y2godCl7Y2FzZSAwOnI9Mwpkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoInJlcnVu
+bmluZyIpCnQ9NgpyZXR1cm4gUC5qUShMLnR5KCIvcmVydW4tbWlncmF0aW9uIiksJGFzeW5jJCQxKQpj
+YXNlIDY6d2luZG93LmxvY2F0aW9uLnJlbG9hZCgpCnAucHVzaCg1KQp0PTQKYnJlYWsKY2FzZSAzOnI9
+MgpsPXEKbz1ILlJ1KGwpCm49SC50cyhsKQpMLkMyKCJGYWlsZWQgdG8gcmVydW4gbWlncmF0aW9uIixv
+LG4pCnAucHVzaCg1KQp0PTQKYnJlYWsKY2FzZSAyOnA9WzFdCmNhc2UgNDpyPTEKZG9jdW1lbnQuYm9k
+eS5jbGFzc0xpc3QucmVtb3ZlKCJyZXJ1bm5pbmciKQp0PXAucG9wKCkKYnJlYWsKY2FzZSA1OnJldHVy
+biBQLnlDKG51bGwscykKY2FzZSAxOnJldHVybiBQLmYzKHEscyl9fSkKcmV0dXJuIFAuREkoJGFzeW5j
+JCQxLHMpfSwKJFM6NDB9CkwuSGkucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQKdS5WLmIo
+YSkKdD11Lk4KQy5vbC5Qbyh3aW5kb3csUC5YZCgiaHR0cHMiLCJnaXRodWIuY29tIiwiZGFydC1sYW5n
+L3Nkay9pc3N1ZXMvbmV3IixQLkVGKFsibGFiZWxzIiwiYXJlYS1hbmFseXplcixhbmFseXplci1ubmJk
+LW1pZ3JhdGlvbix0eXBlLWJ1ZyIsImJvZHkiLCIjIyMjIFN0ZXBzIHRvIHJlcHJvZHVjZVxuXG4jIyMj
+IFdoYXQgZGlkIHlvdSBleHBlY3QgdG8gaGFwcGVuP1xuXG4jIyMjIFdoYXQgYWN0dWFsbHkgaGFwcGVu
+ZWQ/XG5cbl9TY3JlZW5zaG90cyBhcmUgYXBwcmVjaWF0ZWRfXG5cbioqRGFydCBTREsgdmVyc2lvbioq
+OiAiK0guZChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgic2RrLXZlcnNpb24iKS50ZXh0Q29udGVudCkr
+IlxuXG5UaGFua3MgZm9yIGZpbGluZyFcbiJdLHQsdCkpLncoMCksInJlcG9ydC1wcm9ibGVtIil9LAok
+UzozfQpMLkJULnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0CnUuVi5iKGEpCnQ9ZG9jdW1l
+bnQucXVlcnlTZWxlY3RvcigiLnBvcHVwLXBhbmUiKS5zdHlsZQpyZXR1cm4gdC5kaXNwbGF5PSJub25l
+In0sCiRTOjQxfQpMLkwucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyCnUuQi5iKGEp
+CnQ9d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lCnM9TC5HNih3aW5kb3cubG9jYXRpb24uaHJlZikKcj1M
+LmFLKHdpbmRvdy5sb2NhdGlvbi5ocmVmKQppZih0Lmxlbmd0aD4xKUwuRzcodCxzLHIsITEsbnVsbCkK
+ZWxzZXtMLkJFKHQsbmV3IEIucXAoIiIsIiIsIiIsQy5DTSksITApCkwuQlgoIiZuYnNwOyIsbnVsbCl9
+fSwKJFM6MTh9CkwuV3gucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9ImNvbGxh
+cHNlZCIKdS5WLmIoYSkKdD10aGlzLmEKcz1KLlJFKHQpCnI9dGhpcy5iCmlmKCFzLmdQKHQpLnRnKDAs
+cSkpe3MuZ1AodCkuaSgwLHEpCkouZFIocikuaSgwLHEpfWVsc2V7cy5nUCh0KS5SKDAscSkKSi5kUihy
+KS5SKDAscSl9fSwKJFM6M30KTC5BTy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD1KLnFG
+KHUuaC5iKGEpKSxzPXQuJHRpLHI9cy5DKCJ+KDEpIikuYihuZXcgTC5kTih0aGlzLmEpKQp1Lk0uYihu
+dWxsKQpXLkpFKHQuYSx0LmIsciwhMSxzLmQpfSwKJFM6Nn0KTC5kTi5wcm90b3R5cGU9ewokMTpmdW5j
+dGlvbihhKXt2YXIgdAp1LlYuYihhKQp0PWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoInRhYmxlW2RhdGEt
+cGF0aF0iKQp0LnRvU3RyaW5nCkwudDIoYSx0aGlzLmEsdC5nZXRBdHRyaWJ1dGUoImRhdGEtIituZXcg
+Vy5TeShuZXcgVy5pNyh0KSkuTygicGF0aCIpKSl9LAokUzozfQpMLkhvLnByb3RvdHlwZT17CiQxOmZ1
+bmN0aW9uKGEpe3ZhciB0LHMscgp1LmguYihhKQp0PUoucUYoYSkKcz10LiR0aQpyPXMuQygifigxKSIp
+LmIobmV3IEwueHooYSx0aGlzLmEpKQp1Lk0uYihudWxsKQpXLkpFKHQuYSx0LmIsciwhMSxzLmQpfSwK
+JFM6Nn0KTC54ei5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzPW51bGwKdS5WLmIoYSkK
+dD10aGlzLmEKTC5oWCh0aGlzLmIsUC5RQSh0LmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5l
+dyBXLmk3KHQpKS5PKCJvZmZzZXQiKSkscyxzKSxQLlFBKHQuZ2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3
+IFcuU3kobmV3IFcuaTcodCkpLk8oImxpbmUiKSkscyxzKSl9LAokUzozfQpMLklDLnByb3RvdHlwZT17
+CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PUoucUYodS5oLmIoYSkpLHM9dC4kdGkKcy5DKCJ+KDEpIikuYihM
+LmlTKCkpCnUuTS5iKG51bGwpClcuSkUodC5hLHQuYixMLmlTKCksITEscy5kKX0sCiRTOjZ9CkwuTDEu
+cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dS5wLmIoYSkKdGhpcy5hLmFNKDAsdGhpcy5iKX0sCiRT
+OjE1fQpMLm5ULnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlzLmEuYSx0aGlzLmIsdGhp
+cy5jKX0sCiRTOjB9CkwuQloucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtMLkZyKHRoaXMuYS5hLG51
+bGwsbnVsbCl9LAokUzowfQpMLkdILnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3UuaC5iKGEpCiQu
+ekIoKS50b1N0cmluZwp1LnYuYSgkLm93KCkucSgwLCJobGpzIikpLlY3KCJoaWdobGlnaHRCbG9jayIs
+W2FdKX0sCiRTOjZ9CkwuRFQucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscwp1LnIuYihh
+KQp0PWEuc3RhdHVzCmlmKHQ9PT0yMDApe3Q9Qy5DdC5wVygwLGEucmVzcG9uc2VUZXh0LG51bGwpCnM9
+Si5VNih0KQpMLlQxKG5ldyBVLmQyKFUuamYocy5xKHQsImVkaXRzIikpLEguYzAocy5xKHQsImV4cGxh
+bmF0aW9uIikpLEguV1kocy5xKHQsImxpbmUiKSksSC5jMChzLnEodCwicGF0aCIpKSxVLk5kKHMucSh0
+LCJ0cmFjZXMiKSkpKQpMLkZyKHRoaXMuYSx0aGlzLmIsdGhpcy5jKQpMLnlYKCIuZWRpdC1wYW5lbCAu
+cGFuZWwtY29udGVudCIsITEpfWVsc2Ugd2luZG93LmFsZXJ0KCJSZXF1ZXN0IGZhaWxlZDsgc3RhdHVz
+IG9mICIrSC5kKHQpKX0sCiRTOjl9CkwuZUgucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtMLnFK
+KCJsb2FkUmVnaW9uRXhwbGFuYXRpb246ICIrSC5kKGEpLGIpCndpbmRvdy5hbGVydCgiQ291bGQgbm90
+IGxvYWQgIitILmQodGhpcy5hKSsiICgiK0guZChhKSsiKS4iKX0sCiRDOiIkMiIsCiRSOjIsCiRTOjF9
+CkwueXUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPXRoaXMKdS5yLmIoYSkKdD1h
+LnN0YXR1cwppZih0PT09MjAwKXtzPXIuYQpMLkJFKHMsQi5ZZih1LmIuYShDLkN0LnBXKDAsYS5yZXNw
+b25zZVRleHQsbnVsbCkpKSxyLmIpCnQ9ci5jCkwuZkcodCxyLmQpCkwuQlgoQy54Qi50ZyhzLCI/Iik/
+Qy54Qi5OaihzLDAsQy54Qi5PWShzLCI/IikpOnMsdCkKdD1yLmUKaWYodCE9bnVsbCl0LiQwKCl9ZWxz
+ZSB3aW5kb3cuYWxlcnQoIlJlcXVlc3QgZmFpbGVkOyBzdGF0dXMgb2YgIitILmQodCkpfSwKJFM6OX0K
+TC56RC5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe0wucUooImxvYWRGaWxlOiAiK0guZChhKSxi
+KQp3aW5kb3cuYWxlcnQoIkNvdWxkIG5vdCBsb2FkICIrdGhpcy5hKyIgKCIrSC5kKGEpKyIpLiIpfSwK
+JEM6IiQyIiwKJFI6MiwKJFM6MX0KTC5UVy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxz
+LHIKdS5yLmIoYSkKdD1hLnN0YXR1cwppZih0PT09MjAwKXtzPUMuQ3QucFcoMCxhLnJlc3BvbnNlVGV4
+dCxudWxsKQpyPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5uYXYtdHJlZSIpCkoubDUociwiIikKTC50
+WChyLEwubUsocykpfWVsc2Ugd2luZG93LmFsZXJ0KCJSZXF1ZXN0IGZhaWxlZDsgc3RhdHVzIG9mICIr
+SC5kKHQpKX0sCiRTOjl9CkwueHIucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtMLnFKKCJsb2Fk
+TmF2aWdhdGlvblRyZWU6ICIrSC5kKGEpLGIpCndpbmRvdy5hbGVydCgiQ291bGQgbm90IGxvYWQgIit0
+aGlzLmErIiAoIitILmQoYSkrIikuIil9LAokQzoiJDIiLAokUjoyLAokUzoxfQpMLkVFLnByb3RvdHlw
+ZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMKdS5WLmIoYSkKdD10aGlzLmEKcz10aGlzLmIKTC5hZih3
+aW5kb3cubG9jYXRpb24ucGF0aG5hbWUsdCxzLCEwLG5ldyBMLlFMKHQscykpCkwuaFgodGhpcy5jLHQs
+cyl9LAokUzozfQpMLlFMLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih3aW5kb3cubG9jYXRp
+b24ucGF0aG5hbWUsdGhpcy5hLHRoaXMuYil9LAokUzowfQpMLlZTLnByb3RvdHlwZT17CiQxOmZ1bmN0
+aW9uKGEpe3ZhciB0LHM9InNlbGVjdGVkLWZpbGUiCnUuaC5iKGEpCmEudG9TdHJpbmcKdD1KLlJFKGEp
+CmlmKGEuZ2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTcoYSkpLk8oIm5hbWUiKSk9
+PT10aGlzLmEuYSl0LmdQKGEpLmkoMCxzKQplbHNlIHQuZ1AoYSkuUigwLHMpfSwKJFM6Nn0KTC5URC5w
+cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gTC50Mih1LlYuYihhKSwhMCxudWxsKX0sCiRT
+OjE5fQpMLlhBLnByb3RvdHlwZT17CkViOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4hMH0sCmkwOmZ1bmN0
+aW9uKGEpe3JldHVybiEwfSwKJGlrRjoxfQpMLlpaLnByb3RvdHlwZT17fQpMLk85LnByb3RvdHlwZT17
+Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYn19Ck0ubEkucHJvdG90eXBlPXsKV086ZnVuY3Rpb24o
+YSxiKXt2YXIgdCxzPW51bGwKTS5ZRigiYWJzb2x1dGUiLEguVk0oW2IsbnVsbCxudWxsLG51bGwsbnVs
+bCxudWxsLG51bGxdLHUucykpCnQ9dGhpcy5hCnQ9dC5ZcihiKT4wJiYhdC5oSyhiKQppZih0KXJldHVy
+biBiCnQ9RC5SWCgpCnJldHVybiB0aGlzLnE3KDAsdCxiLHMscyxzLHMscyxzKX0sCnRNOmZ1bmN0aW9u
+KGEpe3ZhciB0LHMscj1YLkNMKGEsdGhpcy5hKQpyLklWKCkKdD1yLmQKcz10Lmxlbmd0aAppZihzPT09
+MCl7dD1yLmIKcmV0dXJuIHQ9PW51bGw/Ii4iOnR9aWYocz09PTEpe3Q9ci5iCnJldHVybiB0PT1udWxs
+PyIuIjp0fWlmKDA+PXMpcmV0dXJuIEguT0godCwtMSkKdC5wb3AoKQpDLk5tLm12KHIuZSkKci5JVigp
+CnJldHVybiByLncoMCl9LApxNzpmdW5jdGlvbihhLGIsYyxkLGUsZixnLGgsaSl7dmFyIHQ9SC5WTShb
+YixjLGQsZSxmLGcsaCxpXSx1LnMpCk0uWUYoImpvaW4iLHQpCnJldHVybiB0aGlzLklQKG5ldyBILlU1
+KHQsdS5iQi5iKG5ldyBNLk1pKCkpLHUuY2MpKX0sCklQOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAs
+byxuLG0sbAp1LlguYihhKQpmb3IodD1hLiR0aSxzPXQuQygiYTIoY1guRSkiKS5iKG5ldyBNLnE3KCkp
+LHI9YS5na3ooYSksdD1uZXcgSC5TTyhyLHMsdC5DKCJTTzxjWC5FPiIpKSxzPXRoaXMuYSxxPSExLHA9
+ITEsbz0iIjt0LkYoKTspe249ci5nbCgpCmlmKHMuaEsobikmJnApe209WC5DTChuLHMpCmw9by5jaGFy
+Q29kZUF0KDApPT0wP286bwpvPUMueEIuTmoobCwwLHMuU3AobCwhMCkpCm0uYj1vCmlmKHMuZHMobykp
+Qy5ObS5ZKG0uZSwwLHMuZ21JKCkpCm89bS53KDApfWVsc2UgaWYocy5ZcihuKT4wKXtwPSFzLmhLKG4p
+Cm89SC5kKG4pfWVsc2V7aWYoIShuLmxlbmd0aD4wJiZzLlVkKG5bMF0pKSlpZihxKW8rPXMuZ21JKCkK
+bys9SC5kKG4pfXE9cy5kcyhuKX1yZXR1cm4gby5jaGFyQ29kZUF0KDApPT0wP286b30sCm81OmZ1bmN0
+aW9uKGEpe3ZhciB0CmlmKCF0aGlzLnkzKGEpKXJldHVybiBhCnQ9WC5DTChhLHRoaXMuYSkKdC5yUigp
+CnJldHVybiB0LncoMCl9LAp5MzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsawphLnRv
+U3RyaW5nCnQ9dGhpcy5hCnM9dC5ZcihhKQppZihzIT09MCl7aWYodD09PSQuS2soKSlmb3Iocj0wO3I8
+czsrK3IpaWYoQy54Qi5XKGEscik9PT00NylyZXR1cm4hMApxPXMKcD00N31lbHNle3E9MApwPW51bGx9
+Zm9yKG89bmV3IEgucWooYSkuYSxuPW8ubGVuZ3RoLHI9cSxtPW51bGw7cjxuOysrcixtPXAscD1sKXts
+PUMueEIubShvLHIpCmlmKHQucjQobCkpe2lmKHQ9PT0kLktrKCkmJmw9PT00NylyZXR1cm4hMAppZihw
+IT1udWxsJiZ0LnI0KHApKXJldHVybiEwCmlmKHA9PT00NilrPW09PW51bGx8fG09PT00Nnx8dC5yNCht
+KQplbHNlIGs9ITEKaWYoaylyZXR1cm4hMH19aWYocD09bnVsbClyZXR1cm4hMAppZih0LnI0KHApKXJl
+dHVybiEwCmlmKHA9PT00Nil0PW09PW51bGx8fHQucjQobSl8fG09PT00NgplbHNlIHQ9ITEKaWYodCly
+ZXR1cm4hMApyZXR1cm4hMX0sCkhQOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvPXRoaXMsbj0n
+VW5hYmxlIHRvIGZpbmQgYSBwYXRoIHRvICInCmI9by5XTygwLGIpCnQ9by5hCmlmKHQuWXIoYik8PTAm
+JnQuWXIoYSk+MClyZXR1cm4gby5vNShhKQppZih0LllyKGEpPD0wfHx0LmhLKGEpKWE9by5XTygwLGEp
+CmlmKHQuWXIoYSk8PTAmJnQuWXIoYik+MCl0aHJvdyBILmIoWC5JNyhuK0guZChhKSsnIiBmcm9tICIn
+K0guZChiKSsnIi4nKSkKcz1YLkNMKGIsdCkKcy5yUigpCnI9WC5DTChhLHQpCnIuclIoKQpxPXMuZApp
+ZihxLmxlbmd0aD4wJiZKLlJNKHFbMF0sIi4iKSlyZXR1cm4gci53KDApCnE9cy5iCnA9ci5iCmlmKHEh
+PXApcT1xPT1udWxsfHxwPT1udWxsfHwhdC5OYyhxLHApCmVsc2UgcT0hMQppZihxKXJldHVybiByLnco
+MCkKd2hpbGUoITApe3E9cy5kCmlmKHEubGVuZ3RoPjApe3A9ci5kCnE9cC5sZW5ndGg+MCYmdC5OYyhx
+WzBdLHBbMF0pfWVsc2UgcT0hMQppZighcSlicmVhawpDLk5tLlc0KHMuZCwwKQpDLk5tLlc0KHMuZSwx
+KQpDLk5tLlc0KHIuZCwwKQpDLk5tLlc0KHIuZSwxKX1xPXMuZAppZihxLmxlbmd0aD4wJiZKLlJNKHFb
+MF0sIi4uIikpdGhyb3cgSC5iKFguSTcobitILmQoYSkrJyIgZnJvbSAiJytILmQoYikrJyIuJykpCnE9
+dS5OCkMuTm0uVUcoci5kLDAsUC5POChzLmQubGVuZ3RoLCIuLiIscSkpCkMuTm0uWShyLmUsMCwiIikK
+Qy5ObS5VRyhyLmUsMSxQLk84KHMuZC5sZW5ndGgsdC5nbUkoKSxxKSkKdD1yLmQKcT10Lmxlbmd0aApp
+ZihxPT09MClyZXR1cm4iLiIKaWYocT4xJiZKLlJNKEMuTm0uZ3JaKHQpLCIuIikpe3Q9ci5kCmlmKDA+
+PXQubGVuZ3RoKXJldHVybiBILk9IKHQsLTEpCnQucG9wKCkKdD1yLmUKQy5ObS5tdih0KQpDLk5tLm12
+KHQpCkMuTm0uaSh0LCIiKX1yLmI9IiIKci5JVigpCnJldHVybiByLncoMCl9fQpNLk1pLnByb3RvdHlw
+ZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBILnkoYSkhPW51bGx9LAokUzo3fQpNLnE3LnByb3RvdHlw
+ZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBILnkoYSkhPT0iIn0sCiRTOjd9Ck0uTm8ucHJvdG90eXBl
+PXsKJDE6ZnVuY3Rpb24oYSl7SC55KGEpCnJldHVybiBhPT1udWxsPyJudWxsIjonIicrYSsnIid9LAok
+Uzo1fQpCLmZ2LnByb3RvdHlwZT17CnhaOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5ZcihhKQppZihz
+PjApcmV0dXJuIEoubGQoYSwwLHMpCmlmKHRoaXMuaEsoYSkpe2lmKDA+PWEubGVuZ3RoKXJldHVybiBI
+Lk9IKGEsMCkKdD1hWzBdfWVsc2UgdD1udWxsCnJldHVybiB0fSwKTmM6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gYT09Yn19ClguV0QucHJvdG90eXBlPXsKSVY6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcwp3aGls
+ZSghMCl7dD1yLmQKaWYoISh0Lmxlbmd0aCE9PTAmJkouUk0oQy5ObS5ncloodCksIiIpKSlicmVhawp0
+PXIuZAppZigwPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LC0xKQp0LnBvcCgpCkMuTm0ubXYoci5lKX10
+PXIuZQpzPXQubGVuZ3RoCmlmKHM+MClDLk5tLlkodCxzLTEsIiIpfSwKclI6ZnVuY3Rpb24oKXt2YXIg
+dCxzLHIscSxwLG8sbixtPXRoaXMsbD1ILlZNKFtdLHUucykKZm9yKHQ9bS5kLHM9dC5sZW5ndGgscj0w
+LHE9MDtxPHQubGVuZ3RoO3QubGVuZ3RoPT09c3x8KDAsSC5saykodCksKytxKXtwPXRbcV0Kbz1KLmlh
+KHApCmlmKCEoby5ETihwLCIuIil8fG8uRE4ocCwiIikpKWlmKG8uRE4ocCwiLi4iKSlpZihsLmxlbmd0
+aD4wKWwucG9wKCkKZWxzZSArK3IKZWxzZSBDLk5tLmkobCxwKX1pZihtLmI9PW51bGwpQy5ObS5VRyhs
+LDAsUC5POChyLCIuLiIsdS5OKSkKaWYobC5sZW5ndGg9PT0wJiZtLmI9PW51bGwpQy5ObS5pKGwsIi4i
+KQpuPVAuZEgobC5sZW5ndGgsbmV3IFgucVIobSksITAsdS5OKQp0PW0uYgp0PXQhPW51bGwmJmwubGVu
+Z3RoPjAmJm0uYS5kcyh0KT9tLmEuZ21JKCk6IiIKSC50NihuKS5kLmIodCkKaWYoISFuLmZpeGVkJGxl
+bmd0aClILnZoKFAuTDQoImluc2VydCIpKQpuLnNwbGljZSgwLDAsdCkKbS5zbkoobCkKbS5zUGgobikK
+dD1tLmIKaWYodCE9bnVsbCYmbS5hPT09JC5LaygpKXt0LnRvU3RyaW5nCm0uYj1ILnlzKHQsIi8iLCJc
+XCIpfW0uSVYoKX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPXRoaXMscT1yLmIKcT1xIT1udWxsP3E6
+IiIKZm9yKHQ9MDt0PHIuZC5sZW5ndGg7Kyt0KXtzPXIuZQppZih0Pj1zLmxlbmd0aClyZXR1cm4gSC5P
+SChzLHQpCnM9cStILmQoc1t0XSkKcT1yLmQKaWYodD49cS5sZW5ndGgpcmV0dXJuIEguT0gocSx0KQpx
+PXMrSC5kKHFbdF0pfXErPUguZChDLk5tLmdyWihyLmUpKQpyZXR1cm4gcS5jaGFyQ29kZUF0KDApPT0w
+P3E6cX0sCnNuSjpmdW5jdGlvbihhKXt0aGlzLmQ9dS5hLmIoYSl9LApzUGg6ZnVuY3Rpb24oYSl7dGhp
+cy5lPXUuYS5iKGEpfX0KWC5xUi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5h
+LmEuZ21JKCl9LAokUzo0NX0KWC5kdi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJQYXRo
+RXhjZXB0aW9uOiAiK3RoaXMuYX19Ck8uekwucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4g
+dGhpcy5nb2ModGhpcyl9fQpFLk9GLnByb3RvdHlwZT17ClVkOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhC
+LnRnKGEsIi8iKX0sCnI0OmZ1bmN0aW9uKGEpe3JldHVybiBhPT09NDd9LApkczpmdW5jdGlvbihhKXt2
+YXIgdD1hLmxlbmd0aApyZXR1cm4gdCE9PTAmJkMueEIubShhLHQtMSkhPT00N30sClNwOmZ1bmN0aW9u
+KGEsYil7aWYoYS5sZW5ndGghPT0wJiZDLnhCLlcoYSwwKT09PTQ3KXJldHVybiAxCnJldHVybiAwfSwK
+WXI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuU3AoYSwhMSl9LApoSzpmdW5jdGlvbihhKXtyZXR1cm4h
+MX0sCmdvYzpmdW5jdGlvbigpe3JldHVybiJwb3NpeCJ9LApnbUk6ZnVuY3Rpb24oKXtyZXR1cm4iLyJ9
+fQpGLnJ1LnByb3RvdHlwZT17ClVkOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLnRnKGEsIi8iKX0sCnI0
+OmZ1bmN0aW9uKGEpe3JldHVybiBhPT09NDd9LApkczpmdW5jdGlvbihhKXt2YXIgdD1hLmxlbmd0aApp
+Zih0PT09MClyZXR1cm4hMQppZihDLnhCLm0oYSx0LTEpIT09NDcpcmV0dXJuITAKcmV0dXJuIEMueEIu
+VGMoYSwiOi8vIikmJnRoaXMuWXIoYSk9PT10fSwKU3A6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxw
+PWEubGVuZ3RoCmlmKHA9PT0wKXJldHVybiAwCmlmKEMueEIuVyhhLDApPT09NDcpcmV0dXJuIDEKZm9y
+KHQ9MDt0PHA7Kyt0KXtzPUMueEIuVyhhLHQpCmlmKHM9PT00NylyZXR1cm4gMAppZihzPT09NTgpe2lm
+KHQ9PT0wKXJldHVybiAwCnI9Qy54Qi5YVShhLCIvIixDLnhCLlFpKGEsIi8vIix0KzEpP3QrMzp0KQpp
+ZihyPD0wKXJldHVybiBwCmlmKCFifHxwPHIrMylyZXR1cm4gcgppZighQy54Qi5uKGEsImZpbGU6Ly8i
+KSlyZXR1cm4gcgppZighQi5ZdShhLHIrMSkpcmV0dXJuIHIKcT1yKzMKcmV0dXJuIHA9PT1xP3E6cis0
+fX1yZXR1cm4gMH0sCllyOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLlNwKGEsITEpfSwKaEs6ZnVuY3Rp
+b24oYSl7cmV0dXJuIGEubGVuZ3RoIT09MCYmQy54Qi5XKGEsMCk9PT00N30sCmdvYzpmdW5jdGlvbigp
+e3JldHVybiJ1cmwifSwKZ21JOmZ1bmN0aW9uKCl7cmV0dXJuIi8ifX0KTC5JVi5wcm90b3R5cGU9ewpV
+ZDpmdW5jdGlvbihhKXtyZXR1cm4gQy54Qi50ZyhhLCIvIil9LApyNDpmdW5jdGlvbihhKXtyZXR1cm4g
+YT09PTQ3fHxhPT09OTJ9LApkczpmdW5jdGlvbihhKXt2YXIgdD1hLmxlbmd0aAppZih0PT09MClyZXR1
+cm4hMQp0PUMueEIubShhLHQtMSkKcmV0dXJuISh0PT09NDd8fHQ9PT05Mil9LApTcDpmdW5jdGlvbihh
+LGIpe3ZhciB0LHMscj1hLmxlbmd0aAppZihyPT09MClyZXR1cm4gMAp0PUMueEIuVyhhLDApCmlmKHQ9
+PT00NylyZXR1cm4gMQppZih0PT09OTIpe2lmKHI8Mnx8Qy54Qi5XKGEsMSkhPT05MilyZXR1cm4gMQpz
+PUMueEIuWFUoYSwiXFwiLDIpCmlmKHM+MCl7cz1DLnhCLlhVKGEsIlxcIixzKzEpCmlmKHM+MClyZXR1
+cm4gc31yZXR1cm4gcn1pZihyPDMpcmV0dXJuIDAKaWYoIUIuT1ModCkpcmV0dXJuIDAKaWYoQy54Qi5X
+KGEsMSkhPT01OClyZXR1cm4gMApyPUMueEIuVyhhLDIpCmlmKCEocj09PTQ3fHxyPT09OTIpKXJldHVy
+biAwCnJldHVybiAzfSwKWXI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuU3AoYSwhMSl9LApoSzpmdW5j
+dGlvbihhKXtyZXR1cm4gdGhpcy5ZcihhKT09PTF9LApPdDpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGE9
+PT1iKXJldHVybiEwCmlmKGE9PT00NylyZXR1cm4gYj09PTkyCmlmKGE9PT05MilyZXR1cm4gYj09PTQ3
+CmlmKChhXmIpIT09MzIpcmV0dXJuITEKdD1hfDMyCnJldHVybiB0Pj05NyYmdDw9MTIyfSwKTmM6ZnVu
+Y3Rpb24oYSxiKXt2YXIgdCxzLHIKaWYoYT09YilyZXR1cm4hMAp0PWEubGVuZ3RoCmlmKHQhPT1iLmxl
+bmd0aClyZXR1cm4hMQpmb3Iocz1KLnJZKGIpLHI9MDtyPHQ7KytyKWlmKCF0aGlzLk90KEMueEIuVyhh
+LHIpLHMuVyhiLHIpKSlyZXR1cm4hMQpyZXR1cm4hMH0sCmdvYzpmdW5jdGlvbigpe3JldHVybiJ3aW5k
+b3dzIn0sCmdtSTpmdW5jdGlvbigpe3JldHVybiJcXCJ9fTsoZnVuY3Rpb24gYWxpYXNlcygpe3ZhciB0
+PUoudkIucHJvdG90eXBlCnQuVT10LncKdC5Taj10LmU3CnQ9Si5NRi5wcm90b3R5cGUKdC50PXQudwp0
+PVAuY1gucHJvdG90eXBlCnQuR0c9dC5ldgp0PVAuay5wcm90b3R5cGUKdC54Yj10LncKdD1XLmN2LnBy
+b3RvdHlwZQp0LkRXPXQucjYKdD1XLm02LnByb3RvdHlwZQp0LmpGPXQuRWIKdD1QLkU0LnByb3RvdHlw
+ZQp0LlVyPXQucQp0LmU0PXQuWX0pKCk7KGZ1bmN0aW9uIGluc3RhbGxUZWFyT2Zmcygpe3ZhciB0PWh1
+bmtIZWxwZXJzLl9zdGF0aWNfMSxzPWh1bmtIZWxwZXJzLl9zdGF0aWNfMCxyPWh1bmtIZWxwZXJzLmlu
+c3RhbGxJbnN0YW5jZVRlYXJPZmYscT1odW5rSGVscGVycy5pbnN0YWxsU3RhdGljVGVhck9mZixwPWh1
+bmtIZWxwZXJzLl9pbnN0YW5jZV8xdQp0KFAsIkVYIiwiWlYiLDEwKQp0KFAsInl0Iiwib0EiLDEwKQp0
+KFAsInFXIiwiQnoiLDEwKQpzKFAsIlVJIiwiZU4iLDIpCnIoUC5QZi5wcm90b3R5cGUsImdZSiIsMCwx
+LG51bGwsWyIkMiIsIiQxIl0sWyJ3MCIsInBtIl0sMjksMCkKdChQLCJQSCIsIk10Iiw1KQpxKFcsInBT
+Iiw0LG51bGwsWyIkNCJdLFsieVciXSwxMSwwKQpxKFcsIlY0Iiw0LG51bGwsWyIkNCJdLFsiUVciXSwx
+MSwwKQpwKFAuQXMucHJvdG90eXBlLCJndU0iLCJUIiw1KQp0KFAsImlHIiwid1kiLDQpCnQoUCwidzAi
+LCJMNyIsMzIpCnQoTCwiaVMiLCJpNiIsMTkpfSkoKTsoZnVuY3Rpb24gaW5oZXJpdGFuY2UoKXt2YXIg
+dD1odW5rSGVscGVycy5taXhpbixzPWh1bmtIZWxwZXJzLmluaGVyaXQscj1odW5rSGVscGVycy5pbmhl
+cml0TWFueQpzKFAuayxudWxsKQpyKFAuayxbSC5lbyxKLnZCLEoubTEsUC5uWSxQLmNYLEguYTcsUC5B
+bixILlNVLEguUmUsSC53dixQLlBuLEguV1UsSC5MSSxILlRwLEguZjksUC5YUyxILmJxLEguWE8sUC5Z
+ayxILmRiLEguTjYsSC5WUixILkVLLEguUGIsSC50USxILlNkLEguSmMsSC5HLFAuVzMsUC5paCxQLkZ5
+LFAuR1YsUC5iOCxQLlBmLFAuRmUsUC52cyxQLk9NLFAucWgsUC5NTyxQLmtULFAueEksUC5DdyxQLm0w
+LFAuWHYsUC5ibixQLmxtLFAubEQsUC5LUCxQLmxmLFAuVEMsUC5VayxQLlJ3LFAuYnosUC5hMixQLmlQ
+LFAuRkssUC5rNSxQLktZLFAuQ0QsUC5hRSxQLkVILFAuek0sUC5aMCxQLk4zLFAuYzgsUC5PZCxQLmli
+LFAuR3osUC5xVSxQLlJuLFAuR0QsUC5EbixQLlBFLFAuVWYsVy5pZCxXLkZrLFcuSlEsVy5HbSxXLnZE
+LFcubTYsVy5PdyxXLlc5LFcuZFcsVy5GYixXLmtGLFcubWssVy5LbyxQLmlKLFAuRTQsUC5uNixVLmQy
+LFUuU2UsVS5NbCxVLnlELFUud2IsQi5qOCxCLnFwLFQubVEsTC5YQSxMLlpaLEwuTzksTS5sSSxPLnpM
+LFguV0QsWC5kdl0pCnIoSi52QixbSi55RSxKLllFLEouTUYsSi5qZCxKLnFJLEouRHIsSC5FVCxXLkQw
+LFcuQXosVy5MZSxXLk5oLFcuSUIsVy5uNyxXLmVhLFcuYnIsVy5TZyxXLnU4LFcuSzcsVy5YVyxQLmhG
+XSkKcihKLk1GLFtKLmlDLEoua2QsSi5jNV0pCnMoSi5QbyxKLmpkKQpyKEoucUksW0oudXIsSi5WQV0p
+CnMoUC5MVSxQLm5ZKQpyKFAuTFUsW0guWEMsVy53eixXLmU3XSkKcyhILnFqLEguWEMpCnIoUC5jWCxb
+SC5iUSxILmkxLEguVTUsSC5YUixQLm1XLEgudW5dKQpyKEguYlEsW0guYUwsSC5pNSxQLnh1XSkKcihI
+LmFMLFtILm5ILEguQTgsUC5pOF0pCnMoSC54eSxILmkxKQpyKFAuQW4sW0guTUgsSC5TT10pCnMoUC5S
+VSxQLlBuKQpzKFAuR2osUC5SVSkKcyhILlBELFAuR2opCnMoSC5MUCxILldVKQpyKEguVHAsW0guQ2os
+SC5BbSxILmxjLEguZEMsSC53TixILlZYLFAudGgsUC5oYSxQLlZzLFAuRnQsUC55SCxQLldNLFAuU1gs
+UC5HcyxQLmRhLFAub1EsUC5wVixQLlU3LFAudnIsUC5ySCxQLktGLFAuWkwsUC5SVCxQLmpaLFAucnEs
+UC5SVyxQLkI1LFAudU8sUC5wSyxQLmhqLFAuVnAsUC5PUixQLnJhLFAueVEsUC5XRixQLm4xLFAuY1Ms
+UC5WQyxQLkpULFAuZTEsUC5OWSxQLlJaLFAuTUUsUC55NSxQLnEzLFAueUksUC5jNixQLnFkLFcuQ3Ys
+Vy5iVSxXLmhILFcuS1MsVy5BMyxXLnZOLFcuVXYsVy5FZyxXLkVvLFcuV2ssVy5JQSxXLmZtLFAubFIs
+UC5qZyxQLkdFLFAuTjcsUC51USxQLlBDLFAubXQsUC5OeixQLlFTLFAubnAsTC5lLEwuVlcsTC5vWixM
+LmpyLEwucWwsTC55OCxMLkhpLEwuQlQsTC5MLEwuV3gsTC5BTyxMLmROLEwuSG8sTC54eixMLklDLEwu
+TDEsTC5uVCxMLkJaLEwuR0gsTC5EVCxMLmVILEwueXUsTC56RCxMLlRXLEwueHIsTC5FRSxMLlFMLEwu
+VlMsTC5URCxNLk1pLE0ucTcsTS5ObyxYLnFSXSkKcihQLlhTLFtILlcwLEguYXosSC52VixILkVxLFAu
+QzYsSC51OSxQLm4sUC51LFAubXAsUC51YixQLmRzLFAubGosUC5VVixQLmNdKQpyKEgubGMsW0guengs
 SC5yVF0pCnMoSC5rWSxQLkM2KQpzKFAuaWwsUC5ZaykKcihQLmlsLFtILk41LFAudXcsVy5jZixXLlN5
 XSkKcihQLm1XLFtILktXLFAucTRdKQpzKEguYjAsSC5FVCkKcihILmIwLFtILlJHLEguV0JdKQpzKEgu
 VlAsSC5SRykKcyhILkRnLEguVlApCnMoSC5aRyxILldCKQpzKEguUGcsSC5aRykKcihILlBnLFtILnhq
-LEguZEUsSC5aQSxILmRULEguUHEsSC5lRSxILlY2XSkKcyhILmlNLEgudTkpCnMoUC5aZixQLlBmKQpz
-KFAuSmksUC5tMCkKcyhQLmI2LFAuWHYpCnMoUC5WaixQLldZKQpyKFAuVWssW1AuQ1YsUC5aaSxQLmJ5
-XSkKcyhQLndJLFAua1QpCnIoUC53SSxbUC5VOCxQLk14LFAuRTMsUC5HWV0pCnMoUC51NSxQLlppKQpy
-KFAubGYsW1AuQ1AsUC5JZl0pCnIoUC51LFtQLmJKLFAuZVldKQpzKFAucWUsUC5EbikKcihXLkQwLFtX
-LnVILFcud2EsVy5LNSxXLkNtXSkKcihXLnVILFtXLmN2LFcubngsVy5RRixXLkNRXSkKcihXLmN2LFtX
-LnFFLFAuZDVdKQpyKFcucUUsW1cuR2gsVy5mWSxXLm5CLFcuUVAsVy5oNCxXLlNOLFcubHAsVy5UYixX
-Lkl2LFcuV1AsVy55WV0pCnMoVy5vSixXLkxlKQpzKFcuVDUsVy5BeikKcyhXLlZiLFcuUUYpCnMoVy5m
-SixXLndhKQpyKFcuZWEsW1cudzYsVy5ld10pCnMoVy5PSyxXLnc2KQpzKFcuckIsVy5LNykKcyhXLkJI
-LFcuckIpCnMoVy53NCxXLklCKQpzKFcub2EsVy5YVykKcyhXLnJoLFcub2EpCnMoVy5pNyxXLmNmKQpz
-KFAuQXMsUC5WaikKcihQLkFzLFtXLkk0LFAuS2VdKQpzKFcuUk8sUC5xaCkKcyhXLmV1LFcuUk8pCnMo
-Vy54QyxQLk1PKQpzKFcuY3QsVy5tNikKcyhQLkJmLFAuaUopCnIoUC5FNCxbUC5yNyxQLmNvXSkKcyhQ
-LlR6LFAuY28pCnMoUC5iQixQLmQ1KQpzKEIuZnYsTy56TCkKcihCLmZ2LFtFLk9GLEYucnUsTC5JVl0p
-CnQoSC53MixILlJlKQp0KEguUkcsUC5sRCkKdChILlZQLEguU1UpCnQoSC5XQixQLmxEKQp0KEguWkcs
-SC5TVSkKdChQLm5ZLFAubEQpCnQoUC5XWSxQLk1hKQp0KFAuUlUsUC5LUCkKdChXLkxlLFcuaWQpCnQo
-Vy5LNyxQLmxEKQp0KFcuckIsVy5HbSkKdChXLlhXLFAubEQpCnQoVy5vYSxXLkdtKQp0KFAuY28sUC5s
-RCl9KSgpCnZhciB2PXt0eXBlVW5pdmVyc2U6e2VDOm5ldyBNYXAoKSx0Ujp7fSxlVDp7fSx0UFY6e30s
-c0VBOltdfSxtYW5nbGVkR2xvYmFsTmFtZXM6e0lmOiJpbnQiLENQOiJkb3VibGUiLGxmOiJudW0iLHFV
-OiJTdHJpbmciLGEyOiJib29sIixjODoiTnVsbCIsek06Ikxpc3QifSxtYW5nbGVkTmFtZXM6e30sZ2V0
-VHlwZUZyb21OYW1lOmdldEdsb2JhbEZyb21OYW1lLG1ldGFkYXRhOltdLHR5cGVzOlsiYzgoKSIsIn4o
-KSIsImM4KEAsQCkiLCJjOChPSyopIiwiYzgoY3YqKSIsIkAoQCkiLCJxVShxVSkiLCJjOChxVSxxVSki
-LCJjOChmSiopIiwifih+KCkpIiwiYTIoY3YscVUscVUsSlEpIiwiYzgoQCkiLCJjOChxVSxAKSIsImEy
-KGtGKSIsImEyKHFVKSIsIn4oeHU8cVU+KSIsImM4KGVhKikiLCJ+KE9LKikiLCJhMioocVUqKSIsIlow
-PHFVLHFVPihaMDxxVSxxVT4scVUpIiwiSWYoSWYsSWYpIiwiQChALHFVKSIsIn4ocVUscVU/KSIsIm42
-KElmKSIsIm42KEAsQCkiLCJhMih1SCkiLCJjOChALEd6KSIsImM4KGV3KSIsIkAoZWEpIiwifihAKSIs
-ImM4KH4oKSkiLCJ+KHVILHVIPykiLCJjOChJZixAKSIsImEyKHh1PHFVPikiLCJ+KE1oW0d6P10pIiwi
-TWg/KEApIiwiVHo8QD4oQCkiLCJFNChAKSIsImM4KE1oLEd6KSIsInZzPEA+KEApIiwiYzgoWjA8cVUq
-LE1oKj4qKSIsImI4PGM4PiooT0sqKSIsInFVKihPSyopIiwiYzgoTWg/LE1oPykiLCJjOChldyopIiwi
-QCgpIiwiYzgoR0QsQCkiLCJAKHFVKSIsInFVKihxVSopIiwicVUqKElmKikiLCJ+KHFVLElmKSIsIn4o
-cVVbQF0pIiwiTWg/KE1oPykiLCJyNyhAKSJdLGludGVyY2VwdG9yc0J5VGFnOm51bGwsbGVhZlRhZ3M6
-bnVsbCxhcnJheVJ0aTp0eXBlb2YgU3ltYm9sPT0iZnVuY3Rpb24iJiZ0eXBlb2YgU3ltYm9sKCk9PSJz
-eW1ib2wiP1N5bWJvbCgiJHRpIik6IiR0aSJ9CkgueGIodi50eXBlVW5pdmVyc2UsSlNPTi5wYXJzZSgn
-eyJjNSI6Ik1GIiwiaUMiOiJNRiIsImtkIjoiTUYiLCJyeCI6ImVhIiwiZTUiOiJlYSIsIlkwIjoiZDUi
-LCJ0cCI6ImQ1IiwiRzgiOiJldyIsIk1yIjoicUUiLCJlTCI6InFFIiwiSTAiOiJ1SCIsImhzIjoidUgi
-LCJYZyI6IlFGIiwieWMiOiJPSyIsInk0IjoidzYiLCJhUCI6IkNtIiwieGMiOiJueCIsImtKIjoibngi
-LCJ6VSI6IkRnIiwiZGYiOiJFVCIsInlFIjp7ImEyIjpbXX0sIndlIjp7ImM4IjpbXX0sIk1GIjp7InZt
-IjpbXSwiRUgiOltdfSwiamQiOnsiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIlBvIjp7
-ImpkIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIm0xIjp7IkFuIjpbIjEi
-XX0sInFJIjp7IkNQIjpbXSwibGYiOltdfSwidXIiOnsiSWYiOltdLCJDUCI6W10sImxmIjpbXX0sIlZB
-Ijp7IkNQIjpbXSwibGYiOltdfSwiRHIiOnsicVUiOltdLCJ2WCI6W119LCJuZCI6eyJYUyI6W119LCJx
-aiI6eyJSZSI6WyJJZiJdLCJsRCI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJiUSI6WyJJZiJdLCJjWCI6WyJJ
-ZiJdLCJsRC5FIjoiSWYiLCJSZS5FIjoiSWYifSwiYlEiOnsiY1giOlsiMSJdfSwiYUwiOnsiYlEiOlsi
-MSJdLCJjWCI6WyIxIl19LCJuSCI6eyJhTCI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdLCJhTC5F
-IjoiMSIsImNYLkUiOiIxIn0sImE3Ijp7IkFuIjpbIjEiXX0sImkxIjp7ImNYIjpbIjIiXSwiY1guRSI6
-IjIifSwieHkiOnsiaTEiOlsiMSIsIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl0sImNYLkUiOiIyIn0s
-Ik1IIjp7IkFuIjpbIjIiXX0sImxKIjp7ImFMIjpbIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl0sImFM
-LkUiOiIyIiwiY1guRSI6IjIifSwiVTUiOnsiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJTTyI6eyJBbiI6
-WyIxIl19LCJ3MiI6eyJSZSI6WyIxIl0sImxEIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNY
-IjpbIjEiXX0sInd2Ijp7IkdEIjpbXX0sIlBEIjp7IkdqIjpbIjEiLCIyIl0sIlJVIjpbIjEiLCIyIl0s
-IlBuIjpbIjEiLCIyIl0sIktQIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJXVSI6eyJaMCI6WyIx
-IiwiMiJdfSwiTFAiOnsiV1UiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIlhSIjp7ImNYIjpbIjEi
-XSwiY1guRSI6IjEifSwiTEkiOnsidlEiOltdfSwiVzAiOnsiWFMiOltdfSwiYXoiOnsiWFMiOltdfSwi
-dlYiOnsiWFMiOltdfSwiWE8iOnsiR3oiOltdfSwidiI6eyJFSCI6W119LCJsYyI6eyJFSCI6W119LCJ6
-eCI6eyJFSCI6W119LCJyVCI6eyJFSCI6W119LCJFcSI6eyJYUyI6W119LCJrWSI6eyJYUyI6W119LCJO
-NSI6eyJGbyI6WyIxIiwiMiJdLCJZayI6WyIxIiwiMiJdLCJaMCI6WyIxIiwiMiJdLCJZay5LIjoiMSIs
-IllrLlYiOiIyIn0sImk1Ijp7ImJRIjpbIjEiXSwiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJONiI6eyJB
-biI6WyIxIl19LCJWUiI6eyJ3TCI6W10sInZYIjpbXX0sIkVLIjp7ImliIjpbXSwiT2QiOltdfSwiS1ci
-OnsiY1giOlsiaWIiXSwiY1guRSI6ImliIn0sIlBiIjp7IkFuIjpbImliIl19LCJ0USI6eyJPZCI6W119
-LCJ1biI6eyJjWCI6WyJPZCJdLCJjWC5FIjoiT2QifSwiU2QiOnsiQW4iOlsiT2QiXX0sIkVUIjp7IkFT
-IjpbXX0sImIwIjp7IlhqIjpbIjEiXSwiRVQiOltdLCJBUyI6W119LCJEZyI6eyJsRCI6WyJDUCJdLCJY
-aiI6WyJDUCJdLCJ6TSI6WyJDUCJdLCJFVCI6W10sImJRIjpbIkNQIl0sIlNVIjpbIkNQIl0sIkFTIjpb
-XSwiY1giOlsiQ1AiXSwibEQuRSI6IkNQIn0sIlBnIjp7ImxEIjpbIklmIl0sInpNIjpbIklmIl0sIlhq
-IjpbIklmIl0sIkVUIjpbXSwiYlEiOlsiSWYiXSwiU1UiOlsiSWYiXSwiQVMiOltdLCJjWCI6WyJJZiJd
-fSwieGoiOnsibEQiOlsiSWYiXSwiek0iOlsiSWYiXSwiWGoiOlsiSWYiXSwiRVQiOltdLCJiUSI6WyJJ
-ZiJdLCJTVSI6WyJJZiJdLCJBUyI6W10sImNYIjpbIklmIl0sImxELkUiOiJJZiJ9LCJkRSI6eyJsRCI6
-WyJJZiJdLCJ6TSI6WyJJZiJdLCJYaiI6WyJJZiJdLCJFVCI6W10sImJRIjpbIklmIl0sIlNVIjpbIklm
-Il0sIkFTIjpbXSwiY1giOlsiSWYiXSwibEQuRSI6IklmIn0sIlpBIjp7ImxEIjpbIklmIl0sInpNIjpb
-IklmIl0sIlhqIjpbIklmIl0sIkVUIjpbXSwiYlEiOlsiSWYiXSwiU1UiOlsiSWYiXSwiQVMiOltdLCJj
-WCI6WyJJZiJdLCJsRC5FIjoiSWYifSwiZFQiOnsibEQiOlsiSWYiXSwiek0iOlsiSWYiXSwiWGoiOlsi
-SWYiXSwiRVQiOltdLCJiUSI6WyJJZiJdLCJTVSI6WyJJZiJdLCJBUyI6W10sImNYIjpbIklmIl0sImxE
-LkUiOiJJZiJ9LCJQcSI6eyJsRCI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJYaiI6WyJJZiJdLCJFVCI6W10s
-ImJRIjpbIklmIl0sIlNVIjpbIklmIl0sIkFTIjpbXSwiY1giOlsiSWYiXSwibEQuRSI6IklmIn0sImVF
-Ijp7ImxEIjpbIklmIl0sInpNIjpbIklmIl0sIlhqIjpbIklmIl0sIkVUIjpbXSwiYlEiOlsiSWYiXSwi
-U1UiOlsiSWYiXSwiQVMiOltdLCJjWCI6WyJJZiJdLCJsRC5FIjoiSWYifSwiVjYiOnsibjYiOltdLCJs
-RCI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJYaiI6WyJJZiJdLCJFVCI6W10sImJRIjpbIklmIl0sIlNVIjpb
-IklmIl0sIkFTIjpbXSwiY1giOlsiSWYiXSwibEQuRSI6IklmIn0sInU5Ijp7IlhTIjpbXX0sImlNIjp7
-IlhTIjpbXX0sIkdWIjp7IkFuIjpbIjEiXX0sInE0Ijp7ImNYIjpbIjEiXSwiY1guRSI6IjEifSwiWmYi
-OnsiUGYiOlsiMSJdfSwidnMiOnsiYjgiOlsiMSJdfSwiQ3ciOnsiWFMiOltdfSwibTAiOnsiSkIiOltd
-fSwiSmkiOnsibTAiOltdLCJKQiI6W119LCJiNiI6eyJYdiI6WyIxIl0sInh1IjpbIjEiXSwiYlEiOlsi
-MSJdLCJjWCI6WyIxIl19LCJsbSI6eyJBbiI6WyIxIl19LCJtVyI6eyJjWCI6WyIxIl19LCJMVSI6eyJs
-RCI6WyIxIl0sInpNIjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJpbCI6eyJZayI6WyIxIiwi
-MiJdLCJaMCI6WyIxIiwiMiJdfSwiWWsiOnsiWjAiOlsiMSIsIjIiXX0sIlBuIjp7IlowIjpbIjEiLCIy
-Il19LCJHaiI6eyJSVSI6WyIxIiwiMiJdLCJQbiI6WyIxIiwiMiJdLCJLUCI6WyIxIiwiMiJdLCJaMCI6
-WyIxIiwiMiJdfSwiVmoiOnsiTWEiOlsiMSJdLCJ4dSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJd
-fSwiWHYiOnsieHUiOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sInV3Ijp7IllrIjpbInFVIiwi
-QCJdLCJaMCI6WyJxVSIsIkAiXSwiWWsuSyI6InFVIiwiWWsuViI6IkAifSwiaTgiOnsiYUwiOlsicVUi
-XSwiYlEiOlsicVUiXSwiY1giOlsicVUiXSwiYUwuRSI6InFVIiwiY1guRSI6InFVIn0sIkNWIjp7IlVr
-IjpbInpNPElmPiIsInFVIl0sIlVrLlMiOiJ6TTxJZj4ifSwiVTgiOnsid0kiOlsiek08SWY+IiwicVUi
-XX0sIlppIjp7IlVrIjpbInFVIiwiek08SWY+Il19LCJieSI6eyJVayI6WyJNaD8iLCJxVSJdLCJVay5T
-IjoiTWg/In0sIk14Ijp7IndJIjpbInFVIiwiTWg/Il19LCJ1NSI6eyJVayI6WyJxVSIsInpNPElmPiJd
-LCJVay5TIjoicVUifSwiRTMiOnsid0kiOlsicVUiLCJ6TTxJZj4iXX0sIkdZIjp7IndJIjpbInpNPElm
-PiIsInFVIl19LCJDUCI6eyJsZiI6W119LCJDNiI6eyJYUyI6W119LCJuIjp7IlhTIjpbXX0sInUiOnsi
-WFMiOltdfSwiYkoiOnsiWFMiOltdfSwiZVkiOnsiWFMiOltdfSwibXAiOnsiWFMiOltdfSwidWIiOnsi
-WFMiOltdfSwiZHMiOnsiWFMiOltdfSwibGoiOnsiWFMiOltdfSwiVVYiOnsiWFMiOltdfSwiazUiOnsi
-WFMiOltdfSwiS1kiOnsiWFMiOltdfSwiYyI6eyJYUyI6W119LCJJZiI6eyJsZiI6W119LCJ6TSI6eyJi
-USI6WyIxIl0sImNYIjpbIjEiXX0sImliIjp7Ik9kIjpbXX0sInh1Ijp7ImJRIjpbIjEiXSwiY1giOlsi
-MSJdfSwiWmQiOnsiR3oiOltdfSwicVUiOnsidlgiOltdfSwiUm4iOnsiQkwiOltdfSwiRG4iOnsiaUQi
-OltdfSwiVWYiOnsiaUQiOltdfSwicWUiOnsiaUQiOltdfSwicUUiOnsiY3YiOltdLCJ1SCI6W10sIkQw
-IjpbXX0sIkdoIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJmWSI6eyJjdiI6W10sInVIIjpbXSwi
-RDAiOltdfSwibkIiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIlFQIjp7ImN2IjpbXSwidUgiOltd
-LCJEMCI6W119LCJueCI6eyJ1SCI6W10sIkQwIjpbXX0sIlFGIjp7InVIIjpbXSwiRDAiOltdfSwiSUIi
-OnsidG4iOlsibGYiXX0sInd6Ijp7ImxEIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpb
-IjEiXSwibEQuRSI6IjEifSwiY3YiOnsidUgiOltdLCJEMCI6W119LCJUNSI6eyJBeiI6W119LCJoNCI6
-eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiVmIiOnsidUgiOltdLCJEMCI6W119LCJmSiI6eyJEMCI6
-W119LCJ3YSI6eyJEMCI6W119LCJPSyI6eyJlYSI6W119LCJlNyI6eyJsRCI6WyJ1SCJdLCJ6TSI6WyJ1
-SCJdLCJiUSI6WyJ1SCJdLCJjWCI6WyJ1SCJdLCJsRC5FIjoidUgifSwidUgiOnsiRDAiOltdfSwiQkgi
-OnsiR20iOlsidUgiXSwibEQiOlsidUgiXSwiek0iOlsidUgiXSwiWGoiOlsidUgiXSwiYlEiOlsidUgi
-XSwiY1giOlsidUgiXSwiR20uRSI6InVIIiwibEQuRSI6InVIIn0sIlNOIjp7ImN2IjpbXSwidUgiOltd
-LCJEMCI6W119LCJldyI6eyJlYSI6W119LCJscCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiVGIi
-OnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIkl2Ijp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJX
-UCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwieVkiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0s
-Inc2Ijp7ImVhIjpbXX0sIks1Ijp7InY2IjpbXSwiRDAiOltdfSwiQ20iOnsiRDAiOltdfSwiQ1EiOnsi
-dUgiOltdLCJEMCI6W119LCJ3NCI6eyJ0biI6WyJsZiJdfSwicmgiOnsiR20iOlsidUgiXSwibEQiOlsi
-dUgiXSwiek0iOlsidUgiXSwiWGoiOlsidUgiXSwiYlEiOlsidUgiXSwiY1giOlsidUgiXSwiR20uRSI6
-InVIIiwibEQuRSI6InVIIn0sImNmIjp7IllrIjpbInFVIiwicVUiXSwiWjAiOlsicVUiLCJxVSJdfSwi
-aTciOnsiWWsiOlsicVUiLCJxVSJdLCJaMCI6WyJxVSIsInFVIl0sIllrLksiOiJxVSIsIllrLlYiOiJx
-VSJ9LCJTeSI6eyJZayI6WyJxVSIsInFVIl0sIlowIjpbInFVIiwicVUiXSwiWWsuSyI6InFVIiwiWWsu
-ViI6InFVIn0sIkk0Ijp7Ik1hIjpbInFVIl0sInh1IjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFV
-Il19LCJSTyI6eyJxaCI6WyIxIl19LCJldSI6eyJSTyI6WyIxIl0sInFoIjpbIjEiXX0sInhDIjp7Ik1P
-IjpbIjEiXX0sIkpRIjp7ImtGIjpbXX0sInZEIjp7ImtGIjpbXX0sIm02Ijp7ImtGIjpbXX0sImN0Ijp7
-ImtGIjpbXX0sIk93Ijp7ImtGIjpbXX0sIlc5Ijp7IkFuIjpbIjEiXX0sImRXIjp7InY2IjpbXSwiRDAi
-OltdfSwibWsiOnsieTAiOltdfSwiS28iOnsib24iOltdfSwiQXMiOnsiTWEiOlsicVUiXSwieHUiOlsi
-cVUiXSwiYlEiOlsicVUiXSwiY1giOlsicVUiXX0sInI3Ijp7IkU0IjpbXX0sIlR6Ijp7ImxEIjpbIjEi
-XSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sIkU0IjpbXSwiY1giOlsiMSJdLCJsRC5FIjoiMSJ9LCJiQiI6
-eyJkNSI6W10sImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJLZSI6eyJNYSI6WyJxVSJdLCJ4dSI6WyJx
-VSJdLCJiUSI6WyJxVSJdLCJjWCI6WyJxVSJdfSwiZDUiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0s
-Im42Ijp7InpNIjpbIklmIl0sImJRIjpbIklmIl0sIkFTIjpbXSwiY1giOlsiSWYiXX0sIlhBIjp7ImtG
-IjpbXX0sIk9GIjp7ImZ2IjpbXX0sInJ1Ijp7ImZ2IjpbXX0sIklWIjp7ImZ2IjpbXX19JykpCkguRkYo
-di50eXBlVW5pdmVyc2UsSlNPTi5wYXJzZSgneyJiUSI6MSwidzIiOjEsImIwIjoxLCJrVCI6MiwibVci
-OjEsIkxVIjoxLCJpbCI6MiwiVmoiOjEsIm5ZIjoxLCJXWSI6MSwiY28iOjF9JykpCnZhciB1PShmdW5j
-dGlvbiBydGlpKCl7dmFyIHQ9SC5OMApyZXR1cm57bjp0KCJDdyIpLGNSOnQoIm5CIiksdzp0KCJBeiIp
-LGs6dCgiUVAiKSxnRjp0KCJQRDxHRCxAPiIpLGd3OnQoImJRPEA+IiksaDp0KCJjdiIpLFc6dCgiWFMi
-KSxCOnQoImVhIiksYVM6dCgiRDAiKSxjODp0KCJUNSIpLFk6dCgiRUgiKSxkOnQoImI4PEA+IiksSTp0
-KCJTZyIpLG86dCgidlEiKSxlaDp0KCJjWDx1SD4iKSxROnQoImNYPHFVPiIpLG06dCgiY1g8QD4iKSxw
-OnQoImpkPGtGPiIpLHM6dCgiamQ8cVU+IiksYjp0KCJqZDxAPiIpLHQ6dCgiamQ8SWY+IiksZDc6dCgi
-amQ8U2UqPiIpLGg0OnQoImpkPGo4Kj4iKSxjUTp0KCJqZDxaWio+IiksaTp0KCJqZDxxVSo+IiksYUE6
-dCgiamQ8eUQqPiIpLGFKOnQoImpkPHdiKj4iKSxWOnQoImpkPElmKj4iKSxlSDp0KCJ2bSIpLHI6dCgi
-YzUiKSxhVTp0KCJYajxAPiIpLGFtOnQoIlR6PEA+IiksZW86dCgiTjU8R0QsQD4iKSxkejp0KCJoRiIp
-LGo6dCgiek08QD4iKSxMOnQoInpNPElmPiIpLGY6dCgiWjA8cVUscVU+Iiksdjp0KCJaMDxALEA+Iiks
-ZG86dCgibEo8cVUsQD4iKSxmajp0KCJsSjxxVSoscVU+IiksZEU6dCgiRVQiKSxibTp0KCJWNiIpLEE6
-dCgidUgiKSxlOnQoImtGIiksUDp0KCJjOCIpLEs6dCgiTWgiKSxnWjp0KCJldyIpLHE6dCgidG48bGY+
-IiksZnY6dCgid0wiKSxldzp0KCJiQiIpLEM6dCgieHU8cVU+IiksbDp0KCJHeiIpLE46dCgicVUiKSxk
-MDp0KCJxVShxVSopIiksZzc6dCgiZDUiKSxmbzp0KCJHRCIpLGFXOnQoInlZIikseDp0KCJBUyIpLGdj
-OnQoIm42IiksYWs6dCgia2QiKSxkdzp0KCJHajxxVSxxVT4iKSxkRDp0KCJpRCIpLGZpOnQoIlU1PHFV
-Kj4iKSxnNDp0KCJLNSIpLGNpOnQoInY2IiksZzI6dCgiQ20iKSxiajp0KCJaZjxmSj4iKSxiQzp0KCJa
-ZjxmSio+IiksaDk6dCgiQ1EiKSxhYzp0KCJlNyIpLEc6dCgiZXU8T0sqPiIpLFI6dCgid3o8Y3YqPiIp
-LGFvOnQoInZzPGZKPiIpLGM6dCgidnM8QD4iKSxmSjp0KCJ2czxJZj4iKSxnVjp0KCJ2czxmSio+Iiks
-Y3I6dCgiSlEiKSxKOnQoImJuIikseTp0KCJhMiIpLGFsOnQoImEyKE1oKSIpLGdmOnQoImEyKHFVKiki
-KSxnUjp0KCJDUCIpLHo6dCgiQCIpLGZPOnQoIkAoKSIpLGJJOnQoIkAoTWgpIiksYWc6dCgiQChNaCxH
-eikiKSxiVTp0KCJAKHh1PHFVPikiKSxkTzp0KCJAKHFVKSIpLGI4OnQoIkAoQCxAKSIpLFM6dCgiSWYi
-KSxkZDp0KCJHaCoiKSxnOnQoImN2KiIpLGFMOnQoImVhKiIpLEQ6dCgiZkoqIiksVDp0KCJjWDxAPioi
-KSxlUzp0KCJjWDxxVSo+KiIpLGRIOnQoIkU0KiIpLGRfOnQoInpNPGo4Kj4qIiksZUc6dCgiek08cVUq
-PioiKSxiWjp0KCJ1OCoiKSxibzp0KCJaMDxxVSosQD4qIiksYTp0KCJaMDxxVSosTWgqPioiKSxPOnQo
-Ik9LKiIpLGF3OnQoIjAmKiIpLF86dCgiTWgqIiksRTp0KCJldyoiKSxYOnQoInFVKiIpLGNoOnQoIkQw
-PyIpLGJHOnQoImI4PGM4Pj8iKSxVOnQoImNYPHFVPj8iKSxiazp0KCJ6TTxxVT4/IiksYk06dCgiek08
-QD4/IiksZWc6dCgiek08SWY+PyIpLGNaOnQoIlowPHFVLHFVPj8iKSxjOTp0KCJaMDxxVSxAPj8iKSxj
-Szp0KCJNaD8iKSxGOnQoIkZlPEAsQD4/IiksYjc6dCgiYTIoTWgpPyIpLGJ3OnQoIkAoZWEpPyIpLGZW
-OnQoIk1oPyhNaD8sTWg/KT8iKSxaOnQoIn4oKT8iKSx1OnQoIn4oZXcqKT8iKSxkaTp0KCJsZiIpLEg6
-dCgifiIpLE06dCgifigpIiksZUE6dCgifihxVSxxVSkiKSxjQTp0KCJ+KHFVLEApIil9fSkoKTsoZnVu
-Y3Rpb24gY29uc3RhbnRzKCl7dmFyIHQ9aHVua0hlbHBlcnMubWFrZUNvbnN0TGlzdApDLlJZPVcuUVAu
-cHJvdG90eXBlCkMubUg9Vy5hZS5wcm90b3R5cGUKQy5CWj1XLlZiLnByb3RvdHlwZQpDLkR0PVcuZkou
-cHJvdG90eXBlCkMuT2s9Si52Qi5wcm90b3R5cGUKQy5ObT1KLmpkLnByb3RvdHlwZQpDLmpuPUoudXIu
-cHJvdG90eXBlCkMuQ0Q9Si5xSS5wcm90b3R5cGUKQy54Qj1KLkRyLnByb3RvdHlwZQpDLkRHPUouYzUu
-cHJvdG90eXBlCkMuRXg9Vy51OC5wcm90b3R5cGUKQy5MdD1XLlNOLnByb3RvdHlwZQpDLlpRPUouaUMu
-cHJvdG90eXBlCkMuSWU9Vy5UYi5wcm90b3R5cGUKQy52Qj1KLmtkLnByb3RvdHlwZQpDLm9sPVcuSzUu
-cHJvdG90eXBlCkMueTg9bmV3IFAuVTgoKQpDLmg5PW5ldyBQLkNWKCkKQy5PND1mdW5jdGlvbiBnZXRU
-YWdGYWxsYmFjayhvKSB7CiAgdmFyIHMgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyk7
-CiAgcmV0dXJuIHMuc3Vic3RyaW5nKDgsIHMubGVuZ3RoIC0gMSk7Cn0KQy5ZcT1mdW5jdGlvbigpIHsK
-ICB2YXIgdG9TdHJpbmdGdW5jdGlvbiA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7CiAgZnVuY3Rp
-b24gZ2V0VGFnKG8pIHsKICAgIHZhciBzID0gdG9TdHJpbmdGdW5jdGlvbi5jYWxsKG8pOwogICAgcmV0
-dXJuIHMuc3Vic3RyaW5nKDgsIHMubGVuZ3RoIC0gMSk7CiAgfQogIGZ1bmN0aW9uIGdldFVua25vd25U
-YWcob2JqZWN0LCB0YWcpIHsKICAgIGlmICgvXkhUTUxbQS1aXS4qRWxlbWVudCQvLnRlc3QodGFnKSkg
-ewogICAgICB2YXIgbmFtZSA9IHRvU3RyaW5nRnVuY3Rpb24uY2FsbChvYmplY3QpOwogICAgICBpZiAo
-bmFtZSA9PSAiW29iamVjdCBPYmplY3RdIikgcmV0dXJuIG51bGw7CiAgICAgIHJldHVybiAiSFRNTEVs
-ZW1lbnQiOwogICAgfQogIH0KICBmdW5jdGlvbiBnZXRVbmtub3duVGFnR2VuZXJpY0Jyb3dzZXIob2Jq
-ZWN0LCB0YWcpIHsKICAgIGlmIChzZWxmLkhUTUxFbGVtZW50ICYmIG9iamVjdCBpbnN0YW5jZW9mIEhU
-TUxFbGVtZW50KSByZXR1cm4gIkhUTUxFbGVtZW50IjsKICAgIHJldHVybiBnZXRVbmtub3duVGFnKG9i
-amVjdCwgdGFnKTsKICB9CiAgZnVuY3Rpb24gcHJvdG90eXBlRm9yVGFnKHRhZykgewogICAgaWYgKHR5
-cGVvZiB3aW5kb3cgPT0gInVuZGVmaW5lZCIpIHJldHVybiBudWxsOwogICAgaWYgKHR5cGVvZiB3aW5k
-b3dbdGFnXSA9PSAidW5kZWZpbmVkIikgcmV0dXJuIG51bGw7CiAgICB2YXIgY29uc3RydWN0b3IgPSB3
-aW5kb3dbdGFnXTsKICAgIGlmICh0eXBlb2YgY29uc3RydWN0b3IgIT0gImZ1bmN0aW9uIikgcmV0dXJu
-IG51bGw7CiAgICByZXR1cm4gY29uc3RydWN0b3IucHJvdG90eXBlOwogIH0KICBmdW5jdGlvbiBkaXNj
-cmltaW5hdG9yKHRhZykgeyByZXR1cm4gbnVsbDsgfQogIHZhciBpc0Jyb3dzZXIgPSB0eXBlb2YgbmF2
-aWdhdG9yID09ICJvYmplY3QiOwogIHJldHVybiB7CiAgICBnZXRUYWc6IGdldFRhZywKICAgIGdldFVu
-a25vd25UYWc6IGlzQnJvd3NlciA/IGdldFVua25vd25UYWdHZW5lcmljQnJvd3NlciA6IGdldFVua25v
-d25UYWcsCiAgICBwcm90b3R5cGVGb3JUYWc6IHByb3RvdHlwZUZvclRhZywKICAgIGRpc2NyaW1pbmF0
-b3I6IGRpc2NyaW1pbmF0b3IgfTsKfQpDLndiPWZ1bmN0aW9uKGdldFRhZ0ZhbGxiYWNrKSB7CiAgcmV0
-dXJuIGZ1bmN0aW9uKGhvb2tzKSB7CiAgICBpZiAodHlwZW9mIG5hdmlnYXRvciAhPSAib2JqZWN0Iikg
-cmV0dXJuIGhvb2tzOwogICAgdmFyIHVhID0gbmF2aWdhdG9yLnVzZXJBZ2VudDsKICAgIGlmICh1YS5p
-bmRleE9mKCJEdW1wUmVuZGVyVHJlZSIpID49IDApIHJldHVybiBob29rczsKICAgIGlmICh1YS5pbmRl
-eE9mKCJDaHJvbWUiKSA+PSAwKSB7CiAgICAgIGZ1bmN0aW9uIGNvbmZpcm0ocCkgewogICAgICAgIHJl
-dHVybiB0eXBlb2Ygd2luZG93ID09ICJvYmplY3QiICYmIHdpbmRvd1twXSAmJiB3aW5kb3dbcF0ubmFt
-ZSA9PSBwOwogICAgICB9CiAgICAgIGlmIChjb25maXJtKCJXaW5kb3ciKSAmJiBjb25maXJtKCJIVE1M
-RWxlbWVudCIpKSByZXR1cm4gaG9va3M7CiAgICB9CiAgICBob29rcy5nZXRUYWcgPSBnZXRUYWdGYWxs
-YmFjazsKICB9Owp9CkMuS1U9ZnVuY3Rpb24oaG9va3MpIHsKICBpZiAodHlwZW9mIGRhcnRFeHBlcmlt
-ZW50YWxGaXh1cEdldFRhZyAhPSAiZnVuY3Rpb24iKSByZXR1cm4gaG9va3M7CiAgaG9va3MuZ2V0VGFn
-ID0gZGFydEV4cGVyaW1lbnRhbEZpeHVwR2V0VGFnKGhvb2tzLmdldFRhZyk7Cn0KQy5mUT1mdW5jdGlv
-bihob29rcykgewogIHZhciBnZXRUYWcgPSBob29rcy5nZXRUYWc7CiAgdmFyIHByb3RvdHlwZUZvclRh
-ZyA9IGhvb2tzLnByb3RvdHlwZUZvclRhZzsKICBmdW5jdGlvbiBnZXRUYWdGaXhlZChvKSB7CiAgICB2
-YXIgdGFnID0gZ2V0VGFnKG8pOwogICAgaWYgKHRhZyA9PSAiRG9jdW1lbnQiKSB7CiAgICAgIGlmICgh
-IW8ueG1sVmVyc2lvbikgcmV0dXJuICIhRG9jdW1lbnQiOwogICAgICByZXR1cm4gIiFIVE1MRG9jdW1l
-bnQiOwogICAgfQogICAgcmV0dXJuIHRhZzsKICB9CiAgZnVuY3Rpb24gcHJvdG90eXBlRm9yVGFnRml4
-ZWQodGFnKSB7CiAgICBpZiAodGFnID09ICJEb2N1bWVudCIpIHJldHVybiBudWxsOwogICAgcmV0dXJu
-IHByb3RvdHlwZUZvclRhZyh0YWcpOwogIH0KICBob29rcy5nZXRUYWcgPSBnZXRUYWdGaXhlZDsKICBo
-b29rcy5wcm90b3R5cGVGb3JUYWcgPSBwcm90b3R5cGVGb3JUYWdGaXhlZDsKfQpDLmRrPWZ1bmN0aW9u
-KGhvb2tzKSB7CiAgdmFyIHVzZXJBZ2VudCA9IHR5cGVvZiBuYXZpZ2F0b3IgPT0gIm9iamVjdCIgPyBu
-YXZpZ2F0b3IudXNlckFnZW50IDogIiI7CiAgaWYgKHVzZXJBZ2VudC5pbmRleE9mKCJGaXJlZm94Iikg
-PT0gLTEpIHJldHVybiBob29rczsKICB2YXIgZ2V0VGFnID0gaG9va3MuZ2V0VGFnOwogIHZhciBxdWlj
-a01hcCA9IHsKICAgICJCZWZvcmVVbmxvYWRFdmVudCI6ICJFdmVudCIsCiAgICAiRGF0YVRyYW5zZmVy
-IjogIkNsaXBib2FyZCIsCiAgICAiR2VvR2VvbG9jYXRpb24iOiAiR2VvbG9jYXRpb24iLAogICAgIkxv
-Y2F0aW9uIjogIiFMb2NhdGlvbiIsCiAgICAiV29ya2VyTWVzc2FnZUV2ZW50IjogIk1lc3NhZ2VFdmVu
-dCIsCiAgICAiWE1MRG9jdW1lbnQiOiAiIURvY3VtZW50In07CiAgZnVuY3Rpb24gZ2V0VGFnRmlyZWZv
-eChvKSB7CiAgICB2YXIgdGFnID0gZ2V0VGFnKG8pOwogICAgcmV0dXJuIHF1aWNrTWFwW3RhZ10gfHwg
-dGFnOwogIH0KICBob29rcy5nZXRUYWcgPSBnZXRUYWdGaXJlZm94Owp9CkMueGk9ZnVuY3Rpb24oaG9v
-a3MpIHsKICB2YXIgdXNlckFnZW50ID0gdHlwZW9mIG5hdmlnYXRvciA9PSAib2JqZWN0IiA/IG5hdmln
-YXRvci51c2VyQWdlbnQgOiAiIjsKICBpZiAodXNlckFnZW50LmluZGV4T2YoIlRyaWRlbnQvIikgPT0g
-LTEpIHJldHVybiBob29rczsKICB2YXIgZ2V0VGFnID0gaG9va3MuZ2V0VGFnOwogIHZhciBxdWlja01h
-cCA9IHsKICAgICJCZWZvcmVVbmxvYWRFdmVudCI6ICJFdmVudCIsCiAgICAiRGF0YVRyYW5zZmVyIjog
-IkNsaXBib2FyZCIsCiAgICAiSFRNTERERWxlbWVudCI6ICJIVE1MRWxlbWVudCIsCiAgICAiSFRNTERU
-RWxlbWVudCI6ICJIVE1MRWxlbWVudCIsCiAgICAiSFRNTFBocmFzZUVsZW1lbnQiOiAiSFRNTEVsZW1l
-bnQiLAogICAgIlBvc2l0aW9uIjogIkdlb3Bvc2l0aW9uIgogIH07CiAgZnVuY3Rpb24gZ2V0VGFnSUUo
-bykgewogICAgdmFyIHRhZyA9IGdldFRhZyhvKTsKICAgIHZhciBuZXdUYWcgPSBxdWlja01hcFt0YWdd
-OwogICAgaWYgKG5ld1RhZykgcmV0dXJuIG5ld1RhZzsKICAgIGlmICh0YWcgPT0gIk9iamVjdCIpIHsK
-ICAgICAgaWYgKHdpbmRvdy5EYXRhVmlldyAmJiAobyBpbnN0YW5jZW9mIHdpbmRvdy5EYXRhVmlldykp
-IHJldHVybiAiRGF0YVZpZXciOwogICAgfQogICAgcmV0dXJuIHRhZzsKICB9CiAgZnVuY3Rpb24gcHJv
-dG90eXBlRm9yVGFnSUUodGFnKSB7CiAgICB2YXIgY29uc3RydWN0b3IgPSB3aW5kb3dbdGFnXTsKICAg
-IGlmIChjb25zdHJ1Y3RvciA9PSBudWxsKSByZXR1cm4gbnVsbDsKICAgIHJldHVybiBjb25zdHJ1Y3Rv
-ci5wcm90b3R5cGU7CiAgfQogIGhvb2tzLmdldFRhZyA9IGdldFRhZ0lFOwogIGhvb2tzLnByb3RvdHlw
-ZUZvclRhZyA9IHByb3RvdHlwZUZvclRhZ0lFOwp9CkMuaTc9ZnVuY3Rpb24oaG9va3MpIHsgcmV0dXJu
-IGhvb2tzOyB9CgpDLkN0PW5ldyBQLmJ5KCkKQy5FcT1uZXcgUC5rNSgpCkMueE09bmV3IFAudTUoKQpD
-LlFrPW5ldyBQLkUzKCkKQy5OVT1uZXcgUC5KaSgpCkMucGQ9bmV3IFAuWmQoKQpDLkEzPW5ldyBQLk14
-KG51bGwpCkMuR2I9SC5WTSh0KFsxMjcsMjA0Nyw2NTUzNSwxMTE0MTExXSksdS5WKQpDLmFrPUguVk0o
-dChbMCwwLDMyNzc2LDMzNzkyLDEsMTAyNDAsMCwwXSksdS5WKQpDLmNtPUguVk0odChbIio6OmNsYXNz
-IiwiKjo6ZGlyIiwiKjo6ZHJhZ2dhYmxlIiwiKjo6aGlkZGVuIiwiKjo6aWQiLCIqOjppbmVydCIsIio6
-Oml0ZW1wcm9wIiwiKjo6aXRlbXJlZiIsIio6Oml0ZW1zY29wZSIsIio6OmxhbmciLCIqOjpzcGVsbGNo
-ZWNrIiwiKjo6dGl0bGUiLCIqOjp0cmFuc2xhdGUiLCJBOjphY2Nlc3NrZXkiLCJBOjpjb29yZHMiLCJB
-OjpocmVmbGFuZyIsIkE6Om5hbWUiLCJBOjpzaGFwZSIsIkE6OnRhYmluZGV4IiwiQTo6dGFyZ2V0Iiwi
-QTo6dHlwZSIsIkFSRUE6OmFjY2Vzc2tleSIsIkFSRUE6OmFsdCIsIkFSRUE6OmNvb3JkcyIsIkFSRUE6
-Om5vaHJlZiIsIkFSRUE6OnNoYXBlIiwiQVJFQTo6dGFiaW5kZXgiLCJBUkVBOjp0YXJnZXQiLCJBVURJ
-Tzo6Y29udHJvbHMiLCJBVURJTzo6bG9vcCIsIkFVRElPOjptZWRpYWdyb3VwIiwiQVVESU86Om11dGVk
-IiwiQVVESU86OnByZWxvYWQiLCJCRE86OmRpciIsIkJPRFk6OmFsaW5rIiwiQk9EWTo6Ymdjb2xvciIs
-IkJPRFk6OmxpbmsiLCJCT0RZOjp0ZXh0IiwiQk9EWTo6dmxpbmsiLCJCUjo6Y2xlYXIiLCJCVVRUT046
-OmFjY2Vzc2tleSIsIkJVVFRPTjo6ZGlzYWJsZWQiLCJCVVRUT046Om5hbWUiLCJCVVRUT046OnRhYmlu
-ZGV4IiwiQlVUVE9OOjp0eXBlIiwiQlVUVE9OOjp2YWx1ZSIsIkNBTlZBUzo6aGVpZ2h0IiwiQ0FOVkFT
-Ojp3aWR0aCIsIkNBUFRJT046OmFsaWduIiwiQ09MOjphbGlnbiIsIkNPTDo6Y2hhciIsIkNPTDo6Y2hh
-cm9mZiIsIkNPTDo6c3BhbiIsIkNPTDo6dmFsaWduIiwiQ09MOjp3aWR0aCIsIkNPTEdST1VQOjphbGln
-biIsIkNPTEdST1VQOjpjaGFyIiwiQ09MR1JPVVA6OmNoYXJvZmYiLCJDT0xHUk9VUDo6c3BhbiIsIkNP
-TEdST1VQOjp2YWxpZ24iLCJDT0xHUk9VUDo6d2lkdGgiLCJDT01NQU5EOjpjaGVja2VkIiwiQ09NTUFO
-RDo6Y29tbWFuZCIsIkNPTU1BTkQ6OmRpc2FibGVkIiwiQ09NTUFORDo6bGFiZWwiLCJDT01NQU5EOjpy
-YWRpb2dyb3VwIiwiQ09NTUFORDo6dHlwZSIsIkRBVEE6OnZhbHVlIiwiREVMOjpkYXRldGltZSIsIkRF
-VEFJTFM6Om9wZW4iLCJESVI6OmNvbXBhY3QiLCJESVY6OmFsaWduIiwiREw6OmNvbXBhY3QiLCJGSUVM
-RFNFVDo6ZGlzYWJsZWQiLCJGT05UOjpjb2xvciIsIkZPTlQ6OmZhY2UiLCJGT05UOjpzaXplIiwiRk9S
-TTo6YWNjZXB0IiwiRk9STTo6YXV0b2NvbXBsZXRlIiwiRk9STTo6ZW5jdHlwZSIsIkZPUk06Om1ldGhv
-ZCIsIkZPUk06Om5hbWUiLCJGT1JNOjpub3ZhbGlkYXRlIiwiRk9STTo6dGFyZ2V0IiwiRlJBTUU6Om5h
-bWUiLCJIMTo6YWxpZ24iLCJIMjo6YWxpZ24iLCJIMzo6YWxpZ24iLCJINDo6YWxpZ24iLCJINTo6YWxp
-Z24iLCJINjo6YWxpZ24iLCJIUjo6YWxpZ24iLCJIUjo6bm9zaGFkZSIsIkhSOjpzaXplIiwiSFI6Ondp
-ZHRoIiwiSFRNTDo6dmVyc2lvbiIsIklGUkFNRTo6YWxpZ24iLCJJRlJBTUU6OmZyYW1lYm9yZGVyIiwi
-SUZSQU1FOjpoZWlnaHQiLCJJRlJBTUU6Om1hcmdpbmhlaWdodCIsIklGUkFNRTo6bWFyZ2lud2lkdGgi
-LCJJRlJBTUU6OndpZHRoIiwiSU1HOjphbGlnbiIsIklNRzo6YWx0IiwiSU1HOjpib3JkZXIiLCJJTUc6
-OmhlaWdodCIsIklNRzo6aHNwYWNlIiwiSU1HOjppc21hcCIsIklNRzo6bmFtZSIsIklNRzo6dXNlbWFw
-IiwiSU1HOjp2c3BhY2UiLCJJTUc6OndpZHRoIiwiSU5QVVQ6OmFjY2VwdCIsIklOUFVUOjphY2Nlc3Nr
-ZXkiLCJJTlBVVDo6YWxpZ24iLCJJTlBVVDo6YWx0IiwiSU5QVVQ6OmF1dG9jb21wbGV0ZSIsIklOUFVU
-OjphdXRvZm9jdXMiLCJJTlBVVDo6Y2hlY2tlZCIsIklOUFVUOjpkaXNhYmxlZCIsIklOUFVUOjppbnB1
-dG1vZGUiLCJJTlBVVDo6aXNtYXAiLCJJTlBVVDo6bGlzdCIsIklOUFVUOjptYXgiLCJJTlBVVDo6bWF4
-bGVuZ3RoIiwiSU5QVVQ6Om1pbiIsIklOUFVUOjptdWx0aXBsZSIsIklOUFVUOjpuYW1lIiwiSU5QVVQ6
-OnBsYWNlaG9sZGVyIiwiSU5QVVQ6OnJlYWRvbmx5IiwiSU5QVVQ6OnJlcXVpcmVkIiwiSU5QVVQ6OnNp
-emUiLCJJTlBVVDo6c3RlcCIsIklOUFVUOjp0YWJpbmRleCIsIklOUFVUOjp0eXBlIiwiSU5QVVQ6OnVz
-ZW1hcCIsIklOUFVUOjp2YWx1ZSIsIklOUzo6ZGF0ZXRpbWUiLCJLRVlHRU46OmRpc2FibGVkIiwiS0VZ
-R0VOOjprZXl0eXBlIiwiS0VZR0VOOjpuYW1lIiwiTEFCRUw6OmFjY2Vzc2tleSIsIkxBQkVMOjpmb3Ii
-LCJMRUdFTkQ6OmFjY2Vzc2tleSIsIkxFR0VORDo6YWxpZ24iLCJMSTo6dHlwZSIsIkxJOjp2YWx1ZSIs
-IkxJTks6OnNpemVzIiwiTUFQOjpuYW1lIiwiTUVOVTo6Y29tcGFjdCIsIk1FTlU6OmxhYmVsIiwiTUVO
-VTo6dHlwZSIsIk1FVEVSOjpoaWdoIiwiTUVURVI6OmxvdyIsIk1FVEVSOjptYXgiLCJNRVRFUjo6bWlu
-IiwiTUVURVI6OnZhbHVlIiwiT0JKRUNUOjp0eXBlbXVzdG1hdGNoIiwiT0w6OmNvbXBhY3QiLCJPTDo6
-cmV2ZXJzZWQiLCJPTDo6c3RhcnQiLCJPTDo6dHlwZSIsIk9QVEdST1VQOjpkaXNhYmxlZCIsIk9QVEdS
-T1VQOjpsYWJlbCIsIk9QVElPTjo6ZGlzYWJsZWQiLCJPUFRJT046OmxhYmVsIiwiT1BUSU9OOjpzZWxl
-Y3RlZCIsIk9QVElPTjo6dmFsdWUiLCJPVVRQVVQ6OmZvciIsIk9VVFBVVDo6bmFtZSIsIlA6OmFsaWdu
-IiwiUFJFOjp3aWR0aCIsIlBST0dSRVNTOjptYXgiLCJQUk9HUkVTUzo6bWluIiwiUFJPR1JFU1M6OnZh
-bHVlIiwiU0VMRUNUOjphdXRvY29tcGxldGUiLCJTRUxFQ1Q6OmRpc2FibGVkIiwiU0VMRUNUOjptdWx0
-aXBsZSIsIlNFTEVDVDo6bmFtZSIsIlNFTEVDVDo6cmVxdWlyZWQiLCJTRUxFQ1Q6OnNpemUiLCJTRUxF
-Q1Q6OnRhYmluZGV4IiwiU09VUkNFOjp0eXBlIiwiVEFCTEU6OmFsaWduIiwiVEFCTEU6OmJnY29sb3Ii
-LCJUQUJMRTo6Ym9yZGVyIiwiVEFCTEU6OmNlbGxwYWRkaW5nIiwiVEFCTEU6OmNlbGxzcGFjaW5nIiwi
-VEFCTEU6OmZyYW1lIiwiVEFCTEU6OnJ1bGVzIiwiVEFCTEU6OnN1bW1hcnkiLCJUQUJMRTo6d2lkdGgi
-LCJUQk9EWTo6YWxpZ24iLCJUQk9EWTo6Y2hhciIsIlRCT0RZOjpjaGFyb2ZmIiwiVEJPRFk6OnZhbGln
-biIsIlREOjphYmJyIiwiVEQ6OmFsaWduIiwiVEQ6OmF4aXMiLCJURDo6Ymdjb2xvciIsIlREOjpjaGFy
-IiwiVEQ6OmNoYXJvZmYiLCJURDo6Y29sc3BhbiIsIlREOjpoZWFkZXJzIiwiVEQ6OmhlaWdodCIsIlRE
-Ojpub3dyYXAiLCJURDo6cm93c3BhbiIsIlREOjpzY29wZSIsIlREOjp2YWxpZ24iLCJURDo6d2lkdGgi
-LCJURVhUQVJFQTo6YWNjZXNza2V5IiwiVEVYVEFSRUE6OmF1dG9jb21wbGV0ZSIsIlRFWFRBUkVBOjpj
-b2xzIiwiVEVYVEFSRUE6OmRpc2FibGVkIiwiVEVYVEFSRUE6OmlucHV0bW9kZSIsIlRFWFRBUkVBOjpu
-YW1lIiwiVEVYVEFSRUE6OnBsYWNlaG9sZGVyIiwiVEVYVEFSRUE6OnJlYWRvbmx5IiwiVEVYVEFSRUE6
-OnJlcXVpcmVkIiwiVEVYVEFSRUE6OnJvd3MiLCJURVhUQVJFQTo6dGFiaW5kZXgiLCJURVhUQVJFQTo6
-d3JhcCIsIlRGT09UOjphbGlnbiIsIlRGT09UOjpjaGFyIiwiVEZPT1Q6OmNoYXJvZmYiLCJURk9PVDo6
-dmFsaWduIiwiVEg6OmFiYnIiLCJUSDo6YWxpZ24iLCJUSDo6YXhpcyIsIlRIOjpiZ2NvbG9yIiwiVEg6
-OmNoYXIiLCJUSDo6Y2hhcm9mZiIsIlRIOjpjb2xzcGFuIiwiVEg6OmhlYWRlcnMiLCJUSDo6aGVpZ2h0
-IiwiVEg6Om5vd3JhcCIsIlRIOjpyb3dzcGFuIiwiVEg6OnNjb3BlIiwiVEg6OnZhbGlnbiIsIlRIOjp3
-aWR0aCIsIlRIRUFEOjphbGlnbiIsIlRIRUFEOjpjaGFyIiwiVEhFQUQ6OmNoYXJvZmYiLCJUSEVBRDo6
-dmFsaWduIiwiVFI6OmFsaWduIiwiVFI6OmJnY29sb3IiLCJUUjo6Y2hhciIsIlRSOjpjaGFyb2ZmIiwi
-VFI6OnZhbGlnbiIsIlRSQUNLOjpkZWZhdWx0IiwiVFJBQ0s6OmtpbmQiLCJUUkFDSzo6bGFiZWwiLCJU
-UkFDSzo6c3JjbGFuZyIsIlVMOjpjb21wYWN0IiwiVUw6OnR5cGUiLCJWSURFTzo6Y29udHJvbHMiLCJW
-SURFTzo6aGVpZ2h0IiwiVklERU86Omxvb3AiLCJWSURFTzo6bWVkaWFncm91cCIsIlZJREVPOjptdXRl
-ZCIsIlZJREVPOjpwcmVsb2FkIiwiVklERU86OndpZHRoIl0pLHUuaSkKQy5WQz1ILlZNKHQoWzAsMCw2
-NTQ5MCw0NTA1NSw2NTUzNSwzNDgxNSw2NTUzNCwxODQzMV0pLHUuVikKQy5tSz1ILlZNKHQoWzAsMCwy
-NjYyNCwxMDIzLDY1NTM0LDIwNDcsNjU1MzQsMjA0N10pLHUuVikKQy5TcT1ILlZNKHQoWyJIRUFEIiwi
-QVJFQSIsIkJBU0UiLCJCQVNFRk9OVCIsIkJSIiwiQ09MIiwiQ09MR1JPVVAiLCJFTUJFRCIsIkZSQU1F
-IiwiRlJBTUVTRVQiLCJIUiIsIklNQUdFIiwiSU1HIiwiSU5QVVQiLCJJU0lOREVYIiwiTElOSyIsIk1F
-VEEiLCJQQVJBTSIsIlNPVVJDRSIsIlNUWUxFIiwiVElUTEUiLCJXQlIiXSksdS5pKQpDLmRuPUguVk0o
-dChbXSksdS5iKQpDLnhEPUguVk0odChbXSksdS5pKQpDLnRvPUguVk0odChbMCwwLDMyNzIyLDEyMjg3
-LDY1NTM0LDM0ODE1LDY1NTM0LDE4NDMxXSksdS5WKQpDLkYzPUguVk0odChbMCwwLDI0NTc2LDEwMjMs
-NjU1MzQsMzQ4MTUsNjU1MzQsMTg0MzFdKSx1LlYpCkMuZWE9SC5WTSh0KFswLDAsMzI3NTQsMTEyNjMs
-NjU1MzQsMzQ4MTUsNjU1MzQsMTg0MzFdKSx1LlYpCkMuWko9SC5WTSh0KFswLDAsMzI3MjIsMTIyODcs
-NjU1MzUsMzQ4MTUsNjU1MzQsMTg0MzFdKSx1LlYpCkMuV2Q9SC5WTSh0KFswLDAsNjU0OTAsMTIyODcs
-NjU1MzUsMzQ4MTUsNjU1MzQsMTg0MzFdKSx1LlYpCkMuUXg9SC5WTSh0KFsiYmluZCIsImlmIiwicmVm
-IiwicmVwZWF0Iiwic3ludGF4Il0pLHUuaSkKQy5CST1ILlZNKHQoWyJBOjpocmVmIiwiQVJFQTo6aHJl
-ZiIsIkJMT0NLUVVPVEU6OmNpdGUiLCJCT0RZOjpiYWNrZ3JvdW5kIiwiQ09NTUFORDo6aWNvbiIsIkRF
-TDo6Y2l0ZSIsIkZPUk06OmFjdGlvbiIsIklNRzo6c3JjIiwiSU5QVVQ6OnNyYyIsIklOUzo6Y2l0ZSIs
-IlE6OmNpdGUiLCJWSURFTzo6cG9zdGVyIl0pLHUuaSkKQy5DTT1uZXcgSC5MUCgwLHt9LEMueEQsSC5O
-MCgiTFA8cVUqLHpNPGo4Kj4qPiIpKQpDLldPPW5ldyBILkxQKDAse30sQy54RCxILk4wKCJMUDxxVSos
-cVUqPiIpKQpDLmhVPUguVk0odChbXSksSC5OMCgiamQ8R0QqPiIpKQpDLkR4PW5ldyBILkxQKDAse30s
-Qy5oVSxILk4wKCJMUDxHRCosQD4iKSkKQy5ZMj1uZXcgTC5POSgiTmF2aWdhdGlvblRyZWVOb2RlVHlw
-ZS5kaXJlY3RvcnkiKQpDLnJmPW5ldyBMLk85KCJOYXZpZ2F0aW9uVHJlZU5vZGVUeXBlLmZpbGUiKQpD
-LlRlPW5ldyBILnd2KCJjYWxsIikKQy53UT1uZXcgUC5GeShudWxsLDIpfSkoKTsoZnVuY3Rpb24gc3Rh
-dGljRmllbGRzKCl7JC56bT1udWxsCiQueWo9MAokLm1KPW51bGwKJC5QND1udWxsCiQuTkY9bnVsbAok
-LlRYPW51bGwKJC54Nz1udWxsCiQubnc9bnVsbAokLnZ2PW51bGwKJC5Cdj1udWxsCiQuUzY9bnVsbAok
-Lms4PW51bGwKJC5tZz1udWxsCiQuVUQ9ITEKJC5YMz1DLk5VCiQueGc9SC5WTShbXSxILk4wKCJqZDxN
-aD4iKSkKJC54bz1udWxsCiQuQk89bnVsbAokLmx0PW51bGwKJC5FVT1udWxsCiQub3I9UC5GbCh1Lk4s
-dS5ZKQokLkk2PW51bGwKJC5GZj1udWxsfSkoKTsoZnVuY3Rpb24gbGF6eUluaXRpYWxpemVycygpe3Zh
-ciB0PWh1bmtIZWxwZXJzLmxhenkKdCgkLCJmYSIsInciLGZ1bmN0aW9uKCl7cmV0dXJuIEguWWcoIl8k
-ZGFydF9kYXJ0Q2xvc3VyZSIpfSkKdCgkLCJVMiIsIlNuIixmdW5jdGlvbigpe3JldHVybiBILmNNKEgu
-Uzcoewp0b1N0cmluZzpmdW5jdGlvbigpe3JldHVybiIkcmVjZWl2ZXIkIn19KSl9KQp0KCQsInhxIiwi
-bHEiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5TNyh7JG1ldGhvZCQ6bnVsbCwKdG9TdHJpbmc6ZnVu
-Y3Rpb24oKXtyZXR1cm4iJHJlY2VpdmVyJCJ9fSkpfSkKdCgkLCJSMSIsIk45IixmdW5jdGlvbigpe3Jl
-dHVybiBILmNNKEguUzcobnVsbCkpfSkKdCgkLCJmTiIsImlJIixmdW5jdGlvbigpe3JldHVybiBILmNN
-KGZ1bmN0aW9uKCl7dmFyICRhcmd1bWVudHNFeHByJD0nJGFyZ3VtZW50cyQnCnRyeXtudWxsLiRtZXRo
-b2QkKCRhcmd1bWVudHNFeHByJCl9Y2F0Y2gocyl7cmV0dXJuIHMubWVzc2FnZX19KCkpfSkKdCgkLCJx
-aSIsIlVOIixmdW5jdGlvbigpe3JldHVybiBILmNNKEguUzcodm9pZCAwKSl9KQp0KCQsInJaIiwiWmgi
-LGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oZnVuY3Rpb24oKXt2YXIgJGFyZ3VtZW50c0V4cHIkPSckYXJn
-dW1lbnRzJCcKdHJ5eyh2b2lkIDApLiRtZXRob2QkKCRhcmd1bWVudHNFeHByJCl9Y2F0Y2gocyl7cmV0
-dXJuIHMubWVzc2FnZX19KCkpfSkKdCgkLCJrcSIsInJOIixmdW5jdGlvbigpe3JldHVybiBILmNNKEgu
-TWoobnVsbCkpfSkKdCgkLCJ0dCIsImMzIixmdW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9uKCl7
-dHJ5e251bGwuJG1ldGhvZCR9Y2F0Y2gocyl7cmV0dXJuIHMubWVzc2FnZX19KCkpfSkKdCgkLCJkdCIs
-IkhLIixmdW5jdGlvbigpe3JldHVybiBILmNNKEguTWoodm9pZCAwKSl9KQp0KCQsIkE3IiwicjEiLGZ1
-bmN0aW9uKCl7cmV0dXJuIEguY00oZnVuY3Rpb24oKXt0cnl7KHZvaWQgMCkuJG1ldGhvZCR9Y2F0Y2go
-cyl7cmV0dXJuIHMubWVzc2FnZX19KCkpfSkKdCgkLCJXYyIsInV0IixmdW5jdGlvbigpe3JldHVybiBQ
-Lk9qKCl9KQp0KCQsImtoIiwicmYiLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBQLnBnKCkuJDAoKX0pCnQo
-JCwiYnQiLCJWNyIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEludDhBcnJheShILlhGKEguVk0oWy0yLC0y
-LC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0y
-LC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0xLC0yLC0yLC0yLC0y
-LC0yLDYyLC0yLDYyLC0yLDYzLDUyLDUzLDU0LDU1LDU2LDU3LDU4LDU5LDYwLDYxLC0yLC0yLC0yLC0x
-LC0yLC0yLC0yLDAsMSwyLDMsNCw1LDYsNyw4LDksMTAsMTEsMTIsMTMsMTQsMTUsMTYsMTcsMTgsMTks
-MjAsMjEsMjIsMjMsMjQsMjUsLTIsLTIsLTIsLTIsNjMsLTIsMjYsMjcsMjgsMjksMzAsMzEsMzIsMzMs
-MzQsMzUsMzYsMzcsMzgsMzksNDAsNDEsNDIsNDMsNDQsNDUsNDYsNDcsNDgsNDksNTAsNTEsLTIsLTIs
-LTIsLTIsLTJdLHUudCkpKX0pCnQoJCwiTTUiLCJ3USIsZnVuY3Rpb24oKXtyZXR1cm4gdHlwZW9mIHBy
-b2Nlc3MhPSJ1bmRlZmluZWQiJiZPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwocHJvY2Vzcyk9
-PSJbb2JqZWN0IHByb2Nlc3NdIiYmcHJvY2Vzcy5wbGF0Zm9ybT09IndpbjMyIn0pCnQoJCwibWYiLCJ6
-NCIsZnVuY3Rpb24oKXtyZXR1cm4gUC5udSgiXltcXC1cXC4wLTlBLVpfYS16fl0qJCIpfSkKdCgkLCJK
-RyIsInZaIixmdW5jdGlvbigpe3JldHVybiBQLktOKCl9KQp0KCQsIlNDIiwiQU4iLGZ1bmN0aW9uKCl7
-cmV0dXJuIFAudE0oWyJBIiwiQUJCUiIsIkFDUk9OWU0iLCJBRERSRVNTIiwiQVJFQSIsIkFSVElDTEUi
-LCJBU0lERSIsIkFVRElPIiwiQiIsIkJESSIsIkJETyIsIkJJRyIsIkJMT0NLUVVPVEUiLCJCUiIsIkJV
-VFRPTiIsIkNBTlZBUyIsIkNBUFRJT04iLCJDRU5URVIiLCJDSVRFIiwiQ09ERSIsIkNPTCIsIkNPTEdS
-T1VQIiwiQ09NTUFORCIsIkRBVEEiLCJEQVRBTElTVCIsIkREIiwiREVMIiwiREVUQUlMUyIsIkRGTiIs
-IkRJUiIsIkRJViIsIkRMIiwiRFQiLCJFTSIsIkZJRUxEU0VUIiwiRklHQ0FQVElPTiIsIkZJR1VSRSIs
-IkZPTlQiLCJGT09URVIiLCJGT1JNIiwiSDEiLCJIMiIsIkgzIiwiSDQiLCJINSIsIkg2IiwiSEVBREVS
-IiwiSEdST1VQIiwiSFIiLCJJIiwiSUZSQU1FIiwiSU1HIiwiSU5QVVQiLCJJTlMiLCJLQkQiLCJMQUJF
-TCIsIkxFR0VORCIsIkxJIiwiTUFQIiwiTUFSSyIsIk1FTlUiLCJNRVRFUiIsIk5BViIsIk5PQlIiLCJP
-TCIsIk9QVEdST1VQIiwiT1BUSU9OIiwiT1VUUFVUIiwiUCIsIlBSRSIsIlBST0dSRVNTIiwiUSIsIlMi
-LCJTQU1QIiwiU0VDVElPTiIsIlNFTEVDVCIsIlNNQUxMIiwiU09VUkNFIiwiU1BBTiIsIlNUUklLRSIs
-IlNUUk9ORyIsIlNVQiIsIlNVTU1BUlkiLCJTVVAiLCJUQUJMRSIsIlRCT0RZIiwiVEQiLCJURVhUQVJF
-QSIsIlRGT09UIiwiVEgiLCJUSEVBRCIsIlRJTUUiLCJUUiIsIlRSQUNLIiwiVFQiLCJVIiwiVUwiLCJW
-QVIiLCJWSURFTyIsIldCUiJdLHUuTil9KQp0KCQsIlg0IiwiaEciLGZ1bmN0aW9uKCl7cmV0dXJuIFAu
-bnUoIl5cXFMrJCIpfSkKdCgkLCJ3TyIsIm93IixmdW5jdGlvbigpe3JldHVybiBQLk5EKHNlbGYpfSkK
-dCgkLCJrdCIsIlI4IixmdW5jdGlvbigpe3JldHVybiBILllnKCJfJGRhcnRfZGFydE9iamVjdCIpfSkK
-dCgkLCJmSyIsImtJIixmdW5jdGlvbigpe3JldHVybiBmdW5jdGlvbiBEYXJ0T2JqZWN0KGEpe3RoaXMu
-bz1hfX0pCnQoJCwicXQiLCJ6QiIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IFQubVEoKX0pCnQoJCwiT2wi
-LCJVRSIsZnVuY3Rpb24oKXtyZXR1cm4gUC5oSyhDLm9sLmdtVyhXLngzKCkpLmhyZWYpLmdoWSgpLnEo
-MCwiYXV0aFRva2VuIil9KQp0KCQsImhUIiwieVAiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVy
-eVNlbGVjdG9yKCIuZWRpdC1saXN0IC5wYW5lbC1jb250ZW50Iil9KQp0KCQsIlc2IiwiaEwiLGZ1bmN0
-aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIuZWRpdC1wYW5lbCAucGFuZWwtY29udGVu
-dCIpfSkKdCgkLCJUUiIsIkRXIixmdW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxlY3Rvcigi
-Zm9vdGVyIil9KQp0KCQsIkVZIiwiZmkiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVj
-dG9yKCJoZWFkZXIiKX0pCnQoJCwiYXYiLCJEOSIsZnVuY3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5
-U2VsZWN0b3IoIiN1bml0LW5hbWUiKX0pCnQoJCwiZmUiLCJLRyIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3
-IEwuWEEoKX0pCnQoJCwiZW8iLCJuVSIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IE0ubEkoJC5IaygpKX0p
-CnQoJCwieXIiLCJiRCIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEUuT0YoUC5udSgiLyIpLFAubnUoIlte
-L10kIiksUC5udSgiXi8iKSl9KQp0KCQsIk1rIiwiS2siLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBMLklW
-KFAubnUoIlsvXFxcXF0iKSxQLm51KCJbXi9cXFxcXSQiKSxQLm51KCJeKFxcXFxcXFxcW15cXFxcXStc
-XFxcW15cXFxcL10rfFthLXpBLVpdOlsvXFxcXF0pIiksUC5udSgiXlsvXFxcXF0oPyFbL1xcXFxdKSIp
-KX0pCnQoJCwiYWsiLCJFYiIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEYucnUoUC5udSgiLyIpLFAubnUo
-IiheW2EtekEtWl1bLSsuYS16QS1aXFxkXSo6Ly98W14vXSkkIiksUC5udSgiW2EtekEtWl1bLSsuYS16
-QS1aXFxkXSo6Ly9bXi9dKiIpLFAubnUoIl4vIikpfSkKdCgkLCJscyIsIkhrIixmdW5jdGlvbigpe3Jl
-dHVybiBPLlJoKCl9KX0pKCk7KGZ1bmN0aW9uIG5hdGl2ZVN1cHBvcnQoKXshZnVuY3Rpb24oKXt2YXIg
-dD1mdW5jdGlvbihhKXt2YXIgbj17fQpuW2FdPTEKcmV0dXJuIE9iamVjdC5rZXlzKGh1bmtIZWxwZXJz
-LmNvbnZlcnRUb0Zhc3RPYmplY3QobikpWzBdfQp2LmdldElzb2xhdGVUYWc9ZnVuY3Rpb24oYSl7cmV0
-dXJuIHQoIl9fX2RhcnRfIithK3YuaXNvbGF0ZVRhZyl9CnZhciBzPSJfX19kYXJ0X2lzb2xhdGVfdGFn
-c18iCnZhciByPU9iamVjdFtzXXx8KE9iamVjdFtzXT1PYmplY3QuY3JlYXRlKG51bGwpKQp2YXIgcT0i
-X1p4WXhYIgpmb3IodmFyIHA9MDs7cCsrKXt2YXIgbz10KHErIl8iK3ArIl8iKQppZighKG8gaW4gcikp
-e3Jbb109MQp2Lmlzb2xhdGVUYWc9bwpicmVha319di5kaXNwYXRjaFByb3BlcnR5TmFtZT12LmdldElz
-b2xhdGVUYWcoImRpc3BhdGNoX3JlY29yZCIpfSgpCmh1bmtIZWxwZXJzLnNldE9yVXBkYXRlSW50ZXJj
-ZXB0b3JzQnlUYWcoe0RPTUVycm9yOkoudkIsTWVkaWFFcnJvcjpKLnZCLE5hdmlnYXRvcjpKLnZCLE5h
-dmlnYXRvckNvbmN1cnJlbnRIYXJkd2FyZTpKLnZCLE5hdmlnYXRvclVzZXJNZWRpYUVycm9yOkoudkIs
-T3ZlcmNvbnN0cmFpbmVkRXJyb3I6Si52QixQb3NpdGlvbkVycm9yOkoudkIsUmFuZ2U6Si52QixTUUxF
-cnJvcjpKLnZCLERhdGFWaWV3OkguRVQsQXJyYXlCdWZmZXJWaWV3OkguRVQsRmxvYXQzMkFycmF5Okgu
-RGcsRmxvYXQ2NEFycmF5OkguRGcsSW50MTZBcnJheTpILnhqLEludDMyQXJyYXk6SC5kRSxJbnQ4QXJy
-YXk6SC5aQSxVaW50MTZBcnJheTpILmRULFVpbnQzMkFycmF5OkguUHEsVWludDhDbGFtcGVkQXJyYXk6
-SC5lRSxDYW52YXNQaXhlbEFycmF5OkguZUUsVWludDhBcnJheTpILlY2LEhUTUxBdWRpb0VsZW1lbnQ6
-Vy5xRSxIVE1MQlJFbGVtZW50OlcucUUsSFRNTEJ1dHRvbkVsZW1lbnQ6Vy5xRSxIVE1MQ2FudmFzRWxl
-bWVudDpXLnFFLEhUTUxDb250ZW50RWxlbWVudDpXLnFFLEhUTUxETGlzdEVsZW1lbnQ6Vy5xRSxIVE1M
-RGF0YUVsZW1lbnQ6Vy5xRSxIVE1MRGF0YUxpc3RFbGVtZW50OlcucUUsSFRNTERldGFpbHNFbGVtZW50
-OlcucUUsSFRNTERpYWxvZ0VsZW1lbnQ6Vy5xRSxIVE1MRGl2RWxlbWVudDpXLnFFLEhUTUxFbWJlZEVs
-ZW1lbnQ6Vy5xRSxIVE1MRmllbGRTZXRFbGVtZW50OlcucUUsSFRNTEhSRWxlbWVudDpXLnFFLEhUTUxI
-ZWFkRWxlbWVudDpXLnFFLEhUTUxIZWFkaW5nRWxlbWVudDpXLnFFLEhUTUxIdG1sRWxlbWVudDpXLnFF
-LEhUTUxJRnJhbWVFbGVtZW50OlcucUUsSFRNTEltYWdlRWxlbWVudDpXLnFFLEhUTUxJbnB1dEVsZW1l
-bnQ6Vy5xRSxIVE1MTElFbGVtZW50OlcucUUsSFRNTExhYmVsRWxlbWVudDpXLnFFLEhUTUxMZWdlbmRF
-bGVtZW50OlcucUUsSFRNTExpbmtFbGVtZW50OlcucUUsSFRNTE1hcEVsZW1lbnQ6Vy5xRSxIVE1MTWVk
-aWFFbGVtZW50OlcucUUsSFRNTE1lbnVFbGVtZW50OlcucUUsSFRNTE1ldGFFbGVtZW50OlcucUUsSFRN
-TE1ldGVyRWxlbWVudDpXLnFFLEhUTUxNb2RFbGVtZW50OlcucUUsSFRNTE9MaXN0RWxlbWVudDpXLnFF
-LEhUTUxPYmplY3RFbGVtZW50OlcucUUsSFRNTE9wdEdyb3VwRWxlbWVudDpXLnFFLEhUTUxPcHRpb25F
-bGVtZW50OlcucUUsSFRNTE91dHB1dEVsZW1lbnQ6Vy5xRSxIVE1MUGFyYW1FbGVtZW50OlcucUUsSFRN
-TFBpY3R1cmVFbGVtZW50OlcucUUsSFRNTFByZUVsZW1lbnQ6Vy5xRSxIVE1MUHJvZ3Jlc3NFbGVtZW50
-OlcucUUsSFRNTFF1b3RlRWxlbWVudDpXLnFFLEhUTUxTY3JpcHRFbGVtZW50OlcucUUsSFRNTFNoYWRv
-d0VsZW1lbnQ6Vy5xRSxIVE1MU2xvdEVsZW1lbnQ6Vy5xRSxIVE1MU291cmNlRWxlbWVudDpXLnFFLEhU
-TUxTcGFuRWxlbWVudDpXLnFFLEhUTUxTdHlsZUVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDYXB0aW9uRWxl
-bWVudDpXLnFFLEhUTUxUYWJsZUNlbGxFbGVtZW50OlcucUUsSFRNTFRhYmxlRGF0YUNlbGxFbGVtZW50
-OlcucUUsSFRNTFRhYmxlSGVhZGVyQ2VsbEVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDb2xFbGVtZW50Olcu
-cUUsSFRNTFRleHRBcmVhRWxlbWVudDpXLnFFLEhUTUxUaW1lRWxlbWVudDpXLnFFLEhUTUxUaXRsZUVs
-ZW1lbnQ6Vy5xRSxIVE1MVHJhY2tFbGVtZW50OlcucUUsSFRNTFVMaXN0RWxlbWVudDpXLnFFLEhUTUxV
-bmtub3duRWxlbWVudDpXLnFFLEhUTUxWaWRlb0VsZW1lbnQ6Vy5xRSxIVE1MRGlyZWN0b3J5RWxlbWVu
-dDpXLnFFLEhUTUxGb250RWxlbWVudDpXLnFFLEhUTUxGcmFtZUVsZW1lbnQ6Vy5xRSxIVE1MRnJhbWVT
-ZXRFbGVtZW50OlcucUUsSFRNTE1hcnF1ZWVFbGVtZW50OlcucUUsSFRNTEVsZW1lbnQ6Vy5xRSxIVE1M
-QW5jaG9yRWxlbWVudDpXLkdoLEhUTUxBcmVhRWxlbWVudDpXLmZZLEhUTUxCYXNlRWxlbWVudDpXLm5C
-LEJsb2I6Vy5BeixIVE1MQm9keUVsZW1lbnQ6Vy5RUCxDREFUQVNlY3Rpb246Vy5ueCxDaGFyYWN0ZXJE
-YXRhOlcubngsQ29tbWVudDpXLm54LFByb2Nlc3NpbmdJbnN0cnVjdGlvbjpXLm54LFRleHQ6Vy5ueCxD
-U1NTdHlsZURlY2xhcmF0aW9uOlcub0osTVNTdHlsZUNTU1Byb3BlcnRpZXM6Vy5vSixDU1MyUHJvcGVy
-dGllczpXLm9KLFhNTERvY3VtZW50OlcuUUYsRG9jdW1lbnQ6Vy5RRixET01FeGNlcHRpb246Vy5OaCxE
-T01JbXBsZW1lbnRhdGlvbjpXLmFlLERPTVJlY3RSZWFkT25seTpXLklCLERPTVRva2VuTGlzdDpXLm43
-LEVsZW1lbnQ6Vy5jdixBYm9ydFBheW1lbnRFdmVudDpXLmVhLEFuaW1hdGlvbkV2ZW50OlcuZWEsQW5p
-bWF0aW9uUGxheWJhY2tFdmVudDpXLmVhLEFwcGxpY2F0aW9uQ2FjaGVFcnJvckV2ZW50OlcuZWEsQmFj
-a2dyb3VuZEZldGNoQ2xpY2tFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaEV2ZW50OlcuZWEsQmFja2dy
-b3VuZEZldGNoRmFpbEV2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoZWRFdmVudDpXLmVhLEJlZm9yZUlu
-c3RhbGxQcm9tcHRFdmVudDpXLmVhLEJlZm9yZVVubG9hZEV2ZW50OlcuZWEsQmxvYkV2ZW50OlcuZWEs
-Q2FuTWFrZVBheW1lbnRFdmVudDpXLmVhLENsaXBib2FyZEV2ZW50OlcuZWEsQ2xvc2VFdmVudDpXLmVh
-LEN1c3RvbUV2ZW50OlcuZWEsRGV2aWNlTW90aW9uRXZlbnQ6Vy5lYSxEZXZpY2VPcmllbnRhdGlvbkV2
-ZW50OlcuZWEsRXJyb3JFdmVudDpXLmVhLEV4dGVuZGFibGVFdmVudDpXLmVhLEV4dGVuZGFibGVNZXNz
-YWdlRXZlbnQ6Vy5lYSxGZXRjaEV2ZW50OlcuZWEsRm9udEZhY2VTZXRMb2FkRXZlbnQ6Vy5lYSxGb3Jl
-aWduRmV0Y2hFdmVudDpXLmVhLEdhbWVwYWRFdmVudDpXLmVhLEhhc2hDaGFuZ2VFdmVudDpXLmVhLElu
-c3RhbGxFdmVudDpXLmVhLE1lZGlhRW5jcnlwdGVkRXZlbnQ6Vy5lYSxNZWRpYUtleU1lc3NhZ2VFdmVu
-dDpXLmVhLE1lZGlhUXVlcnlMaXN0RXZlbnQ6Vy5lYSxNZWRpYVN0cmVhbUV2ZW50OlcuZWEsTWVkaWFT
-dHJlYW1UcmFja0V2ZW50OlcuZWEsTWVzc2FnZUV2ZW50OlcuZWEsTUlESUNvbm5lY3Rpb25FdmVudDpX
-LmVhLE1JRElNZXNzYWdlRXZlbnQ6Vy5lYSxNdXRhdGlvbkV2ZW50OlcuZWEsTm90aWZpY2F0aW9uRXZl
-bnQ6Vy5lYSxQYWdlVHJhbnNpdGlvbkV2ZW50OlcuZWEsUGF5bWVudFJlcXVlc3RFdmVudDpXLmVhLFBh
-eW1lbnRSZXF1ZXN0VXBkYXRlRXZlbnQ6Vy5lYSxQb3BTdGF0ZUV2ZW50OlcuZWEsUHJlc2VudGF0aW9u
-Q29ubmVjdGlvbkF2YWlsYWJsZUV2ZW50OlcuZWEsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlRXZl
-bnQ6Vy5lYSxQcm9taXNlUmVqZWN0aW9uRXZlbnQ6Vy5lYSxQdXNoRXZlbnQ6Vy5lYSxSVENEYXRhQ2hh
-bm5lbEV2ZW50OlcuZWEsUlRDRFRNRlRvbmVDaGFuZ2VFdmVudDpXLmVhLFJUQ1BlZXJDb25uZWN0aW9u
-SWNlRXZlbnQ6Vy5lYSxSVENUcmFja0V2ZW50OlcuZWEsU2VjdXJpdHlQb2xpY3lWaW9sYXRpb25FdmVu
-dDpXLmVhLFNlbnNvckVycm9yRXZlbnQ6Vy5lYSxTcGVlY2hSZWNvZ25pdGlvbkVycm9yOlcuZWEsU3Bl
-ZWNoUmVjb2duaXRpb25FdmVudDpXLmVhLFNwZWVjaFN5bnRoZXNpc0V2ZW50OlcuZWEsU3RvcmFnZUV2
-ZW50OlcuZWEsU3luY0V2ZW50OlcuZWEsVHJhY2tFdmVudDpXLmVhLFRyYW5zaXRpb25FdmVudDpXLmVh
-LFdlYktpdFRyYW5zaXRpb25FdmVudDpXLmVhLFZSRGV2aWNlRXZlbnQ6Vy5lYSxWUkRpc3BsYXlFdmVu
-dDpXLmVhLFZSU2Vzc2lvbkV2ZW50OlcuZWEsTW9qb0ludGVyZmFjZVJlcXVlc3RFdmVudDpXLmVhLFVT
-QkNvbm5lY3Rpb25FdmVudDpXLmVhLElEQlZlcnNpb25DaGFuZ2VFdmVudDpXLmVhLEF1ZGlvUHJvY2Vz
-c2luZ0V2ZW50OlcuZWEsT2ZmbGluZUF1ZGlvQ29tcGxldGlvbkV2ZW50OlcuZWEsV2ViR0xDb250ZXh0
-RXZlbnQ6Vy5lYSxFdmVudDpXLmVhLElucHV0RXZlbnQ6Vy5lYSxTdWJtaXRFdmVudDpXLmVhLEV2ZW50
-VGFyZ2V0OlcuRDAsRmlsZTpXLlQ1LEhUTUxGb3JtRWxlbWVudDpXLmg0LEhpc3Rvcnk6Vy5icixIVE1M
-RG9jdW1lbnQ6Vy5WYixYTUxIdHRwUmVxdWVzdDpXLmZKLFhNTEh0dHBSZXF1ZXN0RXZlbnRUYXJnZXQ6
-Vy53YSxJbWFnZURhdGE6Vy5TZyxMb2NhdGlvbjpXLnU4LE1vdXNlRXZlbnQ6Vy5PSyxEcmFnRXZlbnQ6
-Vy5PSyxQb2ludGVyRXZlbnQ6Vy5PSyxXaGVlbEV2ZW50OlcuT0ssRG9jdW1lbnRGcmFnbWVudDpXLnVI
-LFNoYWRvd1Jvb3Q6Vy51SCxEb2N1bWVudFR5cGU6Vy51SCxOb2RlOlcudUgsTm9kZUxpc3Q6Vy5CSCxS
-YWRpb05vZGVMaXN0OlcuQkgsSFRNTFBhcmFncmFwaEVsZW1lbnQ6Vy5TTixQcm9ncmVzc0V2ZW50Olcu
-ZXcsUmVzb3VyY2VQcm9ncmVzc0V2ZW50OlcuZXcsSFRNTFNlbGVjdEVsZW1lbnQ6Vy5scCxIVE1MVGFi
-bGVFbGVtZW50OlcuVGIsSFRNTFRhYmxlUm93RWxlbWVudDpXLkl2LEhUTUxUYWJsZVNlY3Rpb25FbGVt
-ZW50OlcuV1AsSFRNTFRlbXBsYXRlRWxlbWVudDpXLnlZLENvbXBvc2l0aW9uRXZlbnQ6Vy53NixGb2N1
-c0V2ZW50OlcudzYsS2V5Ym9hcmRFdmVudDpXLnc2LFRleHRFdmVudDpXLnc2LFRvdWNoRXZlbnQ6Vy53
-NixVSUV2ZW50OlcudzYsV2luZG93OlcuSzUsRE9NV2luZG93OlcuSzUsRGVkaWNhdGVkV29ya2VyR2xv
-YmFsU2NvcGU6Vy5DbSxTZXJ2aWNlV29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxTaGFyZWRXb3JrZXJHbG9i
-YWxTY29wZTpXLkNtLFdvcmtlckdsb2JhbFNjb3BlOlcuQ20sQXR0cjpXLkNRLENsaWVudFJlY3Q6Vy53
-NCxET01SZWN0OlcudzQsTmFtZWROb2RlTWFwOlcucmgsTW96TmFtZWRBdHRyTWFwOlcucmgsSURCS2V5
-UmFuZ2U6UC5oRixTVkdTY3JpcHRFbGVtZW50OlAuYkIsU1ZHQUVsZW1lbnQ6UC5kNSxTVkdBbmltYXRl
-RWxlbWVudDpQLmQ1LFNWR0FuaW1hdGVNb3Rpb25FbGVtZW50OlAuZDUsU1ZHQW5pbWF0ZVRyYW5zZm9y
-bUVsZW1lbnQ6UC5kNSxTVkdBbmltYXRpb25FbGVtZW50OlAuZDUsU1ZHQ2lyY2xlRWxlbWVudDpQLmQ1
-LFNWR0NsaXBQYXRoRWxlbWVudDpQLmQ1LFNWR0RlZnNFbGVtZW50OlAuZDUsU1ZHRGVzY0VsZW1lbnQ6
-UC5kNSxTVkdEaXNjYXJkRWxlbWVudDpQLmQ1LFNWR0VsbGlwc2VFbGVtZW50OlAuZDUsU1ZHRkVCbGVu
-ZEVsZW1lbnQ6UC5kNSxTVkdGRUNvbG9yTWF0cml4RWxlbWVudDpQLmQ1LFNWR0ZFQ29tcG9uZW50VHJh
-bnNmZXJFbGVtZW50OlAuZDUsU1ZHRkVDb21wb3NpdGVFbGVtZW50OlAuZDUsU1ZHRkVDb252b2x2ZU1h
-dHJpeEVsZW1lbnQ6UC5kNSxTVkdGRURpZmZ1c2VMaWdodGluZ0VsZW1lbnQ6UC5kNSxTVkdGRURpc3Bs
-YWNlbWVudE1hcEVsZW1lbnQ6UC5kNSxTVkdGRURpc3RhbnRMaWdodEVsZW1lbnQ6UC5kNSxTVkdGRUZs
-b29kRWxlbWVudDpQLmQ1LFNWR0ZFRnVuY0FFbGVtZW50OlAuZDUsU1ZHRkVGdW5jQkVsZW1lbnQ6UC5k
-NSxTVkdGRUZ1bmNHRWxlbWVudDpQLmQ1LFNWR0ZFRnVuY1JFbGVtZW50OlAuZDUsU1ZHRkVHYXVzc2lh
-bkJsdXJFbGVtZW50OlAuZDUsU1ZHRkVJbWFnZUVsZW1lbnQ6UC5kNSxTVkdGRU1lcmdlRWxlbWVudDpQ
-LmQ1LFNWR0ZFTWVyZ2VOb2RlRWxlbWVudDpQLmQ1LFNWR0ZFTW9ycGhvbG9neUVsZW1lbnQ6UC5kNSxT
-VkdGRU9mZnNldEVsZW1lbnQ6UC5kNSxTVkdGRVBvaW50TGlnaHRFbGVtZW50OlAuZDUsU1ZHRkVTcGVj
-dWxhckxpZ2h0aW5nRWxlbWVudDpQLmQ1LFNWR0ZFU3BvdExpZ2h0RWxlbWVudDpQLmQ1LFNWR0ZFVGls
-ZUVsZW1lbnQ6UC5kNSxTVkdGRVR1cmJ1bGVuY2VFbGVtZW50OlAuZDUsU1ZHRmlsdGVyRWxlbWVudDpQ
-LmQ1LFNWR0ZvcmVpZ25PYmplY3RFbGVtZW50OlAuZDUsU1ZHR0VsZW1lbnQ6UC5kNSxTVkdHZW9tZXRy
-eUVsZW1lbnQ6UC5kNSxTVkdHcmFwaGljc0VsZW1lbnQ6UC5kNSxTVkdJbWFnZUVsZW1lbnQ6UC5kNSxT
-VkdMaW5lRWxlbWVudDpQLmQ1LFNWR0xpbmVhckdyYWRpZW50RWxlbWVudDpQLmQ1LFNWR01hcmtlckVs
-ZW1lbnQ6UC5kNSxTVkdNYXNrRWxlbWVudDpQLmQ1LFNWR01ldGFkYXRhRWxlbWVudDpQLmQ1LFNWR1Bh
-dGhFbGVtZW50OlAuZDUsU1ZHUGF0dGVybkVsZW1lbnQ6UC5kNSxTVkdQb2x5Z29uRWxlbWVudDpQLmQ1
-LFNWR1BvbHlsaW5lRWxlbWVudDpQLmQ1LFNWR1JhZGlhbEdyYWRpZW50RWxlbWVudDpQLmQ1LFNWR1Jl
-Y3RFbGVtZW50OlAuZDUsU1ZHU2V0RWxlbWVudDpQLmQ1LFNWR1N0b3BFbGVtZW50OlAuZDUsU1ZHU3R5
-bGVFbGVtZW50OlAuZDUsU1ZHU1ZHRWxlbWVudDpQLmQ1LFNWR1N3aXRjaEVsZW1lbnQ6UC5kNSxTVkdT
-eW1ib2xFbGVtZW50OlAuZDUsU1ZHVFNwYW5FbGVtZW50OlAuZDUsU1ZHVGV4dENvbnRlbnRFbGVtZW50
-OlAuZDUsU1ZHVGV4dEVsZW1lbnQ6UC5kNSxTVkdUZXh0UGF0aEVsZW1lbnQ6UC5kNSxTVkdUZXh0UG9z
-aXRpb25pbmdFbGVtZW50OlAuZDUsU1ZHVGl0bGVFbGVtZW50OlAuZDUsU1ZHVXNlRWxlbWVudDpQLmQ1
-LFNWR1ZpZXdFbGVtZW50OlAuZDUsU1ZHR3JhZGllbnRFbGVtZW50OlAuZDUsU1ZHQ29tcG9uZW50VHJh
-bnNmZXJGdW5jdGlvbkVsZW1lbnQ6UC5kNSxTVkdGRURyb3BTaGFkb3dFbGVtZW50OlAuZDUsU1ZHTVBh
-dGhFbGVtZW50OlAuZDUsU1ZHRWxlbWVudDpQLmQ1fSkKaHVua0hlbHBlcnMuc2V0T3JVcGRhdGVMZWFm
-VGFncyh7RE9NRXJyb3I6dHJ1ZSxNZWRpYUVycm9yOnRydWUsTmF2aWdhdG9yOnRydWUsTmF2aWdhdG9y
-Q29uY3VycmVudEhhcmR3YXJlOnRydWUsTmF2aWdhdG9yVXNlck1lZGlhRXJyb3I6dHJ1ZSxPdmVyY29u
-c3RyYWluZWRFcnJvcjp0cnVlLFBvc2l0aW9uRXJyb3I6dHJ1ZSxSYW5nZTp0cnVlLFNRTEVycm9yOnRy
-dWUsRGF0YVZpZXc6dHJ1ZSxBcnJheUJ1ZmZlclZpZXc6ZmFsc2UsRmxvYXQzMkFycmF5OnRydWUsRmxv
-YXQ2NEFycmF5OnRydWUsSW50MTZBcnJheTp0cnVlLEludDMyQXJyYXk6dHJ1ZSxJbnQ4QXJyYXk6dHJ1
-ZSxVaW50MTZBcnJheTp0cnVlLFVpbnQzMkFycmF5OnRydWUsVWludDhDbGFtcGVkQXJyYXk6dHJ1ZSxD
-YW52YXNQaXhlbEFycmF5OnRydWUsVWludDhBcnJheTpmYWxzZSxIVE1MQXVkaW9FbGVtZW50OnRydWUs
-SFRNTEJSRWxlbWVudDp0cnVlLEhUTUxCdXR0b25FbGVtZW50OnRydWUsSFRNTENhbnZhc0VsZW1lbnQ6
-dHJ1ZSxIVE1MQ29udGVudEVsZW1lbnQ6dHJ1ZSxIVE1MRExpc3RFbGVtZW50OnRydWUsSFRNTERhdGFF
-bGVtZW50OnRydWUsSFRNTERhdGFMaXN0RWxlbWVudDp0cnVlLEhUTUxEZXRhaWxzRWxlbWVudDp0cnVl
-LEhUTUxEaWFsb2dFbGVtZW50OnRydWUsSFRNTERpdkVsZW1lbnQ6dHJ1ZSxIVE1MRW1iZWRFbGVtZW50
-OnRydWUsSFRNTEZpZWxkU2V0RWxlbWVudDp0cnVlLEhUTUxIUkVsZW1lbnQ6dHJ1ZSxIVE1MSGVhZEVs
-ZW1lbnQ6dHJ1ZSxIVE1MSGVhZGluZ0VsZW1lbnQ6dHJ1ZSxIVE1MSHRtbEVsZW1lbnQ6dHJ1ZSxIVE1M
-SUZyYW1lRWxlbWVudDp0cnVlLEhUTUxJbWFnZUVsZW1lbnQ6dHJ1ZSxIVE1MSW5wdXRFbGVtZW50OnRy
-dWUsSFRNTExJRWxlbWVudDp0cnVlLEhUTUxMYWJlbEVsZW1lbnQ6dHJ1ZSxIVE1MTGVnZW5kRWxlbWVu
-dDp0cnVlLEhUTUxMaW5rRWxlbWVudDp0cnVlLEhUTUxNYXBFbGVtZW50OnRydWUsSFRNTE1lZGlhRWxl
-bWVudDp0cnVlLEhUTUxNZW51RWxlbWVudDp0cnVlLEhUTUxNZXRhRWxlbWVudDp0cnVlLEhUTUxNZXRl
-ckVsZW1lbnQ6dHJ1ZSxIVE1MTW9kRWxlbWVudDp0cnVlLEhUTUxPTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1M
-T2JqZWN0RWxlbWVudDp0cnVlLEhUTUxPcHRHcm91cEVsZW1lbnQ6dHJ1ZSxIVE1MT3B0aW9uRWxlbWVu
-dDp0cnVlLEhUTUxPdXRwdXRFbGVtZW50OnRydWUsSFRNTFBhcmFtRWxlbWVudDp0cnVlLEhUTUxQaWN0
-dXJlRWxlbWVudDp0cnVlLEhUTUxQcmVFbGVtZW50OnRydWUsSFRNTFByb2dyZXNzRWxlbWVudDp0cnVl
-LEhUTUxRdW90ZUVsZW1lbnQ6dHJ1ZSxIVE1MU2NyaXB0RWxlbWVudDp0cnVlLEhUTUxTaGFkb3dFbGVt
-ZW50OnRydWUsSFRNTFNsb3RFbGVtZW50OnRydWUsSFRNTFNvdXJjZUVsZW1lbnQ6dHJ1ZSxIVE1MU3Bh
-bkVsZW1lbnQ6dHJ1ZSxIVE1MU3R5bGVFbGVtZW50OnRydWUsSFRNTFRhYmxlQ2FwdGlvbkVsZW1lbnQ6
-dHJ1ZSxIVE1MVGFibGVDZWxsRWxlbWVudDp0cnVlLEhUTUxUYWJsZURhdGFDZWxsRWxlbWVudDp0cnVl
-LEhUTUxUYWJsZUhlYWRlckNlbGxFbGVtZW50OnRydWUsSFRNTFRhYmxlQ29sRWxlbWVudDp0cnVlLEhU
-TUxUZXh0QXJlYUVsZW1lbnQ6dHJ1ZSxIVE1MVGltZUVsZW1lbnQ6dHJ1ZSxIVE1MVGl0bGVFbGVtZW50
-OnRydWUsSFRNTFRyYWNrRWxlbWVudDp0cnVlLEhUTUxVTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MVW5rbm93
-bkVsZW1lbnQ6dHJ1ZSxIVE1MVmlkZW9FbGVtZW50OnRydWUsSFRNTERpcmVjdG9yeUVsZW1lbnQ6dHJ1
-ZSxIVE1MRm9udEVsZW1lbnQ6dHJ1ZSxIVE1MRnJhbWVFbGVtZW50OnRydWUsSFRNTEZyYW1lU2V0RWxl
-bWVudDp0cnVlLEhUTUxNYXJxdWVlRWxlbWVudDp0cnVlLEhUTUxFbGVtZW50OmZhbHNlLEhUTUxBbmNo
-b3JFbGVtZW50OnRydWUsSFRNTEFyZWFFbGVtZW50OnRydWUsSFRNTEJhc2VFbGVtZW50OnRydWUsQmxv
-YjpmYWxzZSxIVE1MQm9keUVsZW1lbnQ6dHJ1ZSxDREFUQVNlY3Rpb246dHJ1ZSxDaGFyYWN0ZXJEYXRh
-OnRydWUsQ29tbWVudDp0cnVlLFByb2Nlc3NpbmdJbnN0cnVjdGlvbjp0cnVlLFRleHQ6dHJ1ZSxDU1NT
-dHlsZURlY2xhcmF0aW9uOnRydWUsTVNTdHlsZUNTU1Byb3BlcnRpZXM6dHJ1ZSxDU1MyUHJvcGVydGll
-czp0cnVlLFhNTERvY3VtZW50OnRydWUsRG9jdW1lbnQ6ZmFsc2UsRE9NRXhjZXB0aW9uOnRydWUsRE9N
-SW1wbGVtZW50YXRpb246dHJ1ZSxET01SZWN0UmVhZE9ubHk6ZmFsc2UsRE9NVG9rZW5MaXN0OnRydWUs
-RWxlbWVudDpmYWxzZSxBYm9ydFBheW1lbnRFdmVudDp0cnVlLEFuaW1hdGlvbkV2ZW50OnRydWUsQW5p
-bWF0aW9uUGxheWJhY2tFdmVudDp0cnVlLEFwcGxpY2F0aW9uQ2FjaGVFcnJvckV2ZW50OnRydWUsQmFj
-a2dyb3VuZEZldGNoQ2xpY2tFdmVudDp0cnVlLEJhY2tncm91bmRGZXRjaEV2ZW50OnRydWUsQmFja2dy
-b3VuZEZldGNoRmFpbEV2ZW50OnRydWUsQmFja2dyb3VuZEZldGNoZWRFdmVudDp0cnVlLEJlZm9yZUlu
-c3RhbGxQcm9tcHRFdmVudDp0cnVlLEJlZm9yZVVubG9hZEV2ZW50OnRydWUsQmxvYkV2ZW50OnRydWUs
-Q2FuTWFrZVBheW1lbnRFdmVudDp0cnVlLENsaXBib2FyZEV2ZW50OnRydWUsQ2xvc2VFdmVudDp0cnVl
-LEN1c3RvbUV2ZW50OnRydWUsRGV2aWNlTW90aW9uRXZlbnQ6dHJ1ZSxEZXZpY2VPcmllbnRhdGlvbkV2
-ZW50OnRydWUsRXJyb3JFdmVudDp0cnVlLEV4dGVuZGFibGVFdmVudDp0cnVlLEV4dGVuZGFibGVNZXNz
-YWdlRXZlbnQ6dHJ1ZSxGZXRjaEV2ZW50OnRydWUsRm9udEZhY2VTZXRMb2FkRXZlbnQ6dHJ1ZSxGb3Jl
-aWduRmV0Y2hFdmVudDp0cnVlLEdhbWVwYWRFdmVudDp0cnVlLEhhc2hDaGFuZ2VFdmVudDp0cnVlLElu
-c3RhbGxFdmVudDp0cnVlLE1lZGlhRW5jcnlwdGVkRXZlbnQ6dHJ1ZSxNZWRpYUtleU1lc3NhZ2VFdmVu
-dDp0cnVlLE1lZGlhUXVlcnlMaXN0RXZlbnQ6dHJ1ZSxNZWRpYVN0cmVhbUV2ZW50OnRydWUsTWVkaWFT
-dHJlYW1UcmFja0V2ZW50OnRydWUsTWVzc2FnZUV2ZW50OnRydWUsTUlESUNvbm5lY3Rpb25FdmVudDp0
-cnVlLE1JRElNZXNzYWdlRXZlbnQ6dHJ1ZSxNdXRhdGlvbkV2ZW50OnRydWUsTm90aWZpY2F0aW9uRXZl
-bnQ6dHJ1ZSxQYWdlVHJhbnNpdGlvbkV2ZW50OnRydWUsUGF5bWVudFJlcXVlc3RFdmVudDp0cnVlLFBh
-eW1lbnRSZXF1ZXN0VXBkYXRlRXZlbnQ6dHJ1ZSxQb3BTdGF0ZUV2ZW50OnRydWUsUHJlc2VudGF0aW9u
-Q29ubmVjdGlvbkF2YWlsYWJsZUV2ZW50OnRydWUsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlRXZl
-bnQ6dHJ1ZSxQcm9taXNlUmVqZWN0aW9uRXZlbnQ6dHJ1ZSxQdXNoRXZlbnQ6dHJ1ZSxSVENEYXRhQ2hh
-bm5lbEV2ZW50OnRydWUsUlRDRFRNRlRvbmVDaGFuZ2VFdmVudDp0cnVlLFJUQ1BlZXJDb25uZWN0aW9u
-SWNlRXZlbnQ6dHJ1ZSxSVENUcmFja0V2ZW50OnRydWUsU2VjdXJpdHlQb2xpY3lWaW9sYXRpb25FdmVu
-dDp0cnVlLFNlbnNvckVycm9yRXZlbnQ6dHJ1ZSxTcGVlY2hSZWNvZ25pdGlvbkVycm9yOnRydWUsU3Bl
-ZWNoUmVjb2duaXRpb25FdmVudDp0cnVlLFNwZWVjaFN5bnRoZXNpc0V2ZW50OnRydWUsU3RvcmFnZUV2
-ZW50OnRydWUsU3luY0V2ZW50OnRydWUsVHJhY2tFdmVudDp0cnVlLFRyYW5zaXRpb25FdmVudDp0cnVl
-LFdlYktpdFRyYW5zaXRpb25FdmVudDp0cnVlLFZSRGV2aWNlRXZlbnQ6dHJ1ZSxWUkRpc3BsYXlFdmVu
-dDp0cnVlLFZSU2Vzc2lvbkV2ZW50OnRydWUsTW9qb0ludGVyZmFjZVJlcXVlc3RFdmVudDp0cnVlLFVT
-QkNvbm5lY3Rpb25FdmVudDp0cnVlLElEQlZlcnNpb25DaGFuZ2VFdmVudDp0cnVlLEF1ZGlvUHJvY2Vz
-c2luZ0V2ZW50OnRydWUsT2ZmbGluZUF1ZGlvQ29tcGxldGlvbkV2ZW50OnRydWUsV2ViR0xDb250ZXh0
-RXZlbnQ6dHJ1ZSxFdmVudDpmYWxzZSxJbnB1dEV2ZW50OmZhbHNlLFN1Ym1pdEV2ZW50OmZhbHNlLEV2
-ZW50VGFyZ2V0OmZhbHNlLEZpbGU6dHJ1ZSxIVE1MRm9ybUVsZW1lbnQ6dHJ1ZSxIaXN0b3J5OnRydWUs
-SFRNTERvY3VtZW50OnRydWUsWE1MSHR0cFJlcXVlc3Q6dHJ1ZSxYTUxIdHRwUmVxdWVzdEV2ZW50VGFy
-Z2V0OmZhbHNlLEltYWdlRGF0YTp0cnVlLExvY2F0aW9uOnRydWUsTW91c2VFdmVudDp0cnVlLERyYWdF
-dmVudDp0cnVlLFBvaW50ZXJFdmVudDp0cnVlLFdoZWVsRXZlbnQ6dHJ1ZSxEb2N1bWVudEZyYWdtZW50
-OnRydWUsU2hhZG93Um9vdDp0cnVlLERvY3VtZW50VHlwZTp0cnVlLE5vZGU6ZmFsc2UsTm9kZUxpc3Q6
-dHJ1ZSxSYWRpb05vZGVMaXN0OnRydWUsSFRNTFBhcmFncmFwaEVsZW1lbnQ6dHJ1ZSxQcm9ncmVzc0V2
-ZW50OnRydWUsUmVzb3VyY2VQcm9ncmVzc0V2ZW50OnRydWUsSFRNTFNlbGVjdEVsZW1lbnQ6dHJ1ZSxI
-VE1MVGFibGVFbGVtZW50OnRydWUsSFRNTFRhYmxlUm93RWxlbWVudDp0cnVlLEhUTUxUYWJsZVNlY3Rp
-b25FbGVtZW50OnRydWUsSFRNTFRlbXBsYXRlRWxlbWVudDp0cnVlLENvbXBvc2l0aW9uRXZlbnQ6dHJ1
-ZSxGb2N1c0V2ZW50OnRydWUsS2V5Ym9hcmRFdmVudDp0cnVlLFRleHRFdmVudDp0cnVlLFRvdWNoRXZl
-bnQ6dHJ1ZSxVSUV2ZW50OmZhbHNlLFdpbmRvdzp0cnVlLERPTVdpbmRvdzp0cnVlLERlZGljYXRlZFdv
-cmtlckdsb2JhbFNjb3BlOnRydWUsU2VydmljZVdvcmtlckdsb2JhbFNjb3BlOnRydWUsU2hhcmVkV29y
-a2VyR2xvYmFsU2NvcGU6dHJ1ZSxXb3JrZXJHbG9iYWxTY29wZTp0cnVlLEF0dHI6dHJ1ZSxDbGllbnRS
-ZWN0OnRydWUsRE9NUmVjdDp0cnVlLE5hbWVkTm9kZU1hcDp0cnVlLE1vek5hbWVkQXR0ck1hcDp0cnVl
-LElEQktleVJhbmdlOnRydWUsU1ZHU2NyaXB0RWxlbWVudDp0cnVlLFNWR0FFbGVtZW50OnRydWUsU1ZH
-QW5pbWF0ZUVsZW1lbnQ6dHJ1ZSxTVkdBbmltYXRlTW90aW9uRWxlbWVudDp0cnVlLFNWR0FuaW1hdGVU
-cmFuc2Zvcm1FbGVtZW50OnRydWUsU1ZHQW5pbWF0aW9uRWxlbWVudDp0cnVlLFNWR0NpcmNsZUVsZW1l
-bnQ6dHJ1ZSxTVkdDbGlwUGF0aEVsZW1lbnQ6dHJ1ZSxTVkdEZWZzRWxlbWVudDp0cnVlLFNWR0Rlc2NF
-bGVtZW50OnRydWUsU1ZHRGlzY2FyZEVsZW1lbnQ6dHJ1ZSxTVkdFbGxpcHNlRWxlbWVudDp0cnVlLFNW
-R0ZFQmxlbmRFbGVtZW50OnRydWUsU1ZHRkVDb2xvck1hdHJpeEVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbXBv
-bmVudFRyYW5zZmVyRWxlbWVudDp0cnVlLFNWR0ZFQ29tcG9zaXRlRWxlbWVudDp0cnVlLFNWR0ZFQ29u
-dm9sdmVNYXRyaXhFbGVtZW50OnRydWUsU1ZHRkVEaWZmdXNlTGlnaHRpbmdFbGVtZW50OnRydWUsU1ZH
-RkVEaXNwbGFjZW1lbnRNYXBFbGVtZW50OnRydWUsU1ZHRkVEaXN0YW50TGlnaHRFbGVtZW50OnRydWUs
-U1ZHRkVGbG9vZEVsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNBRWxlbWVudDp0cnVlLFNWR0ZFRnVuY0JFbGVt
-ZW50OnRydWUsU1ZHRkVGdW5jR0VsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNSRWxlbWVudDp0cnVlLFNWR0ZF
-R2F1c3NpYW5CbHVyRWxlbWVudDp0cnVlLFNWR0ZFSW1hZ2VFbGVtZW50OnRydWUsU1ZHRkVNZXJnZUVs
-ZW1lbnQ6dHJ1ZSxTVkdGRU1lcmdlTm9kZUVsZW1lbnQ6dHJ1ZSxTVkdGRU1vcnBob2xvZ3lFbGVtZW50
-OnRydWUsU1ZHRkVPZmZzZXRFbGVtZW50OnRydWUsU1ZHRkVQb2ludExpZ2h0RWxlbWVudDp0cnVlLFNW
-R0ZFU3BlY3VsYXJMaWdodGluZ0VsZW1lbnQ6dHJ1ZSxTVkdGRVNwb3RMaWdodEVsZW1lbnQ6dHJ1ZSxT
-VkdGRVRpbGVFbGVtZW50OnRydWUsU1ZHRkVUdXJidWxlbmNlRWxlbWVudDp0cnVlLFNWR0ZpbHRlckVs
-ZW1lbnQ6dHJ1ZSxTVkdGb3JlaWduT2JqZWN0RWxlbWVudDp0cnVlLFNWR0dFbGVtZW50OnRydWUsU1ZH
-R2VvbWV0cnlFbGVtZW50OnRydWUsU1ZHR3JhcGhpY3NFbGVtZW50OnRydWUsU1ZHSW1hZ2VFbGVtZW50
-OnRydWUsU1ZHTGluZUVsZW1lbnQ6dHJ1ZSxTVkdMaW5lYXJHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdN
-YXJrZXJFbGVtZW50OnRydWUsU1ZHTWFza0VsZW1lbnQ6dHJ1ZSxTVkdNZXRhZGF0YUVsZW1lbnQ6dHJ1
-ZSxTVkdQYXRoRWxlbWVudDp0cnVlLFNWR1BhdHRlcm5FbGVtZW50OnRydWUsU1ZHUG9seWdvbkVsZW1l
-bnQ6dHJ1ZSxTVkdQb2x5bGluZUVsZW1lbnQ6dHJ1ZSxTVkdSYWRpYWxHcmFkaWVudEVsZW1lbnQ6dHJ1
-ZSxTVkdSZWN0RWxlbWVudDp0cnVlLFNWR1NldEVsZW1lbnQ6dHJ1ZSxTVkdTdG9wRWxlbWVudDp0cnVl
-LFNWR1N0eWxlRWxlbWVudDp0cnVlLFNWR1NWR0VsZW1lbnQ6dHJ1ZSxTVkdTd2l0Y2hFbGVtZW50OnRy
-dWUsU1ZHU3ltYm9sRWxlbWVudDp0cnVlLFNWR1RTcGFuRWxlbWVudDp0cnVlLFNWR1RleHRDb250ZW50
-RWxlbWVudDp0cnVlLFNWR1RleHRFbGVtZW50OnRydWUsU1ZHVGV4dFBhdGhFbGVtZW50OnRydWUsU1ZH
-VGV4dFBvc2l0aW9uaW5nRWxlbWVudDp0cnVlLFNWR1RpdGxlRWxlbWVudDp0cnVlLFNWR1VzZUVsZW1l
-bnQ6dHJ1ZSxTVkdWaWV3RWxlbWVudDp0cnVlLFNWR0dyYWRpZW50RWxlbWVudDp0cnVlLFNWR0NvbXBv
-bmVudFRyYW5zZmVyRnVuY3Rpb25FbGVtZW50OnRydWUsU1ZHRkVEcm9wU2hhZG93RWxlbWVudDp0cnVl
-LFNWR01QYXRoRWxlbWVudDp0cnVlLFNWR0VsZW1lbnQ6ZmFsc2V9KQpILmIwLiRuYXRpdmVTdXBlcmNs
-YXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkguUkcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVm
-ZmVyVmlldyIKSC5WUC4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILkRnLiRu
-YXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkguV0IuJG5hdGl2ZVN1cGVyY2xhc3NU
-YWc9IkFycmF5QnVmZmVyVmlldyIKSC5aRy4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJW
-aWV3IgpILlBnLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXcifSkoKQpjb252ZXJ0
-QWxsVG9GYXN0T2JqZWN0KHcpCmNvbnZlcnRUb0Zhc3RPYmplY3QoJCk7KGZ1bmN0aW9uKGEpe2lmKHR5
-cGVvZiBkb2N1bWVudD09PSJ1bmRlZmluZWQiKXthKG51bGwpCnJldHVybn1pZih0eXBlb2YgZG9jdW1l
-bnQuY3VycmVudFNjcmlwdCE9J3VuZGVmaW5lZCcpe2EoZG9jdW1lbnQuY3VycmVudFNjcmlwdCkKcmV0
-dXJufXZhciB0PWRvY3VtZW50LnNjcmlwdHMKZnVuY3Rpb24gb25Mb2FkKGIpe2Zvcih2YXIgcj0wO3I8
-dC5sZW5ndGg7KytyKXRbcl0ucmVtb3ZlRXZlbnRMaXN0ZW5lcigibG9hZCIsb25Mb2FkLGZhbHNlKQph
-KGIudGFyZ2V0KX1mb3IodmFyIHM9MDtzPHQubGVuZ3RoOysrcyl0W3NdLmFkZEV2ZW50TGlzdGVuZXIo
-ImxvYWQiLG9uTG9hZCxmYWxzZSl9KShmdW5jdGlvbihhKXt2LmN1cnJlbnRTY3JpcHQ9YQppZih0eXBl
-b2YgZGFydE1haW5SdW5uZXI9PT0iZnVuY3Rpb24iKWRhcnRNYWluUnVubmVyKEwuSXEsW10pCmVsc2Ug
-TC5JcShbXSl9KX0pKCkKLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWlncmF0aW9uLmpzLm1hcAo=
+LEguZEUsSC5aQSxILndmLEguUHEsSC5lRSxILlY2XSkKcihILnU5LFtILmh6LEguaU1dKQpzKFAuWmYs
+UC5QZikKcyhQLkppLFAubTApCnMoUC5iNixQLlh2KQpzKFAuVmosUC5UQykKcihQLlVrLFtQLkNWLFAu
+WmksUC5ieV0pCnMoUC53SSxQLmtUKQpyKFAud0ksW1AuVTgsUC5NeCxQLkUzLFAuR1ldKQpzKFAudTUs
+UC5aaSkKcihQLkZLLFtQLkNQLFAuS05dKQpyKFAudSxbUC5iSixQLmVZXSkKcyhQLnFlLFAuRG4pCnIo
+Vy5EMCxbVy51SCxXLndhLFcuSzUsVy5DbV0pCnIoVy51SCxbVy5jdixXLm54LFcuUUYsVy5DUV0pCnIo
+Vy5jdixbVy5xRSxQLmQ1XSkKcihXLnFFLFtXLkdoLFcuZlksVy5uQixXLlFQLFcuaDQsVy5TTixXLmxw
+LFcuVGIsVy5JdixXLldQLFcueVldKQpzKFcub0osVy5MZSkKcyhXLlQ1LFcuQXopCnMoVy5WYixXLlFG
+KQpzKFcuTzcsVy53YSkKcihXLmVhLFtXLnc2LFcuZXddKQpzKFcuQWosVy53NikKcyhXLnJCLFcuSzcp
+CnMoVy5CSCxXLnJCKQpzKFcudzQsVy5JQikKcyhXLm9hLFcuWFcpCnMoVy5yaCxXLm9hKQpzKFcuaTcs
+Vy5jZikKcyhQLkFzLFAuVmopCnIoUC5BcyxbVy5JNCxQLktlXSkKcyhXLlJPLFAucWgpCnMoVy5ldSxX
+LlJPKQpzKFcueEMsUC5NTykKcyhXLmN0LFcubTYpCnMoUC5CZixQLmlKKQpyKFAuRTQsW1AucjcsUC5j
+b10pCnMoUC5UeixQLmNvKQpzKFAubmQsUC5kNSkKcyhCLmZ2LE8uekwpCnIoQi5mdixbRS5PRixGLnJ1
+LEwuSVZdKQp0KEguWEMsSC5SZSkKdChILlJHLFAubEQpCnQoSC5WUCxILlNVKQp0KEguV0IsUC5sRCkK
+dChILlpHLEguU1UpCnQoUC5uWSxQLmxEKQp0KFAuVEMsUC5sZikKdChQLlJVLFAuS1ApCnQoVy5MZSxX
+LmlkKQp0KFcuSzcsUC5sRCkKdChXLnJCLFcuR20pCnQoVy5YVyxQLmxEKQp0KFcub2EsVy5HbSkKdChQ
+LmNvLFAubEQpfSkoKQp2YXIgdj17dHlwZVVuaXZlcnNlOntlQzpuZXcgTWFwKCksdFI6e30sZVQ6e30s
+dFBWOnt9LHNFQTpbXX0sbWFuZ2xlZEdsb2JhbE5hbWVzOntLTjoiaW50IixDUDoiZG91YmxlIixGSzoi
+bnVtIixxVToiU3RyaW5nIixhMjoiYm9vbCIsYzg6Ik51bGwiLHpNOiJMaXN0In0sbWFuZ2xlZE5hbWVz
+Ont9LGdldFR5cGVGcm9tTmFtZTpnZXRHbG9iYWxGcm9tTmFtZSxtZXRhZGF0YTpbXSx0eXBlczpbImM4
+KCkiLCJjOChALEApIiwifigpIiwiYzgoQWopIiwiQChAKSIsInFVKHFVKSIsImM4KGN2KSIsImEyKHFV
+KSIsImM4KHFVLHFVKSIsImM4KE83KSIsIn4ofigpKSIsImEyKGN2LHFVLHFVLEpRKSIsImM4KEApIiwi
+YzgocVUsQCkiLCJjOChxVSkiLCJjOChldykiLCJhMihrRikiLCJ+KHh1PHFVPikiLCJjOChlYSkiLCJ+
+KEFqKSIsIlowPHFVLHFVPihaMDxxVSxxVT4scVUpIiwifihAKSIsIn4ocVUscVUpIiwibjYoS04pIiwi
+bjYoQCxAKSIsImEyKHVIKSIsImM4KEAsR3opIiwiYzgoS04sQCkiLCJAKGVhKSIsIn4oa1tHel0pIiwi
+YzgoQFtHel0pIiwifih1SCx1SCkiLCJrKEApIiwidnM8QD4oQCkiLCJyNyhAKSIsIlR6PEA+KEApIiwi
+RTQoQCkiLCJjOCh+KCkpIiwiYzgoR0QsQCkiLCJjOChaMDxxVSxrPikiLCJiODxjOD4oQWopIiwicVUo
+QWopIiwiQChxVSkiLCJ+KHFVLEtOKSIsIn4ocVVbQF0pIiwicVUoS04pIiwiS04oS04sS04pIiwiQChA
+LHFVKSIsImEyKHh1PHFVPikiXSxpbnRlcmNlcHRvcnNCeVRhZzpudWxsLGxlYWZUYWdzOm51bGx9Ckgu
+eGIodi50eXBlVW5pdmVyc2UsSlNPTi5wYXJzZSgneyJjNSI6Ik1GIiwiaUMiOiJNRiIsImtkIjoiTUYi
+LCJyeCI6ImVhIiwiZTUiOiJlYSIsIlkwIjoiZDUiLCJ0cCI6ImQ1IiwidjAiOiJldyIsIk1yIjoicUUi
+LCJlTCI6InFFIiwiSTAiOiJ1SCIsImhzIjoidUgiLCJYZyI6IlFGIiwieWMiOiJBaiIsInk0IjoidzYi
+LCJhUCI6IkNtIiwieGMiOiJueCIsImtKIjoibngiLCJ6VSI6IkRnIiwiZGYiOiJFVCIsInlFIjp7ImEy
+IjpbXX0sIllFIjp7ImM4IjpbXX0sIk1GIjp7InZtIjpbXSwiRUgiOltdfSwiamQiOnsiek0iOlsiMSJd
+LCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIlBvIjp7ImpkIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIx
+Il0sImNYIjpbIjEiXX0sIm0xIjp7IkFuIjpbIjEiXX0sInFJIjp7IkNQIjpbXSwiRksiOltdfSwidXIi
+OnsiS04iOltdLCJDUCI6W10sIkZLIjpbXX0sIlZBIjp7IkNQIjpbXSwiRksiOltdfSwiRHIiOnsicVUi
+OltdLCJ2WCI6W119LCJxaiI6eyJSZSI6WyJLTiJdLCJsRCI6WyJLTiJdLCJ6TSI6WyJLTiJdLCJiUSI6
+WyJLTiJdLCJjWCI6WyJLTiJdLCJsRC5FIjoiS04iLCJSZS5FIjoiS04ifSwiYlEiOnsiY1giOlsiMSJd
+fSwiYUwiOnsiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJuSCI6eyJhTCI6WyIxIl0sImJRIjpbIjEiXSwi
+Y1giOlsiMSJdLCJhTC5FIjoiMSIsImNYLkUiOiIxIn0sImE3Ijp7IkFuIjpbIjEiXX0sImkxIjp7ImNY
+IjpbIjIiXSwiY1guRSI6IjIifSwieHkiOnsiaTEiOlsiMSIsIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIy
+Il0sImNYLkUiOiIyIn0sIk1IIjp7IkFuIjpbIjIiXX0sIkE4Ijp7ImFMIjpbIjIiXSwiYlEiOlsiMiJd
+LCJjWCI6WyIyIl0sImFMLkUiOiIyIiwiY1guRSI6IjIifSwiVTUiOnsiY1giOlsiMSJdLCJjWC5FIjoi
+MSJ9LCJTTyI6eyJBbiI6WyIxIl19LCJYQyI6eyJSZSI6WyIxIl0sImxEIjpbIjEiXSwiek0iOlsiMSJd
+LCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sInd2Ijp7IkdEIjpbXX0sIlBEIjp7IkdqIjpbIjEiLCIyIl0s
+IlJVIjpbIjEiLCIyIl0sIlBuIjpbIjEiLCIyIl0sIktQIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19
+LCJXVSI6eyJaMCI6WyIxIiwiMiJdfSwiTFAiOnsiV1UiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0s
+IlhSIjp7ImNYIjpbIjEiXSwiY1guRSI6IjEifSwiTEkiOnsidlEiOltdfSwiVzAiOnsiWFMiOltdfSwi
+YXoiOnsiWFMiOltdfSwidlYiOnsiWFMiOltdfSwiWE8iOnsiR3oiOltdfSwiVHAiOnsiRUgiOltdfSwi
+bGMiOnsiRUgiOltdfSwiengiOnsiRUgiOltdfSwiclQiOnsiRUgiOltdfSwiRXEiOnsiWFMiOltdfSwi
+a1kiOnsiWFMiOltdfSwiTjUiOnsiRm8iOlsiMSIsIjIiXSwiWWsiOlsiMSIsIjIiXSwiWjAiOlsiMSIs
+IjIiXSwiWWsuSyI6IjEiLCJZay5WIjoiMiJ9LCJpNSI6eyJiUSI6WyIxIl0sImNYIjpbIjEiXSwiY1gu
+RSI6IjEifSwiTjYiOnsiQW4iOlsiMSJdfSwiVlIiOnsid0wiOltdLCJ2WCI6W119LCJFSyI6eyJpYiI6
+W10sIk9kIjpbXX0sIktXIjp7ImNYIjpbImliIl0sImNYLkUiOiJpYiJ9LCJQYiI6eyJBbiI6WyJpYiJd
+fSwidFEiOnsiT2QiOltdfSwidW4iOnsiY1giOlsiT2QiXSwiY1guRSI6Ik9kIn0sIlNkIjp7IkFuIjpb
+Ik9kIl19LCJFVCI6eyJBUyI6W119LCJiMCI6eyJYaiI6WyJAIl0sIkVUIjpbXSwiQVMiOltdfSwiRGci
+OnsibEQiOlsiQ1AiXSwiWGoiOlsiQCJdLCJ6TSI6WyJDUCJdLCJFVCI6W10sImJRIjpbIkNQIl0sIlNV
+IjpbIkNQIl0sIkFTIjpbXSwiY1giOlsiQ1AiXSwibEQuRSI6IkNQIn0sIlBnIjp7ImxEIjpbIktOIl0s
+InpNIjpbIktOIl0sIlhqIjpbIkAiXSwiRVQiOltdLCJiUSI6WyJLTiJdLCJTVSI6WyJLTiJdLCJBUyI6
+W10sImNYIjpbIktOIl19LCJ4aiI6eyJsRCI6WyJLTiJdLCJ6TSI6WyJLTiJdLCJYaiI6WyJAIl0sIkVU
+IjpbXSwiYlEiOlsiS04iXSwiU1UiOlsiS04iXSwiQVMiOltdLCJjWCI6WyJLTiJdLCJsRC5FIjoiS04i
+fSwiZEUiOnsibEQiOlsiS04iXSwiek0iOlsiS04iXSwiWGoiOlsiQCJdLCJFVCI6W10sImJRIjpbIktO
+Il0sIlNVIjpbIktOIl0sIkFTIjpbXSwiY1giOlsiS04iXSwibEQuRSI6IktOIn0sIlpBIjp7ImxEIjpb
+IktOIl0sInpNIjpbIktOIl0sIlhqIjpbIkAiXSwiRVQiOltdLCJiUSI6WyJLTiJdLCJTVSI6WyJLTiJd
+LCJBUyI6W10sImNYIjpbIktOIl0sImxELkUiOiJLTiJ9LCJ3ZiI6eyJsRCI6WyJLTiJdLCJ6TSI6WyJL
+TiJdLCJYaiI6WyJAIl0sIkVUIjpbXSwiYlEiOlsiS04iXSwiU1UiOlsiS04iXSwiQVMiOltdLCJjWCI6
+WyJLTiJdLCJsRC5FIjoiS04ifSwiUHEiOnsibEQiOlsiS04iXSwiek0iOlsiS04iXSwiWGoiOlsiQCJd
+LCJFVCI6W10sImJRIjpbIktOIl0sIlNVIjpbIktOIl0sIkFTIjpbXSwiY1giOlsiS04iXSwibEQuRSI6
+IktOIn0sImVFIjp7ImxEIjpbIktOIl0sInpNIjpbIktOIl0sIlhqIjpbIkAiXSwiRVQiOltdLCJiUSI6
+WyJLTiJdLCJTVSI6WyJLTiJdLCJBUyI6W10sImNYIjpbIktOIl0sImxELkUiOiJLTiJ9LCJWNiI6eyJu
+NiI6W10sImxEIjpbIktOIl0sInpNIjpbIktOIl0sIlhqIjpbIkAiXSwiRVQiOltdLCJiUSI6WyJLTiJd
+LCJTVSI6WyJLTiJdLCJBUyI6W10sImNYIjpbIktOIl0sImxELkUiOiJLTiJ9LCJ1OSI6eyJYUyI6W119
+LCJoeiI6eyJYUyI6W119LCJpTSI6eyJYUyI6W119LCJHViI6eyJBbiI6WyIxIl19LCJxNCI6eyJjWCI6
+WyIxIl0sImNYLkUiOiIxIn0sIlpmIjp7IlBmIjpbIjEiXX0sInZzIjp7ImI4IjpbIjEiXX0sIkN3Ijp7
+IlhTIjpbXX0sIm0wIjp7IkpCIjpbXX0sIkppIjp7IkpCIjpbXX0sImI2Ijp7Ilh2IjpbIjEiXSwieHUi
+OlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sImxtIjp7IkFuIjpbIjEiXX0sIm1XIjp7ImNYIjpb
+IjEiXX0sIkxVIjp7ImxEIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sImls
+Ijp7IllrIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJZayI6eyJaMCI6WyIxIiwiMiJdfSwiUG4i
+OnsiWjAiOlsiMSIsIjIiXX0sIkdqIjp7IlJVIjpbIjEiLCIyIl0sIlBuIjpbIjEiLCIyIl0sIktQIjpb
+IjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJWaiI6eyJsZiI6WyIxIl0sInh1IjpbIjEiXSwiYlEiOlsi
+MSJdLCJjWCI6WyIxIl19LCJYdiI6eyJ4dSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdfSwidXci
+OnsiWWsiOlsicVUiLCJAIl0sIlowIjpbInFVIiwiQCJdLCJZay5LIjoicVUiLCJZay5WIjoiQCJ9LCJp
+OCI6eyJhTCI6WyJxVSJdLCJiUSI6WyJxVSJdLCJjWCI6WyJxVSJdLCJhTC5FIjoicVUiLCJjWC5FIjoi
+cVUifSwiQ1YiOnsiVWsiOlsiek08S04+IiwicVUiXSwiVWsuUyI6InpNPEtOPiJ9LCJVOCI6eyJ3SSI6
+WyJ6TTxLTj4iLCJxVSJdfSwiWmkiOnsiVWsiOlsicVUiLCJ6TTxLTj4iXX0sImJ5Ijp7IlVrIjpbImsi
+LCJxVSJdLCJVay5TIjoiayJ9LCJNeCI6eyJ3SSI6WyJxVSIsImsiXX0sInU1Ijp7IlVrIjpbInFVIiwi
+ek08S04+Il0sIlVrLlMiOiJxVSJ9LCJFMyI6eyJ3SSI6WyJxVSIsInpNPEtOPiJdfSwiR1kiOnsid0ki
+Olsiek08S04+IiwicVUiXX0sIkNQIjp7IkZLIjpbXX0sIkM2Ijp7IlhTIjpbXX0sIm4iOnsiWFMiOltd
+fSwidSI6eyJYUyI6W119LCJiSiI6eyJYUyI6W119LCJlWSI6eyJYUyI6W119LCJtcCI6eyJYUyI6W119
+LCJ1YiI6eyJYUyI6W119LCJkcyI6eyJYUyI6W119LCJsaiI6eyJYUyI6W119LCJVViI6eyJYUyI6W119
+LCJrNSI6eyJYUyI6W119LCJLWSI6eyJYUyI6W119LCJjIjp7IlhTIjpbXX0sIktOIjp7IkZLIjpbXX0s
+InpNIjp7ImJRIjpbIjEiXSwiY1giOlsiMSJdfSwiaWIiOnsiT2QiOltdfSwieHUiOnsiYlEiOlsiMSJd
+LCJjWCI6WyIxIl19LCJxVSI6eyJ2WCI6W119LCJSbiI6eyJCTCI6W119LCJEbiI6eyJpRCI6W119LCJV
+ZiI6eyJpRCI6W119LCJxZSI6eyJpRCI6W119LCJxRSI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwi
+R2giOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sImZZIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119
+LCJuQiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiUVAiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpb
+XX0sIm54Ijp7InVIIjpbXSwiRDAiOltdfSwiUUYiOnsidUgiOltdLCJEMCI6W119LCJJQiI6eyJ0biI6
+WyJGSyJdfSwid3oiOnsibEQiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdLCJs
+RC5FIjoiMSJ9LCJjdiI6eyJ1SCI6W10sIkQwIjpbXX0sIlQ1Ijp7IkF6IjpbXX0sImg0Ijp7ImN2Ijpb
+XSwidUgiOltdLCJEMCI6W119LCJWYiI6eyJ1SCI6W10sIkQwIjpbXX0sIk83Ijp7IkQwIjpbXX0sIndh
+Ijp7IkQwIjpbXX0sIkFqIjp7ImVhIjpbXX0sImU3Ijp7ImxEIjpbInVIIl0sInpNIjpbInVIIl0sImJR
+IjpbInVIIl0sImNYIjpbInVIIl0sImxELkUiOiJ1SCJ9LCJ1SCI6eyJEMCI6W119LCJCSCI6eyJHbSI6
+WyJ1SCJdLCJsRCI6WyJ1SCJdLCJ6TSI6WyJ1SCJdLCJYaiI6WyJ1SCJdLCJiUSI6WyJ1SCJdLCJjWCI6
+WyJ1SCJdLCJHbS5FIjoidUgiLCJsRC5FIjoidUgifSwiU04iOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpb
+XX0sImV3Ijp7ImVhIjpbXX0sImxwIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJUYiI6eyJjdiI6
+W10sInVIIjpbXSwiRDAiOltdfSwiSXYiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIldQIjp7ImN2
+IjpbXSwidUgiOltdLCJEMCI6W119LCJ5WSI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwidzYiOnsi
+ZWEiOltdfSwiSzUiOnsidjYiOltdLCJEMCI6W119LCJDbSI6eyJEMCI6W119LCJDUSI6eyJ1SCI6W10s
+IkQwIjpbXX0sInc0Ijp7InRuIjpbIkZLIl19LCJyaCI6eyJHbSI6WyJ1SCJdLCJsRCI6WyJ1SCJdLCJ6
+TSI6WyJ1SCJdLCJYaiI6WyJ1SCJdLCJiUSI6WyJ1SCJdLCJjWCI6WyJ1SCJdLCJHbS5FIjoidUgiLCJs
+RC5FIjoidUgifSwiY2YiOnsiWWsiOlsicVUiLCJxVSJdLCJaMCI6WyJxVSIsInFVIl19LCJpNyI6eyJZ
+ayI6WyJxVSIsInFVIl0sIlowIjpbInFVIiwicVUiXSwiWWsuSyI6InFVIiwiWWsuViI6InFVIn0sIlN5
+Ijp7IllrIjpbInFVIiwicVUiXSwiWjAiOlsicVUiLCJxVSJdLCJZay5LIjoicVUiLCJZay5WIjoicVUi
+fSwiSTQiOnsibGYiOlsicVUiXSwieHUiOlsicVUiXSwiYlEiOlsicVUiXSwiY1giOlsicVUiXX0sIlJP
+Ijp7InFoIjpbIjEiXX0sImV1Ijp7IlJPIjpbIjEiXSwicWgiOlsiMSJdfSwieEMiOnsiTU8iOlsiMSJd
+fSwiSlEiOnsia0YiOltdfSwidkQiOnsia0YiOltdfSwibTYiOnsia0YiOltdfSwiY3QiOnsia0YiOltd
+fSwiT3ciOnsia0YiOltdfSwiVzkiOnsiQW4iOlsiMSJdfSwiZFciOnsidjYiOltdLCJEMCI6W119LCJt
+ayI6eyJ5MCI6W119LCJLbyI6eyJvbiI6W119LCJBcyI6eyJsZiI6WyJxVSJdLCJ4dSI6WyJxVSJdLCJi
+USI6WyJxVSJdLCJjWCI6WyJxVSJdfSwicjciOnsiRTQiOltdfSwiVHoiOnsibEQiOlsiMSJdLCJ6TSI6
+WyIxIl0sImJRIjpbIjEiXSwiRTQiOltdLCJjWCI6WyIxIl0sImxELkUiOiIxIn0sIm5kIjp7ImQ1Ijpb
+XSwiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIktlIjp7ImxmIjpbInFVIl0sInh1IjpbInFVIl0sImJR
+IjpbInFVIl0sImNYIjpbInFVIl19LCJkNSI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwibjYiOnsi
+ek0iOlsiS04iXSwiYlEiOlsiS04iXSwiQVMiOltdLCJjWCI6WyJLTiJdfSwiWEEiOnsia0YiOltdfSwi
+T0YiOnsiZnYiOltdfSwicnUiOnsiZnYiOltdfSwiSVYiOnsiZnYiOltdfX0nKSkKSC5GRih2LnR5cGVV
+bml2ZXJzZSxKU09OLnBhcnNlKCd7ImJRIjoxLCJYQyI6MSwiTU8iOjEsImtUIjoyLCJtVyI6MSwiTFUi
+OjEsImlsIjoyLCJWaiI6MSwiblkiOjEsIlRDIjoxLCJjbyI6MX0nKSkKdmFyIHU9KGZ1bmN0aW9uIHJ0
+aWkoKXt2YXIgdD1ILk4wCnJldHVybnticTp0KCJHaCIpLG46dCgiQ3ciKSxjUjp0KCJuQiIpLGQ6dCgi
+QXoiKSxpOnQoIlFQIiksZ0Y6dCgiUEQ8R0QsQD4iKSxndzp0KCJiUTxAPiIpLGg6dCgiY3YiKSxiVTp0
+KCJYUyIpLEI6dCgiZWEiKSx1OnQoIkQwIiksYzg6dCgiVDUiKSxaOnQoIkVIIiksYzp0KCJiODxAPiIp
+LHI6dCgiTzciKSxJOnQoIlNnIiksbzp0KCJ2USIpLGVoOnQoImNYPHVIPiIpLFg6dCgiY1g8cVU+Iiks
+Ujp0KCJjWDxAPiIpLGZBOnQoImpkPFNlPiIpLGdpOnQoImpkPGo4PiIpLGZoOnQoImpkPFpaPiIpLGs6
+dCgiamQ8a0Y+Iiksczp0KCJqZDxxVT4iKSxoaDp0KCJqZDx5RD4iKSxhSjp0KCJqZDx3Yj4iKSxtOnQo
+ImpkPEA+IiksdDp0KCJqZDxLTj4iKSxlSDp0KCJ2bSIpLGc6dCgiYzUiKSxhVTp0KCJYajxAPiIpLGFt
+OnQoIlR6PEA+IiksZW86dCgiTjU8R0QsQD4iKSx2OnQoIkU0IiksZHo6dCgiaEYiKSxmNDp0KCJ6TTxq
+OD4iKSxhOnQoInpNPHFVPiIpLGo6dCgiek08QD4iKSxMOnQoInpNPEtOPiIpLGFfOnQoInU4IiksUzp0
+KCJaMDxxVSxrPiIpLGY6dCgiWjA8cVUscVU+IiksYjp0KCJaMDxxVSxAPiIpLEc6dCgiWjA8QCxAPiIp
+LGR2OnQoIkE4PHFVLHFVPiIpLGRvOnQoIkE4PHFVLEA+IiksVjp0KCJBaiIpLGREOnQoIkVUIiksYm06
+dCgiVjYiKSxBOnQoInVIIiksZTp0KCJrRiIpLFA6dCgiYzgiKSxLOnQoImsiKSxwOnQoImV3IikscTp0
+KCJ0bjxGSz4iKSxmdjp0KCJ3TCIpLGF2OnQoIkpjIiksZXc6dCgibmQiKSxDOnQoInh1PHFVPiIpLGw6
+dCgiR3oiKSxOOnQoInFVIiksZEc6dCgicVUocVUpIiksZzc6dCgiZDUiKSxmbzp0KCJHRCIpLGFXOnQo
+InlZIiksdzp0KCJBUyIpLGdjOnQoIm42IiksYWs6dCgia2QiKSxXOnQoIkdqPHFVLHFVPiIpLEQ6dCgi
+aUQiKSxjYzp0KCJVNTxxVT4iKSxnNDp0KCJLNSIpLGNpOnQoInY2IiksZzI6dCgiQ20iKSxFOnQoIlpm
+PE83PiIpLGg5OnQoIkNRIiksYWM6dCgiZTciKSxROnQoImV1PEFqPiIpLFQ6dCgid3o8Y3Y+IikseDp0
+KCJGZTxALEA+IiksWTp0KCJ2czxPNz4iKSxfOnQoInZzPEA+IiksZko6dCgidnM8S04+IiksTzp0KCJK
+USIpLEo6dCgiYm4iKSxjSjp0KCJhMiIpLGFsOnQoImEyKGspIiksYkI6dCgiYTIocVUpIiksYmY6dCgi
+YTIoQCkiKSx6OnQoIkAiKSxmTzp0KCJAKCkiKSxVOnQoIkAoZWEpIikseTp0KCJAKGspIiksZXA6dCgi
+QChrLGspIiksRjp0KCJAKGssR3opIiksY2g6dCgiQCh4dTxxVT4pIiksZE86dCgiQChxVSkiKSxiODp0
+KCJAKEAsQCkiKSxlZzp0KCJLTiIpLEg6dCgifiIpLE06dCgifigpIiksYW46dCgifihldykiKSxlQTp0
+KCJ+KHFVLHFVKSIpLGNBOnQoIn4ocVUsQCkiKX19KSgpOyhmdW5jdGlvbiBjb25zdGFudHMoKXt2YXIg
+dD1odW5rSGVscGVycy5tYWtlQ29uc3RMaXN0CkMuUlk9Vy5RUC5wcm90b3R5cGUKQy5CWj1XLlZiLnBy
+b3RvdHlwZQpDLkR0PVcuTzcucHJvdG90eXBlCkMuT2s9Si52Qi5wcm90b3R5cGUKQy5ObT1KLmpkLnBy
+b3RvdHlwZQpDLmpuPUoudXIucHJvdG90eXBlCkMuQ0Q9Si5xSS5wcm90b3R5cGUKQy54Qj1KLkRyLnBy
+b3RvdHlwZQpDLkRHPUouYzUucHJvdG90eXBlCkMuRXg9Vy51OC5wcm90b3R5cGUKQy5MdD1XLlNOLnBy
+b3RvdHlwZQpDLlpRPUouaUMucHJvdG90eXBlCkMuSWU9Vy5UYi5wcm90b3R5cGUKQy52Qj1KLmtkLnBy
+b3RvdHlwZQpDLm9sPVcuSzUucHJvdG90eXBlCkMueTg9bmV3IFAuVTgoKQpDLmg5PW5ldyBQLkNWKCkK
+Qy5PND1mdW5jdGlvbiBnZXRUYWdGYWxsYmFjayhvKSB7CiAgdmFyIHMgPSBPYmplY3QucHJvdG90eXBl
+LnRvU3RyaW5nLmNhbGwobyk7CiAgcmV0dXJuIHMuc3Vic3RyaW5nKDgsIHMubGVuZ3RoIC0gMSk7Cn0K
+Qy5ZcT1mdW5jdGlvbigpIHsKICB2YXIgdG9TdHJpbmdGdW5jdGlvbiA9IE9iamVjdC5wcm90b3R5cGUu
+dG9TdHJpbmc7CiAgZnVuY3Rpb24gZ2V0VGFnKG8pIHsKICAgIHZhciBzID0gdG9TdHJpbmdGdW5jdGlv
+bi5jYWxsKG8pOwogICAgcmV0dXJuIHMuc3Vic3RyaW5nKDgsIHMubGVuZ3RoIC0gMSk7CiAgfQogIGZ1
+bmN0aW9uIGdldFVua25vd25UYWcob2JqZWN0LCB0YWcpIHsKICAgIGlmICgvXkhUTUxbQS1aXS4qRWxl
+bWVudCQvLnRlc3QodGFnKSkgewogICAgICB2YXIgbmFtZSA9IHRvU3RyaW5nRnVuY3Rpb24uY2FsbChv
+YmplY3QpOwogICAgICBpZiAobmFtZSA9PSAiW29iamVjdCBPYmplY3RdIikgcmV0dXJuIG51bGw7CiAg
+ICAgIHJldHVybiAiSFRNTEVsZW1lbnQiOwogICAgfQogIH0KICBmdW5jdGlvbiBnZXRVbmtub3duVGFn
+R2VuZXJpY0Jyb3dzZXIob2JqZWN0LCB0YWcpIHsKICAgIGlmIChzZWxmLkhUTUxFbGVtZW50ICYmIG9i
+amVjdCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSByZXR1cm4gIkhUTUxFbGVtZW50IjsKICAgIHJldHVy
+biBnZXRVbmtub3duVGFnKG9iamVjdCwgdGFnKTsKICB9CiAgZnVuY3Rpb24gcHJvdG90eXBlRm9yVGFn
+KHRhZykgewogICAgaWYgKHR5cGVvZiB3aW5kb3cgPT0gInVuZGVmaW5lZCIpIHJldHVybiBudWxsOwog
+ICAgaWYgKHR5cGVvZiB3aW5kb3dbdGFnXSA9PSAidW5kZWZpbmVkIikgcmV0dXJuIG51bGw7CiAgICB2
+YXIgY29uc3RydWN0b3IgPSB3aW5kb3dbdGFnXTsKICAgIGlmICh0eXBlb2YgY29uc3RydWN0b3IgIT0g
+ImZ1bmN0aW9uIikgcmV0dXJuIG51bGw7CiAgICByZXR1cm4gY29uc3RydWN0b3IucHJvdG90eXBlOwog
+IH0KICBmdW5jdGlvbiBkaXNjcmltaW5hdG9yKHRhZykgeyByZXR1cm4gbnVsbDsgfQogIHZhciBpc0Jy
+b3dzZXIgPSB0eXBlb2YgbmF2aWdhdG9yID09ICJvYmplY3QiOwogIHJldHVybiB7CiAgICBnZXRUYWc6
+IGdldFRhZywKICAgIGdldFVua25vd25UYWc6IGlzQnJvd3NlciA/IGdldFVua25vd25UYWdHZW5lcmlj
+QnJvd3NlciA6IGdldFVua25vd25UYWcsCiAgICBwcm90b3R5cGVGb3JUYWc6IHByb3RvdHlwZUZvclRh
+ZywKICAgIGRpc2NyaW1pbmF0b3I6IGRpc2NyaW1pbmF0b3IgfTsKfQpDLndiPWZ1bmN0aW9uKGdldFRh
+Z0ZhbGxiYWNrKSB7CiAgcmV0dXJuIGZ1bmN0aW9uKGhvb2tzKSB7CiAgICBpZiAodHlwZW9mIG5hdmln
+YXRvciAhPSAib2JqZWN0IikgcmV0dXJuIGhvb2tzOwogICAgdmFyIHVhID0gbmF2aWdhdG9yLnVzZXJB
+Z2VudDsKICAgIGlmICh1YS5pbmRleE9mKCJEdW1wUmVuZGVyVHJlZSIpID49IDApIHJldHVybiBob29r
+czsKICAgIGlmICh1YS5pbmRleE9mKCJDaHJvbWUiKSA+PSAwKSB7CiAgICAgIGZ1bmN0aW9uIGNvbmZp
+cm0ocCkgewogICAgICAgIHJldHVybiB0eXBlb2Ygd2luZG93ID09ICJvYmplY3QiICYmIHdpbmRvd1tw
+XSAmJiB3aW5kb3dbcF0ubmFtZSA9PSBwOwogICAgICB9CiAgICAgIGlmIChjb25maXJtKCJXaW5kb3ci
+KSAmJiBjb25maXJtKCJIVE1MRWxlbWVudCIpKSByZXR1cm4gaG9va3M7CiAgICB9CiAgICBob29rcy5n
+ZXRUYWcgPSBnZXRUYWdGYWxsYmFjazsKICB9Owp9CkMuS1U9ZnVuY3Rpb24oaG9va3MpIHsKICBpZiAo
+dHlwZW9mIGRhcnRFeHBlcmltZW50YWxGaXh1cEdldFRhZyAhPSAiZnVuY3Rpb24iKSByZXR1cm4gaG9v
+a3M7CiAgaG9va3MuZ2V0VGFnID0gZGFydEV4cGVyaW1lbnRhbEZpeHVwR2V0VGFnKGhvb2tzLmdldFRh
+Zyk7Cn0KQy5mUT1mdW5jdGlvbihob29rcykgewogIHZhciBnZXRUYWcgPSBob29rcy5nZXRUYWc7CiAg
+dmFyIHByb3RvdHlwZUZvclRhZyA9IGhvb2tzLnByb3RvdHlwZUZvclRhZzsKICBmdW5jdGlvbiBnZXRU
+YWdGaXhlZChvKSB7CiAgICB2YXIgdGFnID0gZ2V0VGFnKG8pOwogICAgaWYgKHRhZyA9PSAiRG9jdW1l
+bnQiKSB7CiAgICAgIGlmICghIW8ueG1sVmVyc2lvbikgcmV0dXJuICIhRG9jdW1lbnQiOwogICAgICBy
+ZXR1cm4gIiFIVE1MRG9jdW1lbnQiOwogICAgfQogICAgcmV0dXJuIHRhZzsKICB9CiAgZnVuY3Rpb24g
+cHJvdG90eXBlRm9yVGFnRml4ZWQodGFnKSB7CiAgICBpZiAodGFnID09ICJEb2N1bWVudCIpIHJldHVy
+biBudWxsOwogICAgcmV0dXJuIHByb3RvdHlwZUZvclRhZyh0YWcpOwogIH0KICBob29rcy5nZXRUYWcg
+PSBnZXRUYWdGaXhlZDsKICBob29rcy5wcm90b3R5cGVGb3JUYWcgPSBwcm90b3R5cGVGb3JUYWdGaXhl
+ZDsKfQpDLmRrPWZ1bmN0aW9uKGhvb2tzKSB7CiAgdmFyIHVzZXJBZ2VudCA9IHR5cGVvZiBuYXZpZ2F0
+b3IgPT0gIm9iamVjdCIgPyBuYXZpZ2F0b3IudXNlckFnZW50IDogIiI7CiAgaWYgKHVzZXJBZ2VudC5p
+bmRleE9mKCJGaXJlZm94IikgPT0gLTEpIHJldHVybiBob29rczsKICB2YXIgZ2V0VGFnID0gaG9va3Mu
+Z2V0VGFnOwogIHZhciBxdWlja01hcCA9IHsKICAgICJCZWZvcmVVbmxvYWRFdmVudCI6ICJFdmVudCIs
+CiAgICAiRGF0YVRyYW5zZmVyIjogIkNsaXBib2FyZCIsCiAgICAiR2VvR2VvbG9jYXRpb24iOiAiR2Vv
+bG9jYXRpb24iLAogICAgIkxvY2F0aW9uIjogIiFMb2NhdGlvbiIsCiAgICAiV29ya2VyTWVzc2FnZUV2
+ZW50IjogIk1lc3NhZ2VFdmVudCIsCiAgICAiWE1MRG9jdW1lbnQiOiAiIURvY3VtZW50In07CiAgZnVu
+Y3Rpb24gZ2V0VGFnRmlyZWZveChvKSB7CiAgICB2YXIgdGFnID0gZ2V0VGFnKG8pOwogICAgcmV0dXJu
+IHF1aWNrTWFwW3RhZ10gfHwgdGFnOwogIH0KICBob29rcy5nZXRUYWcgPSBnZXRUYWdGaXJlZm94Owp9
+CkMueGk9ZnVuY3Rpb24oaG9va3MpIHsKICB2YXIgdXNlckFnZW50ID0gdHlwZW9mIG5hdmlnYXRvciA9
+PSAib2JqZWN0IiA/IG5hdmlnYXRvci51c2VyQWdlbnQgOiAiIjsKICBpZiAodXNlckFnZW50LmluZGV4
+T2YoIlRyaWRlbnQvIikgPT0gLTEpIHJldHVybiBob29rczsKICB2YXIgZ2V0VGFnID0gaG9va3MuZ2V0
+VGFnOwogIHZhciBxdWlja01hcCA9IHsKICAgICJCZWZvcmVVbmxvYWRFdmVudCI6ICJFdmVudCIsCiAg
+ICAiRGF0YVRyYW5zZmVyIjogIkNsaXBib2FyZCIsCiAgICAiSFRNTERERWxlbWVudCI6ICJIVE1MRWxl
+bWVudCIsCiAgICAiSFRNTERURWxlbWVudCI6ICJIVE1MRWxlbWVudCIsCiAgICAiSFRNTFBocmFzZUVs
+ZW1lbnQiOiAiSFRNTEVsZW1lbnQiLAogICAgIlBvc2l0aW9uIjogIkdlb3Bvc2l0aW9uIgogIH07CiAg
+ZnVuY3Rpb24gZ2V0VGFnSUUobykgewogICAgdmFyIHRhZyA9IGdldFRhZyhvKTsKICAgIHZhciBuZXdU
+YWcgPSBxdWlja01hcFt0YWddOwogICAgaWYgKG5ld1RhZykgcmV0dXJuIG5ld1RhZzsKICAgIGlmICh0
+YWcgPT0gIk9iamVjdCIpIHsKICAgICAgaWYgKHdpbmRvdy5EYXRhVmlldyAmJiAobyBpbnN0YW5jZW9m
+IHdpbmRvdy5EYXRhVmlldykpIHJldHVybiAiRGF0YVZpZXciOwogICAgfQogICAgcmV0dXJuIHRhZzsK
+ICB9CiAgZnVuY3Rpb24gcHJvdG90eXBlRm9yVGFnSUUodGFnKSB7CiAgICB2YXIgY29uc3RydWN0b3Ig
+PSB3aW5kb3dbdGFnXTsKICAgIGlmIChjb25zdHJ1Y3RvciA9PSBudWxsKSByZXR1cm4gbnVsbDsKICAg
+IHJldHVybiBjb25zdHJ1Y3Rvci5wcm90b3R5cGU7CiAgfQogIGhvb2tzLmdldFRhZyA9IGdldFRhZ0lF
+OwogIGhvb2tzLnByb3RvdHlwZUZvclRhZyA9IHByb3RvdHlwZUZvclRhZ0lFOwp9CkMuaTc9ZnVuY3Rp
+b24oaG9va3MpIHsgcmV0dXJuIGhvb2tzOyB9CgpDLkN0PW5ldyBQLmJ5KCkKQy5FcT1uZXcgUC5rNSgp
+CkMueE09bmV3IFAudTUoKQpDLlFrPW5ldyBQLkUzKCkKQy5OVT1uZXcgUC5KaSgpCkMuQTM9bmV3IFAu
+TXgobnVsbCkKQy5HYj1ILlZNKHQoWzEyNywyMDQ3LDY1NTM1LDExMTQxMTFdKSx1LnQpCkMuYWs9SC5W
+TSh0KFswLDAsMzI3NzYsMzM3OTIsMSwxMDI0MCwwLDBdKSx1LnQpCkMuY209SC5WTSh0KFsiKjo6Y2xh
+c3MiLCIqOjpkaXIiLCIqOjpkcmFnZ2FibGUiLCIqOjpoaWRkZW4iLCIqOjppZCIsIio6OmluZXJ0Iiwi
+Kjo6aXRlbXByb3AiLCIqOjppdGVtcmVmIiwiKjo6aXRlbXNjb3BlIiwiKjo6bGFuZyIsIio6OnNwZWxs
+Y2hlY2siLCIqOjp0aXRsZSIsIio6OnRyYW5zbGF0ZSIsIkE6OmFjY2Vzc2tleSIsIkE6OmNvb3JkcyIs
+IkE6OmhyZWZsYW5nIiwiQTo6bmFtZSIsIkE6OnNoYXBlIiwiQTo6dGFiaW5kZXgiLCJBOjp0YXJnZXQi
+LCJBOjp0eXBlIiwiQVJFQTo6YWNjZXNza2V5IiwiQVJFQTo6YWx0IiwiQVJFQTo6Y29vcmRzIiwiQVJF
+QTo6bm9ocmVmIiwiQVJFQTo6c2hhcGUiLCJBUkVBOjp0YWJpbmRleCIsIkFSRUE6OnRhcmdldCIsIkFV
+RElPOjpjb250cm9scyIsIkFVRElPOjpsb29wIiwiQVVESU86Om1lZGlhZ3JvdXAiLCJBVURJTzo6bXV0
+ZWQiLCJBVURJTzo6cHJlbG9hZCIsIkJETzo6ZGlyIiwiQk9EWTo6YWxpbmsiLCJCT0RZOjpiZ2NvbG9y
+IiwiQk9EWTo6bGluayIsIkJPRFk6OnRleHQiLCJCT0RZOjp2bGluayIsIkJSOjpjbGVhciIsIkJVVFRP
+Tjo6YWNjZXNza2V5IiwiQlVUVE9OOjpkaXNhYmxlZCIsIkJVVFRPTjo6bmFtZSIsIkJVVFRPTjo6dGFi
+aW5kZXgiLCJCVVRUT046OnR5cGUiLCJCVVRUT046OnZhbHVlIiwiQ0FOVkFTOjpoZWlnaHQiLCJDQU5W
+QVM6OndpZHRoIiwiQ0FQVElPTjo6YWxpZ24iLCJDT0w6OmFsaWduIiwiQ09MOjpjaGFyIiwiQ09MOjpj
+aGFyb2ZmIiwiQ09MOjpzcGFuIiwiQ09MOjp2YWxpZ24iLCJDT0w6OndpZHRoIiwiQ09MR1JPVVA6OmFs
+aWduIiwiQ09MR1JPVVA6OmNoYXIiLCJDT0xHUk9VUDo6Y2hhcm9mZiIsIkNPTEdST1VQOjpzcGFuIiwi
+Q09MR1JPVVA6OnZhbGlnbiIsIkNPTEdST1VQOjp3aWR0aCIsIkNPTU1BTkQ6OmNoZWNrZWQiLCJDT01N
+QU5EOjpjb21tYW5kIiwiQ09NTUFORDo6ZGlzYWJsZWQiLCJDT01NQU5EOjpsYWJlbCIsIkNPTU1BTkQ6
+OnJhZGlvZ3JvdXAiLCJDT01NQU5EOjp0eXBlIiwiREFUQTo6dmFsdWUiLCJERUw6OmRhdGV0aW1lIiwi
+REVUQUlMUzo6b3BlbiIsIkRJUjo6Y29tcGFjdCIsIkRJVjo6YWxpZ24iLCJETDo6Y29tcGFjdCIsIkZJ
+RUxEU0VUOjpkaXNhYmxlZCIsIkZPTlQ6OmNvbG9yIiwiRk9OVDo6ZmFjZSIsIkZPTlQ6OnNpemUiLCJG
+T1JNOjphY2NlcHQiLCJGT1JNOjphdXRvY29tcGxldGUiLCJGT1JNOjplbmN0eXBlIiwiRk9STTo6bWV0
+aG9kIiwiRk9STTo6bmFtZSIsIkZPUk06Om5vdmFsaWRhdGUiLCJGT1JNOjp0YXJnZXQiLCJGUkFNRTo6
+bmFtZSIsIkgxOjphbGlnbiIsIkgyOjphbGlnbiIsIkgzOjphbGlnbiIsIkg0OjphbGlnbiIsIkg1Ojph
+bGlnbiIsIkg2OjphbGlnbiIsIkhSOjphbGlnbiIsIkhSOjpub3NoYWRlIiwiSFI6OnNpemUiLCJIUjo6
+d2lkdGgiLCJIVE1MOjp2ZXJzaW9uIiwiSUZSQU1FOjphbGlnbiIsIklGUkFNRTo6ZnJhbWVib3JkZXIi
+LCJJRlJBTUU6OmhlaWdodCIsIklGUkFNRTo6bWFyZ2luaGVpZ2h0IiwiSUZSQU1FOjptYXJnaW53aWR0
+aCIsIklGUkFNRTo6d2lkdGgiLCJJTUc6OmFsaWduIiwiSU1HOjphbHQiLCJJTUc6OmJvcmRlciIsIklN
+Rzo6aGVpZ2h0IiwiSU1HOjpoc3BhY2UiLCJJTUc6OmlzbWFwIiwiSU1HOjpuYW1lIiwiSU1HOjp1c2Vt
+YXAiLCJJTUc6OnZzcGFjZSIsIklNRzo6d2lkdGgiLCJJTlBVVDo6YWNjZXB0IiwiSU5QVVQ6OmFjY2Vz
+c2tleSIsIklOUFVUOjphbGlnbiIsIklOUFVUOjphbHQiLCJJTlBVVDo6YXV0b2NvbXBsZXRlIiwiSU5Q
+VVQ6OmF1dG9mb2N1cyIsIklOUFVUOjpjaGVja2VkIiwiSU5QVVQ6OmRpc2FibGVkIiwiSU5QVVQ6Omlu
+cHV0bW9kZSIsIklOUFVUOjppc21hcCIsIklOUFVUOjpsaXN0IiwiSU5QVVQ6Om1heCIsIklOUFVUOjpt
+YXhsZW5ndGgiLCJJTlBVVDo6bWluIiwiSU5QVVQ6Om11bHRpcGxlIiwiSU5QVVQ6Om5hbWUiLCJJTlBV
+VDo6cGxhY2Vob2xkZXIiLCJJTlBVVDo6cmVhZG9ubHkiLCJJTlBVVDo6cmVxdWlyZWQiLCJJTlBVVDo6
+c2l6ZSIsIklOUFVUOjpzdGVwIiwiSU5QVVQ6OnRhYmluZGV4IiwiSU5QVVQ6OnR5cGUiLCJJTlBVVDo6
+dXNlbWFwIiwiSU5QVVQ6OnZhbHVlIiwiSU5TOjpkYXRldGltZSIsIktFWUdFTjo6ZGlzYWJsZWQiLCJL
+RVlHRU46OmtleXR5cGUiLCJLRVlHRU46Om5hbWUiLCJMQUJFTDo6YWNjZXNza2V5IiwiTEFCRUw6OmZv
+ciIsIkxFR0VORDo6YWNjZXNza2V5IiwiTEVHRU5EOjphbGlnbiIsIkxJOjp0eXBlIiwiTEk6OnZhbHVl
+IiwiTElOSzo6c2l6ZXMiLCJNQVA6Om5hbWUiLCJNRU5VOjpjb21wYWN0IiwiTUVOVTo6bGFiZWwiLCJN
+RU5VOjp0eXBlIiwiTUVURVI6OmhpZ2giLCJNRVRFUjo6bG93IiwiTUVURVI6Om1heCIsIk1FVEVSOjpt
+aW4iLCJNRVRFUjo6dmFsdWUiLCJPQkpFQ1Q6OnR5cGVtdXN0bWF0Y2giLCJPTDo6Y29tcGFjdCIsIk9M
+OjpyZXZlcnNlZCIsIk9MOjpzdGFydCIsIk9MOjp0eXBlIiwiT1BUR1JPVVA6OmRpc2FibGVkIiwiT1BU
+R1JPVVA6OmxhYmVsIiwiT1BUSU9OOjpkaXNhYmxlZCIsIk9QVElPTjo6bGFiZWwiLCJPUFRJT046OnNl
+bGVjdGVkIiwiT1BUSU9OOjp2YWx1ZSIsIk9VVFBVVDo6Zm9yIiwiT1VUUFVUOjpuYW1lIiwiUDo6YWxp
+Z24iLCJQUkU6OndpZHRoIiwiUFJPR1JFU1M6Om1heCIsIlBST0dSRVNTOjptaW4iLCJQUk9HUkVTUzo6
+dmFsdWUiLCJTRUxFQ1Q6OmF1dG9jb21wbGV0ZSIsIlNFTEVDVDo6ZGlzYWJsZWQiLCJTRUxFQ1Q6Om11
+bHRpcGxlIiwiU0VMRUNUOjpuYW1lIiwiU0VMRUNUOjpyZXF1aXJlZCIsIlNFTEVDVDo6c2l6ZSIsIlNF
+TEVDVDo6dGFiaW5kZXgiLCJTT1VSQ0U6OnR5cGUiLCJUQUJMRTo6YWxpZ24iLCJUQUJMRTo6Ymdjb2xv
+ciIsIlRBQkxFOjpib3JkZXIiLCJUQUJMRTo6Y2VsbHBhZGRpbmciLCJUQUJMRTo6Y2VsbHNwYWNpbmci
+LCJUQUJMRTo6ZnJhbWUiLCJUQUJMRTo6cnVsZXMiLCJUQUJMRTo6c3VtbWFyeSIsIlRBQkxFOjp3aWR0
+aCIsIlRCT0RZOjphbGlnbiIsIlRCT0RZOjpjaGFyIiwiVEJPRFk6OmNoYXJvZmYiLCJUQk9EWTo6dmFs
+aWduIiwiVEQ6OmFiYnIiLCJURDo6YWxpZ24iLCJURDo6YXhpcyIsIlREOjpiZ2NvbG9yIiwiVEQ6OmNo
+YXIiLCJURDo6Y2hhcm9mZiIsIlREOjpjb2xzcGFuIiwiVEQ6OmhlYWRlcnMiLCJURDo6aGVpZ2h0Iiwi
+VEQ6Om5vd3JhcCIsIlREOjpyb3dzcGFuIiwiVEQ6OnNjb3BlIiwiVEQ6OnZhbGlnbiIsIlREOjp3aWR0
+aCIsIlRFWFRBUkVBOjphY2Nlc3NrZXkiLCJURVhUQVJFQTo6YXV0b2NvbXBsZXRlIiwiVEVYVEFSRUE6
+OmNvbHMiLCJURVhUQVJFQTo6ZGlzYWJsZWQiLCJURVhUQVJFQTo6aW5wdXRtb2RlIiwiVEVYVEFSRUE6
+Om5hbWUiLCJURVhUQVJFQTo6cGxhY2Vob2xkZXIiLCJURVhUQVJFQTo6cmVhZG9ubHkiLCJURVhUQVJF
+QTo6cmVxdWlyZWQiLCJURVhUQVJFQTo6cm93cyIsIlRFWFRBUkVBOjp0YWJpbmRleCIsIlRFWFRBUkVB
+Ojp3cmFwIiwiVEZPT1Q6OmFsaWduIiwiVEZPT1Q6OmNoYXIiLCJURk9PVDo6Y2hhcm9mZiIsIlRGT09U
+Ojp2YWxpZ24iLCJUSDo6YWJiciIsIlRIOjphbGlnbiIsIlRIOjpheGlzIiwiVEg6OmJnY29sb3IiLCJU
+SDo6Y2hhciIsIlRIOjpjaGFyb2ZmIiwiVEg6OmNvbHNwYW4iLCJUSDo6aGVhZGVycyIsIlRIOjpoZWln
+aHQiLCJUSDo6bm93cmFwIiwiVEg6OnJvd3NwYW4iLCJUSDo6c2NvcGUiLCJUSDo6dmFsaWduIiwiVEg6
+OndpZHRoIiwiVEhFQUQ6OmFsaWduIiwiVEhFQUQ6OmNoYXIiLCJUSEVBRDo6Y2hhcm9mZiIsIlRIRUFE
+Ojp2YWxpZ24iLCJUUjo6YWxpZ24iLCJUUjo6Ymdjb2xvciIsIlRSOjpjaGFyIiwiVFI6OmNoYXJvZmYi
+LCJUUjo6dmFsaWduIiwiVFJBQ0s6OmRlZmF1bHQiLCJUUkFDSzo6a2luZCIsIlRSQUNLOjpsYWJlbCIs
+IlRSQUNLOjpzcmNsYW5nIiwiVUw6OmNvbXBhY3QiLCJVTDo6dHlwZSIsIlZJREVPOjpjb250cm9scyIs
+IlZJREVPOjpoZWlnaHQiLCJWSURFTzo6bG9vcCIsIlZJREVPOjptZWRpYWdyb3VwIiwiVklERU86Om11
+dGVkIiwiVklERU86OnByZWxvYWQiLCJWSURFTzo6d2lkdGgiXSksdS5zKQpDLlZDPUguVk0odChbMCww
+LDY1NDkwLDQ1MDU1LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMxXSksdS50KQpDLm1LPUguVk0odChbMCww
+LDI2NjI0LDEwMjMsNjU1MzQsMjA0Nyw2NTUzNCwyMDQ3XSksdS50KQpDLlNxPUguVk0odChbIkhFQUQi
+LCJBUkVBIiwiQkFTRSIsIkJBU0VGT05UIiwiQlIiLCJDT0wiLCJDT0xHUk9VUCIsIkVNQkVEIiwiRlJB
+TUUiLCJGUkFNRVNFVCIsIkhSIiwiSU1BR0UiLCJJTUciLCJJTlBVVCIsIklTSU5ERVgiLCJMSU5LIiwi
+TUVUQSIsIlBBUkFNIiwiU09VUkNFIiwiU1RZTEUiLCJUSVRMRSIsIldCUiJdKSx1LnMpCkMueEQ9SC5W
+TSh0KFtdKSx1LnMpCkMuZG49SC5WTSh0KFtdKSx1Lm0pCkMudG89SC5WTSh0KFswLDAsMzI3MjIsMTIy
+ODcsNjU1MzQsMzQ4MTUsNjU1MzQsMTg0MzFdKSx1LnQpCkMuRjM9SC5WTSh0KFswLDAsMjQ1NzYsMTAy
+Myw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5lYT1ILlZNKHQoWzAsMCwzMjc1NCwxMTI2
+Myw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5aSj1ILlZNKHQoWzAsMCwzMjcyMiwxMjI4
+Nyw2NTUzNSwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5XZD1ILlZNKHQoWzAsMCw2NTQ5MCwxMjI4
+Nyw2NTUzNSwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5ReD1ILlZNKHQoWyJiaW5kIiwiaWYiLCJy
+ZWYiLCJyZXBlYXQiLCJzeW50YXgiXSksdS5zKQpDLkJJPUguVk0odChbIkE6OmhyZWYiLCJBUkVBOjpo
+cmVmIiwiQkxPQ0tRVU9URTo6Y2l0ZSIsIkJPRFk6OmJhY2tncm91bmQiLCJDT01NQU5EOjppY29uIiwi
+REVMOjpjaXRlIiwiRk9STTo6YWN0aW9uIiwiSU1HOjpzcmMiLCJJTlBVVDo6c3JjIiwiSU5TOjpjaXRl
+IiwiUTo6Y2l0ZSIsIlZJREVPOjpwb3N0ZXIiXSksdS5zKQpDLkNNPW5ldyBILkxQKDAse30sQy54RCxI
+Lk4wKCJMUDxxVSx6TTxqOD4+IikpCkMuV089bmV3IEguTFAoMCx7fSxDLnhELEguTjAoIkxQPHFVLHFV
+PiIpKQpDLmhVPUguVk0odChbXSksSC5OMCgiamQ8R0Q+IikpCkMuRHg9bmV3IEguTFAoMCx7fSxDLmhV
+LEguTjAoIkxQPEdELEA+IikpCkMuWTI9bmV3IEwuTzkoIk5hdmlnYXRpb25UcmVlTm9kZVR5cGUuZGly
+ZWN0b3J5IikKQy5yZj1uZXcgTC5POSgiTmF2aWdhdGlvblRyZWVOb2RlVHlwZS5maWxlIikKQy5UZT1u
+ZXcgSC53digiY2FsbCIpCkMud1E9bmV3IFAuRnkobnVsbCwyKX0pKCk7KGZ1bmN0aW9uIHN0YXRpY0Zp
+ZWxkcygpeyQueWo9MAokLm1KPW51bGwKJC5QND1udWxsCiQuTkY9bnVsbAokLlRYPW51bGwKJC54Nz1u
+dWxsCiQubnc9bnVsbAokLnZ2PW51bGwKJC5Cdj1udWxsCiQuUzY9bnVsbAokLms4PW51bGwKJC5tZz1u
+dWxsCiQuVUQ9ITEKJC5YMz1DLk5VCiQueGc9W10KJC54bz1udWxsCiQuQk89bnVsbAokLmx0PW51bGwK
+JC5FVT1udWxsCiQub3I9UC5GbCh1Lk4sdS5aKQokLkk2PW51bGwKJC5GZj1udWxsfSkoKTsoZnVuY3Rp
+b24gbGF6eUluaXRpYWxpemVycygpe3ZhciB0PWh1bmtIZWxwZXJzLmxhenkKdCgkLCJmYSIsInciLGZ1
+bmN0aW9uKCl7cmV0dXJuIEguWWcoIl8kZGFydF9kYXJ0Q2xvc3VyZSIpfSkKdCgkLCJZMiIsIlVOIixm
+dW5jdGlvbigpe3JldHVybiBILllnKCJfJGRhcnRfanMiKX0pCnQoJCwiVTIiLCJTbiIsZnVuY3Rpb24o
+KXtyZXR1cm4gSC5jTShILlM3KHsKdG9TdHJpbmc6ZnVuY3Rpb24oKXtyZXR1cm4iJHJlY2VpdmVyJCJ9
+fSkpfSkKdCgkLCJ4cSIsImxxIixmdW5jdGlvbigpe3JldHVybiBILmNNKEguUzcoeyRtZXRob2QkOm51
+bGwsCnRvU3RyaW5nOmZ1bmN0aW9uKCl7cmV0dXJuIiRyZWNlaXZlciQifX0pKX0pCnQoJCwiUjEiLCJO
+OSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KG51bGwpKX0pCnQoJCwiZk4iLCJpSSIsZnVuY3Rp
+b24oKXtyZXR1cm4gSC5jTShmdW5jdGlvbigpe3ZhciAkYXJndW1lbnRzRXhwciQ9JyRhcmd1bWVudHMk
+Jwp0cnl7bnVsbC4kbWV0aG9kJCgkYXJndW1lbnRzRXhwciQpfWNhdGNoKHMpe3JldHVybiBzLm1lc3Nh
+Z2V9fSgpKX0pCnQoJCwicWkiLCJLZiIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KHZvaWQgMCkp
+fSkKdCgkLCJyWiIsIlpoIixmdW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9uKCl7dmFyICRhcmd1
+bWVudHNFeHByJD0nJGFyZ3VtZW50cyQnCnRyeXsodm9pZCAwKS4kbWV0aG9kJCgkYXJndW1lbnRzRXhw
+ciQpfWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fSgpKX0pCnQoJCwia3EiLCJyTiIsZnVuY3Rpb24o
+KXtyZXR1cm4gSC5jTShILk1qKG51bGwpKX0pCnQoJCwidHQiLCJjMyIsZnVuY3Rpb24oKXtyZXR1cm4g
+SC5jTShmdW5jdGlvbigpe3RyeXtudWxsLiRtZXRob2QkfWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9
+fSgpKX0pCnQoJCwiZHQiLCJISyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILk1qKHZvaWQgMCkpfSkK
+dCgkLCJBNyIsInIxIixmdW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9uKCl7dHJ5eyh2b2lkIDAp
+LiRtZXRob2QkfWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fSgpKX0pCnQoJCwiV2MiLCJ1dCIsZnVu
+Y3Rpb24oKXtyZXR1cm4gUC5PaigpfSkKdCgkLCJraCIsInJmIixmdW5jdGlvbigpe3JldHVybiBQLldJ
+KCl9KQp0KCQsImJ0IiwiVjciLGZ1bmN0aW9uKCl7cmV0dXJuIEguRFEoSC5YRihILlZNKFstMiwtMiwt
+MiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwt
+MiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMSwtMiwtMiwtMiwtMiwt
+Miw2MiwtMiw2MiwtMiw2Myw1Miw1Myw1NCw1NSw1Niw1Nyw1OCw1OSw2MCw2MSwtMiwtMiwtMiwtMSwt
+MiwtMiwtMiwwLDEsMiwzLDQsNSw2LDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5LDIw
+LDIxLDIyLDIzLDI0LDI1LC0yLC0yLC0yLC0yLDYzLC0yLDI2LDI3LDI4LDI5LDMwLDMxLDMyLDMzLDM0
+LDM1LDM2LDM3LDM4LDM5LDQwLDQxLDQyLDQzLDQ0LDQ1LDQ2LDQ3LDQ4LDQ5LDUwLDUxLC0yLC0yLC0y
+LC0yLC0yXSx1LnQpKSl9KQp0KCQsIk01Iiwid1EiLGZ1bmN0aW9uKCl7cmV0dXJuIHR5cGVvZiBwcm9j
+ZXNzIT0idW5kZWZpbmVkIiYmT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHByb2Nlc3MpPT0i
+W29iamVjdCBwcm9jZXNzXSImJnByb2Nlc3MucGxhdGZvcm09PSJ3aW4zMiJ9KQp0KCQsIm1mIiwiejQi
+LGZ1bmN0aW9uKCl7cmV0dXJuIFAubnUoIl5bXFwtXFwuMC05QS1aX2Eten5dKiQiKX0pCnQoJCwiSkci
+LCJ2WiIsZnVuY3Rpb24oKXtyZXR1cm4gUC51eCgpfSkKdCgkLCJTQyIsIkFOIixmdW5jdGlvbigpe3Jl
+dHVybiBQLnRNKFsiQSIsIkFCQlIiLCJBQ1JPTllNIiwiQUREUkVTUyIsIkFSRUEiLCJBUlRJQ0xFIiwi
+QVNJREUiLCJBVURJTyIsIkIiLCJCREkiLCJCRE8iLCJCSUciLCJCTE9DS1FVT1RFIiwiQlIiLCJCVVRU
+T04iLCJDQU5WQVMiLCJDQVBUSU9OIiwiQ0VOVEVSIiwiQ0lURSIsIkNPREUiLCJDT0wiLCJDT0xHUk9V
+UCIsIkNPTU1BTkQiLCJEQVRBIiwiREFUQUxJU1QiLCJERCIsIkRFTCIsIkRFVEFJTFMiLCJERk4iLCJE
+SVIiLCJESVYiLCJETCIsIkRUIiwiRU0iLCJGSUVMRFNFVCIsIkZJR0NBUFRJT04iLCJGSUdVUkUiLCJG
+T05UIiwiRk9PVEVSIiwiRk9STSIsIkgxIiwiSDIiLCJIMyIsIkg0IiwiSDUiLCJINiIsIkhFQURFUiIs
+IkhHUk9VUCIsIkhSIiwiSSIsIklGUkFNRSIsIklNRyIsIklOUFVUIiwiSU5TIiwiS0JEIiwiTEFCRUwi
+LCJMRUdFTkQiLCJMSSIsIk1BUCIsIk1BUksiLCJNRU5VIiwiTUVURVIiLCJOQVYiLCJOT0JSIiwiT0wi
+LCJPUFRHUk9VUCIsIk9QVElPTiIsIk9VVFBVVCIsIlAiLCJQUkUiLCJQUk9HUkVTUyIsIlEiLCJTIiwi
+U0FNUCIsIlNFQ1RJT04iLCJTRUxFQ1QiLCJTTUFMTCIsIlNPVVJDRSIsIlNQQU4iLCJTVFJJS0UiLCJT
+VFJPTkciLCJTVUIiLCJTVU1NQVJZIiwiU1VQIiwiVEFCTEUiLCJUQk9EWSIsIlREIiwiVEVYVEFSRUEi
+LCJURk9PVCIsIlRIIiwiVEhFQUQiLCJUSU1FIiwiVFIiLCJUUkFDSyIsIlRUIiwiVSIsIlVMIiwiVkFS
+IiwiVklERU8iLCJXQlIiXSx1Lk4pfSkKdCgkLCJYNCIsImhHIixmdW5jdGlvbigpe3JldHVybiBQLm51
+KCJeXFxTKyQiKX0pCnQoJCwid08iLCJvdyIsZnVuY3Rpb24oKXtyZXR1cm4gdS52LmIoUC5ORChzZWxm
+KSl9KQp0KCQsImt0IiwiUjgiLGZ1bmN0aW9uKCl7cmV0dXJuIEguWWcoIl8kZGFydF9kYXJ0T2JqZWN0
+Iil9KQp0KCQsImZLIiwia0kiLGZ1bmN0aW9uKCl7cmV0dXJuIGZ1bmN0aW9uIERhcnRPYmplY3QoYSl7
+dGhpcy5vPWF9fSkKdCgkLCJxdCIsInpCIixmdW5jdGlvbigpe3JldHVybiBuZXcgVC5tUSgpfSkKdCgk
+LCJPbCIsIlVFIixmdW5jdGlvbigpe3JldHVybiBQLmhLKEMub2wuZ21XKFcueDMoKSkuaHJlZikuZ2hZ
+KCkucSgwLCJhdXRoVG9rZW4iKX0pCnQoJCwiaFQiLCJ5UCIsZnVuY3Rpb24oKXtyZXR1cm4gVy5acigp
+LnF1ZXJ5U2VsZWN0b3IoIi5lZGl0LWxpc3QgLnBhbmVsLWNvbnRlbnQiKX0pCnQoJCwiVzYiLCJoTCIs
+ZnVuY3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5U2VsZWN0b3IoIi5lZGl0LXBhbmVsIC5wYW5lbC1j
+b250ZW50Iil9KQp0KCQsIlRSIiwiRFciLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVj
+dG9yKCJmb290ZXIiKX0pCnQoJCwiRVkiLCJmaSIsZnVuY3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5
+U2VsZWN0b3IoImhlYWRlciIpfSkKdCgkLCJhdiIsIkQ5IixmdW5jdGlvbigpe3JldHVybiBXLlpyKCku
+cXVlcnlTZWxlY3RvcigiI3VuaXQtbmFtZSIpfSkKdCgkLCJmZSIsIktHIixmdW5jdGlvbigpe3JldHVy
+biBuZXcgTC5YQSgpfSkKdCgkLCJtTSIsIm5VIixmdW5jdGlvbigpe3JldHVybiBuZXcgTS5sSSgkLkhr
+KCkpfSkKdCgkLCJ5ciIsImJEIixmdW5jdGlvbigpe3JldHVybiBuZXcgRS5PRihQLm51KCIvIiksUC5u
+dSgiW14vXSQiKSxQLm51KCJeLyIpKX0pCnQoJCwiTWsiLCJLayIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3
+IEwuSVYoUC5udSgiWy9cXFxcXSIpLFAubnUoIlteL1xcXFxdJCIpLFAubnUoIl4oXFxcXFxcXFxbXlxc
+XFxdK1xcXFxbXlxcXFwvXSt8W2EtekEtWl06Wy9cXFxcXSkiKSxQLm51KCJeWy9cXFxcXSg/IVsvXFxc
+XF0pIikpfSkKdCgkLCJhayIsIkViIixmdW5jdGlvbigpe3JldHVybiBuZXcgRi5ydShQLm51KCIvIiks
+UC5udSgiKF5bYS16QS1aXVstKy5hLXpBLVpcXGRdKjovL3xbXi9dKSQiKSxQLm51KCJbYS16QS1aXVst
+Ky5hLXpBLVpcXGRdKjovL1teL10qIiksUC5udSgiXi8iKSl9KQp0KCQsImxzIiwiSGsiLGZ1bmN0aW9u
+KCl7cmV0dXJuIE8uUmgoKX0pfSkoKTsoZnVuY3Rpb24gbmF0aXZlU3VwcG9ydCgpeyFmdW5jdGlvbigp
+e3ZhciB0PWZ1bmN0aW9uKGEpe3ZhciBuPXt9Cm5bYV09MQpyZXR1cm4gT2JqZWN0LmtleXMoaHVua0hl
+bHBlcnMuY29udmVydFRvRmFzdE9iamVjdChuKSlbMF19CnYuZ2V0SXNvbGF0ZVRhZz1mdW5jdGlvbihh
+KXtyZXR1cm4gdCgiX19fZGFydF8iK2Erdi5pc29sYXRlVGFnKX0KdmFyIHM9Il9fX2RhcnRfaXNvbGF0
+ZV90YWdzXyIKdmFyIHI9T2JqZWN0W3NdfHwoT2JqZWN0W3NdPU9iamVjdC5jcmVhdGUobnVsbCkpCnZh
+ciBxPSJfWnhZeFgiCmZvcih2YXIgcD0wOztwKyspe3ZhciBvPXQocSsiXyIrcCsiXyIpCmlmKCEobyBp
+biByKSl7cltvXT0xCnYuaXNvbGF0ZVRhZz1vCmJyZWFrfX12LmRpc3BhdGNoUHJvcGVydHlOYW1lPXYu
+Z2V0SXNvbGF0ZVRhZygiZGlzcGF0Y2hfcmVjb3JkIil9KCkKaHVua0hlbHBlcnMuc2V0T3JVcGRhdGVJ
+bnRlcmNlcHRvcnNCeVRhZyh7RE9NRXJyb3I6Si52QixET01JbXBsZW1lbnRhdGlvbjpKLnZCLE1lZGlh
+RXJyb3I6Si52QixOYXZpZ2F0b3I6Si52QixOYXZpZ2F0b3JDb25jdXJyZW50SGFyZHdhcmU6Si52QixO
+YXZpZ2F0b3JVc2VyTWVkaWFFcnJvcjpKLnZCLE92ZXJjb25zdHJhaW5lZEVycm9yOkoudkIsUG9zaXRp
+b25FcnJvcjpKLnZCLFJhbmdlOkoudkIsU1FMRXJyb3I6Si52QixEYXRhVmlldzpILkVULEFycmF5QnVm
+ZmVyVmlldzpILkVULEZsb2F0MzJBcnJheTpILkRnLEZsb2F0NjRBcnJheTpILkRnLEludDE2QXJyYXk6
+SC54aixJbnQzMkFycmF5OkguZEUsSW50OEFycmF5OkguWkEsVWludDE2QXJyYXk6SC53ZixVaW50MzJB
+cnJheTpILlBxLFVpbnQ4Q2xhbXBlZEFycmF5OkguZUUsQ2FudmFzUGl4ZWxBcnJheTpILmVFLFVpbnQ4
+QXJyYXk6SC5WNixIVE1MQXVkaW9FbGVtZW50OlcucUUsSFRNTEJSRWxlbWVudDpXLnFFLEhUTUxCdXR0
+b25FbGVtZW50OlcucUUsSFRNTENhbnZhc0VsZW1lbnQ6Vy5xRSxIVE1MQ29udGVudEVsZW1lbnQ6Vy5x
+RSxIVE1MRExpc3RFbGVtZW50OlcucUUsSFRNTERhdGFFbGVtZW50OlcucUUsSFRNTERhdGFMaXN0RWxl
+bWVudDpXLnFFLEhUTUxEZXRhaWxzRWxlbWVudDpXLnFFLEhUTUxEaWFsb2dFbGVtZW50OlcucUUsSFRN
+TERpdkVsZW1lbnQ6Vy5xRSxIVE1MRW1iZWRFbGVtZW50OlcucUUsSFRNTEZpZWxkU2V0RWxlbWVudDpX
+LnFFLEhUTUxIUkVsZW1lbnQ6Vy5xRSxIVE1MSGVhZEVsZW1lbnQ6Vy5xRSxIVE1MSGVhZGluZ0VsZW1l
+bnQ6Vy5xRSxIVE1MSHRtbEVsZW1lbnQ6Vy5xRSxIVE1MSUZyYW1lRWxlbWVudDpXLnFFLEhUTUxJbWFn
+ZUVsZW1lbnQ6Vy5xRSxIVE1MSW5wdXRFbGVtZW50OlcucUUsSFRNTExJRWxlbWVudDpXLnFFLEhUTUxM
+YWJlbEVsZW1lbnQ6Vy5xRSxIVE1MTGVnZW5kRWxlbWVudDpXLnFFLEhUTUxMaW5rRWxlbWVudDpXLnFF
+LEhUTUxNYXBFbGVtZW50OlcucUUsSFRNTE1lZGlhRWxlbWVudDpXLnFFLEhUTUxNZW51RWxlbWVudDpX
+LnFFLEhUTUxNZXRhRWxlbWVudDpXLnFFLEhUTUxNZXRlckVsZW1lbnQ6Vy5xRSxIVE1MTW9kRWxlbWVu
+dDpXLnFFLEhUTUxPTGlzdEVsZW1lbnQ6Vy5xRSxIVE1MT2JqZWN0RWxlbWVudDpXLnFFLEhUTUxPcHRH
+cm91cEVsZW1lbnQ6Vy5xRSxIVE1MT3B0aW9uRWxlbWVudDpXLnFFLEhUTUxPdXRwdXRFbGVtZW50Olcu
+cUUsSFRNTFBhcmFtRWxlbWVudDpXLnFFLEhUTUxQaWN0dXJlRWxlbWVudDpXLnFFLEhUTUxQcmVFbGVt
+ZW50OlcucUUsSFRNTFByb2dyZXNzRWxlbWVudDpXLnFFLEhUTUxRdW90ZUVsZW1lbnQ6Vy5xRSxIVE1M
+U2NyaXB0RWxlbWVudDpXLnFFLEhUTUxTaGFkb3dFbGVtZW50OlcucUUsSFRNTFNsb3RFbGVtZW50Olcu
+cUUsSFRNTFNvdXJjZUVsZW1lbnQ6Vy5xRSxIVE1MU3BhbkVsZW1lbnQ6Vy5xRSxIVE1MU3R5bGVFbGVt
+ZW50OlcucUUsSFRNTFRhYmxlQ2FwdGlvbkVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDZWxsRWxlbWVudDpX
+LnFFLEhUTUxUYWJsZURhdGFDZWxsRWxlbWVudDpXLnFFLEhUTUxUYWJsZUhlYWRlckNlbGxFbGVtZW50
+OlcucUUsSFRNTFRhYmxlQ29sRWxlbWVudDpXLnFFLEhUTUxUZXh0QXJlYUVsZW1lbnQ6Vy5xRSxIVE1M
+VGltZUVsZW1lbnQ6Vy5xRSxIVE1MVGl0bGVFbGVtZW50OlcucUUsSFRNTFRyYWNrRWxlbWVudDpXLnFF
+LEhUTUxVTGlzdEVsZW1lbnQ6Vy5xRSxIVE1MVW5rbm93bkVsZW1lbnQ6Vy5xRSxIVE1MVmlkZW9FbGVt
+ZW50OlcucUUsSFRNTERpcmVjdG9yeUVsZW1lbnQ6Vy5xRSxIVE1MRm9udEVsZW1lbnQ6Vy5xRSxIVE1M
+RnJhbWVFbGVtZW50OlcucUUsSFRNTEZyYW1lU2V0RWxlbWVudDpXLnFFLEhUTUxNYXJxdWVlRWxlbWVu
+dDpXLnFFLEhUTUxFbGVtZW50OlcucUUsSFRNTEFuY2hvckVsZW1lbnQ6Vy5HaCxIVE1MQXJlYUVsZW1l
+bnQ6Vy5mWSxIVE1MQmFzZUVsZW1lbnQ6Vy5uQixCbG9iOlcuQXosSFRNTEJvZHlFbGVtZW50OlcuUVAs
+Q0RBVEFTZWN0aW9uOlcubngsQ2hhcmFjdGVyRGF0YTpXLm54LENvbW1lbnQ6Vy5ueCxQcm9jZXNzaW5n
+SW5zdHJ1Y3Rpb246Vy5ueCxUZXh0OlcubngsQ1NTU3R5bGVEZWNsYXJhdGlvbjpXLm9KLE1TU3R5bGVD
+U1NQcm9wZXJ0aWVzOlcub0osQ1NTMlByb3BlcnRpZXM6Vy5vSixYTUxEb2N1bWVudDpXLlFGLERvY3Vt
+ZW50OlcuUUYsRE9NRXhjZXB0aW9uOlcuTmgsRE9NUmVjdFJlYWRPbmx5OlcuSUIsRE9NVG9rZW5MaXN0
+OlcubjcsRWxlbWVudDpXLmN2LEFib3J0UGF5bWVudEV2ZW50OlcuZWEsQW5pbWF0aW9uRXZlbnQ6Vy5l
+YSxBbmltYXRpb25QbGF5YmFja0V2ZW50OlcuZWEsQXBwbGljYXRpb25DYWNoZUVycm9yRXZlbnQ6Vy5l
+YSxCYWNrZ3JvdW5kRmV0Y2hDbGlja0V2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoRXZlbnQ6Vy5lYSxC
+YWNrZ3JvdW5kRmV0Y2hGYWlsRXZlbnQ6Vy5lYSxCYWNrZ3JvdW5kRmV0Y2hlZEV2ZW50OlcuZWEsQmVm
+b3JlSW5zdGFsbFByb21wdEV2ZW50OlcuZWEsQmVmb3JlVW5sb2FkRXZlbnQ6Vy5lYSxCbG9iRXZlbnQ6
+Vy5lYSxDYW5NYWtlUGF5bWVudEV2ZW50OlcuZWEsQ2xpcGJvYXJkRXZlbnQ6Vy5lYSxDbG9zZUV2ZW50
+OlcuZWEsQ3VzdG9tRXZlbnQ6Vy5lYSxEZXZpY2VNb3Rpb25FdmVudDpXLmVhLERldmljZU9yaWVudGF0
+aW9uRXZlbnQ6Vy5lYSxFcnJvckV2ZW50OlcuZWEsRXh0ZW5kYWJsZUV2ZW50OlcuZWEsRXh0ZW5kYWJs
+ZU1lc3NhZ2VFdmVudDpXLmVhLEZldGNoRXZlbnQ6Vy5lYSxGb250RmFjZVNldExvYWRFdmVudDpXLmVh
+LEZvcmVpZ25GZXRjaEV2ZW50OlcuZWEsR2FtZXBhZEV2ZW50OlcuZWEsSGFzaENoYW5nZUV2ZW50Olcu
+ZWEsSW5zdGFsbEV2ZW50OlcuZWEsTWVkaWFFbmNyeXB0ZWRFdmVudDpXLmVhLE1lZGlhS2V5TWVzc2Fn
+ZUV2ZW50OlcuZWEsTWVkaWFRdWVyeUxpc3RFdmVudDpXLmVhLE1lZGlhU3RyZWFtRXZlbnQ6Vy5lYSxN
+ZWRpYVN0cmVhbVRyYWNrRXZlbnQ6Vy5lYSxNZXNzYWdlRXZlbnQ6Vy5lYSxNSURJQ29ubmVjdGlvbkV2
+ZW50OlcuZWEsTUlESU1lc3NhZ2VFdmVudDpXLmVhLE11dGF0aW9uRXZlbnQ6Vy5lYSxOb3RpZmljYXRp
+b25FdmVudDpXLmVhLFBhZ2VUcmFuc2l0aW9uRXZlbnQ6Vy5lYSxQYXltZW50UmVxdWVzdEV2ZW50Olcu
+ZWEsUGF5bWVudFJlcXVlc3RVcGRhdGVFdmVudDpXLmVhLFBvcFN0YXRlRXZlbnQ6Vy5lYSxQcmVzZW50
+YXRpb25Db25uZWN0aW9uQXZhaWxhYmxlRXZlbnQ6Vy5lYSxQcmVzZW50YXRpb25Db25uZWN0aW9uQ2xv
+c2VFdmVudDpXLmVhLFByb21pc2VSZWplY3Rpb25FdmVudDpXLmVhLFB1c2hFdmVudDpXLmVhLFJUQ0Rh
+dGFDaGFubmVsRXZlbnQ6Vy5lYSxSVENEVE1GVG9uZUNoYW5nZUV2ZW50OlcuZWEsUlRDUGVlckNvbm5l
+Y3Rpb25JY2VFdmVudDpXLmVhLFJUQ1RyYWNrRXZlbnQ6Vy5lYSxTZWN1cml0eVBvbGljeVZpb2xhdGlv
+bkV2ZW50OlcuZWEsU2Vuc29yRXJyb3JFdmVudDpXLmVhLFNwZWVjaFJlY29nbml0aW9uRXJyb3I6Vy5l
+YSxTcGVlY2hSZWNvZ25pdGlvbkV2ZW50OlcuZWEsU3BlZWNoU3ludGhlc2lzRXZlbnQ6Vy5lYSxTdG9y
+YWdlRXZlbnQ6Vy5lYSxTeW5jRXZlbnQ6Vy5lYSxUcmFja0V2ZW50OlcuZWEsVHJhbnNpdGlvbkV2ZW50
+OlcuZWEsV2ViS2l0VHJhbnNpdGlvbkV2ZW50OlcuZWEsVlJEZXZpY2VFdmVudDpXLmVhLFZSRGlzcGxh
+eUV2ZW50OlcuZWEsVlJTZXNzaW9uRXZlbnQ6Vy5lYSxNb2pvSW50ZXJmYWNlUmVxdWVzdEV2ZW50Olcu
+ZWEsVVNCQ29ubmVjdGlvbkV2ZW50OlcuZWEsSURCVmVyc2lvbkNoYW5nZUV2ZW50OlcuZWEsQXVkaW9Q
+cm9jZXNzaW5nRXZlbnQ6Vy5lYSxPZmZsaW5lQXVkaW9Db21wbGV0aW9uRXZlbnQ6Vy5lYSxXZWJHTENv
+bnRleHRFdmVudDpXLmVhLEV2ZW50OlcuZWEsSW5wdXRFdmVudDpXLmVhLEV2ZW50VGFyZ2V0OlcuRDAs
+RmlsZTpXLlQ1LEhUTUxGb3JtRWxlbWVudDpXLmg0LEhpc3Rvcnk6Vy5icixIVE1MRG9jdW1lbnQ6Vy5W
+YixYTUxIdHRwUmVxdWVzdDpXLk83LFhNTEh0dHBSZXF1ZXN0RXZlbnRUYXJnZXQ6Vy53YSxJbWFnZURh
+dGE6Vy5TZyxMb2NhdGlvbjpXLnU4LE1vdXNlRXZlbnQ6Vy5BaixEcmFnRXZlbnQ6Vy5BaixQb2ludGVy
+RXZlbnQ6Vy5BaixXaGVlbEV2ZW50OlcuQWosRG9jdW1lbnRGcmFnbWVudDpXLnVILFNoYWRvd1Jvb3Q6
+Vy51SCxEb2N1bWVudFR5cGU6Vy51SCxOb2RlOlcudUgsTm9kZUxpc3Q6Vy5CSCxSYWRpb05vZGVMaXN0
+OlcuQkgsSFRNTFBhcmFncmFwaEVsZW1lbnQ6Vy5TTixQcm9ncmVzc0V2ZW50OlcuZXcsUmVzb3VyY2VQ
+cm9ncmVzc0V2ZW50OlcuZXcsSFRNTFNlbGVjdEVsZW1lbnQ6Vy5scCxIVE1MVGFibGVFbGVtZW50Olcu
+VGIsSFRNTFRhYmxlUm93RWxlbWVudDpXLkl2LEhUTUxUYWJsZVNlY3Rpb25FbGVtZW50OlcuV1AsSFRN
+TFRlbXBsYXRlRWxlbWVudDpXLnlZLENvbXBvc2l0aW9uRXZlbnQ6Vy53NixGb2N1c0V2ZW50OlcudzYs
+S2V5Ym9hcmRFdmVudDpXLnc2LFRleHRFdmVudDpXLnc2LFRvdWNoRXZlbnQ6Vy53NixVSUV2ZW50Olcu
+dzYsV2luZG93OlcuSzUsRE9NV2luZG93OlcuSzUsRGVkaWNhdGVkV29ya2VyR2xvYmFsU2NvcGU6Vy5D
+bSxTZXJ2aWNlV29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxTaGFyZWRXb3JrZXJHbG9iYWxTY29wZTpXLkNt
+LFdvcmtlckdsb2JhbFNjb3BlOlcuQ20sQXR0cjpXLkNRLENsaWVudFJlY3Q6Vy53NCxET01SZWN0Olcu
+dzQsTmFtZWROb2RlTWFwOlcucmgsTW96TmFtZWRBdHRyTWFwOlcucmgsSURCS2V5UmFuZ2U6UC5oRixT
+VkdTY3JpcHRFbGVtZW50OlAubmQsU1ZHQUVsZW1lbnQ6UC5kNSxTVkdBbmltYXRlRWxlbWVudDpQLmQ1
+LFNWR0FuaW1hdGVNb3Rpb25FbGVtZW50OlAuZDUsU1ZHQW5pbWF0ZVRyYW5zZm9ybUVsZW1lbnQ6UC5k
+NSxTVkdBbmltYXRpb25FbGVtZW50OlAuZDUsU1ZHQ2lyY2xlRWxlbWVudDpQLmQ1LFNWR0NsaXBQYXRo
+RWxlbWVudDpQLmQ1LFNWR0RlZnNFbGVtZW50OlAuZDUsU1ZHRGVzY0VsZW1lbnQ6UC5kNSxTVkdEaXNj
+YXJkRWxlbWVudDpQLmQ1LFNWR0VsbGlwc2VFbGVtZW50OlAuZDUsU1ZHRkVCbGVuZEVsZW1lbnQ6UC5k
+NSxTVkdGRUNvbG9yTWF0cml4RWxlbWVudDpQLmQ1LFNWR0ZFQ29tcG9uZW50VHJhbnNmZXJFbGVtZW50
+OlAuZDUsU1ZHRkVDb21wb3NpdGVFbGVtZW50OlAuZDUsU1ZHRkVDb252b2x2ZU1hdHJpeEVsZW1lbnQ6
+UC5kNSxTVkdGRURpZmZ1c2VMaWdodGluZ0VsZW1lbnQ6UC5kNSxTVkdGRURpc3BsYWNlbWVudE1hcEVs
+ZW1lbnQ6UC5kNSxTVkdGRURpc3RhbnRMaWdodEVsZW1lbnQ6UC5kNSxTVkdGRUZsb29kRWxlbWVudDpQ
+LmQ1LFNWR0ZFRnVuY0FFbGVtZW50OlAuZDUsU1ZHRkVGdW5jQkVsZW1lbnQ6UC5kNSxTVkdGRUZ1bmNH
+RWxlbWVudDpQLmQ1LFNWR0ZFRnVuY1JFbGVtZW50OlAuZDUsU1ZHRkVHYXVzc2lhbkJsdXJFbGVtZW50
+OlAuZDUsU1ZHRkVJbWFnZUVsZW1lbnQ6UC5kNSxTVkdGRU1lcmdlRWxlbWVudDpQLmQ1LFNWR0ZFTWVy
+Z2VOb2RlRWxlbWVudDpQLmQ1LFNWR0ZFTW9ycGhvbG9neUVsZW1lbnQ6UC5kNSxTVkdGRU9mZnNldEVs
+ZW1lbnQ6UC5kNSxTVkdGRVBvaW50TGlnaHRFbGVtZW50OlAuZDUsU1ZHRkVTcGVjdWxhckxpZ2h0aW5n
+RWxlbWVudDpQLmQ1LFNWR0ZFU3BvdExpZ2h0RWxlbWVudDpQLmQ1LFNWR0ZFVGlsZUVsZW1lbnQ6UC5k
+NSxTVkdGRVR1cmJ1bGVuY2VFbGVtZW50OlAuZDUsU1ZHRmlsdGVyRWxlbWVudDpQLmQ1LFNWR0ZvcmVp
+Z25PYmplY3RFbGVtZW50OlAuZDUsU1ZHR0VsZW1lbnQ6UC5kNSxTVkdHZW9tZXRyeUVsZW1lbnQ6UC5k
+NSxTVkdHcmFwaGljc0VsZW1lbnQ6UC5kNSxTVkdJbWFnZUVsZW1lbnQ6UC5kNSxTVkdMaW5lRWxlbWVu
+dDpQLmQ1LFNWR0xpbmVhckdyYWRpZW50RWxlbWVudDpQLmQ1LFNWR01hcmtlckVsZW1lbnQ6UC5kNSxT
+VkdNYXNrRWxlbWVudDpQLmQ1LFNWR01ldGFkYXRhRWxlbWVudDpQLmQ1LFNWR1BhdGhFbGVtZW50OlAu
+ZDUsU1ZHUGF0dGVybkVsZW1lbnQ6UC5kNSxTVkdQb2x5Z29uRWxlbWVudDpQLmQ1LFNWR1BvbHlsaW5l
+RWxlbWVudDpQLmQ1LFNWR1JhZGlhbEdyYWRpZW50RWxlbWVudDpQLmQ1LFNWR1JlY3RFbGVtZW50OlAu
+ZDUsU1ZHU2V0RWxlbWVudDpQLmQ1LFNWR1N0b3BFbGVtZW50OlAuZDUsU1ZHU3R5bGVFbGVtZW50OlAu
+ZDUsU1ZHU1ZHRWxlbWVudDpQLmQ1LFNWR1N3aXRjaEVsZW1lbnQ6UC5kNSxTVkdTeW1ib2xFbGVtZW50
+OlAuZDUsU1ZHVFNwYW5FbGVtZW50OlAuZDUsU1ZHVGV4dENvbnRlbnRFbGVtZW50OlAuZDUsU1ZHVGV4
+dEVsZW1lbnQ6UC5kNSxTVkdUZXh0UGF0aEVsZW1lbnQ6UC5kNSxTVkdUZXh0UG9zaXRpb25pbmdFbGVt
+ZW50OlAuZDUsU1ZHVGl0bGVFbGVtZW50OlAuZDUsU1ZHVXNlRWxlbWVudDpQLmQ1LFNWR1ZpZXdFbGVt
+ZW50OlAuZDUsU1ZHR3JhZGllbnRFbGVtZW50OlAuZDUsU1ZHQ29tcG9uZW50VHJhbnNmZXJGdW5jdGlv
+bkVsZW1lbnQ6UC5kNSxTVkdGRURyb3BTaGFkb3dFbGVtZW50OlAuZDUsU1ZHTVBhdGhFbGVtZW50OlAu
+ZDUsU1ZHRWxlbWVudDpQLmQ1fSkKaHVua0hlbHBlcnMuc2V0T3JVcGRhdGVMZWFmVGFncyh7RE9NRXJy
+b3I6dHJ1ZSxET01JbXBsZW1lbnRhdGlvbjp0cnVlLE1lZGlhRXJyb3I6dHJ1ZSxOYXZpZ2F0b3I6dHJ1
+ZSxOYXZpZ2F0b3JDb25jdXJyZW50SGFyZHdhcmU6dHJ1ZSxOYXZpZ2F0b3JVc2VyTWVkaWFFcnJvcjp0
+cnVlLE92ZXJjb25zdHJhaW5lZEVycm9yOnRydWUsUG9zaXRpb25FcnJvcjp0cnVlLFJhbmdlOnRydWUs
+U1FMRXJyb3I6dHJ1ZSxEYXRhVmlldzp0cnVlLEFycmF5QnVmZmVyVmlldzpmYWxzZSxGbG9hdDMyQXJy
+YXk6dHJ1ZSxGbG9hdDY0QXJyYXk6dHJ1ZSxJbnQxNkFycmF5OnRydWUsSW50MzJBcnJheTp0cnVlLElu
+dDhBcnJheTp0cnVlLFVpbnQxNkFycmF5OnRydWUsVWludDMyQXJyYXk6dHJ1ZSxVaW50OENsYW1wZWRB
+cnJheTp0cnVlLENhbnZhc1BpeGVsQXJyYXk6dHJ1ZSxVaW50OEFycmF5OmZhbHNlLEhUTUxBdWRpb0Vs
+ZW1lbnQ6dHJ1ZSxIVE1MQlJFbGVtZW50OnRydWUsSFRNTEJ1dHRvbkVsZW1lbnQ6dHJ1ZSxIVE1MQ2Fu
+dmFzRWxlbWVudDp0cnVlLEhUTUxDb250ZW50RWxlbWVudDp0cnVlLEhUTUxETGlzdEVsZW1lbnQ6dHJ1
+ZSxIVE1MRGF0YUVsZW1lbnQ6dHJ1ZSxIVE1MRGF0YUxpc3RFbGVtZW50OnRydWUsSFRNTERldGFpbHNF
+bGVtZW50OnRydWUsSFRNTERpYWxvZ0VsZW1lbnQ6dHJ1ZSxIVE1MRGl2RWxlbWVudDp0cnVlLEhUTUxF
+bWJlZEVsZW1lbnQ6dHJ1ZSxIVE1MRmllbGRTZXRFbGVtZW50OnRydWUsSFRNTEhSRWxlbWVudDp0cnVl
+LEhUTUxIZWFkRWxlbWVudDp0cnVlLEhUTUxIZWFkaW5nRWxlbWVudDp0cnVlLEhUTUxIdG1sRWxlbWVu
+dDp0cnVlLEhUTUxJRnJhbWVFbGVtZW50OnRydWUsSFRNTEltYWdlRWxlbWVudDp0cnVlLEhUTUxJbnB1
+dEVsZW1lbnQ6dHJ1ZSxIVE1MTElFbGVtZW50OnRydWUsSFRNTExhYmVsRWxlbWVudDp0cnVlLEhUTUxM
+ZWdlbmRFbGVtZW50OnRydWUsSFRNTExpbmtFbGVtZW50OnRydWUsSFRNTE1hcEVsZW1lbnQ6dHJ1ZSxI
+VE1MTWVkaWFFbGVtZW50OnRydWUsSFRNTE1lbnVFbGVtZW50OnRydWUsSFRNTE1ldGFFbGVtZW50OnRy
+dWUsSFRNTE1ldGVyRWxlbWVudDp0cnVlLEhUTUxNb2RFbGVtZW50OnRydWUsSFRNTE9MaXN0RWxlbWVu
+dDp0cnVlLEhUTUxPYmplY3RFbGVtZW50OnRydWUsSFRNTE9wdEdyb3VwRWxlbWVudDp0cnVlLEhUTUxP
+cHRpb25FbGVtZW50OnRydWUsSFRNTE91dHB1dEVsZW1lbnQ6dHJ1ZSxIVE1MUGFyYW1FbGVtZW50OnRy
+dWUsSFRNTFBpY3R1cmVFbGVtZW50OnRydWUsSFRNTFByZUVsZW1lbnQ6dHJ1ZSxIVE1MUHJvZ3Jlc3NF
+bGVtZW50OnRydWUsSFRNTFF1b3RlRWxlbWVudDp0cnVlLEhUTUxTY3JpcHRFbGVtZW50OnRydWUsSFRN
+TFNoYWRvd0VsZW1lbnQ6dHJ1ZSxIVE1MU2xvdEVsZW1lbnQ6dHJ1ZSxIVE1MU291cmNlRWxlbWVudDp0
+cnVlLEhUTUxTcGFuRWxlbWVudDp0cnVlLEhUTUxTdHlsZUVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVDYXB0
+aW9uRWxlbWVudDp0cnVlLEhUTUxUYWJsZUNlbGxFbGVtZW50OnRydWUsSFRNTFRhYmxlRGF0YUNlbGxF
+bGVtZW50OnRydWUsSFRNTFRhYmxlSGVhZGVyQ2VsbEVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVDb2xFbGVt
+ZW50OnRydWUsSFRNTFRleHRBcmVhRWxlbWVudDp0cnVlLEhUTUxUaW1lRWxlbWVudDp0cnVlLEhUTUxU
+aXRsZUVsZW1lbnQ6dHJ1ZSxIVE1MVHJhY2tFbGVtZW50OnRydWUsSFRNTFVMaXN0RWxlbWVudDp0cnVl
+LEhUTUxVbmtub3duRWxlbWVudDp0cnVlLEhUTUxWaWRlb0VsZW1lbnQ6dHJ1ZSxIVE1MRGlyZWN0b3J5
+RWxlbWVudDp0cnVlLEhUTUxGb250RWxlbWVudDp0cnVlLEhUTUxGcmFtZUVsZW1lbnQ6dHJ1ZSxIVE1M
+RnJhbWVTZXRFbGVtZW50OnRydWUsSFRNTE1hcnF1ZWVFbGVtZW50OnRydWUsSFRNTEVsZW1lbnQ6ZmFs
+c2UsSFRNTEFuY2hvckVsZW1lbnQ6dHJ1ZSxIVE1MQXJlYUVsZW1lbnQ6dHJ1ZSxIVE1MQmFzZUVsZW1l
+bnQ6dHJ1ZSxCbG9iOmZhbHNlLEhUTUxCb2R5RWxlbWVudDp0cnVlLENEQVRBU2VjdGlvbjp0cnVlLENo
+YXJhY3RlckRhdGE6dHJ1ZSxDb21tZW50OnRydWUsUHJvY2Vzc2luZ0luc3RydWN0aW9uOnRydWUsVGV4
+dDp0cnVlLENTU1N0eWxlRGVjbGFyYXRpb246dHJ1ZSxNU1N0eWxlQ1NTUHJvcGVydGllczp0cnVlLENT
+UzJQcm9wZXJ0aWVzOnRydWUsWE1MRG9jdW1lbnQ6dHJ1ZSxEb2N1bWVudDpmYWxzZSxET01FeGNlcHRp
+b246dHJ1ZSxET01SZWN0UmVhZE9ubHk6ZmFsc2UsRE9NVG9rZW5MaXN0OnRydWUsRWxlbWVudDpmYWxz
+ZSxBYm9ydFBheW1lbnRFdmVudDp0cnVlLEFuaW1hdGlvbkV2ZW50OnRydWUsQW5pbWF0aW9uUGxheWJh
+Y2tFdmVudDp0cnVlLEFwcGxpY2F0aW9uQ2FjaGVFcnJvckV2ZW50OnRydWUsQmFja2dyb3VuZEZldGNo
+Q2xpY2tFdmVudDp0cnVlLEJhY2tncm91bmRGZXRjaEV2ZW50OnRydWUsQmFja2dyb3VuZEZldGNoRmFp
+bEV2ZW50OnRydWUsQmFja2dyb3VuZEZldGNoZWRFdmVudDp0cnVlLEJlZm9yZUluc3RhbGxQcm9tcHRF
+dmVudDp0cnVlLEJlZm9yZVVubG9hZEV2ZW50OnRydWUsQmxvYkV2ZW50OnRydWUsQ2FuTWFrZVBheW1l
+bnRFdmVudDp0cnVlLENsaXBib2FyZEV2ZW50OnRydWUsQ2xvc2VFdmVudDp0cnVlLEN1c3RvbUV2ZW50
+OnRydWUsRGV2aWNlTW90aW9uRXZlbnQ6dHJ1ZSxEZXZpY2VPcmllbnRhdGlvbkV2ZW50OnRydWUsRXJy
+b3JFdmVudDp0cnVlLEV4dGVuZGFibGVFdmVudDp0cnVlLEV4dGVuZGFibGVNZXNzYWdlRXZlbnQ6dHJ1
+ZSxGZXRjaEV2ZW50OnRydWUsRm9udEZhY2VTZXRMb2FkRXZlbnQ6dHJ1ZSxGb3JlaWduRmV0Y2hFdmVu
+dDp0cnVlLEdhbWVwYWRFdmVudDp0cnVlLEhhc2hDaGFuZ2VFdmVudDp0cnVlLEluc3RhbGxFdmVudDp0
+cnVlLE1lZGlhRW5jcnlwdGVkRXZlbnQ6dHJ1ZSxNZWRpYUtleU1lc3NhZ2VFdmVudDp0cnVlLE1lZGlh
+UXVlcnlMaXN0RXZlbnQ6dHJ1ZSxNZWRpYVN0cmVhbUV2ZW50OnRydWUsTWVkaWFTdHJlYW1UcmFja0V2
+ZW50OnRydWUsTWVzc2FnZUV2ZW50OnRydWUsTUlESUNvbm5lY3Rpb25FdmVudDp0cnVlLE1JRElNZXNz
+YWdlRXZlbnQ6dHJ1ZSxNdXRhdGlvbkV2ZW50OnRydWUsTm90aWZpY2F0aW9uRXZlbnQ6dHJ1ZSxQYWdl
+VHJhbnNpdGlvbkV2ZW50OnRydWUsUGF5bWVudFJlcXVlc3RFdmVudDp0cnVlLFBheW1lbnRSZXF1ZXN0
+VXBkYXRlRXZlbnQ6dHJ1ZSxQb3BTdGF0ZUV2ZW50OnRydWUsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkF2
+YWlsYWJsZUV2ZW50OnRydWUsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlRXZlbnQ6dHJ1ZSxQcm9t
+aXNlUmVqZWN0aW9uRXZlbnQ6dHJ1ZSxQdXNoRXZlbnQ6dHJ1ZSxSVENEYXRhQ2hhbm5lbEV2ZW50OnRy
+dWUsUlRDRFRNRlRvbmVDaGFuZ2VFdmVudDp0cnVlLFJUQ1BlZXJDb25uZWN0aW9uSWNlRXZlbnQ6dHJ1
+ZSxSVENUcmFja0V2ZW50OnRydWUsU2VjdXJpdHlQb2xpY3lWaW9sYXRpb25FdmVudDp0cnVlLFNlbnNv
+ckVycm9yRXZlbnQ6dHJ1ZSxTcGVlY2hSZWNvZ25pdGlvbkVycm9yOnRydWUsU3BlZWNoUmVjb2duaXRp
+b25FdmVudDp0cnVlLFNwZWVjaFN5bnRoZXNpc0V2ZW50OnRydWUsU3RvcmFnZUV2ZW50OnRydWUsU3lu
+Y0V2ZW50OnRydWUsVHJhY2tFdmVudDp0cnVlLFRyYW5zaXRpb25FdmVudDp0cnVlLFdlYktpdFRyYW5z
+aXRpb25FdmVudDp0cnVlLFZSRGV2aWNlRXZlbnQ6dHJ1ZSxWUkRpc3BsYXlFdmVudDp0cnVlLFZSU2Vz
+c2lvbkV2ZW50OnRydWUsTW9qb0ludGVyZmFjZVJlcXVlc3RFdmVudDp0cnVlLFVTQkNvbm5lY3Rpb25F
+dmVudDp0cnVlLElEQlZlcnNpb25DaGFuZ2VFdmVudDp0cnVlLEF1ZGlvUHJvY2Vzc2luZ0V2ZW50OnRy
+dWUsT2ZmbGluZUF1ZGlvQ29tcGxldGlvbkV2ZW50OnRydWUsV2ViR0xDb250ZXh0RXZlbnQ6dHJ1ZSxF
+dmVudDpmYWxzZSxJbnB1dEV2ZW50OmZhbHNlLEV2ZW50VGFyZ2V0OmZhbHNlLEZpbGU6dHJ1ZSxIVE1M
+Rm9ybUVsZW1lbnQ6dHJ1ZSxIaXN0b3J5OnRydWUsSFRNTERvY3VtZW50OnRydWUsWE1MSHR0cFJlcXVl
+c3Q6dHJ1ZSxYTUxIdHRwUmVxdWVzdEV2ZW50VGFyZ2V0OmZhbHNlLEltYWdlRGF0YTp0cnVlLExvY2F0
+aW9uOnRydWUsTW91c2VFdmVudDp0cnVlLERyYWdFdmVudDp0cnVlLFBvaW50ZXJFdmVudDp0cnVlLFdo
+ZWVsRXZlbnQ6dHJ1ZSxEb2N1bWVudEZyYWdtZW50OnRydWUsU2hhZG93Um9vdDp0cnVlLERvY3VtZW50
+VHlwZTp0cnVlLE5vZGU6ZmFsc2UsTm9kZUxpc3Q6dHJ1ZSxSYWRpb05vZGVMaXN0OnRydWUsSFRNTFBh
+cmFncmFwaEVsZW1lbnQ6dHJ1ZSxQcm9ncmVzc0V2ZW50OnRydWUsUmVzb3VyY2VQcm9ncmVzc0V2ZW50
+OnRydWUsSFRNTFNlbGVjdEVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVFbGVtZW50OnRydWUsSFRNTFRhYmxl
+Um93RWxlbWVudDp0cnVlLEhUTUxUYWJsZVNlY3Rpb25FbGVtZW50OnRydWUsSFRNTFRlbXBsYXRlRWxl
+bWVudDp0cnVlLENvbXBvc2l0aW9uRXZlbnQ6dHJ1ZSxGb2N1c0V2ZW50OnRydWUsS2V5Ym9hcmRFdmVu
+dDp0cnVlLFRleHRFdmVudDp0cnVlLFRvdWNoRXZlbnQ6dHJ1ZSxVSUV2ZW50OmZhbHNlLFdpbmRvdzp0
+cnVlLERPTVdpbmRvdzp0cnVlLERlZGljYXRlZFdvcmtlckdsb2JhbFNjb3BlOnRydWUsU2VydmljZVdv
+cmtlckdsb2JhbFNjb3BlOnRydWUsU2hhcmVkV29ya2VyR2xvYmFsU2NvcGU6dHJ1ZSxXb3JrZXJHbG9i
+YWxTY29wZTp0cnVlLEF0dHI6dHJ1ZSxDbGllbnRSZWN0OnRydWUsRE9NUmVjdDp0cnVlLE5hbWVkTm9k
+ZU1hcDp0cnVlLE1vek5hbWVkQXR0ck1hcDp0cnVlLElEQktleVJhbmdlOnRydWUsU1ZHU2NyaXB0RWxl
+bWVudDp0cnVlLFNWR0FFbGVtZW50OnRydWUsU1ZHQW5pbWF0ZUVsZW1lbnQ6dHJ1ZSxTVkdBbmltYXRl
+TW90aW9uRWxlbWVudDp0cnVlLFNWR0FuaW1hdGVUcmFuc2Zvcm1FbGVtZW50OnRydWUsU1ZHQW5pbWF0
+aW9uRWxlbWVudDp0cnVlLFNWR0NpcmNsZUVsZW1lbnQ6dHJ1ZSxTVkdDbGlwUGF0aEVsZW1lbnQ6dHJ1
+ZSxTVkdEZWZzRWxlbWVudDp0cnVlLFNWR0Rlc2NFbGVtZW50OnRydWUsU1ZHRGlzY2FyZEVsZW1lbnQ6
+dHJ1ZSxTVkdFbGxpcHNlRWxlbWVudDp0cnVlLFNWR0ZFQmxlbmRFbGVtZW50OnRydWUsU1ZHRkVDb2xv
+ck1hdHJpeEVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbXBvbmVudFRyYW5zZmVyRWxlbWVudDp0cnVlLFNWR0ZF
+Q29tcG9zaXRlRWxlbWVudDp0cnVlLFNWR0ZFQ29udm9sdmVNYXRyaXhFbGVtZW50OnRydWUsU1ZHRkVE
+aWZmdXNlTGlnaHRpbmdFbGVtZW50OnRydWUsU1ZHRkVEaXNwbGFjZW1lbnRNYXBFbGVtZW50OnRydWUs
+U1ZHRkVEaXN0YW50TGlnaHRFbGVtZW50OnRydWUsU1ZHRkVGbG9vZEVsZW1lbnQ6dHJ1ZSxTVkdGRUZ1
+bmNBRWxlbWVudDp0cnVlLFNWR0ZFRnVuY0JFbGVtZW50OnRydWUsU1ZHRkVGdW5jR0VsZW1lbnQ6dHJ1
+ZSxTVkdGRUZ1bmNSRWxlbWVudDp0cnVlLFNWR0ZFR2F1c3NpYW5CbHVyRWxlbWVudDp0cnVlLFNWR0ZF
+SW1hZ2VFbGVtZW50OnRydWUsU1ZHRkVNZXJnZUVsZW1lbnQ6dHJ1ZSxTVkdGRU1lcmdlTm9kZUVsZW1l
+bnQ6dHJ1ZSxTVkdGRU1vcnBob2xvZ3lFbGVtZW50OnRydWUsU1ZHRkVPZmZzZXRFbGVtZW50OnRydWUs
+U1ZHRkVQb2ludExpZ2h0RWxlbWVudDp0cnVlLFNWR0ZFU3BlY3VsYXJMaWdodGluZ0VsZW1lbnQ6dHJ1
+ZSxTVkdGRVNwb3RMaWdodEVsZW1lbnQ6dHJ1ZSxTVkdGRVRpbGVFbGVtZW50OnRydWUsU1ZHRkVUdXJi
+dWxlbmNlRWxlbWVudDp0cnVlLFNWR0ZpbHRlckVsZW1lbnQ6dHJ1ZSxTVkdGb3JlaWduT2JqZWN0RWxl
+bWVudDp0cnVlLFNWR0dFbGVtZW50OnRydWUsU1ZHR2VvbWV0cnlFbGVtZW50OnRydWUsU1ZHR3JhcGhp
+Y3NFbGVtZW50OnRydWUsU1ZHSW1hZ2VFbGVtZW50OnRydWUsU1ZHTGluZUVsZW1lbnQ6dHJ1ZSxTVkdM
+aW5lYXJHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdNYXJrZXJFbGVtZW50OnRydWUsU1ZHTWFza0VsZW1l
+bnQ6dHJ1ZSxTVkdNZXRhZGF0YUVsZW1lbnQ6dHJ1ZSxTVkdQYXRoRWxlbWVudDp0cnVlLFNWR1BhdHRl
+cm5FbGVtZW50OnRydWUsU1ZHUG9seWdvbkVsZW1lbnQ6dHJ1ZSxTVkdQb2x5bGluZUVsZW1lbnQ6dHJ1
+ZSxTVkdSYWRpYWxHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdSZWN0RWxlbWVudDp0cnVlLFNWR1NldEVs
+ZW1lbnQ6dHJ1ZSxTVkdTdG9wRWxlbWVudDp0cnVlLFNWR1N0eWxlRWxlbWVudDp0cnVlLFNWR1NWR0Vs
+ZW1lbnQ6dHJ1ZSxTVkdTd2l0Y2hFbGVtZW50OnRydWUsU1ZHU3ltYm9sRWxlbWVudDp0cnVlLFNWR1RT
+cGFuRWxlbWVudDp0cnVlLFNWR1RleHRDb250ZW50RWxlbWVudDp0cnVlLFNWR1RleHRFbGVtZW50OnRy
+dWUsU1ZHVGV4dFBhdGhFbGVtZW50OnRydWUsU1ZHVGV4dFBvc2l0aW9uaW5nRWxlbWVudDp0cnVlLFNW
+R1RpdGxlRWxlbWVudDp0cnVlLFNWR1VzZUVsZW1lbnQ6dHJ1ZSxTVkdWaWV3RWxlbWVudDp0cnVlLFNW
+R0dyYWRpZW50RWxlbWVudDp0cnVlLFNWR0NvbXBvbmVudFRyYW5zZmVyRnVuY3Rpb25FbGVtZW50OnRy
+dWUsU1ZHRkVEcm9wU2hhZG93RWxlbWVudDp0cnVlLFNWR01QYXRoRWxlbWVudDp0cnVlLFNWR0VsZW1l
+bnQ6ZmFsc2V9KQpILmIwLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkguUkcu
+JG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5WUC4kbmF0aXZlU3VwZXJjbGFz
+c1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILkRnLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZl
+clZpZXciCkguV0IuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5aRy4kbmF0
+aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILlBnLiRuYXRpdmVTdXBlcmNsYXNzVGFn
+PSJBcnJheUJ1ZmZlclZpZXcifSkoKQpjb252ZXJ0QWxsVG9GYXN0T2JqZWN0KHcpCmNvbnZlcnRUb0Zh
+c3RPYmplY3QoJCk7KGZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBkb2N1bWVudD09PSJ1bmRlZmluZWQiKXth
+KG51bGwpCnJldHVybn1pZih0eXBlb2YgZG9jdW1lbnQuY3VycmVudFNjcmlwdCE9J3VuZGVmaW5lZCcp
+e2EoZG9jdW1lbnQuY3VycmVudFNjcmlwdCkKcmV0dXJufXZhciB0PWRvY3VtZW50LnNjcmlwdHMKZnVu
+Y3Rpb24gb25Mb2FkKGIpe2Zvcih2YXIgcj0wO3I8dC5sZW5ndGg7KytyKXRbcl0ucmVtb3ZlRXZlbnRM
+aXN0ZW5lcigibG9hZCIsb25Mb2FkLGZhbHNlKQphKGIudGFyZ2V0KX1mb3IodmFyIHM9MDtzPHQubGVu
+Z3RoOysrcyl0W3NdLmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLG9uTG9hZCxmYWxzZSl9KShmdW5jdGlv
+bihhKXt2LmN1cnJlbnRTY3JpcHQ9YQppZih0eXBlb2YgZGFydE1haW5SdW5uZXI9PT0iZnVuY3Rpb24i
+KWRhcnRNYWluUnVubmVyKEwuSXEsW10pCmVsc2UgTC5JcShbXSl9KX0pKCkKLy8jIHNvdXJjZU1hcHBp
+bmdVUkw9bWlncmF0aW9uLmpzLm1hcAo=
 ''';
diff --git a/pkg/nnbd_migration/lib/src/front_end/web/migration.dart b/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
index 05ffafa..dba292b 100644
--- a/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
@@ -61,8 +61,7 @@
 
     final reportProblemButton = document.querySelector('.report-problem');
     reportProblemButton.onClick.listen((_) {
-      window.open('https://goo.gle/dart-null-safety-migration-tool-issue',
-          'report-problem');
+      window.open(getGitHubProblemUri().toString(), 'report-problem');
     });
 
     document.querySelector('.popup-pane .close').onClick.listen(
@@ -106,6 +105,8 @@
 
 String get rootPath => querySelector('.root').text.trim();
 
+String get sdkVersion => document.getElementById('sdk-version').text;
+
 void addArrowClickHandler(Element arrow) {
   var childList = (arrow.parentNode as Element).querySelector(':scope > ul');
   // Animating height from "auto" to "0" is not supported by CSS [1], so all we
@@ -187,7 +188,11 @@
   }
 }
 
-Uri getGithubUri(String description, Object exception, Object stackTrace) =>
+/// Returns the URL of the "new issue" form for the SDK repository,
+/// pre-populating the title, some labels, using [description], [exception], and
+/// [stackTrace] in the body.
+Uri getGitHubErrorUri(
+        String description, Object exception, Object stackTrace) =>
     Uri.https('github.com', 'dart-lang/sdk/issues/new', {
       'title': 'Issue with NNBD migration tool: $description',
       'labels': 'area-analyzer,analyzer-nnbd-migration,type-bug',
@@ -202,7 +207,7 @@
 **What I was doing when this issue occurred**:
 **Is it possible to work around this issue**:
 **Has this issue happened before, and if so, how often**:
-**Dart SDK version**: (visible in lower left of migration preview)
+**Dart SDK version**: $sdkVersion
 **Additional details**:
 
 Thanks for filing!
@@ -215,6 +220,26 @@
 ''',
     });
 
+/// Returns the URL of the "new issue" form for the SDK repository,
+/// pre-populating some labels and a body template.
+Uri getGitHubProblemUri() =>
+    Uri.https('github.com', 'dart-lang/sdk/issues/new', {
+      'labels': 'area-analyzer,analyzer-nnbd-migration,type-bug',
+      'body': '''
+#### Steps to reproduce
+
+#### What did you expect to happen?
+
+#### What actually happened?
+
+_Screenshots are appreciated_
+
+**Dart SDK version**: $sdkVersion
+
+Thanks for filing!
+''',
+    });
+
 int getLine(String location) {
   var str = Uri.parse(location).queryParameters['line'];
   return str == null ? null : int.tryParse(str);
@@ -258,7 +283,7 @@
   popupPane.querySelector('p').innerText = subheader;
   popupPane.querySelector('pre').innerText = stackTrace.toString();
   (popupPane.querySelector('a.bottom') as AnchorElement).href =
-      getGithubUri(header, subheader, stackTrace).toString();
+      getGitHubErrorUri(header, subheader, stackTrace).toString();
   popupPane..style.display = 'initial';
   logError('$header: $exception', stackTrace);
 }
diff --git a/pkg/nnbd_migration/test/fix_aggregator_test.dart b/pkg/nnbd_migration/test/fix_aggregator_test.dart
index 671c1f3..db9f2ba 100644
--- a/pkg/nnbd_migration/test/fix_aggregator_test.dart
+++ b/pkg/nnbd_migration/test/fix_aggregator_test.dart
@@ -91,7 +91,7 @@
     await analyze(content);
     var previewInfo = run({
       findNode.assignment('+='): NodeChangeForAssignment()
-        ..isCompoundAssignmentWithBadCombinedType = true
+        ..hasBadCombinedType = true
     });
     expect(previewInfo.applyTo(code), content);
     expect(previewInfo, hasLength(1));
@@ -107,7 +107,7 @@
     await analyze(content);
     var previewInfo = run({
       findNode.assignment('+='): NodeChangeForAssignment()
-        ..isCompoundAssignmentWithNullableSource = true
+        ..hasNullableSource = true
     });
     expect(previewInfo.applyTo(code), content);
     expect(previewInfo, hasLength(1));
@@ -144,6 +144,16 @@
     expect(edit.length, '??='.length);
   }
 
+  Future<void> test_assignment_weak_null_aware_remove() async {
+    var content = 'f(int x, int y) => x ??= y;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.assignment('??='): NodeChangeForAssignment()
+        ..isWeakNullAware = true
+    }, warnOnWeakCode: false);
+    expect(previewInfo.applyTo(code), 'f(int x, int y) => x;');
+  }
+
   Future<void> test_eliminateDeadIf_changesInKeptCode() async {
     await analyze('''
 f(int i, int/*?*/ j) {
@@ -856,6 +866,131 @@
     expect(previewInfo.applyTo(code), 'f(a) => a..b!.c;');
   }
 
+  Future<void> test_post_increment_add_null_check() async {
+    var content = 'f(int x) => x++;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.postfix('++'): NodeChangeForPostfixExpression()
+        ..addNullCheck(null)
+    });
+    expect(previewInfo.applyTo(code), 'f(int x) => x++!;');
+  }
+
+  Future<void> test_post_increment_change_target() async {
+    var content = 'f(List<int> x) => x[0]++;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.postfix('++'): NodeChangeForPostfixExpression(),
+      findNode.index('[0]').target: NodeChangeForExpression()
+        ..addNullCheck(null)
+    });
+    expect(previewInfo.applyTo(code), 'f(List<int> x) => x![0]++;');
+  }
+
+  Future<void> test_post_increment_introduce_as() async {
+    var content = 'f(int x) => x++;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.postfix('++'): NodeChangeForPostfixExpression()
+        ..introduceAs(nnbdTypeProvider.intType, null)
+    });
+    expect(previewInfo.applyTo(code), 'f(int x) => x++ as int;');
+  }
+
+  Future<void> test_post_increment_with_bad_combined_type() async {
+    var content = 'f(int x) => x++;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.postfix('++'): NodeChangeForPostfixExpression()
+        ..hasBadCombinedType = true
+    });
+    expect(previewInfo.applyTo(code), content);
+    expect(previewInfo, hasLength(1));
+    var edit = previewInfo[content.indexOf('++')].single;
+    expect(edit.info.description,
+        NullabilityFixDescription.compoundAssignmentHasBadCombinedType);
+    expect(edit.isInformative, isTrue);
+    expect(edit.length, '++'.length);
+  }
+
+  Future<void> test_post_increment_with_nullable_source() async {
+    var content = 'f(int x) => x++;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.postfix('++'): NodeChangeForPostfixExpression()
+        ..hasNullableSource = true
+    });
+    expect(previewInfo.applyTo(code), content);
+    expect(previewInfo, hasLength(1));
+    var edit = previewInfo[content.indexOf('++')].single;
+    expect(edit.info.description,
+        NullabilityFixDescription.compoundAssignmentHasNullableSource);
+    expect(edit.isInformative, isTrue);
+    expect(edit.length, '++'.length);
+  }
+
+  Future<void> test_pre_increment_add_null_check() async {
+    var content = 'f(int x) => ++x;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.prefix('++'): NodeChangeForPrefixExpression()..addNullCheck(null)
+    });
+    expect(previewInfo.applyTo(code), 'f(int x) => (++x)!;');
+  }
+
+  Future<void> test_pre_increment_change_target() async {
+    var content = 'f(List<int> x) => ++x[0];';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.prefix('++'): NodeChangeForPrefixExpression(),
+      findNode.index('[0]').target: NodeChangeForExpression()
+        ..addNullCheck(null)
+    });
+    expect(previewInfo.applyTo(code), 'f(List<int> x) => ++x![0];');
+  }
+
+  Future<void> test_pre_increment_introduce_as() async {
+    var content = 'f(int x) => ++x;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.prefix('++'): NodeChangeForPrefixExpression()
+        ..introduceAs(nnbdTypeProvider.intType, null)
+    });
+    expect(previewInfo.applyTo(code), 'f(int x) => ++x as int;');
+  }
+
+  Future<void> test_pre_increment_with_bad_combined_type() async {
+    var content = 'f(int x) => ++x;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.prefix('++'): NodeChangeForPrefixExpression()
+        ..hasBadCombinedType = true
+    });
+    expect(previewInfo.applyTo(code), content);
+    expect(previewInfo, hasLength(1));
+    var edit = previewInfo[content.indexOf('++')].single;
+    expect(edit.info.description,
+        NullabilityFixDescription.compoundAssignmentHasBadCombinedType);
+    expect(edit.isInformative, isTrue);
+    expect(edit.length, '++'.length);
+  }
+
+  Future<void> test_pre_increment_with_nullable_source() async {
+    var content = 'f(int x) => ++x;';
+    await analyze(content);
+    var previewInfo = run({
+      findNode.prefix('++'): NodeChangeForPrefixExpression()
+        ..hasNullableSource = true
+    });
+    expect(previewInfo.applyTo(code), content);
+    expect(previewInfo, hasLength(1));
+    var edit = previewInfo[content.indexOf('++')].single;
+    expect(edit.info.description,
+        NullabilityFixDescription.compoundAssignmentHasNullableSource);
+    expect(edit.isInformative, isTrue);
+    expect(edit.length, '++'.length);
+  }
+
   Future<void>
       test_removeAs_in_cascade_target_no_parens_needed_cascade() async {
     await analyze('f(a) => ((a..b) as dynamic)..c;');
diff --git a/pkg/nnbd_migration/test/fix_builder_test.dart b/pkg/nnbd_migration/test/fix_builder_test.dart
index 5212cf2..b151462 100644
--- a/pkg/nnbd_migration/test/fix_builder_test.dart
+++ b/pkg/nnbd_migration/test/fix_builder_test.dart
@@ -47,18 +47,6 @@
       TypeMatcher<NodeChangeForDefaultFormalParameter>()
           .having((c) => c.addRequiredKeyword, 'addRequiredKeyword', true);
 
-  static final isCompoundAssignmentNullableSource =
-      TypeMatcher<NodeChangeForAssignment>().having(
-          (c) => c.isCompoundAssignmentWithNullableSource,
-          'isCompoundAssignmentWithNullableSource',
-          true);
-
-  static final isCompoundAssignmentBadCombinedType =
-      TypeMatcher<NodeChangeForAssignment>().having(
-          (c) => c.isCompoundAssignmentWithBadCombinedType,
-          'isCompoundAssignmentWithBadCombinedType',
-          true);
-
   static final isMakeNullable = TypeMatcher<NodeChangeForTypeAnnotation>()
       .having((c) => c.makeNullable, 'makeNullable', true)
       .having((c) => c.nullabilityHint, 'nullabilityHint', isNull);
@@ -73,6 +61,12 @@
   static final isExplainNonNullable = TypeMatcher<NodeChangeForTypeAnnotation>()
       .having((c) => c.makeNullable, 'makeNullable', false);
 
+  static final isBadCombinedType = TypeMatcher<NodeChangeForAssignmentLike>()
+      .having((c) => c.hasBadCombinedType, 'hasBadCombinedType', true);
+
+  static final isNullableSource = TypeMatcher<NodeChangeForAssignmentLike>()
+      .having((c) => c.hasNullableSource, 'hasNullableSource', true);
+
   static final isNodeChangeForExpression =
       TypeMatcher<NodeChangeForExpression>();
 
@@ -1064,6 +1058,22 @@
     visitSubexpression(findNode.booleanLiteral('true'), 'bool');
   }
 
+  Future<void> test_compound_assignment_null_shorted_ok() async {
+    await analyze('''
+class C {
+  int/*!*/ x;
+}
+_f(C/*?*/ c) {
+  c?.x += 1;
+}
+''');
+    // Even though c?.x is nullable, it should not be a problem to use it as the
+    // LHS of a compound assignment, because null shorting will ensure that the
+    // assignment only happens if c is non-null.
+    var assignment = findNode.assignment('+=');
+    visitSubexpression(assignment, 'int?');
+  }
+
   Future<void> test_compound_assignment_nullable_result_bad() async {
     await analyze('''
 abstract class C {
@@ -1075,7 +1085,7 @@
 ''');
     var assignment = findNode.assignment('+=');
     visitSubexpression(assignment, 'C?',
-        changes: {assignment: isCompoundAssignmentBadCombinedType});
+        changes: {assignment: isBadCombinedType});
   }
 
   Future<void> test_compound_assignment_nullable_result_ok() async {
@@ -1103,7 +1113,7 @@
 ''');
     var assignment = findNode.assignment('+=');
     visitSubexpression(assignment, 'int',
-        changes: {assignment: isCompoundAssignmentNullableSource});
+        changes: {assignment: isNullableSource});
   }
 
   Future<void> test_compound_assignment_potentially_nullable_source() async {
@@ -1116,7 +1126,25 @@
 ''');
     var assignment = findNode.assignment('+=');
     visitSubexpression(assignment, 'T',
-        changes: {assignment: isCompoundAssignmentNullableSource});
+        changes: {assignment: isNullableSource});
+  }
+
+  Future<void> test_compound_assignment_promoted_ok() async {
+    await analyze('''
+abstract class C {
+  C/*?*/ operator+(int i);
+}
+f(C/*?*/ x) {
+  if (x != null) {
+    x += 1;
+  }
+}
+''');
+    // The compound assignment is ok, because:
+    // - prior to the assignment, x's value is promoted to non-nullable
+    // - the nullable return value of operator+ is ok to assign to x, because it
+    //   un-does the promotion.
+    visitSubexpression(findNode.assignment('+='), 'C?');
   }
 
   Future<void> test_conditionalExpression_dead_else_remove() async {
@@ -1960,6 +1988,113 @@
     visitSubexpression(findNode.binary('&&'), 'bool');
   }
 
+  Future<void> test_post_decrement_int_behavior() async {
+    await analyze('''
+_f(int x) => x--;
+''');
+    // It's not a problem that int.operator- returns `num` (which is not
+    // assignable to `int`) because the value implicitly passed to operator- has
+    // type `int`, so the static type of the result is `int`.
+    visitSubexpression(findNode.postfix('--'), 'int');
+  }
+
+  Future<void> test_post_increment_int_behavior() async {
+    await analyze('''
+_f(int x) => x++;
+''');
+    // It's not a problem that int.operator+ returns `num` (which is not
+    // assignable to `int`) because the value implicitly passed to operator- has
+    // type `int`, so the static type of the result is `int`.
+    visitSubexpression(findNode.postfix('++'), 'int');
+  }
+
+  Future<void> test_post_increment_null_shorted_ok() async {
+    await analyze('''
+class C {
+  int/*!*/ x;
+}
+_f(C/*?*/ c) {
+  c?.x++;
+}
+''');
+    // Even though c?.x is nullable, it should not be a problem to use it as the
+    // target of a post-increment, because null shorting will ensure that the
+    // increment only happens if c is non-null.
+    var increment = findNode.postfix('++');
+    visitSubexpression(increment, 'int?');
+  }
+
+  Future<void> test_post_increment_nullable_result_bad() async {
+    await analyze('''
+abstract class C {
+  C/*?*/ operator+(int i);
+}
+f(C c) {
+  c++;
+}
+''');
+    var increment = findNode.postfix('++');
+    visitSubexpression(increment, 'C', changes: {increment: isBadCombinedType});
+  }
+
+  Future<void> test_post_increment_nullable_result_ok() async {
+    await analyze('''
+abstract class C {
+  C/*?*/ operator+(int i);
+}
+abstract class D {
+  void set x(C/*?*/ value);
+  C/*!*/ get x;
+  f() {
+    x++;
+  }
+}
+''');
+    var increment = findNode.postfix('++');
+    visitSubexpression(increment, 'C');
+  }
+
+  Future<void> test_post_increment_nullable_source() async {
+    await analyze('''
+_f(int/*?*/ x) {
+  x++;
+}
+''');
+    var increment = findNode.postfix('++');
+    visitSubexpression(increment, 'int?',
+        changes: {increment: isNullableSource});
+  }
+
+  Future<void> test_post_increment_potentially_nullable_source() async {
+    await analyze('''
+class C<T extends num/*?*/> {
+  _f(T/*!*/ x) {
+    x++;
+  }
+}
+''');
+    var increment = findNode.postfix('++');
+    visitSubexpression(increment, 'T', changes: {increment: isNullableSource});
+  }
+
+  Future<void> test_post_increment_promoted_ok() async {
+    await analyze('''
+abstract class C {
+  C/*?*/ operator+(int i);
+}
+f(C/*?*/ x) {
+  if (x != null) {
+    x++;
+  }
+}
+''');
+    // The increment is ok, because:
+    // - prior to the increment, x's value is promoted to non-nullable
+    // - the nullable return value of operator+ is ok to assign to x, because it
+    //   un-does the promotion.
+    visitSubexpression(findNode.postfix('++'), 'C');
+  }
+
   Future<void> test_postfixExpression_combined_nullable_noProblem() async {
     await analyze('''
 abstract class _C {
@@ -2077,6 +2212,115 @@
     visitSubexpression(findNode.postfix('++'), '_C');
   }
 
+  Future<void> test_pre_decrement_int_behavior() async {
+    await analyze('''
+_f(int x) => --x;
+''');
+    // It's not a problem that int.operator- returns `num` (which is not
+    // assignable to `int`) because the value implicitly passed to operator- has
+    // type `int`, so the static type of the result is `int`.
+    visitSubexpression(findNode.prefix('--'), 'int');
+  }
+
+  Future<void> test_pre_increment_int_behavior() async {
+    await analyze('''
+_f(int x) => ++x;
+''');
+    // It's not a problem that int.operator+ returns `num` (which is not
+    // assignable to `int`) because the value implicitly passed to operator- has
+    // type `int`, so the static type of the result is `int`.
+    visitSubexpression(findNode.prefix('++'), 'int');
+  }
+
+  Future<void> test_pre_increment_null_shorted_ok() async {
+    await analyze('''
+class C {
+  int/*!*/ x;
+}
+_f(C/*?*/ c) {
+  ++c?.x;
+}
+''');
+    // Even though c?.x is nullable, it should not be a problem to use it as the
+    // target of a pre-increment, because null shorting will ensure that the
+    // increment only happens if c is non-null.
+    var increment = findNode.prefix('++');
+    visitSubexpression(increment, 'int?');
+  }
+
+  Future<void> test_pre_increment_nullable_result_bad() async {
+    await analyze('''
+abstract class C {
+  C/*?*/ operator+(int i);
+}
+f(C c) {
+  ++c;
+}
+''');
+    var increment = findNode.prefix('++');
+    visitSubexpression(increment, 'C?',
+        changes: {increment: isBadCombinedType});
+  }
+
+  Future<void> test_pre_increment_nullable_result_ok() async {
+    await analyze('''
+abstract class C {
+  C/*?*/ operator+(int i);
+}
+abstract class D {
+  void set x(C/*?*/ value);
+  C/*!*/ get x;
+  f() {
+    ++x;
+  }
+}
+''');
+    var increment = findNode.prefix('++');
+    visitSubexpression(increment, 'C?');
+  }
+
+  Future<void> test_pre_increment_nullable_source() async {
+    await analyze('''
+_f(int/*?*/ x) {
+  ++x;
+}
+''');
+    var increment = findNode.prefix('++');
+    visitSubexpression(increment, 'int',
+        changes: {increment: isNullableSource});
+  }
+
+  Future<void> test_pre_increment_potentially_nullable_source() async {
+    await analyze('''
+class C<T extends num/*?*/> {
+  _f(T/*!*/ x) {
+    ++x;
+  }
+}
+''');
+    var increment = findNode.prefix('++');
+    visitSubexpression(increment, 'num',
+        changes: {increment: isNullableSource});
+  }
+
+  Future<void> test_pre_increment_promoted_ok() async {
+    await analyze('''
+abstract class C {
+  C/*?*/ operator+(int i);
+}
+f(C/*?*/ x) {
+  if (x != null) {
+    ++x;
+  }
+}
+''');
+    // The increment is ok, because:
+    // - prior to the increment, x's value is promoted to non-nullable
+    // - the nullable return value of operator+ is ok to assign to x, because it
+    //   un-does the promotion.
+    visitSubexpression(findNode.prefix('++'), 'C?');
+  }
+
   Future<void> test_prefixedIdentifier_dynamic() async {
     await analyze('''
 Object/*!*/ _f(dynamic d) => d.x;
@@ -2191,7 +2435,6 @@
         changes: {findNode.simple('x;'): isNullCheck});
   }
 
-  @FailingTest(reason: 'TODO(paulberry)')
   Future<void> test_prefixExpression_combined_nullable_noProblem() async {
     await analyze('''
 abstract class _C {
diff --git a/pkg/nnbd_migration/test/front_end/info_builder_test.dart b/pkg/nnbd_migration/test/front_end/info_builder_test.dart
index ece8325..a1490f0 100644
--- a/pkg/nnbd_migration/test/front_end/info_builder_test.dart
+++ b/pkg/nnbd_migration/test/front_end/info_builder_test.dart
@@ -694,6 +694,56 @@
         explanation: "Changed type 'String' to be nullable");
   }
 
+  Future<void> test_increment_nullable_result() async {
+    var unit = await buildInfoForSingleTestFile('''
+abstract class C {
+  C/*?*/ operator+(int i);
+}
+void f(C/*!*/ a) {
+  a++;
+}
+''', migratedContent: '''
+abstract class C {
+  C/*?*/ operator+(int  i);
+}
+void f(C/*!*/ a) {
+  a++;
+}
+''');
+    var operator = '++';
+    var operatorOffset = unit.content.indexOf(operator);
+    var region =
+        unit.regions.where((region) => region.offset == operatorOffset).single;
+    assertRegion(
+        region: region,
+        length: operator.length,
+        explanation: 'Compound assignment has bad combined type',
+        kind: NullabilityFixKind.compoundAssignmentHasBadCombinedType,
+        edits: isEmpty);
+  }
+
+  Future<void> test_increment_nullable_source() async {
+    var unit = await buildInfoForSingleTestFile('''
+void f(int/*?*/ a) {
+  a++;
+}
+''', migratedContent: '''
+void f(int/*?*/ a) {
+  a++;
+}
+''');
+    var operator = '++';
+    var operatorOffset = unit.content.indexOf(operator);
+    var region =
+        unit.regions.where((region) => region.offset == operatorOffset).single;
+    assertRegion(
+        region: region,
+        length: operator.length,
+        explanation: 'Compound assignment has nullable source',
+        kind: NullabilityFixKind.compoundAssignmentHasNullableSource,
+        edits: isEmpty);
+  }
+
   Future<void> test_insertedRequired_fieldFormal() async {
     var unit = await buildInfoForSingleTestFile('''
 class C {
@@ -784,6 +834,45 @@
         kind: NullabilityFixKind.checkExpression);
   }
 
+  void test_nullAwareAssignment_remove() async {
+    var unit = await buildInfoForSingleTestFile('''
+int f(int/*!*/ x, int y) => x ??= y;
+''', migratedContent: '''
+int  f(int/*!*/ x, int  y) => x ??= y;
+''', warnOnWeakCode: false, removeViaComments: false);
+    var codeToRemove = ' ??= y';
+    var removalOffset = unit.content.indexOf(codeToRemove);
+    var region =
+        unit.regions.where((region) => region.offset == removalOffset).single;
+    assertRegion(
+        region: region,
+        length: codeToRemove.length,
+        explanation:
+            'Removed a null-aware assignment, because the target cannot be '
+            'null',
+        kind: NullabilityFixKind.removeDeadCode,
+        edits: isEmpty);
+  }
+
+  void test_nullAwareAssignment_unnecessaryInStrongMode() async {
+    var unit = await buildInfoForSingleTestFile('''
+int f(int/*!*/ x, int y) => x ??= y;
+''', migratedContent: '''
+int  f(int/*!*/ x, int  y) => x ??= y;
+''', warnOnWeakCode: true);
+    var operator = '??=';
+    var operatorOffset = unit.content.indexOf(operator);
+    var region =
+        unit.regions.where((region) => region.offset == operatorOffset).single;
+    assertRegion(
+        region: region,
+        length: operator.length,
+        explanation:
+            'Null-aware assignment will be unnecessary in strong checking mode',
+        kind: NullabilityFixKind.nullAwareAssignmentUnnecessaryInStrongMode,
+        edits: isEmpty);
+  }
+
   void test_nullAwarenessUnnecessaryInStrongMode() async {
     var unit = await buildInfoForSingleTestFile('''
 int f(String s) => s?.length;
diff --git a/pkg/telemetry/lib/crash_reporting.dart b/pkg/telemetry/lib/crash_reporting.dart
index 1590da8..7b4b958 100644
--- a/pkg/telemetry/lib/crash_reporting.dart
+++ b/pkg/telemetry/lib/crash_reporting.dart
@@ -18,9 +18,11 @@
 /// Crash backend host.
 const String _crashServerHost = 'clients2.google.com';
 
-// This should be one of 'report' or 'staging_report'.
-/// Path to the crash servlet.
-const String _crashEndpointPath = '/cr/staging_report';
+/// Path to the staging crash servlet.
+const String _crashEndpointPathStaging = '/cr/staging_report';
+
+/// Path to the prod crash servlet.
+const String _crashEndpointPathProd = '/cr/report';
 
 /// The field corresponding to the multipart/form-data file attachment where
 /// crash backend expects to find the Dart stack trace.
@@ -36,8 +38,7 @@
 ///
 /// Clients shouldn't extend, mixin or implement this class.
 class CrashReportSender {
-  static final Uri _baseUri = new Uri(
-      scheme: 'https', host: _crashServerHost, path: _crashEndpointPath);
+  final Uri _baseUri;
 
   static const int _maxReportsToSend = 1000;
 
@@ -50,12 +51,30 @@
   int _reportsSent = 0;
   int _skippedReports = 0;
 
-  /// Create a new [CrashReportSender].
-  CrashReportSender(
+  CrashReportSender._(
     this.crashProductId,
     this.shouldSend, {
     http.Client httpClient,
-  }) : _httpClient = httpClient ?? new http.Client();
+    String endpointPath = _crashEndpointPathStaging,
+  })  : _httpClient = httpClient ?? new http.Client(),
+        _baseUri = new Uri(
+            scheme: 'https', host: _crashServerHost, path: endpointPath);
+
+  /// Create a new [CrashReportSender] connected to the staging endpoint.
+  CrashReportSender.staging(
+    String crashProductId,
+    EnablementCallback shouldSend, {
+    http.Client httpClient,
+  }) : this._(crashProductId, shouldSend,
+            httpClient: httpClient, endpointPath: _crashEndpointPathStaging);
+
+  /// Create a new [CrashReportSender] connected to the prod endpoint.
+  CrashReportSender.prod(
+    String crashProductId,
+    EnablementCallback shouldSend, {
+    http.Client httpClient,
+  }) : this._(crashProductId, shouldSend,
+            httpClient: httpClient, endpointPath: _crashEndpointPathProd);
 
   /// Sends one crash report.
   ///
diff --git a/pkg/telemetry/test/crash_reporting_test.dart b/pkg/telemetry/test/crash_reporting_test.dart
index be93424..440eee9 100644
--- a/pkg/telemetry/test/crash_reporting_test.dart
+++ b/pkg/telemetry/test/crash_reporting_test.dart
@@ -31,7 +31,7 @@
     };
 
     test('general', () async {
-      CrashReportSender sender = new CrashReportSender(
+      CrashReportSender sender = new CrashReportSender.prod(
           analytics.trackingId, shouldSend,
           httpClient: mockClient);
 
@@ -43,7 +43,7 @@
     });
 
     test('reportsSent', () async {
-      CrashReportSender sender = new CrashReportSender(
+      CrashReportSender sender = new CrashReportSender.prod(
           analytics.trackingId, shouldSend,
           httpClient: mockClient);
 
@@ -59,7 +59,7 @@
     });
 
     test('contains message', () async {
-      CrashReportSender sender = new CrashReportSender(
+      CrashReportSender sender = new CrashReportSender.prod(
           analytics.trackingId, shouldSend,
           httpClient: mockClient);
 
@@ -73,7 +73,7 @@
     });
 
     test('has attachments', () async {
-      CrashReportSender sender = new CrashReportSender(
+      CrashReportSender sender = new CrashReportSender.prod(
           analytics.trackingId, shouldSend,
           httpClient: mockClient);
 
@@ -94,7 +94,7 @@
     });
 
     test('has ptime', () async {
-      CrashReportSender sender = new CrashReportSender(
+      CrashReportSender sender = new CrashReportSender.prod(
           analytics.trackingId, shouldSend,
           httpClient: mockClient);
 
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index d9ace1d..ebabe3f 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -1435,6 +1435,8 @@
   TypeCheck explicitCast(AsExpression cast) =>
       summaryCollector.explicitCasts[cast];
 
+  NarrowNotNull nullTest(TreeNode node) => summaryCollector.nullTests[node];
+
   Type fieldType(Field field) => _fieldValues[field]?.value;
 
   Args<Type> argumentTypes(Member member) => _summaries[member]?.argumentTypes;
diff --git a/pkg/vm/lib/transformations/type_flow/summary.dart b/pkg/vm/lib/transformations/type_flow/summary.dart
index 0b4ab0f..8e66c3e 100644
--- a/pkg/vm/lib/transformations/type_flow/summary.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary.dart
@@ -134,6 +134,49 @@
       arg.getComputedType(computedTypes).intersection(type, typeHierarchy);
 }
 
+/// A flavor of [Narrow] statement which narrows argument
+/// to a non-nullable type and records if argument can be
+/// null or not null.
+class NarrowNotNull extends Narrow {
+  static const int canBeNullFlag = 1 << 0;
+  static const int canBeNotNullFlag = 1 << 1;
+  int _flags = 0;
+
+  NarrowNotNull(TypeExpr arg) : super(arg, const AnyType());
+
+  // Shared NarrowNotNull instances which are used when the outcome is
+  // known at summary creation time.
+  static final NarrowNotNull alwaysNotNull = NarrowNotNull(null)
+    .._flags = canBeNotNullFlag;
+  static final NarrowNotNull alwaysNull = NarrowNotNull(null)
+    .._flags = canBeNullFlag;
+  static final NarrowNotNull unknown = NarrowNotNull(null)
+    .._flags = canBeNullFlag | canBeNotNullFlag;
+
+  bool get isAlwaysNull => (_flags & canBeNotNullFlag) == 0;
+  bool get isAlwaysNotNull => (_flags & canBeNullFlag) == 0;
+
+  Type handleArgument(Type argType) {
+    if (argType is NullableType) {
+      final baseType = argType.baseType;
+      if (baseType is EmptyType) {
+        _flags |= canBeNullFlag;
+      } else {
+        _flags |= (canBeNullFlag | canBeNotNullFlag);
+      }
+      return baseType;
+    } else {
+      _flags |= canBeNotNullFlag;
+      return argType;
+    }
+  }
+
+  @override
+  Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+          CallHandler callHandler) =>
+      handleArgument(arg.getComputedType(computedTypes));
+}
+
 /// Joins values from multiple sources. Its type is a union of [values].
 class Join extends Statement {
   final String _name;
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index 348f562..b95602b 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -65,7 +65,7 @@
     }
 
     for (Statement st in statements) {
-      if (st is Call || st is TypeCheck) {
+      if (st is Call || st is TypeCheck || st is NarrowNotNull) {
         _normalizeExpr(st, false);
       } else if (st is Use) {
         _normalizeExpr(st.arg, true);
@@ -114,6 +114,14 @@
               }
             }
           }
+        } else if (st is NarrowNotNull) {
+          // This pattern may appear after approximations during summary
+          // normalization, so it's not enough to handle it in
+          // _makeNarrowNotNull.
+          final arg = st.arg;
+          if (arg is Type) {
+            return st.handleArgument(arg);
+          }
         } else if (st is Narrow) {
           // This pattern may appear after approximations during summary
           // normalization (so it's not enough to handle it in _makeNarrow).
@@ -517,6 +525,7 @@
   final Map<TreeNode, Call> callSites = <TreeNode, Call>{};
   final Map<AsExpression, TypeCheck> explicitCasts =
       <AsExpression, TypeCheck>{};
+  final Map<TreeNode, NarrowNotNull> nullTests = <TreeNode, NarrowNotNull>{};
   final _FallthroughDetector _fallthroughDetector = new _FallthroughDetector();
   final Set<Name> _nullMethodsAndGetters = <Name>{};
   final Set<Name> _nullSetters = <Name>{};
@@ -1104,6 +1113,37 @@
     return _makeNarrow(arg, _typesBuilder.fromStaticType(type, canBeNull));
   }
 
+  TypeExpr _makeNarrowNotNull(TreeNode node, TypeExpr arg) {
+    assertx(node is NullCheck ||
+        node is MethodInvocation && isComparisonWithNull(node));
+    if (arg is NarrowNotNull) {
+      nullTests[node] = arg;
+      return arg;
+    } else if (arg is Narrow) {
+      if (arg.type is! NullableType) {
+        nullTests[node] = NarrowNotNull.alwaysNotNull;
+        return arg;
+      }
+    } else if (arg is Type) {
+      if (arg is NullableType) {
+        final baseType = arg.baseType;
+        if (baseType is EmptyType) {
+          nullTests[node] = NarrowNotNull.alwaysNull;
+        } else {
+          nullTests[node] = NarrowNotNull.unknown;
+        }
+        return baseType;
+      } else {
+        nullTests[node] = NarrowNotNull.alwaysNotNull;
+        return arg;
+      }
+    }
+    final narrow = NarrowNotNull(arg);
+    nullTests[node] = narrow;
+    _summary.add(narrow);
+    return narrow;
+  }
+
   // Add an artificial use of given expression in order to make it possible to
   // infer its type even if it is not used in a summary.
   void _addUse(TypeExpr arg) {
@@ -1303,13 +1343,16 @@
           node.arguments.named.isEmpty);
       final lhs = node.receiver as VariableGet;
       final rhs = node.arguments.positional.single;
-      if (rhs is NullLiteral) {
+      if (isNullLiteral(rhs)) {
         // 'x == null', where x is a variable.
-        _addUse(_visit(node));
+        final expr = _visit(lhs);
+        _makeCall(node, DirectSelector(_environment.coreTypes.objectEquals),
+            Args<TypeExpr>([expr, _nullType]));
+        final narrowedNotNull = _makeNarrowNotNull(node, expr);
         final int varIndex = _variablesInfo.varIndex[lhs.variable];
         if (_variableCells[varIndex] == null) {
           trueState[varIndex] = _nullType;
-          falseState[varIndex] = _makeNarrow(_visit(lhs), const AnyType());
+          falseState[varIndex] = narrowedNotNull;
         }
         _variableValues = null;
         return;
@@ -1389,7 +1432,7 @@
   @override
   TypeExpr visitNullCheck(NullCheck node) {
     final operandNode = node.operand;
-    final TypeExpr result = _makeNarrow(_visit(operandNode), const AnyType());
+    final TypeExpr result = _makeNarrowNotNull(node, _visit(operandNode));
     if (operandNode is VariableGet) {
       final int varIndex = _variablesInfo.varIndex[operandNode.variable];
       if (_variableCells[varIndex] == null) {
@@ -1572,6 +1615,13 @@
 
   @override
   TypeExpr visitMethodInvocation(MethodInvocation node) {
+    if (isComparisonWithNull(node)) {
+      final arg = _visit(getArgumentOfComparisonWithNull(node));
+      _makeNarrowNotNull(node, arg);
+      _makeCall(node, DirectSelector(_environment.coreTypes.objectEquals),
+          Args<TypeExpr>([arg, _nullType]));
+      return _boolType;
+    }
     final receiverNode = node.receiver;
     final receiver = _visit(receiverNode);
     final args = _visitArguments(receiver, node.arguments);
@@ -1585,10 +1635,6 @@
     TypeExpr result;
     if (target == null) {
       if (node.name.name == '==') {
-        assertx(args.values.length == 2);
-        if ((args.values[0] == _nullType) || (args.values[1] == _nullType)) {
-          return _boolType;
-        }
         _makeCall(node, new DynamicSelector(CallKind.Method, node.name), args);
         return new Type.nullable(_boolType);
       }
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index b24f12e..65d3abc 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -904,8 +904,18 @@
     return expr is Throw;
   }
 
+  TreeNode _evaluateArguments(List<Expression> args, Expression result) {
+    Expression node = result;
+    for (var arg in args.reversed) {
+      if (mayHaveSideEffects(arg)) {
+        node = Let(VariableDeclaration(null, initializer: arg), node);
+      }
+    }
+    return node;
+  }
+
   TreeNode _makeUnreachableCall(List<Expression> args) {
-    TreeNode node;
+    Expression node;
     final int last = args.indexWhere(_isThrowExpression);
     if (last >= 0) {
       // One of the arguments is a Throw expression.
@@ -914,16 +924,11 @@
       args = args.sublist(0, last);
       Statistics.throwExpressionsPruned++;
     } else {
-      node = new Throw(new StringLiteral(
+      node = Throw(StringLiteral(
           'Attempt to execute code removed by Dart AOT compiler (TFA)'));
     }
-    for (var arg in args.reversed) {
-      if (mayHaveSideEffects(arg)) {
-        node = new Let(new VariableDeclaration(null, initializer: arg), node);
-      }
-    }
     Statistics.callsDropped++;
-    return node;
+    return _evaluateArguments(args, node);
   }
 
   TreeNode _makeUnreachableInitializer(List<Expression> args) {
@@ -931,6 +936,9 @@
         new VariableDeclaration(null, initializer: _makeUnreachableCall(args)));
   }
 
+  NarrowNotNull _getNullTest(TreeNode node) =>
+      shaker.typeFlowAnalysis.nullTest(node);
+
   TreeNode _visitAssertNode(TreeNode node) {
     if (kRemoveAsserts) {
       return null;
@@ -1038,14 +1046,21 @@
     if (_isUnreachable(node)) {
       return _makeUnreachableCall(
           _flattenArguments(node.arguments, receiver: node.receiver));
-    } else {
-      node.interfaceTarget =
-          fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
-      if (node.interfaceTarget != null) {
-        shaker.addUsedMember(node.interfaceTarget);
-      }
-      return node;
     }
+    if (isComparisonWithNull(node)) {
+      final nullTest = _getNullTest(node);
+      if (nullTest.isAlwaysNull || nullTest.isAlwaysNotNull) {
+        return _evaluateArguments(
+            _flattenArguments(node.arguments, receiver: node.receiver),
+            BoolLiteral(nullTest.isAlwaysNull));
+      }
+    }
+    node.interfaceTarget =
+        fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
+    if (node.interfaceTarget != null) {
+      shaker.addUsedMember(node.interfaceTarget);
+    }
+    return node;
   }
 
   @override
@@ -1384,6 +1399,19 @@
     return node;
   }
 
+  @override
+  TreeNode visitNullCheck(NullCheck node) {
+    node.transformChildren(this);
+    final nullTest = _getNullTest(node);
+    if (nullTest.isAlwaysNotNull) {
+      return StaticInvocation(
+          unsafeCast,
+          Arguments([node.operand],
+              types: [node.getStaticType(staticTypeContext)]));
+    }
+    return node;
+  }
+
   Procedure get unsafeCast {
     _unsafeCast ??= shaker.typeFlowAnalysis.environment.coreTypes.index
         .getTopLevelMember('dart:_internal', 'unsafeCast');
diff --git a/pkg/vm/lib/transformations/type_flow/utils.dart b/pkg/vm/lib/transformations/type_flow/utils.dart
index 1bd903f..07f6454 100644
--- a/pkg/vm/lib/transformations/type_flow/utils.dart
+++ b/pkg/vm/lib/transformations/type_flow/utils.dart
@@ -6,16 +6,7 @@
 /// analysis.
 library vm.transformations.type_flow.utils;
 
-import 'package:kernel/ast.dart'
-    show
-        Class,
-        Constructor,
-        DartType,
-        FunctionNode,
-        Member,
-        Nullability,
-        Procedure,
-        VariableDeclaration;
+import 'package:kernel/ast.dart';
 
 const bool kPrintTrace =
     const bool.fromEnvironment('global.type.flow.print.trace');
@@ -268,3 +259,23 @@
 extension NullabilitySuffix on Nullability {
   String get suffix => nullabilitySuffix[this];
 }
+
+bool isNullLiteral(Expression expr) =>
+    expr is NullLiteral ||
+    (expr is ConstantExpression && expr.constant is NullConstant);
+
+Expression getArgumentOfComparisonWithNull(MethodInvocation node) {
+  if (node.name.name == '==') {
+    final lhs = node.receiver;
+    final rhs = node.arguments.positional.single;
+    if (isNullLiteral(lhs)) {
+      return rhs;
+    } else if (isNullLiteral(rhs)) {
+      return lhs;
+    }
+  }
+  return null;
+}
+
+bool isComparisonWithNull(MethodInvocation node) =>
+    getArgumentOfComparisonWithNull(node) != null;
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect
index b840c08..9bea26d 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect
@@ -116,11 +116,11 @@
 %z = _Parameter #2 [_T ANY?]
 t3* = _Call [num::==] (%x, _T (dart.core::_Smi, 5))
 t4* = _Call [String::==] (%y, _T (dart.core::_OneByteString, hi))
-t5* = _Call [Object::==] (%z, _T {}?)
-t6 = _Call direct [foo] (_T (dart.core::_Smi, 5))
-t7 = _Call direct [foo] (_T (dart.core::_OneByteString, hi))
-t8 = _Narrow (%z to _T ANY)
-t9 = _Call direct [foo] (t8)
+t5 = _Call direct [Object::==] (%z, _T {}?)
+t6 = _Narrow (%z to _T ANY)
+t7 = _Call direct [foo] (_T (dart.core::_Smi, 5))
+t8 = _Call direct [foo] (_T (dart.core::_OneByteString, hi))
+t9 = _Call direct [foo] (t6)
 RESULT: _T {}?
 ------------ if8 ------------
 %x = _Parameter #0 [_T ANY?]
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart b/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart
new file mode 100644
index 0000000..1d5fb04
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2020, 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.
+
+// Tests elimination of null checks.
+// This test requires non-nullable experiment.
+
+// @dart = 2.9
+
+class A {
+  String? nonNullable;
+  String? nullable;
+  String? alwaysNull;
+  A({this.nonNullable, this.nullable, this.alwaysNull});
+}
+
+testNonNullable(A a) => a.nonNullable!;
+testNullable(A a) => a.nullable!;
+testAlwaysNull(A a) => a.alwaysNull!;
+
+unused() => A(nonNullable: null, alwaysNull: 'abc');
+
+A staticField = A(nonNullable: 'hi', nullable: 'bye');
+
+void main() {
+  final list = [
+    A(nonNullable: 'foo', nullable: null, alwaysNull: null),
+    staticField,
+  ];
+  for (A a in list) {
+    testNonNullable(a);
+    testNullable(a);
+    testAlwaysNull(a);
+  }
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart.expect
new file mode 100644
index 0000000..c69020d9
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart.expect
@@ -0,0 +1,34 @@
+library #lib /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class A extends core::Object {
+[@vm.inferred-type.metadata=dart.core::_OneByteString] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  field core::String? nonNullable;
+[@vm.inferred-type.metadata=dart.core::_OneByteString?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  field core::String? nullable;
+[@vm.inferred-type.metadata=dart.core::Null? (value: null)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6]  field core::String? alwaysNull;
+  constructor •([@vm.inferred-type.metadata=dart.core::_OneByteString] core::String? nonNullable, [@vm.inferred-type.metadata=dart.core::_OneByteString?] core::String? nullable, {[@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::String? alwaysNull = #C1}) → self::A
+    : self::A::nonNullable = nonNullable, self::A::nullable = nullable, self::A::alwaysNull = alwaysNull, super core::Object::•()
+    ;
+}
+[@vm.inferred-type.metadata=#lib::A?]static field self::A staticField = let core::String #arg1 = "hi" in let core::String #arg2 = "bye" in new self::A::•(#arg1, #arg2);
+static method testNonNullable([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic
+  return _in::unsafeCast<core::String>([@vm.direct-call.metadata=A::nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable});
+static method testNullable([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic
+  return [@vm.direct-call.metadata=A::nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}!;
+static method testAlwaysNull([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic
+  return [@vm.direct-call.metadata=A::alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull}!;
+static method main() → void {
+  final core::List<self::A> list = <self::A>[let core::String #arg1 = "foo" in let core::Null? #arg2 = null in let core::Null? #arg3 = null in new self::A::•(#arg1, #arg2, alwaysNull: #arg3), self::staticField];
+  {
+    core::Iterator<self::A*> :sync-for-iterator = [@vm.direct-call.metadata=_GrowableList::iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<InterfaceType(A*)>] list.{core::Iterable::iterator};
+    for (; [@vm.direct-call.metadata=ListIterator::moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+      self::A a = [@vm.direct-call.metadata=ListIterator::current] [@vm.inferred-type.metadata=#lib::A?] :sync-for-iterator.{core::Iterator::current};
+      {
+        self::testNonNullable(a);
+        self::testNullable(a);
+        self::testAlwaysNull(a);
+      }
+    }
+  }
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart b/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart
new file mode 100644
index 0000000..98488d3
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2020, 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.
+
+// Tests elimination of null tests.
+
+class A {
+  String nonNullable;
+  String nullable;
+  String alwaysNull;
+  A({this.nonNullable, this.nullable, this.alwaysNull});
+}
+
+testNonNullableIf1(A a) {
+  if (a.nonNullable == null) {
+    print('null');
+  }
+}
+
+testNullableIf1(A a) {
+  if (a.nullable == null) {
+    print('null');
+  }
+}
+
+testAlwaysNullIf1(A a) {
+  if (a.alwaysNull == null) {
+    print('null');
+  }
+}
+
+testNonNullableIf2(A a) {
+  if (a.nonNullable != null && someCondition()) {
+    print('not null');
+  }
+}
+
+testNullableIf2(A a) {
+  if (a.nullable != null && someCondition()) {
+    print('not null');
+  }
+}
+
+testAlwaysNullIf2(A a) {
+  if (a.alwaysNull != null && someCondition()) {
+    print('not null');
+  }
+}
+
+testNonNullableCondExpr(A a) => a.nonNullable != null ? 'not null' : 'null';
+testNullableCondExpr(A a) => a.nullable != null ? 'not null' : 'null';
+testAlwaysNullCondExpr(A a) => a.alwaysNull != null ? 'not null' : 'null';
+
+someCondition() => int.parse("1") == 1;
+unused() => A(nonNullable: null, alwaysNull: 'abc');
+
+A staticField = A(nonNullable: 'hi', nullable: 'bye');
+
+void main() {
+  final list = [
+    A(nonNullable: 'foo', nullable: null, alwaysNull: null),
+    staticField,
+  ];
+  for (A a in list) {
+    testNonNullableIf1(a);
+    testNullableIf1(a);
+    testAlwaysNullIf1(a);
+    testNonNullableIf2(a);
+    testNullableIf2(a);
+    testAlwaysNullIf2(a);
+    testNonNullableCondExpr(a);
+    testNullableCondExpr(a);
+    testAlwaysNullCondExpr(a);
+  }
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect
new file mode 100644
index 0000000..89327df
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect
@@ -0,0 +1,72 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class A extends core::Object {
+[@vm.inferred-type.metadata=dart.core::_OneByteString] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  field core::String* nonNullable;
+[@vm.inferred-type.metadata=dart.core::_OneByteString?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  field core::String* nullable;
+[@vm.inferred-type.metadata=dart.core::Null? (value: null)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6]  field core::String* alwaysNull;
+  constructor •([@vm.inferred-type.metadata=dart.core::_OneByteString] core::String* nonNullable, [@vm.inferred-type.metadata=dart.core::_OneByteString?] core::String* nullable, {[@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::String* alwaysNull = #C1}) → self::A*
+    : self::A::nonNullable = nonNullable, self::A::nullable = nullable, self::A::alwaysNull = alwaysNull, super core::Object::•()
+    ;
+}
+[@vm.inferred-type.metadata=#lib::A?]static field self::A* staticField = let core::String* #arg1 = "hi" in let core::String* #arg2 = "bye" in new self::A::•(#arg1, #arg2);
+static method testNonNullableIf1([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
+  if(let dynamic #t1 = [@vm.direct-call.metadata=A::nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable} in false) {
+    core::print("null");
+  }
+}
+static method testNullableIf1([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
+  if([@vm.direct-call.metadata=A::nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}.{core::String::==}(null)) {
+    core::print("null");
+  }
+}
+static method testAlwaysNullIf1([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
+  if(let dynamic #t2 = [@vm.direct-call.metadata=A::alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull} in true) {
+    core::print("null");
+  }
+}
+static method testNonNullableIf2([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
+  if(!(let dynamic #t3 = [@vm.direct-call.metadata=A::nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable} in false) && _in::unsafeCast<core::bool*>([@vm.inferred-type.metadata=dart.core::bool] self::someCondition())) {
+    core::print("not null");
+  }
+}
+static method testNullableIf2([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
+  if(![@vm.direct-call.metadata=A::nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}.{core::String::==}(null) && _in::unsafeCast<core::bool*>([@vm.inferred-type.metadata=dart.core::bool] self::someCondition())) {
+    core::print("not null");
+  }
+}
+static method testAlwaysNullIf2([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
+  if(!(let dynamic #t4 = [@vm.direct-call.metadata=A::alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull} in true) && _in::unsafeCast<core::bool*>([@vm.inferred-type.metadata=dart.core::bool] self::someCondition())) {
+    core::print("not null");
+  }
+}
+static method testNonNullableCondExpr([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic
+  return !(let dynamic #t5 = [@vm.direct-call.metadata=A::nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable} in false) ?{core::String*} "not null" : "null";
+static method testNullableCondExpr([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic
+  return ![@vm.direct-call.metadata=A::nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}.{core::String::==}(null) ?{core::String*} "not null" : "null";
+static method testAlwaysNullCondExpr([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic
+  return !(let dynamic #t6 = [@vm.direct-call.metadata=A::alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull} in true) ?{core::String*} "not null" : "null";
+static method someCondition() → dynamic
+  return [@vm.direct-call.metadata=_IntegerImplementation::==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(1);
+static method main() → void {
+  final core::List<self::A*>* list = <self::A*>[let core::String* #arg1 = "foo" in let core::Null? #arg2 = null in let core::Null? #arg3 = null in new self::A::•(#arg1, #arg2, alwaysNull: #arg3), self::staticField];
+  {
+    core::Iterator<self::A*>* :sync-for-iterator = [@vm.direct-call.metadata=_GrowableList::iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<InterfaceType(A*)>] list.{core::Iterable::iterator};
+    for (; [@vm.direct-call.metadata=ListIterator::moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+      self::A* a = [@vm.direct-call.metadata=ListIterator::current] [@vm.inferred-type.metadata=#lib::A?] :sync-for-iterator.{core::Iterator::current};
+      {
+        self::testNonNullableIf1(a);
+        self::testNullableIf1(a);
+        self::testAlwaysNullIf1(a);
+        self::testNonNullableIf2(a);
+        self::testNullableIf2(a);
+        self::testAlwaysNullIf2(a);
+        self::testNonNullableCondExpr(a);
+        self::testNullableCondExpr(a);
+        self::testAlwaysNullCondExpr(a);
+      }
+    }
+  }
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_41452_nnbd_strong.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/regress_41452_nnbd_strong.dart.expect
index 3128139..31685ef 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_41452_nnbd_strong.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_41452_nnbd_strong.dart.expect
@@ -19,7 +19,7 @@
     ;
 [@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  method add(generic-covariant-impl self::_SplayTree::Node n) → dynamic {
     self::_SplayTree::Node? root = [@vm.direct-call.metadata=SplayTreeMap::_root] [@vm.inferred-type.metadata=#lib::_SplayTreeMapNode] this.{self::_SplayTree::_root};
-    if([@vm.direct-call.metadata=Object::==] [@vm.inferred-type.metadata=dart.core::bool (skip check) (receiver not int)] root.{core::Object::==}(null))
+    if(false)
       return;
     core::print([@vm.direct-call.metadata=_SplayTreeNode::left] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] root{self::_SplayTree::Node}.{self::_SplayTreeNode::left});
   }
diff --git a/pkg/vm_service/CHANGELOG.md b/pkg/vm_service/CHANGELOG.md
index 71cb31c..9a99196 100644
--- a/pkg/vm_service/CHANGELOG.md
+++ b/pkg/vm_service/CHANGELOG.md
@@ -1,5 +1,10 @@
 # Changelog
 
+## next
+- Update to version `3.33.0` of the spec.
+- Add static error code constants to `RPCError`.
+- Update the toString() method or `RPCError` and add a toMap() method.
+
 ## 4.0.2
 - Fixed issue where RPC format did not conform to the JSON-RPC 2.0
   specification.
diff --git a/pkg/vm_service/java/version.properties b/pkg/vm_service/java/version.properties
index af022cb..47ae094 100644
--- a/pkg/vm_service/java/version.properties
+++ b/pkg/vm_service/java/version.properties
@@ -1 +1 @@
-version=3.32
+version=3.33
diff --git a/pkg/vm_service/lib/src/vm_service.dart b/pkg/vm_service/lib/src/vm_service.dart
index d6569a9..d9ce8d7 100644
--- a/pkg/vm_service/lib/src/vm_service.dart
+++ b/pkg/vm_service/lib/src/vm_service.dart
@@ -28,7 +28,7 @@
         HeapSnapshotObjectNoData,
         HeapSnapshotObjectNullData;
 
-const String vmServiceVersion = '3.32.0';
+const String vmServiceVersion = '3.33.0';
 
 /// @optional
 const String optional = 'optional';
@@ -1196,7 +1196,8 @@
       }
       var method = request['method'] as String;
       if (method == null) {
-        throw RPCError(null, -32600, 'Invalid Request', request);
+        throw RPCError(
+            null, RPCError.kInvalidRequest, 'Invalid Request', request);
       }
       var params = request['params'] as Map;
       Response response;
@@ -1463,9 +1464,12 @@
           var id = params['streamId'];
           var existing = _streamSubscriptions.remove(id);
           if (existing == null) {
-            throw RPCError('streamCancel', 104, 'Stream not subscribed', {
-              'details': "The stream '$id' is not subscribed",
-            });
+            throw RPCError.withDetails(
+              'streamCancel',
+              104,
+              'Stream not subscribed',
+              details: "The stream '$id' is not subscribed",
+            );
           }
           await existing.cancel();
           response = Success();
@@ -1473,9 +1477,12 @@
         case 'streamListen':
           var id = params['streamId'];
           if (_streamSubscriptions.containsKey(id)) {
-            throw RPCError('streamListen', 103, 'Stream already subscribed', {
-              'details': "The stream '$id' is already subscribed",
-            });
+            throw RPCError.withDetails(
+              'streamListen',
+              103,
+              'Stream already subscribed',
+              details: "The stream '$id' is already subscribed",
+            );
           }
 
           var stream = id == 'Service'
@@ -1511,7 +1518,8 @@
             response = await _serviceImplementation.callServiceExtension(method,
                 isolateId: isolateId, args: args);
           } else {
-            throw RPCError(method, -32601, 'Method not found', request);
+            throw RPCError(
+                method, RPCError.kMethodNotFound, 'Method not found', request);
           }
       }
       if (response == null) {
@@ -1524,8 +1532,12 @@
       });
     } catch (e, st) {
       var error = e is RPCError
-          ? {'code': e.code, 'data': e.data, 'message': e.message}
-          : {'code': -32603, 'message': '$e\n$st'};
+          ? e.toMap()
+          : {
+              'code': RPCError.kInternalError,
+              'message': '${request['method']}: $e',
+              'data': {'details': '$st'},
+            };
       _responseSink.add({
         'jsonrpc': '2.0',
         'id': request['id'],
@@ -1963,8 +1975,8 @@
     _streamSub.cancel();
     _completers.forEach((id, c) {
       final method = _methodCalls[id];
-      return c.completeError(
-          RPCError(method, -32000, 'Service connection disposed'));
+      return c.completeError(RPCError(
+          method, RPCError.kServerError, 'Service connection disposed'));
     });
     _completers.clear();
     if (_disposeHandler != null) {
@@ -2083,7 +2095,7 @@
   }
 
   Future _processRequest(Map<String, dynamic> json) async {
-    final Map m = await _routeRequest(json['method'], json['params']);
+    final Map m = await _routeRequest(json['method'], json['params'] ?? {});
     m['id'] = json['id'];
     m['jsonrpc'] = '2.0';
     String message = jsonEncode(m);
@@ -2093,7 +2105,7 @@
 
   Future _processNotification(Map<String, dynamic> json) async {
     final String method = json['method'];
-    final Map params = json['params'];
+    final Map params = json['params'] ?? {};
     if (method == 'streamNotify') {
       String streamId = params['streamId'];
       _getEventController(streamId)
@@ -2104,23 +2116,22 @@
   }
 
   Future<Map> _routeRequest(String method, Map params) async {
+    if (!_services.containsKey(method)) {
+      RPCError error = RPCError(
+          method, RPCError.kMethodNotFound, 'method not found \'$method\'');
+      return {'error': error.toMap()};
+    }
+
     try {
-      if (_services.containsKey(method)) {
-        return await _services[method](params);
-      }
-      return {
-        'error': {
-          'code': -32601, // Method not found
-          'message': 'Method not found \'$method\''
-        }
-      };
+      return await _services[method](params);
     } catch (e, st) {
-      return {
-        'error': {
-          'code': -32000, // SERVER ERROR
-          'message': 'Unexpected Server Error $e\n$st'
-        }
-      };
+      RPCError error = RPCError.withDetails(
+        method,
+        RPCError.kServerError,
+        '$e',
+        details: '$st',
+      );
+      return {'error': error.toMap()};
     }
   }
 }
@@ -2128,6 +2139,21 @@
 typedef DisposeHandler = Future Function();
 
 class RPCError implements Exception {
+  /// Application specific error codes.
+  static const int kServerError = -32000;
+
+  /// The JSON sent is not a valid Request object.
+  static const int kInvalidRequest = -32600;
+
+  /// The method does not exist or is not available.
+  static const int kMethodNotFound = -32601;
+
+  /// Invalid method parameter(s), such as a mismatched type.
+  static const int kInvalidParams = -32602;
+
+  /// Internal JSON-RPC error.
+  static const int kInternalError = -32603;
+
   static RPCError parse(String callingMethod, dynamic json) {
     return RPCError(callingMethod, json['code'], json['message'], json['data']);
   }
@@ -2139,13 +2165,34 @@
 
   RPCError(this.callingMethod, this.code, this.message, [this.data]);
 
+  RPCError.withDetails(this.callingMethod, this.code, this.message,
+      {Object details})
+      : data = details == null ? null : <String, dynamic>{} {
+    if (details != null) {
+      data['details'] = details;
+    }
+  }
+
   String get details => data == null ? null : data['details'];
 
+  /// Return a map representation of this error suitable for converstion to
+  /// json.
+  Map<String, dynamic> toMap() {
+    Map<String, dynamic> map = {
+      'code': code,
+      'message': message,
+    };
+    if (data != null) {
+      map['data'] = data;
+    }
+    return map;
+  }
+
   String toString() {
     if (details == null) {
-      return '${message} (${code}) from ${callingMethod}()';
+      return '$callingMethod: ($code) $message';
     } else {
-      return '${message} (${code}) from ${callingMethod}():\n${details}';
+      return '$callingMethod: ($code) $message\n$details';
     }
   }
 }
@@ -3540,7 +3587,6 @@
   /// The status (success or failure) related to the event. This is provided for
   /// the event kinds:
   ///  - IsolateReloaded
-  ///  - IsolateSpawn
   @optional
   String status;
 
diff --git a/pkg/vm_service/test/server_test.dart b/pkg/vm_service/test/server_test.dart
index d0ed5b0..ab0347c 100644
--- a/pkg/vm_service/test/server_test.dart
+++ b/pkg/vm_service/test/server_test.dart
@@ -193,7 +193,7 @@
       expect(
           responsesController.stream.map((response) => '$response'),
           emits(startsWith(
-              '{jsonrpc: 2.0, id: 1, error: {code: -32603, message: UnimplementedError')));
+              '{jsonrpc: 2.0, id: 1, error: {code: -32603, message: getVersion: UnimplementedError')));
       requestsController.add(request);
     });
   });
diff --git a/pkg/vm_service/tool/dart/generate_dart.dart b/pkg/vm_service/tool/dart/generate_dart.dart
index b85bc8c..68b7daa 100644
--- a/pkg/vm_service/tool/dart/generate_dart.dart
+++ b/pkg/vm_service/tool/dart/generate_dart.dart
@@ -104,8 +104,8 @@
     _streamSub.cancel();
     _completers.forEach((id, c) {
       final method = _methodCalls[id];
-      return c.completeError(
-          RPCError(method, -32000, 'Service connection disposed'));
+      return c.completeError(RPCError(
+          method, RPCError.kServerError, 'Service connection disposed'));
     });
     _completers.clear();
     if (_disposeHandler != null) {
@@ -220,7 +220,7 @@
   }
 
   Future _processRequest(Map<String, dynamic> json) async {
-    final Map m = await _routeRequest(json['method'], json['params']);
+    final Map m = await _routeRequest(json['method'], json['params'] ?? {});
     m['id'] = json['id'];
     m['jsonrpc'] = '2.0';
     String message = jsonEncode(m);
@@ -230,7 +230,7 @@
 
   Future _processNotification(Map<String, dynamic> json) async {
     final String method = json['method'];
-    final Map params = json['params'];
+    final Map params = json['params'] ?? {};
     if (method == 'streamNotify') {
       String streamId = params['streamId'];
       _getEventController(streamId).add(createServiceObject(params['event'], const ['Event']));
@@ -240,23 +240,18 @@
   }
 
   Future<Map> _routeRequest(String method, Map params) async{
+    if (!_services.containsKey(method)) {
+      RPCError error = RPCError(
+          method, RPCError.kMethodNotFound, 'method not found \'$method\'');
+      return {'error': error.toMap()};
+    }
+
     try {
-      if (_services.containsKey(method)) {
-        return await _services[method](params);
-      }
-      return {
-        'error': {
-          'code': -32601, // Method not found
-          'message': 'Method not found \'$method\''
-        }
-      };
+      return await _services[method](params);
     } catch (e, st) {
-      return {
-        'error': {
-          'code': -32000, // SERVER ERROR
-          'message': 'Unexpected Server Error $e\n$st'
-        }
-      };
+      RPCError error = RPCError.withDetails(
+        method, RPCError.kServerError, '$e', details: '$st',);
+      return {'error': error.toMap()};
     }
   }
 ''';
@@ -267,6 +262,21 @@
 typedef DisposeHandler = Future Function();
 
 class RPCError implements Exception {
+  /// Application specific error codes.
+  static const int kServerError = -32000;
+
+  /// The JSON sent is not a valid Request object.
+  static const int kInvalidRequest = -32600;
+
+  /// The method does not exist or is not available.
+  static const int kMethodNotFound = -32601;
+
+  /// Invalid method parameter(s), such as a mismatched type.
+  static const int kInvalidParams = -32602;
+
+  /// Internal JSON-RPC error.
+  static const int kInternalError = -32603;
+
   static RPCError parse(String callingMethod, dynamic json) {
     return RPCError(callingMethod, json['code'], json['message'], json['data']);
   }
@@ -278,13 +288,34 @@
 
   RPCError(this.callingMethod, this.code, this.message, [this.data]);
 
+  RPCError.withDetails(this.callingMethod, this.code, this.message,
+      {Object details})
+      : data = details == null ? null : <String, dynamic>{} {
+    if (details != null) {
+      data['details'] = details;
+    }
+  }
+
   String get details => data == null ? null : data['details'];
 
+  /// Return a map representation of this error suitable for converstion to
+  /// json.
+  Map<String, dynamic> toMap() {
+    Map<String, dynamic> map = {
+      'code': code,
+      'message': message,
+    };
+    if (data != null) {
+      map['data'] = data;
+    }
+    return map;
+  }
+
   String toString() {
     if (details == null) {
-      return '${message} (${code}) from ${callingMethod}()';
+      return '$callingMethod: ($code) $message';
     } else {
-      return '${message} (${code}) from ${callingMethod}():\n${details}';
+      return '$callingMethod: ($code) $message\n$details';
     }
   }
 }
@@ -337,9 +368,10 @@
 final _streamListenCaseImpl = '''
 var id = params['streamId'];
 if (_streamSubscriptions.containsKey(id)) {
-  throw RPCError('streamListen', 103, 'Stream already subscribed', {
-      'details': "The stream '\$id' is already subscribed",
-    });
+  throw RPCError.withDetails(
+    'streamListen', 103, 'Stream already subscribed',
+    details: "The stream '\$id' is already subscribed",
+  );
 }
 
 var stream = id == 'Service'
@@ -361,9 +393,10 @@
 var id = params['streamId'];
 var existing = _streamSubscriptions.remove(id);
 if (existing == null) {
-  throw RPCError('streamCancel', 104, 'Stream not subscribed', {
-      'details': "The stream '\$id' is not subscribed",
-    });
+  throw RPCError.withDetails(
+    'streamCancel', 104, 'Stream not subscribed',
+    details: "The stream '\$id' is not subscribed",
+  );
 }
 await existing.cancel();
 response = Success();''';
@@ -663,7 +696,8 @@
         }
         var method = request['method'] as String;
         if (method == null) {
-          throw RPCError(null, -32600, 'Invalid Request', request);
+          throw RPCError(
+            null, RPCError.kInvalidRequest, 'Invalid Request', request);
         }
         var params = request['params'] as Map;
         Response response;
@@ -728,7 +762,7 @@
           response = await _serviceImplementation.callServiceExtension(method,
               isolateId: isolateId, args: args);
         } else {
-          throw RPCError(method, -32601, 'Method not found', request);
+          throw RPCError(method, RPCError.kMethodNotFound, 'Method not found', request);
         }
 ''');
     // Terminate the switch
@@ -753,8 +787,12 @@
     gen.write(r'''
       } catch (e, st) {
         var error = e is RPCError
-            ? {'code': e.code, 'data': e.data, 'message': e.message}
-            : {'code': -32603, 'message': '$e\n$st'};
+            ? e.toMap()
+            : {
+                'code': RPCError.kInternalError,
+                'message': '${request['method']}: $e',
+                'data': {'details': '$st'},
+              };
         _responseSink.add({
           'jsonrpc': '2.0',
           'id': request['id'],
diff --git a/runtime/bin/directory.cc b/runtime/bin/directory.cc
index 6b3ce66..cb6f882 100644
--- a/runtime/bin/directory.cc
+++ b/runtime/bin/directory.cc
@@ -453,7 +453,7 @@
     size_t len = strlen(arg);
     Dart_CObject* io_buffer = CObject::NewIOBuffer(len);
     uint8_t* data = io_buffer->value.as_external_typed_data.data;
-    strncpy(reinterpret_cast<char*>(data), arg, len);
+    memmove(reinterpret_cast<char*>(data), arg, len);
 
     CObjectExternalUint8Array* external_array =
         new CObjectExternalUint8Array(io_buffer);
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 568fa5f..eb40122 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -670,7 +670,7 @@
   }
 
   auto isolate_group_data = std::unique_ptr<IsolateGroupData>(
-      new IsolateGroupData(nullptr, nullptr, nullptr, nullptr, false));
+      new IsolateGroupData(nullptr, nullptr, nullptr, false));
   Dart_Isolate isolate;
   char* error = NULL;
 
diff --git a/runtime/bin/isolate_data.cc b/runtime/bin/isolate_data.cc
index 3bf497c..1547975 100644
--- a/runtime/bin/isolate_data.cc
+++ b/runtime/bin/isolate_data.cc
@@ -10,21 +10,16 @@
 namespace bin {
 
 IsolateGroupData::IsolateGroupData(const char* url,
-                                   const char* package_root,
                                    const char* packages_file,
                                    AppSnapshot* app_snapshot,
                                    bool isolate_run_app_snapshot)
     : script_url((url != NULL) ? strdup(url) : NULL),
-      package_root(NULL),
       app_snapshot_(app_snapshot),
       resolved_packages_config_(NULL),
       kernel_buffer_(NULL),
       kernel_buffer_size_(0),
       isolate_run_app_snapshot_(isolate_run_app_snapshot) {
-  if (package_root != NULL) {
-    ASSERT(packages_file == NULL);
-    package_root = strdup(package_root);
-  } else if (packages_file != NULL) {
+  if (packages_file != NULL) {
     packages_file_ = strdup(packages_file);
   }
 }
@@ -32,8 +27,6 @@
 IsolateGroupData::~IsolateGroupData() {
   free(script_url);
   script_url = NULL;
-  free(package_root);
-  package_root = NULL;
   free(packages_file_);
   packages_file_ = NULL;
   free(resolved_packages_config_);
diff --git a/runtime/bin/isolate_data.h b/runtime/bin/isolate_data.h
index c4523a1..6dae87a 100644
--- a/runtime/bin/isolate_data.h
+++ b/runtime/bin/isolate_data.h
@@ -34,14 +34,12 @@
 class IsolateGroupData {
  public:
   IsolateGroupData(const char* url,
-                   const char* package_root,
                    const char* packages_file,
                    AppSnapshot* app_snapshot,
                    bool isolate_run_app_snapshot);
   ~IsolateGroupData();
 
   char* script_url;
-  char* package_root;
 
   const std::shared_ptr<uint8_t>& kernel_buffer() const {
     return kernel_buffer_;
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index ac3baa5..06b9109 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -180,7 +180,7 @@
 
   // Prepare builtin and other core libraries for use to resolve URIs.
   // Set up various closures, e.g: printing, timers etc.
-  // Set up 'package root' for URI resolution.
+  // Set up package configuration for URI resolution.
   result = DartUtils::PrepareForScriptLoading(false, Options::trace_loading());
   if (Dart_IsError(result)) return result;
 
@@ -417,7 +417,6 @@
 // For now we only support the kernel isolate coming up from an
 // application snapshot or from a .dill file.
 static Dart_Isolate CreateAndSetupKernelIsolate(const char* script_uri,
-                                                const char* package_root,
                                                 const char* packages_config,
                                                 Dart_IsolateFlags* flags,
                                                 char** error,
@@ -459,9 +458,8 @@
     app_snapshot->SetBuffers(
         &ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
         &isolate_snapshot_data, &isolate_snapshot_instructions);
-    isolate_group_data =
-        new IsolateGroupData(uri, package_root, packages_config, app_snapshot,
-                             isolate_run_app_snapshot);
+    isolate_group_data = new IsolateGroupData(
+        uri, packages_config, app_snapshot, isolate_run_app_snapshot);
     isolate_data = new IsolateData(isolate_group_data);
     isolate = Dart_CreateIsolateGroup(
         DART_KERNEL_ISOLATE_NAME, DART_KERNEL_ISOLATE_NAME,
@@ -479,8 +477,8 @@
     intptr_t kernel_service_buffer_size = 0;
     dfe.LoadKernelService(&kernel_service_buffer, &kernel_service_buffer_size);
     ASSERT(kernel_service_buffer != NULL);
-    isolate_group_data = new IsolateGroupData(
-        uri, package_root, packages_config, nullptr, isolate_run_app_snapshot);
+    isolate_group_data = new IsolateGroupData(uri, packages_config, nullptr,
+                                              isolate_run_app_snapshot);
     isolate_group_data->SetKernelBufferUnowned(
         const_cast<uint8_t*>(kernel_service_buffer),
         kernel_service_buffer_size);
@@ -508,7 +506,6 @@
 // For now we only support the service isolate coming up from sources
 // which are compiled by the VM parser.
 static Dart_Isolate CreateAndSetupServiceIsolate(const char* script_uri,
-                                                 const char* package_root,
                                                  const char* packages_config,
                                                  Dart_IsolateFlags* flags,
                                                  char** error,
@@ -516,8 +513,8 @@
 #if !defined(PRODUCT)
   ASSERT(script_uri != NULL);
   Dart_Isolate isolate = NULL;
-  auto isolate_group_data = new IsolateGroupData(
-      script_uri, package_root, packages_config, nullptr, false);
+  auto isolate_group_data =
+      new IsolateGroupData(script_uri, packages_config, nullptr, false);
 
 #if defined(DART_PRECOMPILED_RUNTIME)
   // AOT: All isolates start from the app snapshot.
@@ -580,7 +577,6 @@
     bool is_main_isolate,
     const char* script_uri,
     const char* name,
-    const char* package_root,
     const char* packages_config,
     Dart_IsolateFlags* flags,
     void* callback_data,
@@ -637,9 +633,8 @@
   }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-  auto isolate_group_data =
-      new IsolateGroupData(script_uri, package_root, packages_config,
-                           app_snapshot, isolate_run_app_snapshot);
+  auto isolate_group_data = new IsolateGroupData(
+      script_uri, packages_config, app_snapshot, isolate_run_app_snapshot);
   if (kernel_buffer != NULL) {
     if (parent_kernel_buffer) {
       isolate_group_data->SetKernelBufferAlreadyOwned(
@@ -716,28 +711,22 @@
   // The VM should never call the isolate helper with a NULL flags.
   ASSERT(flags != NULL);
   ASSERT(flags->version == DART_FLAGS_CURRENT_VERSION);
-  if ((package_root != NULL) && (package_config != NULL)) {
-    *error = strdup(
-        "Invalid arguments - Cannot simultaneously specify "
-        "package root and package map.");
-    return NULL;
-  }
-
+  ASSERT(package_root == nullptr);
   int exit_code = 0;
 #if !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
   if (strcmp(script_uri, DART_KERNEL_ISOLATE_NAME) == 0) {
-    return CreateAndSetupKernelIsolate(script_uri, package_root, package_config,
-                                       flags, error, &exit_code);
+    return CreateAndSetupKernelIsolate(script_uri, package_config, flags, error,
+                                       &exit_code);
   }
 #endif  // !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
   if (strcmp(script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0) {
-    return CreateAndSetupServiceIsolate(
-        script_uri, package_root, package_config, flags, error, &exit_code);
+    return CreateAndSetupServiceIsolate(script_uri, package_config, flags,
+                                        error, &exit_code);
   }
   bool is_main_isolate = false;
   return CreateIsolateGroupAndSetupHelper(is_main_isolate, script_uri, main,
-                                          package_root, package_config, flags,
-                                          callback_data, error, &exit_code);
+                                          package_config, flags, callback_data,
+                                          error, &exit_code);
 }
 
 static void OnIsolateShutdown(void* isolate_group_data, void* isolate_data) {
@@ -845,10 +834,15 @@
   Dart_IsolateFlags flags;
   Dart_IsolateFlagsInitialize(&flags);
 
+  if (Options::package_root() != nullptr) {
+    Syslog::PrintErr(
+        "Warning: The --package-root option is deprecated (was: %s)\n",
+        Options::package_root());
+  }
+
   Dart_Isolate isolate = CreateIsolateGroupAndSetupHelper(
-      is_main_isolate, script_name, "main", Options::package_root(),
-      Options::packages_file(), &flags, NULL /* callback_data */, &error,
-      &exit_code);
+      is_main_isolate, script_name, "main", Options::packages_file(), &flags,
+      NULL /* callback_data */, &error, &exit_code);
 
   if (isolate == NULL) {
     Syslog::PrintErr("%s\n", error);
diff --git a/runtime/bin/process.h b/runtime/bin/process.h
index a1aa3b9..34fc299 100644
--- a/runtime/bin/process.h
+++ b/runtime/bin/process.h
@@ -147,6 +147,7 @@
   // isolate. When 'port' is ILLEGAL_PORT, this clears all signal handlers for
   // 'signal' for all Isolates.
   static void ClearSignalHandler(intptr_t signal, Dart_Port port);
+  static void ClearSignalHandlerByFd(intptr_t fd, Dart_Port port);
   static void ClearAllSignalHandlers();
 
   static Dart_Handle GetProcessIdNativeField(Dart_Handle process,
diff --git a/runtime/bin/process_android.cc b/runtime/bin/process_android.cc
index 2a01538..10082b98 100644
--- a/runtime/bin/process_android.cc
+++ b/runtime/bin/process_android.cc
@@ -1063,6 +1063,39 @@
   }
 }
 
+void Process::ClearSignalHandlerByFd(intptr_t fd, Dart_Port port) {
+  ThreadSignalBlocker blocker(kSignalsCount, kSignals);
+  MutexLocker lock(signal_mutex);
+  SignalInfo* handler = signal_handlers;
+  bool unlisten = true;
+  intptr_t signal = -1;
+  while (handler != NULL) {
+    bool remove = false;
+    if (handler->fd() == fd) {
+      if ((port == ILLEGAL_PORT) || (handler->port() == port)) {
+        if (signal_handlers == handler) {
+          signal_handlers = handler->next();
+        }
+        handler->Unlink();
+        remove = true;
+        signal = handler->signal();
+      } else {
+        unlisten = false;
+      }
+    }
+    SignalInfo* next = handler->next();
+    if (remove) {
+      delete handler;
+    }
+    handler = next;
+  }
+  if (unlisten && (signal != -1)) {
+    struct sigaction act = {};
+    act.sa_handler = SIG_DFL;
+    VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
+  }
+}
+
 void ProcessInfoList::Init() {
   ASSERT(ProcessInfoList::mutex_ == nullptr);
   ProcessInfoList::mutex_ = new Mutex();
diff --git a/runtime/bin/process_fuchsia.cc b/runtime/bin/process_fuchsia.cc
index 009560b..8805d09 100644
--- a/runtime/bin/process_fuchsia.cc
+++ b/runtime/bin/process_fuchsia.cc
@@ -818,6 +818,8 @@
 
 void Process::ClearSignalHandler(intptr_t signal, Dart_Port port) {}
 
+void Process::ClearSignalHandlerByFd(intptr_t fd, Dart_Port port) {}
+
 void ProcessInfoList::Init() {
   ASSERT(ProcessInfoList::mutex_ == nullptr);
   ProcessInfoList::mutex_ = new Mutex();
diff --git a/runtime/bin/process_linux.cc b/runtime/bin/process_linux.cc
index 0f4106e..fac361f 100644
--- a/runtime/bin/process_linux.cc
+++ b/runtime/bin/process_linux.cc
@@ -1015,7 +1015,7 @@
     for (int i = 0; i < kSignalsCount; i++) {
       sigaddset(&act.sa_mask, kSignals[i]);
     }
-    int status = sigaction(signal, &act, NULL);
+    int status = NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
     if (status < 0) {
       int err = errno;
       close(fds[0]);
@@ -1055,7 +1055,40 @@
   if (unlisten) {
     struct sigaction act = {};
     act.sa_handler = SIG_DFL;
-    sigaction(signal, &act, NULL);
+    VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
+  }
+}
+
+void Process::ClearSignalHandlerByFd(intptr_t fd, Dart_Port port) {
+  ThreadSignalBlocker blocker(kSignalsCount, kSignals);
+  MutexLocker lock(signal_mutex);
+  SignalInfo* handler = signal_handlers;
+  bool unlisten = true;
+  intptr_t signal = -1;
+  while (handler != NULL) {
+    bool remove = false;
+    if (handler->fd() == fd) {
+      if ((port == ILLEGAL_PORT) || (handler->port() == port)) {
+        if (signal_handlers == handler) {
+          signal_handlers = handler->next();
+        }
+        handler->Unlink();
+        remove = true;
+        signal = handler->signal();
+      } else {
+        unlisten = false;
+      }
+    }
+    SignalInfo* next = handler->next();
+    if (remove) {
+      delete handler;
+    }
+    handler = next;
+  }
+  if (unlisten && (signal != -1)) {
+    struct sigaction act = {};
+    act.sa_handler = SIG_DFL;
+    VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
   }
 }
 
diff --git a/runtime/bin/process_macos.cc b/runtime/bin/process_macos.cc
index df67348..3583a284 100644
--- a/runtime/bin/process_macos.cc
+++ b/runtime/bin/process_macos.cc
@@ -1095,6 +1095,39 @@
   }
 }
 
+void Process::ClearSignalHandlerByFd(intptr_t fd, Dart_Port port) {
+  ThreadSignalBlocker blocker(kSignalsCount, kSignals);
+  MutexLocker lock(signal_mutex);
+  SignalInfo* handler = signal_handlers;
+  bool unlisten = true;
+  intptr_t signal = -1;
+  while (handler != NULL) {
+    bool remove = false;
+    if (handler->fd() == fd) {
+      if ((port == ILLEGAL_PORT) || (handler->port() == port)) {
+        if (signal_handlers == handler) {
+          signal_handlers = handler->next();
+        }
+        handler->Unlink();
+        remove = true;
+        signal = handler->signal();
+      } else {
+        unlisten = false;
+      }
+    }
+    SignalInfo* next = handler->next();
+    if (remove) {
+      delete handler;
+    }
+    handler = next;
+  }
+  if (unlisten && (signal != -1)) {
+    struct sigaction act = {};
+    act.sa_handler = SIG_DFL;
+    VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
+  }
+}
+
 void ProcessInfoList::Init() {
   ASSERT(ProcessInfoList::mutex_ == nullptr);
   ProcessInfoList::mutex_ = new Mutex();
diff --git a/runtime/bin/process_win.cc b/runtime/bin/process_win.cc
index f2264a3..dd11341 100644
--- a/runtime/bin/process_win.cc
+++ b/runtime/bin/process_win.cc
@@ -1056,6 +1056,33 @@
   }
 }
 
+void Process::ClearSignalHandlerByFd(intptr_t fd, Dart_Port port) {
+  MutexLocker lock(signal_mutex);
+  SignalInfo* handler = signal_handlers;
+  while (handler != NULL) {
+    bool remove = false;
+    if (handler->fd() == fd) {
+      if ((port == ILLEGAL_PORT) || (handler->port() == port)) {
+        if (signal_handlers == handler) {
+          signal_handlers = handler->next();
+        }
+        handler->Unlink();
+        FileHandle* file_handle = reinterpret_cast<FileHandle*>(handler->fd());
+        file_handle->Release();
+        remove = true;
+      }
+    }
+    SignalInfo* next = handler->next();
+    if (remove) {
+      delete handler;
+    }
+    handler = next;
+  }
+  if (signal_handlers == NULL) {
+    USE(SetConsoleCtrlHandler(SignalHandler, false));
+  }
+}
+
 void ProcessInfoList::Init() {
   ASSERT(ProcessInfoList::mutex_ == nullptr);
   ProcessInfoList::mutex_ = new Mutex();
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc
index 5e44275..c7b4df6 100644
--- a/runtime/bin/run_vm_tests.cc
+++ b/runtime/bin/run_vm_tests.cc
@@ -101,7 +101,6 @@
   }
 
 static Dart_Isolate CreateAndSetupServiceIsolate(const char* script_uri,
-                                                 const char* package_root,
                                                  const char* packages_config,
                                                  Dart_IsolateFlags* flags,
                                                  char** error) {
@@ -117,7 +116,7 @@
   ASSERT(script_uri != nullptr);
   Dart_Isolate isolate = nullptr;
   auto isolate_group_data = new bin::IsolateGroupData(
-      script_uri, package_root, packages_config, /*app_snapshot=*/nullptr,
+      script_uri, packages_config, /*app_snapshot=*/nullptr,
       /*isolate_run_app_snapshot=*/false);
 
   const uint8_t* kernel_buffer = nullptr;
@@ -169,9 +168,10 @@
                                           void* data,
                                           char** error) {
   ASSERT(script_uri != nullptr);
+  ASSERT(package_root == nullptr);
   if (strcmp(script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0) {
-    return CreateAndSetupServiceIsolate(script_uri, package_root,
-                                        packages_config, flags, error);
+    return CreateAndSetupServiceIsolate(script_uri, packages_config, flags,
+                                        error);
   }
   const bool is_kernel_isolate =
       strcmp(script_uri, DART_KERNEL_ISOLATE_NAME) == 0;
@@ -200,9 +200,8 @@
     app_snapshot->SetBuffers(
         &ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
         &isolate_snapshot_data, &isolate_snapshot_instructions);
-    isolate_group_data =
-        new bin::IsolateGroupData(script_uri, package_root, packages_config,
-                                  app_snapshot, app_snapshot != nullptr);
+    isolate_group_data = new bin::IsolateGroupData(
+        script_uri, packages_config, app_snapshot, app_snapshot != nullptr);
     isolate = Dart_CreateIsolateGroup(
         DART_KERNEL_ISOLATE_NAME, DART_KERNEL_ISOLATE_NAME,
         isolate_snapshot_data, isolate_snapshot_instructions, flags,
@@ -229,8 +228,8 @@
     bin::dfe.LoadKernelService(&kernel_service_buffer,
                                &kernel_service_buffer_size);
     ASSERT(kernel_service_buffer != nullptr);
-    isolate_group_data = new bin::IsolateGroupData(
-        script_uri, package_root, packages_config, nullptr, false);
+    isolate_group_data =
+        new bin::IsolateGroupData(script_uri, packages_config, nullptr, false);
     isolate_group_data->SetKernelBufferUnowned(
         const_cast<uint8_t*>(kernel_service_buffer),
         kernel_service_buffer_size);
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index 46bcef0..1017655 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -1258,7 +1258,7 @@
                                   void* data) {
   Socket* socket = reinterpret_cast<Socket*>(data);
   if (socket->fd() >= 0) {
-    Process::ClearSignalHandler(socket->fd(), socket->isolate_port());
+    Process::ClearSignalHandlerByFd(socket->fd(), socket->isolate_port());
     const int64_t flags = 1 << kCloseCommand;
     socket->Retain();
     EventHandler::SendFromNative(reinterpret_cast<intptr_t>(socket),
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 0da49b0..e5ad04f 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -570,10 +570,7 @@
  *   eventually run.  This is provided for advisory purposes only to
  *   improve debugging messages.  The main function is not invoked by
  *   this function.
- * \param package_root The package root path for this isolate to resolve
- *   package imports against. Only one of package_root and package_map
- *   parameters is non-NULL. If neither parameter is passed the package
- *   resolution of the parent isolate should be used.
+ * \param package_root Ignored.
  * \param package_map The package map for this isolate to resolve package
  *   imports against. The array contains alternating keys and values,
  *   terminated by a NULL key. Only one of package_root and package_map
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 27e688f..7833f4a 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -390,7 +390,7 @@
   return result;
 }
 
-DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 0, 11) {
+DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 0, 10) {
   GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(String, script_uri, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(2));
@@ -399,9 +399,8 @@
   GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(5));
   GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(6));
   GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(7));
-  GET_NATIVE_ARGUMENT(String, packageRoot, arguments->NativeArgAt(8));
-  GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(9));
-  GET_NATIVE_ARGUMENT(String, debugName, arguments->NativeArgAt(10));
+  GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(8));
+  GET_NATIVE_ARGUMENT(String, debugName, arguments->NativeArgAt(9));
 
   if (closure.IsClosure()) {
     Function& func = Function::Handle();
@@ -482,26 +481,19 @@
   return result;
 }
 
-DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 0, 13) {
+DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 0, 12) {
   GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(1));
-
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, args, arguments->NativeArgAt(2));
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(3));
-
   GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(4));
   GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(5));
   GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(6));
-
   GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(7));
   GET_NATIVE_ARGUMENT(Bool, checked, arguments->NativeArgAt(8));
-
   GET_NATIVE_ARGUMENT(Array, environment, arguments->NativeArgAt(9));
-
-  GET_NATIVE_ARGUMENT(String, packageRoot, arguments->NativeArgAt(10));
-  GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(11));
-
-  GET_NATIVE_ARGUMENT(String, debugName, arguments->NativeArgAt(12));
+  GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(10));
+  GET_NATIVE_ARGUMENT(String, debugName, arguments->NativeArgAt(11));
 
   if (Dart::vm_snapshot_kind() == Snapshot::kFullAOT) {
     const Array& args = Array::Handle(Array::New(1));
diff --git a/runtime/lib/vmservice.cc b/runtime/lib/vmservice.cc
index 1d3484d..95e16c4 100644
--- a/runtime/lib/vmservice.cc
+++ b/runtime/lib/vmservice.cc
@@ -415,38 +415,4 @@
 #endif
 }
 
-DEFINE_NATIVE_ENTRY(VMService_spawnUriNotify, 0, 2) {
-#ifndef PRODUCT
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, result, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(String, token, arguments->NativeArgAt(1));
-
-  if (result.IsSendPort()) {
-    Dart_Port id = SendPort::Cast(result).Id();
-    Isolate* isolate = PortMap::GetIsolate(id);
-    if (isolate != NULL) {
-      ServiceEvent spawn_event(isolate, ServiceEvent::kIsolateSpawn);
-      spawn_event.set_spawn_token(&token);
-      Service::HandleEvent(&spawn_event);
-    } else {
-      // There is no isolate at the control port anymore.  Must have
-      // died already.
-      ServiceEvent spawn_event(NULL, ServiceEvent::kIsolateSpawn);
-      const String& error = String::Handle(
-          String::New("spawned isolate exited before notification completed"));
-      spawn_event.set_spawn_token(&token);
-      spawn_event.set_spawn_error(&error);
-      Service::HandleEvent(&spawn_event);
-    }
-  } else {
-    // The isolate failed to spawn.
-    ASSERT(result.IsString());
-    ServiceEvent spawn_event(NULL, ServiceEvent::kIsolateSpawn);
-    spawn_event.set_spawn_token(&token);
-    spawn_event.set_spawn_error(&String::Cast(result));
-    Service::HandleEvent(&spawn_event);
-  }
-#endif  // PRODUCT
-  return Object::null();
-}
-
 }  // namespace dart
diff --git a/runtime/observatory/tests/service/dev_fs_spawn_test.dart b/runtime/observatory/tests/service/dev_fs_spawn_test.dart
deleted file mode 100644
index 4e76990..0000000
--- a/runtime/observatory/tests/service/dev_fs_spawn_test.dart
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:convert';
-import 'package:observatory/models.dart' as M;
-import 'package:observatory/service_io.dart';
-import 'package:test/test.dart';
-import 'service_test_common.dart';
-import 'test_helper.dart';
-
-var tests = <VMTest>[
-  (VM vm) async {
-    // Create a new fs.
-    var fsName = 'scratch';
-    var result = await vm.invokeRpcNoUpgrade('_createDevFS', {
-      'fsName': fsName,
-    });
-    expect(result['type'], equals('FileSystem'));
-    expect(result['name'], equals('scratch'));
-    expect(result['uri'], new isInstanceOf<String>());
-    var fsUri = result['uri'];
-
-    // Spawn a script with a bad uri and make sure that the error is
-    // delivered asynchronously.
-    Completer completer = new Completer();
-    var sub;
-    sub = await vm.listenEventStream(VM.kIsolateStream, (ServiceEvent event) {
-      if (event.kind == ServiceEvent.kIsolateSpawn) {
-        expect(event.spawnToken, equals('someSpawnToken'));
-        expect(event.spawnError,
-            startsWith('IsolateSpawnException: Unable to spawn isolate: '));
-        expect(event.isolate, isNull);
-        completer.complete();
-        sub.cancel();
-      }
-    });
-
-    result = await vm.invokeRpcNoUpgrade('_spawnUri', {
-      'token': 'someSpawnToken',
-      'uri': '${fsUri}doesnotexist.dart',
-    });
-    expect(result['type'], equals('Success'));
-    await completer.future;
-
-    // Delete the fs.
-    result = await vm.invokeRpcNoUpgrade('_deleteDevFS', {
-      'fsName': fsName,
-    });
-    expect(result['type'], equals('Success'));
-  },
-  (VM vm) async {
-    // Create a new fs.
-    var fsName = 'scratch';
-    var result = await vm.invokeRpcNoUpgrade('_createDevFS', {
-      'fsName': fsName,
-    });
-    expect(result['type'], equals('FileSystem'));
-    expect(result['name'], equals('scratch'));
-    expect(result['uri'], new isInstanceOf<String>());
-    var fsUri = result['uri'];
-
-    var filePaths = [
-      'devfs_file0.dart',
-      'devfs_file1.dart',
-      'devfs_file2.dart'
-    ];
-    var scripts = [
-      '''
-import 'dart:developer';
-proofOfLife() => 'I live!';
-main() {
-  print('HELLO WORLD 1');
-  debugger();
-}
-''',
-      '''
-import 'dart:developer';
-var globalArgs;
-proofOfLife() => 'I live, \${globalArgs}!';
-main(args) {
-  globalArgs = args;
-  print('HELLO WORLD 2');
-  debugger();
-}
-''',
-      '''
-import 'dart:developer';
-var globalArgs;
-var globalMsg;
-proofOfLife() => 'I live, \${globalArgs}, \${globalMsg}!';
-main(args, msg) {
-  globalArgs = args;
-  globalMsg = msg;
-  print('HELLO WORLD 3');
-  debugger();
-}
-''',
-    ];
-
-    // Write three scripts to the fs.
-    for (int i = 0; i < 3; i++) {
-      var fileContents = base64Encode(utf8.encode(scripts[i]));
-      result = await vm.invokeRpcNoUpgrade('_writeDevFSFile', {
-        'fsName': fsName,
-        'path': filePaths[i],
-        'fileContents': fileContents
-      });
-      expect(result['type'], equals('Success'));
-    }
-
-    // Spawn the script with no arguments or message and make sure
-    // that we are notified.
-    Completer completer = new Completer();
-    var sub;
-    sub = await vm.listenEventStream(VM.kIsolateStream, (ServiceEvent event) {
-      if (event.kind == ServiceEvent.kIsolateSpawn) {
-        expect(event.spawnToken, equals('mySpawnToken0'));
-        expect(event.isolate, isNotNull);
-        expect(event.isolate.name, equals('main'));
-        completer.complete(event.isolate);
-        sub.cancel();
-      }
-    });
-    result = await vm.invokeRpcNoUpgrade('_spawnUri', {
-      'token': 'mySpawnToken0',
-      'uri': '${fsUri}${filePaths[0]}',
-    });
-    expect(result['type'], equals('Success'));
-    var spawnedIsolate = await completer.future;
-
-    // Wait for the spawned isolate to hit a breakpoint.
-    await spawnedIsolate.load();
-    await hasStoppedAtBreakpoint(spawnedIsolate);
-
-    // Make sure that we are running code from the spawned isolate.
-    var instance = (await spawnedIsolate.rootLibrary.evaluate('proofOfLife()'))
-        as Instance;
-    expect(instance.type, equals('Instance'));
-    expect(instance.kind, equals(M.InstanceKind.string));
-    expect(instance.valueAsString, equals('I live!'));
-
-    // Spawn the script with arguments.
-    completer = new Completer();
-    sub = await vm.listenEventStream(VM.kIsolateStream, (ServiceEvent event) {
-      if (event.kind == ServiceEvent.kIsolateSpawn) {
-        expect(event.spawnToken, equals('mySpawnToken1'));
-        expect(event.isolate, isNotNull);
-        expect(event.isolate.name, equals('main'));
-        completer.complete(event.isolate);
-        sub.cancel();
-      }
-    });
-    result = await vm.invokeRpcNoUpgrade('_spawnUri', {
-      'token': 'mySpawnToken1',
-      'uri': '${fsUri}${filePaths[1]}',
-      'args': <String>['one', 'two', 'three']
-    });
-    expect(result['type'], equals('Success'));
-    spawnedIsolate = await completer.future;
-
-    // Wait for the spawned isolate to hit a breakpoint.
-    await spawnedIsolate.load();
-    await hasStoppedAtBreakpoint(spawnedIsolate);
-
-    // Make sure that we are running code from the spawned isolate.
-    instance = (await spawnedIsolate.rootLibrary.evaluate('proofOfLife()'))
-        as Instance;
-    expect(instance.type, equals('Instance'));
-    expect(instance.kind, equals(M.InstanceKind.string));
-    expect(instance.valueAsString, equals('I live, [one, two, three]!'));
-
-    // Spawn the script with arguments and message
-    completer = new Completer();
-    sub = await vm.listenEventStream(VM.kIsolateStream, (ServiceEvent event) {
-      if (event.kind == ServiceEvent.kIsolateSpawn) {
-        expect(event.spawnToken, equals('mySpawnToken2'));
-        expect(event.isolate, isNotNull);
-        expect(event.isolate.name, equals('main'));
-        completer.complete(event.isolate);
-        sub.cancel();
-      }
-    });
-    result = await vm.invokeRpcNoUpgrade('_spawnUri', {
-      'token': 'mySpawnToken2',
-      'uri': '${fsUri}${filePaths[2]}',
-      'args': ['A', 'B', 'C'],
-      'message': 'test'
-    });
-    expect(result['type'], equals('Success'));
-    spawnedIsolate = await completer.future;
-
-    // Wait for the spawned isolate to hit a breakpoint.
-    await spawnedIsolate.load();
-    await hasStoppedAtBreakpoint(spawnedIsolate);
-
-    // Make sure that we are running code from the spawned isolate.
-    instance = (await spawnedIsolate.rootLibrary.evaluate('proofOfLife()'))
-        as Instance;
-    expect(instance.type, equals('Instance'));
-    expect(instance.kind, equals(M.InstanceKind.string));
-    expect(instance.valueAsString, equals('I live, [A, B, C], test!'));
-
-    // Delete the fs.
-    result = await vm.invokeRpcNoUpgrade('_deleteDevFS', {
-      'fsName': fsName,
-    });
-    expect(result['type'], equals('Success'));
-  },
-];
-
-main(args) async => runVMTests(args, tests);
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index e2a35ca..ac995f4 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -613,9 +613,8 @@
 // type to another thus avoiding the warning.
 template <class D, class S>
 inline D bit_cast(const S& source) {
-  // Compile time assertion: sizeof(D) == sizeof(S). A compile error
-  // here means your D and S have different sizes.
-  DART_UNUSED typedef char VerifySizesAreEqual[sizeof(D) == sizeof(S) ? 1 : -1];
+  static_assert(sizeof(D) == sizeof(S),
+                "Source and destination must have the same size");
 
   D destination;
   // This use of memcpy is safe: source and destination cannot overlap.
diff --git a/runtime/platform/utils_fuchsia.cc b/runtime/platform/utils_fuchsia.cc
index fd1b082..22d2800 100644
--- a/runtime/platform/utils_fuchsia.cc
+++ b/runtime/platform/utils_fuchsia.cc
@@ -39,7 +39,7 @@
 
 sys::ComponentContext* ComponentContext() {
   static std::unique_ptr<sys::ComponentContext> context =
-      sys::ComponentContext::Create();
+      sys::ComponentContext::CreateAndServeOutgoingDirectory();
   return context.get();
 }
 
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 65e0dae..aab5d58 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -317,8 +317,8 @@
   V(Int32x4_setFlagZ, 2)                                                       \
   V(Int32x4_setFlagW, 2)                                                       \
   V(Int32x4_select, 3)                                                         \
-  V(Isolate_spawnFunction, 11)                                                 \
-  V(Isolate_spawnUri, 13)                                                      \
+  V(Isolate_spawnFunction, 10)                                                 \
+  V(Isolate_spawnUri, 12)                                                      \
   V(Isolate_getPortAndCapabilitiesOfCurrentIsolate, 0)                         \
   V(Isolate_getCurrentRootUriStr, 0)                                           \
   V(Isolate_sendOOB, 2)                                                        \
@@ -371,7 +371,6 @@
   V(VMService_CancelStream, 1)                                                 \
   V(VMService_RequestAssets, 0)                                                \
   V(VMService_DecodeAssets, 1)                                                 \
-  V(VMService_spawnUriNotify, 2)                                               \
   V(Ffi_loadInt8, 2)                                                           \
   V(Ffi_loadInt16, 2)                                                          \
   V(Ffi_loadInt32, 2)                                                          \
diff --git a/runtime/vm/bss_relocs.cc b/runtime/vm/bss_relocs.cc
index 12809a7..7df4242 100644
--- a/runtime/vm/bss_relocs.cc
+++ b/runtime/vm/bss_relocs.cc
@@ -8,16 +8,23 @@
 
 namespace dart {
 
-void BSS::Initialize(Thread* current, uword* bss_start) {
-  std::atomic<uword>* slot =
-      reinterpret_cast<std::atomic<uword>*>(&bss_start[BSS::RelocationIndex(
-          BSS::Relocation::DRT_GetThreadForNativeCallback)]);
+static void InitializeBSSEntry(BSS::Relocation relocation,
+                               uword function_address,
+                               uword* bss_start) {
+  std::atomic<uword>* slot = reinterpret_cast<std::atomic<uword>*>(
+      &bss_start[BSS::RelocationIndex(relocation)]);
   uword old_value = slot->load(std::memory_order_relaxed);
-  uword new_value = reinterpret_cast<uword>(DLRT_GetThreadForNativeCallback);
+  uword new_value = function_address;
   if (!slot->compare_exchange_strong(old_value, new_value,
                                      std::memory_order_relaxed)) {
     RELEASE_ASSERT(old_value == new_value);
   }
 }
 
+void BSS::Initialize(Thread* current, uword* bss_start) {
+  InitializeBSSEntry(BSS::Relocation::DRT_GetThreadForNativeCallback,
+                     reinterpret_cast<uword>(DLRT_GetThreadForNativeCallback),
+                     bss_start);
+}
+
 }  // namespace dart
diff --git a/runtime/vm/class_id.h b/runtime/vm/class_id.h
index 4a79fa7..40f6897 100644
--- a/runtime/vm/class_id.h
+++ b/runtime/vm/class_id.h
@@ -178,7 +178,7 @@
   V(Object)                                                                    \
   CLASS_LIST_NO_OBJECT(V)
 
-enum ClassId {
+enum ClassId : intptr_t {
   // Illegal class id.
   kIllegalCid = 0,
 
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 5804c37..16baa7a 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -121,11 +121,10 @@
   intptr_t stop_data = serializer->GetDataSize();
   intptr_t stop_objects = serializer->next_ref_index();
   if (FLAG_print_cluster_information) {
-    const int hex_size = kWordSize * 2;
-    OS::PrintErr("Snapshot 0x%0*.*" Px " (%" Pd "), ", hex_size, hex_size,
-                 start_size, stop_size - start_size);
-    OS::PrintErr("Data 0x%0*.*" Px " (%" Pd "): ", hex_size, hex_size,
-                 start_data, stop_data - start_data);
+    OS::PrintErr("Snapshot 0x%" Pp " (%" Pd "), ", start_size,
+                 stop_size - start_size);
+    OS::PrintErr("Data 0x%" Pp " (%" Pd "): ", start_data,
+                 stop_data - start_data);
     OS::PrintErr("Alloc %s (%" Pd ")\n", name(), stop_objects - start_objects);
   }
   size_ += (stop_size - start_size) + (stop_data - start_data);
@@ -137,9 +136,8 @@
   WriteFill(serializer);
   intptr_t stop = serializer->bytes_written();
   if (FLAG_print_cluster_information) {
-    const int hex_size = kWordSize * 2;
-    OS::PrintErr("Snapshot 0x%0*.*" Px " (%" Pd "): Fill %s\n", hex_size,
-                 hex_size, start, stop - start, name());
+    OS::PrintErr("Snapshot 0x%" Pp " (%" Pd "): Fill %s\n", start, stop - start,
+                 name());
   }
   size_ += (stop - start);
 }
diff --git a/runtime/vm/compiler/assembler/assembler_arm64_test.cc b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
index e9fc68c..e133f9f 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
@@ -2551,7 +2551,8 @@
 }
 
 ASSEMBLER_TEST_RUN(LoadObjectNull, test) {
-  EXPECT_EQ(Object::null(), test->InvokeWithCodeAndThread<ObjectPtr>());
+  EXPECT_EQ(static_cast<uword>(Object::null()),
+            test->InvokeWithCodeAndThread<uword>());
 }
 
 // PushObject null.
@@ -2566,7 +2567,8 @@
 }
 
 ASSEMBLER_TEST_RUN(PushObjectNull, test) {
-  EXPECT_EQ(Object::null(), test->InvokeWithCodeAndThread<ObjectPtr>());
+  EXPECT_EQ(static_cast<uword>(Object::null()),
+            test->InvokeWithCodeAndThread<uword>());
 }
 
 // CompareObject null.
@@ -2584,7 +2586,8 @@
 }
 
 ASSEMBLER_TEST_RUN(CompareObjectNull, test) {
-  EXPECT_EQ(Bool::True().raw(), test->InvokeWithCodeAndThread<ObjectPtr>());
+  EXPECT_EQ(static_cast<uword>(Bool::True().raw()),
+            test->InvokeWithCodeAndThread<uword>());
 }
 
 ASSEMBLER_TEST_GENERATE(LoadObjectTrue, assembler) {
@@ -2597,7 +2600,8 @@
 }
 
 ASSEMBLER_TEST_RUN(LoadObjectTrue, test) {
-  EXPECT_EQ(Bool::True().raw(), test->InvokeWithCodeAndThread<ObjectPtr>());
+  EXPECT_EQ(static_cast<uword>(Bool::True().raw()),
+            test->InvokeWithCodeAndThread<uword>());
 }
 
 ASSEMBLER_TEST_GENERATE(LoadObjectFalse, assembler) {
@@ -2610,7 +2614,8 @@
 }
 
 ASSEMBLER_TEST_RUN(LoadObjectFalse, test) {
-  EXPECT_EQ(Bool::False().raw(), test->InvokeWithCodeAndThread<ObjectPtr>());
+  EXPECT_EQ(static_cast<uword>(Bool::False().raw()),
+            test->InvokeWithCodeAndThread<uword>());
 }
 
 ASSEMBLER_TEST_GENERATE(CSelTrue, assembler) {
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.h b/runtime/vm/compiler/backend/flow_graph_compiler.h
index 3c2ee5c..62a91c6 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.h
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.h
@@ -460,6 +460,7 @@
   bool is_optimizing() const { return is_optimizing_; }
 
   void InsertBSSRelocation(BSS::Relocation reloc);
+  void LoadBSSEntry(BSS::Relocation relocation, Register dst, Register tmp);
 
   // The function was fully intrinsified, so the body is unreachable.
   //
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index 77a9a11..58b1ee1 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -1722,6 +1722,31 @@
   }
 }
 
+void FlowGraphCompiler::LoadBSSEntry(BSS::Relocation relocation,
+                                     Register dst,
+                                     Register tmp) {
+  compiler::Label skip_reloc;
+  __ b(&skip_reloc);
+  InsertBSSRelocation(relocation);
+  __ Bind(&skip_reloc);
+
+  // For historical reasons, the PC on ARM points 8 bytes (two instructions)
+  // past the current instruction.
+  __ sub(tmp, PC,
+         compiler::Operand(Instr::kPCReadOffset + compiler::target::kWordSize));
+
+  // tmp holds the address of the relocation.
+  __ ldr(dst, compiler::Address(tmp));
+
+  // dst holds the relocation itself: tmp - bss_start.
+  // tmp = tmp + (bss_start - tmp) = bss_start
+  __ add(tmp, tmp, compiler::Operand(dst));
+
+  // tmp holds the start of the BSS section.
+  // Load the "get-thread" routine: *bss_start.
+  __ ldr(dst, compiler::Address(tmp));
+}
+
 #undef __
 #define __ compiler_->assembler()->
 
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index d338e4c..60bad9af 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -1663,6 +1663,28 @@
   }
 }
 
+void FlowGraphCompiler::LoadBSSEntry(BSS::Relocation relocation,
+                                     Register dst,
+                                     Register tmp) {
+  compiler::Label skip_reloc;
+  __ b(&skip_reloc);
+  InsertBSSRelocation(relocation);
+  __ Bind(&skip_reloc);
+
+  __ adr(tmp, compiler::Immediate(-compiler::target::kWordSize));
+
+  // tmp holds the address of the relocation.
+  __ ldr(dst, compiler::Address(tmp));
+
+  // dst holds the relocation itself: tmp - bss_start.
+  // tmp = tmp + (bss_start - tmp) = bss_start
+  __ add(tmp, tmp, compiler::Operand(dst));
+
+  // tmp holds the start of the BSS section.
+  // Load the "get-thread" routine: *bss_start.
+  __ ldr(dst, compiler::Address(tmp));
+}
+
 #undef __
 #define __ compiler_->assembler()->
 
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index e6502dd..091b51f 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -1646,6 +1646,32 @@
   }
 }
 
+void FlowGraphCompiler::LoadBSSEntry(BSS::Relocation relocation,
+                                     Register dst,
+                                     Register tmp) {
+  compiler::Label skip_reloc;
+  __ jmp(&skip_reloc);
+  InsertBSSRelocation(relocation);
+  const intptr_t reloc_end = __ CodeSize();
+  __ Bind(&skip_reloc);
+
+  const intptr_t kLeaqLength = 7;
+  __ leaq(dst, compiler::Address::AddressRIPRelative(
+                   -kLeaqLength - compiler::target::kWordSize));
+  ASSERT((__ CodeSize() - reloc_end) == kLeaqLength);
+
+  // dst holds the address of the relocation.
+  __ movq(tmp, compiler::Address(dst, 0));
+
+  // tmp holds the relocation itself: dst - bss_start.
+  // dst = dst + (bss_start - dst) = bss_start
+  __ addq(dst, tmp);
+
+  // dst holds the start of the BSS section.
+  // Load the routine.
+  __ movq(dst, compiler::Address(dst, 0));
+}
+
 #undef __
 #define __ compiler_->assembler()->
 
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 4612792..63a8bf0 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -3726,15 +3726,7 @@
     }
   }
 
-  StringPtr Selector() {
-    if (auto static_call = this->AsStaticCall()) {
-      return static_call->function().name();
-    } else if (auto instance_call = this->AsInstanceCall()) {
-      return instance_call->function_name().raw();
-    } else {
-      UNREACHABLE();
-    }
-  }
+  inline StringPtr Selector();
 
   virtual bool MayThrow() const { return true; }
   virtual bool CanCallDart() const { return true; }
@@ -9196,6 +9188,17 @@
   }                                                                            \
   void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); }
 
+template <intptr_t kExtraInputs>
+StringPtr TemplateDartCall<kExtraInputs>::Selector() {
+  if (auto static_call = this->AsStaticCall()) {
+    return static_call->function().name();
+  } else if (auto instance_call = this->AsInstanceCall()) {
+    return instance_call->function_name().raw();
+  } else {
+    UNREACHABLE();
+  }
+}
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_COMPILER_BACKEND_IL_H_
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index ceb2152..59da8b5 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -1345,28 +1345,8 @@
   // Load the thread object. If we were called by a trampoline, the thread is
   // already loaded.
   if (FLAG_precompiled_mode) {
-    compiler::Label skip_reloc;
-    __ b(&skip_reloc);
-    compiler->InsertBSSRelocation(
-        BSS::Relocation::DRT_GetThreadForNativeCallback);
-    __ Bind(&skip_reloc);
-
-    // For historical reasons, the PC on ARM points 8 bytes (two instructions)
-    // past the current instruction.
-    __ sub(
-        R0, PC,
-        compiler::Operand(Instr::kPCReadOffset + compiler::target::kWordSize));
-
-    // R0 holds the address of the relocation.
-    __ ldr(R1, compiler::Address(R0));
-
-    // R1 holds the relocation itself: R0 - bss_start.
-    // R0 = R0 + (bss_start - R0) = bss_start
-    __ add(R0, R0, compiler::Operand(R1));
-
-    // R0 holds the start of the BSS section.
-    // Load the "get-thread" routine: *bss_start.
-    __ ldr(R1, compiler::Address(R0));
+    compiler->LoadBSSEntry(BSS::Relocation::DRT_GetThreadForNativeCallback, R1,
+                           R0);
   } else if (!NativeCallbackTrampolines::Enabled()) {
     // In JIT mode, we can just paste the address of the runtime entry into the
     // generated code directly. This is not a problem since we don't save
@@ -4825,10 +4805,10 @@
         live_fpu_regs ? object_store->allocate_mint_with_fpu_regs_stub()
                       : object_store->allocate_mint_without_fpu_regs_stub());
 
-      ASSERT(!locs()->live_registers()->ContainsRegister(R0));
-      auto extended_env = compiler->SlowPathEnvironmentFor(this, 0);
-      compiler->GenerateStubCall(token_pos(), stub, PcDescriptorsLayout::kOther,
-                                 locs(), DeoptId::kNone, extended_env);
+    ASSERT(!locs()->live_registers()->ContainsRegister(R0));
+    auto extended_env = compiler->SlowPathEnvironmentFor(this, 0);
+    compiler->GenerateStubCall(token_pos(), stub, PcDescriptorsLayout::kOther,
+                               locs(), DeoptId::kNone, extended_env);
   } else {
     BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(),
                                     out_reg, tmp);
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 0e5989c..8b5b9e8 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -1173,24 +1173,8 @@
   // Load the thread object. If we were called by a trampoline, the thread is
   // already loaded.
   if (FLAG_precompiled_mode) {
-    compiler::Label skip_reloc;
-    __ b(&skip_reloc);
-    compiler->InsertBSSRelocation(
-        BSS::Relocation::DRT_GetThreadForNativeCallback);
-    __ Bind(&skip_reloc);
-
-    __ adr(R0, compiler::Immediate(-compiler::target::kWordSize));
-
-    // R0 holds the address of the relocation.
-    __ ldr(R1, compiler::Address(R0));
-
-    // R1 holds the relocation itself: R0 - bss_start.
-    // R0 = R0 + (bss_start - R0) = bss_start
-    __ add(R0, R0, compiler::Operand(R1));
-
-    // R0 holds the start of the BSS section.
-    // Load the "get-thread" routine: *bss_start.
-    __ ldr(R1, compiler::Address(R0));
+    compiler->LoadBSSEntry(BSS::Relocation::DRT_GetThreadForNativeCallback, R1,
+                           R0);
   } else if (!NativeCallbackTrampolines::Enabled()) {
     // In JIT mode, we can just paste the address of the runtime entry into the
     // generated code directly. This is not a problem since we don't save
@@ -1728,7 +1712,7 @@
 
   switch (class_id()) {
     case kArrayCid:
-      ASSERT(!ShouldEmitStoreBarrier());   // Specially treated above.
+      ASSERT(!ShouldEmitStoreBarrier());  // Specially treated above.
       if (locs()->in(2).IsConstant()) {
         const Object& constant = locs()->in(2).constant();
         __ StoreIntoObjectNoBarrier(array, element_address, constant);
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index d9324dc..19ddebf 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -1070,28 +1070,8 @@
 
   // Load the address of DLRT_GetThreadForNativeCallback without using Thread.
   if (FLAG_precompiled_mode) {
-    compiler::Label skip_reloc;
-    __ jmp(&skip_reloc);
-    compiler->InsertBSSRelocation(
-        BSS::Relocation::DRT_GetThreadForNativeCallback);
-    const intptr_t reloc_end = __ CodeSize();
-    __ Bind(&skip_reloc);
-
-    const intptr_t kLeaqLength = 7;
-    __ leaq(RAX, compiler::Address::AddressRIPRelative(
-                     -kLeaqLength - compiler::target::kWordSize));
-    ASSERT((__ CodeSize() - reloc_end) == kLeaqLength);
-
-    // RAX holds the address of the relocation.
-    __ movq(RCX, compiler::Address(RAX, 0));
-
-    // RCX holds the relocation itself: RAX - bss_start.
-    // RAX = RAX + (bss_start - RAX) = bss_start
-    __ addq(RAX, RCX);
-
-    // RAX holds the start of the BSS section.
-    // Load the "get-thread" routine: *bss_start.
-    __ movq(RAX, compiler::Address(RAX, 0));
+    compiler->LoadBSSEntry(BSS::Relocation::DRT_GetThreadForNativeCallback, RAX,
+                           RCX);
   } else if (!NativeCallbackTrampolines::Enabled()) {
     // In JIT mode, we can just paste the address of the runtime entry into the
     // generated code directly. This is not a problem since we don't save
diff --git a/runtime/vm/compiler/ffi/native_calling_convention.cc b/runtime/vm/compiler/ffi/native_calling_convention.cc
index fa6f4eb..56e4690 100644
--- a/runtime/vm/compiler/ffi/native_calling_convention.cc
+++ b/runtime/vm/compiler/ffi/native_calling_convention.cc
@@ -131,6 +131,7 @@
   }
 
   Register AllocateCpuRegister() {
+    RELEASE_ASSERT(cpu_regs_used >= 0);  // Avoids -Werror=array-bounds in GCC.
     ASSERT(cpu_regs_used < CallingConventions::kNumArgRegs);
 
     const auto result = CallingConventions::ArgumentRegisters[cpu_regs_used];
diff --git a/runtime/vm/compiler/ffi/native_location.cc b/runtime/vm/compiler/ffi/native_location.cc
index 27c0388..0c7fb16 100644
--- a/runtime/vm/compiler/ffi/native_location.cc
+++ b/runtime/vm/compiler/ffi/native_location.cc
@@ -305,6 +305,7 @@
     case kSingleFpuReg:
       return DRegisterOf(fpu_s_reg());
   }
+  UNREACHABLE();
 }
 
 SRegister NativeFpuRegistersLocation::fpu_as_s_reg() const {
@@ -316,6 +317,7 @@
     case kSingleFpuReg:
       return fpu_s_reg();
   }
+  UNREACHABLE();
 }
 
 bool NativeFpuRegistersLocation::IsLowestBits() const {
diff --git a/runtime/vm/compiler/ffi/native_type.cc b/runtime/vm/compiler/ffi/native_type.cc
index adcc57a..d06d73f 100644
--- a/runtime/vm/compiler/ffi/native_type.cc
+++ b/runtime/vm/compiler/ffi/native_type.cc
@@ -103,8 +103,9 @@
     case kAlignedToValueSize:
       // iOS on arm64 only aligns to size.
       return SizeInBytes();
+    default:
+      UNREACHABLE();
   }
-  UNREACHABLE();
 }
 
 intptr_t NativeFundamentalType::AlignmentInBytesField() const {
@@ -120,8 +121,9 @@
       }
       return SizeInBytes();
     }
+    default:
+      UNREACHABLE();
   }
-  UNREACHABLE();
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index 7c9f60a..ca41bd5 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -375,7 +375,7 @@
       }
   }
   FATAL3("Unsupported class for size translation: %s (id=%" Pd
-         ", kNumPredefinedCids=%d)\n",
+         ", kNumPredefinedCids=%" Pd ")\n",
          handle.ToCString(), handle.id(), kNumPredefinedCids);
   return -1;
 }
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 180a7e0..08ae076 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -566,6 +566,22 @@
   delete predefined_handles_;
   predefined_handles_ = NULL;
 
+  // Set the VM isolate as current isolate.
+  if (FLAG_trace_shutdown) {
+    OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Cleaning up vm isolate\n",
+                 UptimeMillis());
+  }
+
+  // If Dart_Cleanup() is called on a thread which hasn't invoked any Dart API
+  // functions before, entering the "vm-isolate" will cause lazy creation of a
+  // OSThread (which is attached to the current thread via TLS).
+  //
+  // If we run in PRODUCT mode this lazy creation of OSThread can happen here,
+  // which is why disabling the OSThread creation has to come after entering the
+  // "vm-isolate".
+  const bool result = Thread::EnterIsolate(vm_isolate_);
+  ASSERT(result);
+
   // Disable creation of any new OSThread structures which means no more new
   // threads can do an EnterIsolate. This must come after isolate shutdown
   // because new threads may need to be spawned to shutdown the isolates.
@@ -578,14 +594,6 @@
   }
   OSThread::DisableOSThreadCreation();
 
-  // Set the VM isolate as current isolate.
-  if (FLAG_trace_shutdown) {
-    OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Cleaning up vm isolate\n",
-                 UptimeMillis());
-  }
-  bool result = Thread::EnterIsolate(vm_isolate_);
-  ASSERT(result);
-
   ShutdownIsolate();
   vm_isolate_ = NULL;
   ASSERT(Isolate::IsolateListLength() == 0);
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 6106c7c..4f1551d 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -3373,6 +3373,7 @@
     weak2 = Dart_NewWeakPersistentHandle(obj, NULL, kWeak2ExternalSize,
                                          NopCallback);
     EXPECT_VALID(AsHandle(strong_ref));
+    EXPECT_VALID(AsHandle(weak2));
     Dart_ExitScope();
   }
   {
diff --git a/runtime/vm/datastream.h b/runtime/vm/datastream.h
index 77c74bc..d34cdbe 100644
--- a/runtime/vm/datastream.h
+++ b/runtime/vm/datastream.h
@@ -120,11 +120,11 @@
   }
 
  private:
-  int16_t Read16() { return Read16(kEndByteMarker); }
+  uint16_t Read16() { return Read16(kEndByteMarker); }
 
-  int32_t Read32() { return Read32(kEndByteMarker); }
+  uint32_t Read32() { return Read32(kEndByteMarker); }
 
-  int64_t Read64() { return Read64(kEndByteMarker); }
+  uint64_t Read64() { return Read64(kEndByteMarker); }
 
   template <typename T>
   T Read(uint8_t end_byte_marker) {
@@ -147,153 +147,153 @@
     return r | ((static_cast<T>(b) - end_byte_marker) << s);
   }
 
-  int16_t Read16(uint8_t end_byte_marker) {
+  uint16_t Read16(uint8_t end_byte_marker) {
     const uint8_t* c = current_;
     ASSERT(c < end_);
     uint8_t b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return static_cast<int16_t>(b) - end_byte_marker;
+      return static_cast<uint16_t>(b) - end_byte_marker;
     }
-    int16_t r = 0;
-    r |= static_cast<int16_t>(b);
+    uint16_t r = 0;
+    r |= static_cast<uint16_t>(b);
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int16_t>(b) - end_byte_marker) << 7);
+      return r | ((static_cast<uint16_t>(b) - end_byte_marker) << 7);
     }
 
-    r |= static_cast<int16_t>(b) << 7;
+    r |= static_cast<uint16_t>(b) << 7;
     ASSERT(c < end_);
     b = *c++;
     ASSERT(b > kMaxUnsignedDataPerByte);
     current_ = c;
-    return r | ((static_cast<int16_t>(b) - end_byte_marker) << 14);
+    return r | ((static_cast<uint16_t>(b) - end_byte_marker) << 14);
   }
 
-  int32_t Read32(uint8_t end_byte_marker) {
+  uint32_t Read32(uint8_t end_byte_marker) {
     const uint8_t* c = current_;
     ASSERT(c < end_);
     uint8_t b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return static_cast<int32_t>(b) - end_byte_marker;
+      return static_cast<uint32_t>(b) - end_byte_marker;
     }
 
-    int32_t r = 0;
-    r |= static_cast<int32_t>(b);
+    uint32_t r = 0;
+    r |= static_cast<uint32_t>(b);
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int32_t>(b) - end_byte_marker) << 7);
+      return r | ((static_cast<uint32_t>(b) - end_byte_marker) << 7);
     }
 
-    r |= static_cast<int32_t>(b) << 7;
+    r |= static_cast<uint32_t>(b) << 7;
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int32_t>(b) - end_byte_marker) << 14);
+      return r | ((static_cast<uint32_t>(b) - end_byte_marker) << 14);
     }
 
-    r |= static_cast<int32_t>(b) << 14;
+    r |= static_cast<uint32_t>(b) << 14;
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int32_t>(b) - end_byte_marker) << 21);
+      return r | ((static_cast<uint32_t>(b) - end_byte_marker) << 21);
     }
 
-    r |= static_cast<int32_t>(b) << 21;
+    r |= static_cast<uint32_t>(b) << 21;
     ASSERT(c < end_);
     b = *c++;
     ASSERT(b > kMaxUnsignedDataPerByte);
     current_ = c;
-    return r | ((static_cast<int32_t>(b) - end_byte_marker) << 28);
+    return r | ((static_cast<uint32_t>(b) - end_byte_marker) << 28);
   }
 
-  int64_t Read64(uint8_t end_byte_marker) {
+  uint64_t Read64(uint8_t end_byte_marker) {
     const uint8_t* c = current_;
     ASSERT(c < end_);
     uint8_t b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return static_cast<int64_t>(b) - end_byte_marker;
+      return static_cast<uint64_t>(b) - end_byte_marker;
     }
-    int64_t r = 0;
+    uint64_t r = 0;
 
-    r |= static_cast<int64_t>(b);
+    r |= static_cast<uint64_t>(b);
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int64_t>(b) - end_byte_marker) << 7);
+      return r | ((static_cast<uint64_t>(b) - end_byte_marker) << 7);
     }
 
-    r |= static_cast<int64_t>(b) << 7;
+    r |= static_cast<uint64_t>(b) << 7;
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int64_t>(b) - end_byte_marker) << 14);
+      return r | ((static_cast<uint64_t>(b) - end_byte_marker) << 14);
     }
 
-    r |= static_cast<int64_t>(b) << 14;
+    r |= static_cast<uint64_t>(b) << 14;
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int64_t>(b) - end_byte_marker) << 21);
+      return r | ((static_cast<uint64_t>(b) - end_byte_marker) << 21);
     }
 
-    r |= static_cast<int64_t>(b) << 21;
+    r |= static_cast<uint64_t>(b) << 21;
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int64_t>(b) - end_byte_marker) << 28);
+      return r | ((static_cast<uint64_t>(b) - end_byte_marker) << 28);
     }
 
-    r |= static_cast<int64_t>(b) << 28;
+    r |= static_cast<uint64_t>(b) << 28;
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int64_t>(b) - end_byte_marker) << 35);
+      return r | ((static_cast<uint64_t>(b) - end_byte_marker) << 35);
     }
 
-    r |= static_cast<int64_t>(b) << 35;
+    r |= static_cast<uint64_t>(b) << 35;
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int64_t>(b) - end_byte_marker) << 42);
+      return r | ((static_cast<uint64_t>(b) - end_byte_marker) << 42);
     }
 
-    r |= static_cast<int64_t>(b) << 42;
+    r |= static_cast<uint64_t>(b) << 42;
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int64_t>(b) - end_byte_marker) << 49);
+      return r | ((static_cast<uint64_t>(b) - end_byte_marker) << 49);
     }
 
-    r |= static_cast<int64_t>(b) << 49;
+    r |= static_cast<uint64_t>(b) << 49;
     ASSERT(c < end_);
     b = *c++;
     if (b > kMaxUnsignedDataPerByte) {
       current_ = c;
-      return r | ((static_cast<int64_t>(b) - end_byte_marker) << 56);
+      return r | ((static_cast<uint64_t>(b) - end_byte_marker) << 56);
     }
 
-    r |= static_cast<int64_t>(b) << 56;
+    r |= static_cast<uint64_t>(b) << 56;
     ASSERT(c < end_);
     b = *c++;
     ASSERT(b > kMaxUnsignedDataPerByte);
     current_ = c;
-    return r | ((static_cast<int64_t>(b) - end_byte_marker) << 63);
+    return r | ((static_cast<uint64_t>(b) - end_byte_marker) << 63);
   }
 
   uint8_t ReadByte() {
diff --git a/runtime/vm/elf.cc b/runtime/vm/elf.cc
index 9654d8e..a90dfa2 100644
--- a/runtime/vm/elf.cc
+++ b/runtime/vm/elf.cc
@@ -87,36 +87,49 @@
   intptr_t section_info = 0;
   intptr_t section_entry_size = 0;
 
+  static constexpr intptr_t kInitValue = -1;
+
 #define FOR_EACH_SECTION_LINEAR_FIELD(M)                                       \
-  M(section_name, intptr_t, -1)                                                \
-  M(section_index, intptr_t, -1)                                               \
-  M(file_offset, intptr_t, -1)
+  M(section_name, intptr_t, kInitValue)                                        \
+  M(section_index, intptr_t, kInitValue)                                       \
+  M(file_offset, intptr_t, kInitValue)
 
   FOR_EACH_SECTION_LINEAR_FIELD(DEFINE_LINEAR_FIELD_METHODS);
 
-  virtual intptr_t FileSize() = 0;
+  virtual intptr_t FileSize() const = 0;
 
   // Loader view.
   const intptr_t segment_type;
   const intptr_t segment_flags;
 
-#define FOR_EACH_SEGMENT_LINEAR_FIELD(M) M(memory_offset, intptr_t, -1)
+#define FOR_EACH_SEGMENT_LINEAR_FIELD(M) M(memory_offset, intptr_t, kInitValue)
 
   FOR_EACH_SEGMENT_LINEAR_FIELD(DEFINE_LINEAR_FIELD_METHODS);
 
-  virtual intptr_t MemorySize() = 0;
+  virtual intptr_t MemorySize() const = 0;
 
   // Other methods.
+  bool IsSegment() const { return segment_type != 0; }
+  // Returns whether new content can be added to a section.
+  bool HasBeenFinalized() const {
+    if (IsSegment()) {
+      // The contents of a segment must not change after the segment is added
+      // (when its memory offset is calculated).
+      return memory_offset_ != kInitValue;
+    } else {
+      // Sections with an in-memory segment can have new content added until
+      // we calculate file offsets.
+      return file_offset_ != kInitValue;
+    }
+  }
+
   virtual void Write(Elf* stream) = 0;
 
-  void WriteSegmentEntry(Elf* stream, bool dynamic = false) {
-    // This should never be used on either the reserved 0-filled section or
-    // on sections without a segment.
+  void WriteSegmentEntry(Elf* stream) {
+    // This should never be used on sections without a segment.
     ASSERT(MemorySize() > 0);
-    // dynamic should only be true if this section is the dynamic table.
-    ASSERT(!dynamic || section_type == elf::SHT_DYNAMIC);
 #if defined(TARGET_ARCH_IS_32_BIT)
-    stream->WriteWord(dynamic ? elf::PT_DYNAMIC : segment_type);
+    stream->WriteWord(segment_type);
     stream->WriteOff(file_offset());
     stream->WriteAddr(memory_offset());  // Virtual address.
     stream->WriteAddr(memory_offset());  // Physical address, not used.
@@ -125,7 +138,7 @@
     stream->WriteWord(segment_flags);
     stream->WriteWord(alignment);
 #else
-    stream->WriteWord(dynamic ? elf::PT_DYNAMIC : segment_type);
+    stream->WriteWord(segment_type);
     stream->WriteWord(segment_flags);
     stream->WriteOff(file_offset());
     stream->WriteAddr(memory_offset());  // Virtual address.
@@ -198,8 +211,7 @@
 #undef DEFINE_LINEAR_FIELD_METHODS
 
 // Represents the first entry in the section table, which should only contain
-// zero values. Only used for WriteSectionEntry and should never actually appear
-// in sections_.
+// zero values and does not correspond to a memory segment.
 class ReservedSection : public Section {
  public:
   ReservedSection()
@@ -213,9 +225,9 @@
     set_file_offset(0);
   }
 
-  intptr_t FileSize() { return 0; }
-  intptr_t MemorySize() { return 0; }
-  void Write(Elf* stream) { UNREACHABLE(); }
+  intptr_t FileSize() const { return 0; }
+  intptr_t MemorySize() const { return 0; }
+  void Write(Elf* stream) {}
 };
 
 class BlobSection : public Section {
@@ -248,8 +260,8 @@
                     memsz,
                     alignment) {}
 
-  intptr_t FileSize() { return file_size_; }
-  intptr_t MemorySize() { return memory_size_; }
+  intptr_t FileSize() const { return file_size_; }
+  intptr_t MemorySize() const { return memory_size_; }
 
   virtual void Write(Elf* stream) = 0;
 
@@ -258,11 +270,11 @@
   const intptr_t memory_size_;
 };
 
-// A section for representing the program header segment in the program header
-// table. Only used for WriteSegmentEntry.
-class ProgramTable : public BlobSection {
+// A segment for representing the program header table self-reference in the
+// program header table. There is no corresponding section for this segment.
+class ProgramTableSelfSegment : public BlobSection {
  public:
-  ProgramTable(intptr_t offset, intptr_t size)
+  ProgramTableSelfSegment(intptr_t offset, intptr_t size)
       : BlobSection(/*type=*/0,
                     /*segment_type=*/elf::PT_PHDR,
                     /*allocate=*/true,
@@ -274,13 +286,12 @@
     set_memory_offset(offset);
   }
 
-  // This should never actually be added to sections_ or segments_.
   void Write(Elf* stream) { UNREACHABLE(); }
 };
 
-// A section for representing the program header table load segment in the
-// program header table. Only used for WriteSegmentEntry.
-class ProgramTableLoad : public BlobSection {
+// A segment for representing the program header table load segment in the
+// program header table. There is no corresponding section for this segment.
+class ProgramTableLoadSegment : public BlobSection {
  public:
   // The Android dynamic linker in Jelly Bean incorrectly assumes that all
   // non-writable segments are continguous. Since the BSS segment comes directly
@@ -290,7 +301,7 @@
   //
   // The bug is here:
   //   https://github.com/aosp-mirror/platform_bionic/blob/94963af28e445384e19775a838a29e6a71708179/linker/linker.c#L1991-L2001
-  explicit ProgramTableLoad(intptr_t size)
+  explicit ProgramTableLoadSegment(intptr_t size)
       : BlobSection(/*type=*/0,
                     /*allocate=*/true,
                     /*executable=*/false,
@@ -301,7 +312,6 @@
     set_memory_offset(0);
   }
 
-  // This should never actually be added to sections_ or segments_.
   void Write(Elf* stream) { UNREACHABLE(); }
 };
 
@@ -353,8 +363,8 @@
     text_indices_.Insert({"", 1});
   }
 
-  intptr_t FileSize() { return text_.length(); }
-  intptr_t MemorySize() { return dynamic_ ? FileSize() : 0; }
+  intptr_t FileSize() const { return text_.length(); }
+  intptr_t MemorySize() const { return dynamic_ ? FileSize() : 0; }
 
   void Write(Elf* stream) {
     stream->WriteBytes(reinterpret_cast<const uint8_t*>(text_.buffer()),
@@ -435,8 +445,8 @@
     section_info = 1;  // One "local" symbol, the reserved first entry.
   }
 
-  intptr_t FileSize() { return Length() * kElfSymbolTableEntrySize; }
-  intptr_t MemorySize() { return dynamic_ ? FileSize() : 0; }
+  intptr_t FileSize() const { return Length() * kElfSymbolTableEntrySize; }
+  intptr_t MemorySize() const { return dynamic_ ? FileSize() : 0; }
 
   void Write(Elf* stream) {
     for (intptr_t i = 0; i < Length(); i++) {
@@ -503,8 +513,8 @@
     }
   }
 
-  intptr_t FileSize() { return 4 * (nbucket_ + nchain_ + 2); }
-  intptr_t MemorySize() { return FileSize(); }
+  intptr_t FileSize() const { return 4 * (nbucket_ + nchain_ + 2); }
+  intptr_t MemorySize() const { return FileSize(); }
 
   void Write(Elf* stream) {
     stream->WriteWord(nbucket_);
@@ -543,8 +553,10 @@
     AddEntry(elf::DT_NULL, 0);
   }
 
-  intptr_t FileSize() { return entries_.length() * kElfDynamicTableEntrySize; }
-  intptr_t MemorySize() { return FileSize(); }
+  intptr_t FileSize() const {
+    return entries_.length() * kElfDynamicTableEntrySize;
+  }
+  intptr_t MemorySize() const { return FileSize(); }
 
   void Write(Elf* stream) {
     for (intptr_t i = 0; i < entries_.length(); i++) {
@@ -578,12 +590,23 @@
   GrowableArray<Entry*> entries_;
 };
 
-// The first section must be written out and contains only zeros.
-static const intptr_t kNumInvalidSections = 1;
+// A segment for representing the dynamic table segment in the program header
+// table. There is no corresponding section for this segment.
+class DynamicSegment : public BlobSection {
+ public:
+  explicit DynamicSegment(DynamicTable* dynamic)
+      : BlobSection(dynamic->section_type,
+                    /*segment_type=*/elf::PT_DYNAMIC,
+                    /*allocate=*/true,
+                    /*executable=*/false,
+                    /*writable=*/true,
+                    /*filesz=*/dynamic->FileSize(),
+                    /*memsz=*/dynamic->MemorySize()) {
+    set_memory_offset(dynamic->memory_offset());
+  }
 
-// Extra segments put in the program table that aren't reified in
-// Elf::segments_.
-static const intptr_t kNumImplicitSegments = 3;
+  void Write(Elf* stream) { UNREACHABLE(); }
+};
 
 static const intptr_t kProgramTableSegmentSize = Elf::kPageSize;
 
@@ -596,14 +619,22 @@
       memory_offset_(kProgramTableSegmentSize) {
   // Assumed by various offset logic in this file.
   ASSERT(stream_->position() == 0);
+  // The first section in the section header table is always a reserved
+  // entry containing only 0 values.
+  sections_.Add(new (zone_) ReservedSection());
+  // Go ahead and add the section header string table, since it doesn't have
+  // an in-memory segment and so can be added to until we compute file offsets.
+  AddSection(shstrtab_, ".shstrtab");
 }
 
 void Elf::AddSection(Section* section, const char* name) {
-  ASSERT(shstrtab_ != nullptr);
+  ASSERT(section_table_file_size_ < 0);
+  ASSERT(!shstrtab_->HasBeenFinalized());
   section->set_section_name(shstrtab_->AddString(name));
-  section->set_section_index(sections_.length() + kNumInvalidSections);
+  section->set_section_index(sections_.length());
   sections_.Add(section);
   if (section->MemorySize() > 0) {
+    ASSERT(program_table_file_size_ < 0);
     memory_offset_ = Utils::RoundUp(memory_offset_, section->alignment);
     section->set_memory_offset(memory_offset_);
     segments_.Add(section);
@@ -612,17 +643,10 @@
   }
 }
 
-intptr_t Elf::NextMemoryOffset() const {
-  return memory_offset_;
-}
-
-intptr_t Elf::NextSectionIndex() const {
-  return sections_.length() + kNumInvalidSections;
-}
-
 intptr_t Elf::AddSectionSymbol(const Section* section,
                                const char* name,
                                intptr_t size) {
+  ASSERT(!dynstrtab_->HasBeenFinalized() && !dynsym_->HasBeenFinalized());
   auto const name_index = dynstrtab_->AddString(name);
   auto const info = (elf::STB_GLOBAL << 4) | elf::STT_FUNC;
   auto const section_index = section->section_index();
@@ -656,10 +680,15 @@
   // symbols in unstripped ELF files.
   if (strtab_ == nullptr) {
     ASSERT(symtab_ == nullptr);
+    ASSERT(section_table_file_size_ < 0);
     strtab_ = new (zone_) StringTable(/* allocate= */ false);
+    AddSection(strtab_, ".strtab");
     symtab_ = new (zone_) SymbolTable(/*dynamic=*/false);
+    AddSection(symtab_, ".symtab");
+    symtab_->section_link = strtab_->section_index();
   }
 
+  ASSERT(!strtab_->HasBeenFinalized() && !symtab_->HasBeenFinalized());
   auto const name_index = strtab_->AddString(name);
   auto const info = (elf::STB_GLOBAL << 4) | elf::STT_FUNC;
   Symbol* symbol =
@@ -699,6 +728,8 @@
 }
 
 void Elf::Finalize() {
+  // Unlike the static tables, we must wait until finalization to add the
+  // dynamic tables, as adding them marks them as finalized.
   AddSection(dynstrtab_, ".dynstr");
   AddSection(dynsym_, ".dynsym");
   dynsym_->section_link = dynstrtab_->section_index();
@@ -706,45 +737,81 @@
   auto const hash = new (zone_) SymbolHashTable(dynstrtab_, dynsym_);
   AddSection(hash, ".hash");
 
-  if (symtab_ != nullptr) {
-    ASSERT(strtab_ != nullptr);
-    AddSection(strtab_, ".strtab");
-    AddSection(symtab_, ".symtab");
-    symtab_->section_link = strtab_->section_index();
-  }
-
   dynamic_ = new (zone_) DynamicTable(dynstrtab_, dynsym_, hash);
   AddSection(dynamic_, ".dynamic");
 
-  AddSection(shstrtab_, ".shstrtab");
+  // Also add a PT_DYNAMIC segment for the dynamic symbol table.
+  dynamic_segment_ = new (zone_) DynamicSegment(dynamic_);
+  segments_.Add(dynamic_segment_);
 
+  // At this point, all sections and user-defined segments have been added. Add
+  // any program table-specific segments and then calculate file offsets for all
+  // sections and segments.
+  FinalizeProgramTable();
   ComputeFileOffsets();
 
+  // Finally, write the ELF file contents.
   WriteHeader();
   WriteProgramTable();
   WriteSections();
   WriteSectionTable();
 }
 
-void Elf::ComputeFileOffsets() {
-  intptr_t file_offset = kElfHeaderSize;
+void Elf::FinalizeProgramTable() {
+  ASSERT(program_table_file_size_ < 0);
 
-  program_table_file_offset_ = file_offset;
+  program_table_file_offset_ = kElfHeaderSize;
+
+  // There are two segments we need the size of the program table to create, so
+  // calculate it as if those two segments were already in place.
   program_table_file_size_ =
-      (segments_.length() + kNumImplicitSegments) * kElfProgramTableEntrySize;
-  file_offset += program_table_file_size_;
+      (2 + segments_.length()) * kElfProgramTableEntrySize;
 
-  for (intptr_t i = 0; i < sections_.length(); i++) {
+  // We pre-allocated the virtual memory space for the program table itself.
+  // Check that we didn't generate too many segments. Currently we generate a
+  // fixed num of segments based on the four pieces of a snapshot, but if we
+  // use more in the future we'll likely need to do something more compilated
+  // to generate DWARF without knowing a piece's virtual address in advance.
+  auto const program_table_segment_size =
+      program_table_file_offset_ + program_table_file_size_;
+  RELEASE_ASSERT(program_table_segment_size < kProgramTableSegmentSize);
+
+  // Self-reference to program header table. Required by Android but not by
+  // Linux. Must appear before any PT_LOAD entries.
+  segments_.InsertAt(
+      0, new (zone_) ProgramTableSelfSegment(program_table_file_offset_,
+                                             program_table_file_size_));
+
+  // Segment for loading the initial part of the ELF file, including the
+  // program header table. Required by Android but not by Linux.
+  segments_.InsertAt(
+      1, new (zone_) ProgramTableLoadSegment(program_table_segment_size));
+}
+
+void Elf::ComputeFileOffsets() {
+  // We calculate the size and offset of the program header table during
+  // finalization.
+  ASSERT(program_table_file_offset_ > 0 && program_table_file_size_ > 0);
+  intptr_t file_offset = program_table_file_offset_ + program_table_file_size_;
+
+  // The first (reserved) section's file offset is set to 0 during construction,
+  // so skip it.
+  ASSERT(sections_.length() >= 1 && sections_[0]->section_type == 0);
+  // The others are output to the file in order after the program header table.
+  for (intptr_t i = 1; i < sections_.length(); i++) {
     Section* section = sections_[i];
     file_offset = Utils::RoundUp(file_offset, section->alignment);
     section->set_file_offset(file_offset);
     file_offset += section->FileSize();
   }
 
+  // Make the dynamic segment's file offset the same as the dynamic table now
+  // that it's been calculated for the latter.
+  dynamic_segment_->set_file_offset(dynamic_->file_offset());
+
   file_offset = Utils::RoundUp(file_offset, kElfSectionTableAlignment);
   section_table_file_offset_ = file_offset;
-  section_table_file_size_ =
-      (sections_.length() + kNumInvalidSections) * kElfSectionTableEntrySize;
+  section_table_file_size_ = sections_.length() * kElfSectionTableEntrySize;
   file_offset += section_table_file_size_;
 }
 
@@ -802,9 +869,9 @@
 
   WriteHalf(kElfHeaderSize);
   WriteHalf(kElfProgramTableEntrySize);
-  WriteHalf(segments_.length() + kNumImplicitSegments);
+  WriteHalf(segments_.length());
   WriteHalf(kElfSectionTableEntrySize);
-  WriteHalf(sections_.length() + kNumInvalidSections);
+  WriteHalf(sections_.length());
   WriteHalf(shstrtab_->section_index());
 
   ASSERT(stream_->position() == kElfHeaderSize);
@@ -813,41 +880,6 @@
 void Elf::WriteProgramTable() {
   ASSERT(stream_->position() == program_table_file_offset_);
 
-  // Self-reference to program header table. Required by Android but not by
-  // Linux. Must appear before any PT_LOAD entries.
-  {
-    ProgramTable program_table(program_table_file_offset_,
-                               program_table_file_size_);
-
-    ASSERT(kNumImplicitSegments == 3);
-    const intptr_t start = stream_->position();
-    program_table.WriteSegmentEntry(this);
-    const intptr_t end = stream_->position();
-    ASSERT((end - start) == kElfProgramTableEntrySize);
-  }
-  // Load for self-reference to program header table. Required by Android but
-  // not by Linux.
-  {
-    // We pre-allocated the virtual memory space for the program table itself.
-    // Check that we didn't generate too many segments. Currently we generate a
-    // fixed num of segments based on the four pieces of a snapshot, but if we
-    // use more in the future we'll likely need to do something more compilated
-    // to generate DWARF without knowing a piece's virtual address in advance.
-    auto const program_table_segment_size =
-        program_table_file_offset_ + program_table_file_size_;
-    RELEASE_ASSERT(program_table_segment_size < kProgramTableSegmentSize);
-
-    // We create a section that, when printed as a segment, contains the
-    // appropriate info for the program table.
-    ProgramTableLoad program_table_load(program_table_segment_size);
-
-    ASSERT(kNumImplicitSegments == 3);
-    const intptr_t start = stream_->position();
-    program_table_load.WriteSegmentEntry(this);
-    const intptr_t end = stream_->position();
-    ASSERT((end - start) == kElfProgramTableEntrySize);
-  }
-
   for (intptr_t i = 0; i < segments_.length(); i++) {
     Section* section = segments_[i];
     const intptr_t start = stream_->position();
@@ -855,16 +887,6 @@
     const intptr_t end = stream_->position();
     ASSERT((end - start) == kElfProgramTableEntrySize);
   }
-
-  // Special case: the dynamic section requires both LOAD and DYNAMIC program
-  // header table entries.
-  {
-    ASSERT(kNumImplicitSegments == 3);
-    const intptr_t start = stream_->position();
-    dynamic_->WriteSegmentEntry(this, /*dynamic=*/true);
-    const intptr_t end = stream_->position();
-    ASSERT((end - start) == kElfProgramTableEntrySize);
-  }
 }
 
 void Elf::WriteSectionTable() {
@@ -872,16 +894,6 @@
 
   ASSERT(stream_->position() == section_table_file_offset_);
 
-  {
-    // The first entry in the section table is reserved and must be all zeros.
-    ASSERT(kNumInvalidSections == 1);
-    const intptr_t start = stream_->position();
-    ReservedSection reserved;
-    reserved.WriteSectionEntry(this);
-    const intptr_t end = stream_->position();
-    ASSERT((end - start) == kElfSectionTableEntrySize);
-  }
-
   for (intptr_t i = 0; i < sections_.length(); i++) {
     Section* section = sections_[i];
     const intptr_t start = stream_->position();
@@ -892,7 +904,10 @@
 }
 
 void Elf::WriteSections() {
-  for (intptr_t i = 0; i < sections_.length(); i++) {
+  // Skip the reserved first section, as its alignment is 0 and it does not
+  // contain any contents.
+  ASSERT(sections_[0]->alignment == 0 && sections_[0]->section_type == 0);
+  for (intptr_t i = 1; i < sections_.length(); i++) {
     Section* section = sections_[i];
     stream_->Align(section->alignment);
     ASSERT(stream_->position() == section->file_offset());
diff --git a/runtime/vm/elf.h b/runtime/vm/elf.h
index 4cd877a..1adad3a 100644
--- a/runtime/vm/elf.h
+++ b/runtime/vm/elf.h
@@ -13,6 +13,7 @@
 
 namespace dart {
 
+class DynamicSegment;
 class DynamicTable;
 class Section;
 class StringTable;
@@ -25,8 +26,8 @@
 
   static const intptr_t kPageSize = 4096;
 
-  intptr_t NextMemoryOffset() const;
-  intptr_t NextSectionIndex() const;
+  intptr_t NextMemoryOffset() const { return memory_offset_; }
+  intptr_t NextSectionIndex() const { return sections_.length(); }
   intptr_t AddText(const char* name, const uint8_t* bytes, intptr_t size);
   intptr_t AddROData(const char* name, const uint8_t* bytes, intptr_t size);
   intptr_t AddBSSData(const char* name, intptr_t size);
@@ -69,6 +70,7 @@
                             const char* name,
                             intptr_t size);
 
+  void FinalizeProgramTable();
   void ComputeFileOffsets();
   void WriteHeader();
   void WriteSectionTable();
@@ -86,6 +88,7 @@
 
   // Can only be created once the dynamic symbol table is complete.
   DynamicTable* dynamic_ = nullptr;
+  DynamicSegment* dynamic_segment_ = nullptr;
 
   // The static tables are lazily created when static symbols are added.
   StringTable* strtab_ = nullptr;
diff --git a/runtime/vm/field_table.cc b/runtime/vm/field_table.cc
index 8ff6f03..495d7a0 100644
--- a/runtime/vm/field_table.cc
+++ b/runtime/vm/field_table.cc
@@ -82,12 +82,18 @@
 void FieldTable::Grow(intptr_t new_capacity) {
   ASSERT(new_capacity > capacity_);
 
+  auto old_table = table_;
   auto new_table = static_cast<InstancePtr*>(
       malloc(new_capacity * sizeof(InstancePtr)));  // NOLINT
-  memmove(new_table, table_, top_ * sizeof(InstancePtr));
-  memset(new_table + top_, 0, (new_capacity - top_) * sizeof(InstancePtr));
+  intptr_t i;
+  for (i = 0; i < top_; i++) {
+    new_table[i] = old_table[i];
+  }
+  for (; i < new_capacity; i++) {
+    new_table[i] = InstancePtr();
+  }
   capacity_ = new_capacity;
-  old_tables_->Add(table_);
+  old_tables_->Add(old_table);
   // Ensure that new_table_ is populated before it is published
   // via store to table_.
   std::atomic_thread_fence(std::memory_order_release);
diff --git a/runtime/vm/os_test.cc b/runtime/vm/os_test.cc
index 331b3d2..d1b7791 100644
--- a/runtime/vm/os_test.cc
+++ b/runtime/vm/os_test.cc
@@ -26,13 +26,6 @@
   EXPECT_EQ(3, length);
 }
 
-// This test is expected to crash when it runs.
-VM_UNIT_TEST_CASE_WITH_EXPECTATION(SNPrint_BadArgs, "Crash") {
-  int width = kMaxInt32;
-  int num = 7;
-  Utils::SNPrint(NULL, 0, "%*d%*d", width, num, width, num);
-}
-
 VM_UNIT_TEST_CASE(OsFuncs) {
   EXPECT(Utils::IsPowerOfTwo(OS::ActivationFrameAlignment()));
   int procs = OS::NumberOfAvailableProcessors();
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index 43cd2d0..f4741fd 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -1132,12 +1132,13 @@
     }
   }
 
+  OS::PrintErr("version=%s\n", Version::String());
   OSThread* os_thread = OSThread::Current();
   ASSERT(os_thread != NULL);
   Isolate* isolate = Isolate::Current();
-  const char* name = isolate == NULL ? NULL : isolate->name();
-  OS::PrintErr("version=%s\npid=%" Pd ", thread=%" Pd ", isolate=%s(%p)\n",
-               Version::String(), OS::ProcessId(),
+  const char* name = isolate == NULL ? "(nil)" : isolate->name();
+  OS::PrintErr("pid=%" Pd ", thread=%" Pd ", isolate=%s(%p)\n",
+               static_cast<intptr_t>(OS::ProcessId()),
                OSThread::ThreadIdToIntPtr(os_thread->trace_id()), name,
                isolate);
   const IsolateGroupSource* source =
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index 7fe9b39..3c91049 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -345,10 +345,9 @@
   if (name == NULL) {
     name_ = NULL;
   }
-  intptr_t len = strlen(name);
-  name_ = Thread::Current()->zone()->Alloc<char>(len + 1);
+  intptr_t len = strlen(name) + 1;
+  name_ = Thread::Current()->zone()->Alloc<char>(len);
   strncpy(name_, name, len);
-  name_[len] = '\0';
 }
 
 void ProfileCode::GenerateAndSetSymbolName(const char* prefix) {
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index ada6634..5611f2c 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -45,7 +45,7 @@
     return;
   }
   // Validate that the tags_ field is sensible.
-  uint32_t tags = ptr()->tags_;
+  uint32_t tags = tags_;
   if (IsNewObject()) {
     if (!NewBit::decode(tags)) {
       FATAL1("New object missing kNewBit: %x\n", tags);
@@ -362,7 +362,7 @@
       break;
     default:
       FATAL3("Invalid cid: %" Pd ", obj: %p, tags: %x. Corrupt heap?", class_id,
-             this, static_cast<uint32_t>(ptr()->tags_));
+             this, static_cast<uint32_t>(tags_));
       break;
   }
 
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index d9cccf9..fd0ddb6 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -37,10 +37,10 @@
 class CodeStatistics;
 
 #define VISIT_FROM(type, first)                                                \
-  type* from() { return reinterpret_cast<type*>(&ptr()->first); }
+  type* from() { return reinterpret_cast<type*>(&first); }
 
 #define VISIT_TO(type, last)                                                   \
-  type* to() { return reinterpret_cast<type*>(&ptr()->last); }
+  type* to() { return reinterpret_cast<type*>(&last); }
 
 #define VISIT_TO_LENGTH(type, last)                                            \
   type* to(intptr_t length) { return reinterpret_cast<type*>(last); }
@@ -89,11 +89,9 @@
   DISALLOW_ALLOCATION();                                                       \
   DISALLOW_IMPLICIT_CONSTRUCTORS(object##Layout)
 
-// TODO(koda): Make ptr() return const*, like Object::raw_ptr().
 #define RAW_HEAP_OBJECT_IMPLEMENTATION(object)                                 \
  private:                                                                      \
   RAW_OBJECT_IMPLEMENTATION(object);                                           \
-  object##Layout* ptr() const { return const_cast<object##Layout*>(this); }    \
   SNAPSHOT_WRITER_SUPPORT()                                                    \
   HEAP_PROFILER_SUPPORT()                                                      \
   friend class object##SerializationCluster;                                   \
@@ -286,51 +284,51 @@
   // visited) or black (already visited).
   bool IsMarked() const {
     ASSERT(IsOldObject());
-    return !ptr()->tags_.Read<OldAndNotMarkedBit>();
+    return !tags_.Read<OldAndNotMarkedBit>();
   }
   void SetMarkBit() {
     ASSERT(IsOldObject());
     ASSERT(!IsMarked());
-    ptr()->tags_.UpdateBool<OldAndNotMarkedBit>(false);
+    tags_.UpdateBool<OldAndNotMarkedBit>(false);
   }
   void SetMarkBitUnsynchronized() {
     ASSERT(IsOldObject());
     ASSERT(!IsMarked());
-    ptr()->tags_.UpdateUnsynchronized<OldAndNotMarkedBit>(false);
+    tags_.UpdateUnsynchronized<OldAndNotMarkedBit>(false);
   }
   void ClearMarkBit() {
     ASSERT(IsOldObject());
     ASSERT(IsMarked());
-    ptr()->tags_.UpdateBool<OldAndNotMarkedBit>(true);
+    tags_.UpdateBool<OldAndNotMarkedBit>(true);
   }
   // Returns false if the bit was already set.
   DART_WARN_UNUSED_RESULT
   bool TryAcquireMarkBit() {
     ASSERT(IsOldObject());
-    return ptr()->tags_.TryClear<OldAndNotMarkedBit>();
+    return tags_.TryClear<OldAndNotMarkedBit>();
   }
 
   // Canonical objects have the property that two canonical objects are
   // logically equal iff they are the same object (pointer equal).
-  bool IsCanonical() const { return ptr()->tags_.Read<CanonicalBit>(); }
-  void SetCanonical() { ptr()->tags_.UpdateBool<CanonicalBit>(true); }
-  void ClearCanonical() { ptr()->tags_.UpdateBool<CanonicalBit>(false); }
+  bool IsCanonical() const { return tags_.Read<CanonicalBit>(); }
+  void SetCanonical() { tags_.UpdateBool<CanonicalBit>(true); }
+  void ClearCanonical() { tags_.UpdateBool<CanonicalBit>(false); }
 
   bool InVMIsolateHeap() const;
 
   // Support for GC remembered bit.
   bool IsRemembered() const {
     ASSERT(IsOldObject());
-    return !ptr()->tags_.Read<OldAndNotRememberedBit>();
+    return !tags_.Read<OldAndNotRememberedBit>();
   }
   void SetRememberedBit() {
     ASSERT(!IsRemembered());
     ASSERT(!IsCardRemembered());
-    ptr()->tags_.UpdateBool<OldAndNotRememberedBit>(false);
+    tags_.UpdateBool<OldAndNotRememberedBit>(false);
   }
   void ClearRememberedBit() {
     ASSERT(IsOldObject());
-    ptr()->tags_.UpdateBool<OldAndNotRememberedBit>(true);
+    tags_.UpdateBool<OldAndNotRememberedBit>(true);
   }
 
   DART_FORCE_INLINE
@@ -340,19 +338,17 @@
     thread->StoreBufferAddObject(ObjectPtr(this));
   }
 
-  bool IsCardRemembered() const {
-    return ptr()->tags_.Read<CardRememberedBit>();
-  }
+  bool IsCardRemembered() const { return tags_.Read<CardRememberedBit>(); }
   void SetCardRememberedBitUnsynchronized() {
     ASSERT(!IsRemembered());
     ASSERT(!IsCardRemembered());
-    ptr()->tags_.UpdateUnsynchronized<CardRememberedBit>(true);
+    tags_.UpdateUnsynchronized<CardRememberedBit>(true);
   }
 
-  intptr_t GetClassId() const { return ptr()->tags_.Read<ClassIdTag>(); }
+  intptr_t GetClassId() const { return tags_.Read<ClassIdTag>(); }
 
   intptr_t HeapSize() const {
-    uint32_t tags = ptr()->tags_;
+    uint32_t tags = tags_;
     intptr_t result = SizeTag::decode(tags);
     if (result != 0) {
 #if defined(DEBUG)
@@ -363,8 +359,8 @@
       // recomputing size from tags.
       const intptr_t size_from_class = HeapSizeFromClass(tags);
       if ((result > size_from_class) && (GetClassId() == kArrayCid) &&
-          (ptr()->tags_) != tags) {
-        result = SizeTag::decode(ptr()->tags_);
+          (tags_ != tags)) {
+        result = SizeTag::decode(tags_);
       }
       ASSERT(result == size_from_class);
 #endif
@@ -375,7 +371,7 @@
     return result;
   }
 
-  // This variant must not deference ptr()->tags_.
+  // This variant must not deference this->tags_.
   intptr_t HeapSize(uint32_t tags) const {
     intptr_t result = SizeTag::decode(tags);
     if (result != 0) {
@@ -505,16 +501,13 @@
   uint32_t padding_;
 #endif
 
-  // TODO(koda): After handling tags_, return const*, like Object::raw_ptr().
-  ObjectLayout* ptr() const { return const_cast<ObjectLayout*>(this); }
-
   intptr_t VisitPointersPredefined(ObjectPointerVisitor* visitor,
                                    intptr_t class_id);
 
   intptr_t HeapSizeFromClass(uint32_t tags) const;
 
   void SetClassId(intptr_t new_cid) {
-    ptr()->tags_.UpdateUnsynchronized<ClassIdTag>(new_cid);
+    tags_.UpdateUnsynchronized<ClassIdTag>(new_cid);
   }
 
   // All writes to heap objects should ultimately pass through one of the
@@ -546,7 +539,7 @@
 
   DART_FORCE_INLINE
   void CheckHeapPointerStore(ObjectPtr value, Thread* thread) {
-    uint32_t source_tags = this->ptr()->tags_;
+    uint32_t source_tags = this->tags_;
     uint32_t target_tags = value->ptr()->tags_;
     if (((source_tags >> kBarrierOverlapShift) & target_tags &
          thread->write_barrier_mask()) != 0) {
@@ -593,7 +586,7 @@
   DART_FORCE_INLINE void CheckArrayPointerStore(type const* addr,
                                                 ObjectPtr value,
                                                 Thread* thread) {
-    uint32_t source_tags = this->ptr()->tags_;
+    uint32_t source_tags = this->tags_;
     uint32_t target_tags = value->ptr()->tags_;
     if (((source_tags >> kBarrierOverlapShift) & target_tags &
          thread->write_barrier_mask()) != 0) {
@@ -746,11 +739,11 @@
   ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
-        return reinterpret_cast<ObjectPtr*>(&ptr()->allocation_stub_);
+        return reinterpret_cast<ObjectPtr*>(&allocation_stub_);
       case Snapshot::kFull:
-        return reinterpret_cast<ObjectPtr*>(&ptr()->direct_subclasses_);
+        return reinterpret_cast<ObjectPtr*>(&direct_subclasses_);
       case Snapshot::kFullJIT:
-        return reinterpret_cast<ObjectPtr*>(&ptr()->dependent_code_);
+        return reinterpret_cast<ObjectPtr*>(&dependent_code_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -819,10 +812,10 @@
   ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
-        return reinterpret_cast<ObjectPtr*>(&ptr()->script_);
+        return reinterpret_cast<ObjectPtr*>(&script_);
       case Snapshot::kFull:
       case Snapshot::kFullJIT:
-        return reinterpret_cast<ObjectPtr*>(&ptr()->library_kernel_data_);
+        return reinterpret_cast<ObjectPtr*>(&library_kernel_data_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -1003,7 +996,7 @@
       case Snapshot::kFullAOT:
       case Snapshot::kFull:
       case Snapshot::kFullJIT:
-        return reinterpret_cast<ObjectPtr*>(&ptr()->data_);
+        return reinterpret_cast<ObjectPtr*>(&data_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -1014,7 +1007,7 @@
   }
   ArrayPtr ic_data_array_;  // ICData of unoptimized code.
   ObjectPtr* to_no_code() {
-    return reinterpret_cast<ObjectPtr*>(&ptr()->ic_data_array_);
+    return reinterpret_cast<ObjectPtr*>(&ic_data_array_);
   }
   CodePtr code_;  // Currently active code. Accessed from generated code.
   NOT_IN_PRECOMPILED(BytecodePtr bytecode_);
@@ -1168,7 +1161,7 @@
       case Snapshot::kFull:
       case Snapshot::kFullJIT:
       case Snapshot::kFullAOT:
-        return reinterpret_cast<ObjectPtr*>(&ptr()->initializer_function_);
+        return reinterpret_cast<ObjectPtr*>(&initializer_function_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -1237,10 +1230,10 @@
   ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
-        return reinterpret_cast<ObjectPtr*>(&ptr()->url_);
+        return reinterpret_cast<ObjectPtr*>(&url_);
       case Snapshot::kFull:
       case Snapshot::kFullJIT:
-        return reinterpret_cast<ObjectPtr*>(&ptr()->kernel_program_info_);
+        return reinterpret_cast<ObjectPtr*>(&kernel_program_info_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -1308,10 +1301,10 @@
   ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
-        return reinterpret_cast<ObjectPtr*>(&ptr()->exports_);
+        return reinterpret_cast<ObjectPtr*>(&exports_);
       case Snapshot::kFull:
       case Snapshot::kFullJIT:
-        return reinterpret_cast<ObjectPtr*>(&ptr()->kernel_data_);
+        return reinterpret_cast<ObjectPtr*>(&kernel_data_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -1378,7 +1371,7 @@
   uint32_t kernel_binary_version_;
 
   ObjectPtr* to_snapshot(Snapshot::Kind kind) {
-    return reinterpret_cast<ObjectPtr*>(&ptr()->constants_table_);
+    return reinterpret_cast<ObjectPtr*>(&constants_table_);
   }
 };
 
@@ -1528,7 +1521,7 @@
 #endif
 
   ObjectPtr* to_snapshot(Snapshot::Kind kind) {
-    return reinterpret_cast<ObjectPtr*>(&ptr()->pc_descriptors_);
+    return reinterpret_cast<ObjectPtr*>(&pc_descriptors_);
   }
 
   int32_t instructions_binary_offset_;
@@ -1862,12 +1855,12 @@
     // Array of [num_entries_] variable names.
     OPEN_ARRAY_START(StringPtr, StringPtr);
   }
-  StringPtr* nameAddrAt(intptr_t i) { return &(ptr()->names()[i]); }
+  StringPtr* nameAddrAt(intptr_t i) { return &(names()[i]); }
   VISIT_TO_LENGTH(ObjectPtr, nameAddrAt(length - 1));
 
   // Variable info with [num_entries_] entries.
   VarInfo* data() {
-    return reinterpret_cast<VarInfo*>(nameAddrAt(ptr()->num_entries_));
+    return reinterpret_cast<VarInfo*>(nameAddrAt(num_entries_));
   }
 
   friend class Object;
@@ -1884,7 +1877,7 @@
   // exception types.
   VISIT_FROM(ObjectPtr, handled_types_data_)
   ArrayPtr handled_types_data_;
-  VISIT_TO_LENGTH(ObjectPtr, &ptr()->handled_types_data_);
+  VISIT_TO_LENGTH(ObjectPtr, &handled_types_data_);
 
   // Exception handler info of length [num_entries_].
   const ExceptionHandlerInfo* data() const {
@@ -1908,7 +1901,7 @@
   // Variable length data follows here.
   ObjectPtr* data() { OPEN_ARRAY_START(ObjectPtr, ObjectPtr); }
   ObjectPtr const* data() const { OPEN_ARRAY_START(ObjectPtr, ObjectPtr); }
-  VISIT_TO_LENGTH(ObjectPtr, &ptr()->data()[length - 1]);
+  VISIT_TO_LENGTH(ObjectPtr, &data()[length - 1]);
 
   friend class Object;
   friend class SnapshotReader;
@@ -1940,7 +1933,7 @@
   bool is_implicit_;  // true, if this context scope is for an implicit closure.
 
   ObjectPtr* from() {
-    VariableDesc* begin = const_cast<VariableDesc*>(ptr()->VariableDescAddr(0));
+    VariableDesc* begin = const_cast<VariableDesc*>(VariableDescAddr(0));
     return reinterpret_cast<ObjectPtr*>(begin);
   }
   // Variable length data follows here.
@@ -1951,7 +1944,7 @@
     return &(reinterpret_cast<const VariableDesc*>(data())[index]);
   }
   ObjectPtr* to(intptr_t num_vars) {
-    uword end = reinterpret_cast<uword>(ptr()->VariableDescAddr(num_vars));
+    uword end = reinterpret_cast<uword>(VariableDescAddr(num_vars));
     // 'end' is the address just beyond the last descriptor, so step back.
     return reinterpret_cast<ObjectPtr*>(end - kWordSize);
   }
@@ -2028,7 +2021,7 @@
   ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kFullAOT:
-        return reinterpret_cast<ObjectPtr*>(&ptr()->entries_);
+        return reinterpret_cast<ObjectPtr*>(&entries_);
       case Snapshot::kFull:
       case Snapshot::kFullJIT:
         return to();
@@ -2125,9 +2118,9 @@
     switch (kind) {
       case Snapshot::kFull:
       case Snapshot::kFullJIT:
-        return reinterpret_cast<ObjectPtr*>(&ptr()->imports_);
+        return reinterpret_cast<ObjectPtr*>(&imports_);
       case Snapshot::kFullAOT:
-        return reinterpret_cast<ObjectPtr*>(&ptr()->importer_);
+        return reinterpret_cast<ObjectPtr*>(&importer_);
       case Snapshot::kMessage:
       case Snapshot::kNone:
       case Snapshot::kInvalid:
@@ -2159,7 +2152,7 @@
     OPEN_ARRAY_START(AbstractTypePtr, AbstractTypePtr);
   }
   ObjectPtr* to(intptr_t length) {
-    return reinterpret_cast<ObjectPtr*>(&ptr()->types()[length - 1]);
+    return reinterpret_cast<ObjectPtr*>(&types()[length - 1]);
   }
 
   friend class Object;
@@ -2426,11 +2419,11 @@
   }
 
   // Recompute [data_] pointer to internal data.
-  void RecomputeDataField() { ptr()->data_ = ptr()->internal_data(); }
+  void RecomputeDataField() { data_ = internal_data(); }
 
  protected:
   VISIT_FROM(RawCompressed, length_)
-  VISIT_TO_LENGTH(RawCompressed, &ptr()->length_)
+  VISIT_TO_LENGTH(RawCompressed, &length_)
 
   // Variable length data follows here.
 
@@ -2464,9 +2457,9 @@
  public:
   // Recompute [data_] based on internal/external [typed_data_].
   void RecomputeDataField() {
-    const intptr_t offset_in_bytes = RawSmiValue(ptr()->offset_in_bytes_);
-    uint8_t* payload = ptr()->typed_data_->ptr()->data_;
-    ptr()->data_ = payload + offset_in_bytes;
+    const intptr_t offset_in_bytes = RawSmiValue(offset_in_bytes_);
+    uint8_t* payload = typed_data_->ptr()->data_;
+    data_ = payload + offset_in_bytes;
   }
 
   // Recopute [data_] based on internal [typed_data_] - needs to be called by GC
@@ -2476,25 +2469,23 @@
   // [typed_data_] pointer points to the new backing store. The backing store's
   // fields don't need to be valid - only it's address.
   void RecomputeDataFieldForInternalTypedData() {
-    const intptr_t offset_in_bytes = RawSmiValue(ptr()->offset_in_bytes_);
-    uint8_t* payload =
-        reinterpret_cast<uint8_t*>(ObjectLayout::ToAddr(ptr()->typed_data_) +
-                                   TypedDataLayout::payload_offset());
-    ptr()->data_ = payload + offset_in_bytes;
+    const intptr_t offset_in_bytes = RawSmiValue(offset_in_bytes_);
+    uint8_t* payload = reinterpret_cast<uint8_t*>(
+        ObjectLayout::ToAddr(typed_data_) + TypedDataLayout::payload_offset());
+    data_ = payload + offset_in_bytes;
   }
 
   void ValidateInnerPointer() {
-    if (ptr()->typed_data_->ptr()->GetClassId() == kNullCid) {
+    if (typed_data_->ptr()->GetClassId() == kNullCid) {
       // The view object must have gotten just initialized.
-      if (ptr()->data_ != nullptr ||
-          RawSmiValue(ptr()->offset_in_bytes_) != 0 ||
-          RawSmiValue(ptr()->length_) != 0) {
+      if (data_ != nullptr || RawSmiValue(offset_in_bytes_) != 0 ||
+          RawSmiValue(length_) != 0) {
         FATAL("RawTypedDataView has invalid inner pointer.");
       }
     } else {
-      const intptr_t offset_in_bytes = RawSmiValue(ptr()->offset_in_bytes_);
-      uint8_t* payload = ptr()->typed_data_->ptr()->data_;
-      if ((payload + offset_in_bytes) != ptr()->data_) {
+      const intptr_t offset_in_bytes = RawSmiValue(offset_in_bytes_);
+      uint8_t* payload = typed_data_->ptr()->data_;
+      if ((payload + offset_in_bytes) != data_) {
         FATAL("RawTypedDataView has invalid inner pointer.");
       }
     }
@@ -2554,7 +2545,7 @@
   // Variable length data follows here.
   ObjectPtr* data() { OPEN_ARRAY_START(ObjectPtr, ObjectPtr); }
   ObjectPtr const* data() const { OPEN_ARRAY_START(ObjectPtr, ObjectPtr); }
-  VISIT_TO_LENGTH(RawCompressed, &ptr()->data()[length - 1])
+  VISIT_TO_LENGTH(RawCompressed, &data()[length - 1])
 
   friend class LinkedHashMapSerializationCluster;
   friend class LinkedHashMapDeserializationCluster;
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 487ae69..2f9a9a6 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -61,7 +61,7 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   if (writer->can_send_any_object() ||
-      writer->AllowObjectsInDartLibrary(ptr()->library_)) {
+      writer->AllowObjectsInDartLibrary(library_)) {
     writer->WriteClassId(this);
   } else {
     // We do not allow regular dart instances in isolate messages.
@@ -122,7 +122,7 @@
                          bool as_reference) {
   ASSERT(writer != NULL);
 
-  if (ptr()->signature_ != Function::null()) {
+  if (signature_ != Function::null()) {
     writer->SetWriteException(Exceptions::kArgument,
                               "Illegal argument in isolate message"
                               " : (function types are not supported yet)");
@@ -130,9 +130,9 @@
   }
 
   // Only resolved and finalized types should be written to a snapshot.
-  ASSERT((ptr()->type_state_ == TypeLayout::kFinalizedInstantiated) ||
-         (ptr()->type_state_ == TypeLayout::kFinalizedUninstantiated));
-  ASSERT(ptr()->type_class_id_ != Object::null());
+  ASSERT((type_state_ == TypeLayout::kFinalizedInstantiated) ||
+         (type_state_ == TypeLayout::kFinalizedUninstantiated));
+  ASSERT(type_class_id_ != Object::null());
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -141,13 +141,13 @@
   writer->WriteIndexedObject(kTypeCid);
   writer->WriteTags(writer->GetObjectTags(this));
 
-  if (ptr()->type_class_id_->IsHeapObject()) {
+  if (type_class_id_->IsHeapObject()) {
     // Type class is still an unresolved class.
     UNREACHABLE();
   }
 
   // Lookup the type class.
-  SmiPtr raw_type_class_id = Smi::RawCast(ptr()->type_class_id_);
+  SmiPtr raw_type_class_id = Smi::RawCast(type_class_id_);
   ClassPtr type_class =
       writer->isolate()->class_table()->At(Smi::Value(raw_type_class_id));
 
@@ -160,14 +160,14 @@
   writer->Write<bool>(typeclass_is_in_fullsnapshot);
 
   // Write out all the non object pointer fields.
-  writer->Write<int32_t>(ptr()->token_pos_.SnapshotEncode());
-  const uint8_t combined = (ptr()->type_state_ << 4) | ptr()->nullability_;
-  ASSERT(ptr()->type_state_ == (combined >> 4));
-  ASSERT(ptr()->nullability_ == (combined & 0xf));
+  writer->Write<int32_t>(token_pos_.SnapshotEncode());
+  const uint8_t combined = (type_state_ << 4) | nullability_;
+  ASSERT(type_state_ == (combined >> 4));
+  ASSERT(nullability_ == (combined & 0xf));
   writer->Write<uint8_t>(combined);
 
   // Write out all the object pointer fields.
-  ASSERT(ptr()->type_class_id_ != Object::null());
+  ASSERT(type_class_id_ != Object::null());
   SnapshotWriterVisitor visitor(writer, as_reference);
   visitor.VisitPointers(from(), to());
 
@@ -266,7 +266,7 @@
   ASSERT(writer != NULL);
 
   // Only finalized type parameters should be written to a snapshot.
-  ASSERT(FinalizedBit::decode(ptr()->flags_));
+  ASSERT(FinalizedBit::decode(flags_));
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -276,11 +276,11 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out all the non object pointer fields.
-  writer->Write<int32_t>(ptr()->token_pos_.SnapshotEncode());
-  writer->Write<int16_t>(ptr()->index_);
-  const uint8_t combined = (ptr()->flags_ << 4) | ptr()->nullability_;
-  ASSERT(ptr()->flags_ == (combined >> 4));
-  ASSERT(ptr()->nullability_ == (combined & 0xf));
+  writer->Write<int32_t>(token_pos_.SnapshotEncode());
+  writer->Write<int16_t>(index_);
+  const uint8_t combined = (flags_ << 4) | nullability_;
+  ASSERT(flags_ == (combined >> 4));
+  ASSERT(nullability_ == (combined & 0xf));
   writer->Write<uint8_t>(combined);
 
   // Write out all the object pointer fields.
@@ -289,7 +289,7 @@
 
   // Write out the parameterized class.
   ClassPtr param_class =
-      writer->isolate()->class_table()->At(ptr()->parameterized_class_id_);
+      writer->isolate()->class_table()->At(parameterized_class_id_);
   writer->WriteObjectImpl(param_class, kAsReference);
 }
 
@@ -339,10 +339,10 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out the length field.
-  writer->Write<ObjectPtr>(ptr()->length_);
+  writer->Write<ObjectPtr>(length_);
 
   // Write out the individual types.
-  intptr_t len = Smi::Value(ptr()->length_);
+  intptr_t len = Smi::Value(length_);
   for (intptr_t i = 0; i < len; i++) {
     // The Dart VM reuses type argument lists across instances in order
     // to reduce memory footprint, this can sometimes lead to a type from
@@ -351,17 +351,17 @@
     // across (isolates spawned using spawnURI) we send them as dynamic.
     if (!writer->can_send_any_object()) {
       // Lookup the type class.
-      TypePtr raw_type = Type::RawCast(ptr()->types()[i]);
+      TypePtr raw_type = Type::RawCast(types()[i]);
       SmiPtr raw_type_class_id = Smi::RawCast(raw_type->ptr()->type_class_id_);
       ClassPtr type_class =
           writer->isolate()->class_table()->At(Smi::Value(raw_type_class_id));
       if (!writer->AllowObjectsInDartLibrary(type_class->ptr()->library_)) {
         writer->WriteVMIsolateObject(kDynamicType);
       } else {
-        writer->WriteObjectImpl(ptr()->types()[i], as_reference);
+        writer->WriteObjectImpl(types()[i], as_reference);
       }
     } else {
-      writer->WriteObjectImpl(ptr()->types()[i], as_reference);
+      writer->WriteObjectImpl(types()[i], as_reference);
     }
   }
 }
@@ -435,7 +435,7 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out num of variables in the context.
-  int32_t num_variables = ptr()->num_variables_;
+  const int32_t num_variables = num_variables_;
   writer->Write<int32_t>(num_variables);
   if (num_variables != 0) {
     // Write out all the object pointer fields.
@@ -481,9 +481,9 @@
                                  bool as_reference) {
   ASSERT(writer != NULL);
 
-  if (ptr()->is_implicit_) {
-    ASSERT(ptr()->num_variables_ == 1);
-    const VariableDesc* var = ptr()->VariableDescAddr(0);
+  if (is_implicit_) {
+    ASSERT(num_variables_ == 1);
+    const VariableDesc* var = VariableDescAddr(0);
 
     // Write out the serialization header value for this object.
     writer->WriteInlinedObjectHeader(object_id);
@@ -650,9 +650,9 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out all the non object fields.
-  writer->Write<int32_t>(ptr()->token_pos_.SnapshotEncode());
-  writer->Write<bool>(ptr()->report_after_token_);
-  writer->Write<uint8_t>(ptr()->kind_);
+  writer->Write<int32_t>(token_pos_.SnapshotEncode());
+  writer->Write<bool>(report_after_token_);
+  writer->Write<uint8_t>(kind_);
 
   // Write out all the object pointer fields.
   SnapshotWriterVisitor visitor(writer, kAsReference);
@@ -777,7 +777,7 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out the 64 bit value.
-  writer->Write<int64_t>(ptr()->value_);
+  writer->Write<int64_t>(value_);
 }
 
 DoublePtr Double::ReadFrom(SnapshotReader* reader,
@@ -820,7 +820,7 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out the double value.
-  writer->WriteDouble(ptr()->value_);
+  writer->WriteDouble(value_);
 }
 
 template <typename StringType, typename CharacterType, typename CallbackType>
@@ -925,7 +925,7 @@
                                   Snapshot::Kind kind,
                                   bool as_reference) {
   StringWriteTo(writer, object_id, kind, kOneByteStringCid,
-                writer->GetObjectTags(this), ptr()->length_, ptr()->data());
+                writer->GetObjectTags(this), length_, data());
 }
 
 void TwoByteStringLayout::WriteTo(SnapshotWriter* writer,
@@ -933,7 +933,7 @@
                                   Snapshot::Kind kind,
                                   bool as_reference) {
   StringWriteTo(writer, object_id, kind, kTwoByteStringCid,
-                writer->GetObjectTags(this), ptr()->length_, ptr()->data());
+                writer->GetObjectTags(this), length_, data());
 }
 
 ExternalOneByteStringPtr ExternalOneByteString::ReadFrom(SnapshotReader* reader,
@@ -960,8 +960,7 @@
                                           bool as_reference) {
   // Serialize as a non-external one byte string.
   StringWriteTo(writer, object_id, kind, kOneByteStringCid,
-                writer->GetObjectTags(this), ptr()->length_,
-                ptr()->external_data_);
+                writer->GetObjectTags(this), length_, external_data_);
 }
 
 void ExternalTwoByteStringLayout::WriteTo(SnapshotWriter* writer,
@@ -970,8 +969,7 @@
                                           bool as_reference) {
   // Serialize as a non-external two byte string.
   StringWriteTo(writer, object_id, kind, kTwoByteStringCid,
-                writer->GetObjectTags(this), ptr()->length_,
-                ptr()->external_data_);
+                writer->GetObjectTags(this), length_, external_data_);
 }
 
 ArrayPtr Array::ReadFrom(SnapshotReader* reader,
@@ -1044,8 +1042,7 @@
                           bool as_reference) {
   ASSERT(!this->IsCanonical());
   writer->ArrayWriteTo(object_id, kArrayCid, writer->GetObjectTags(this),
-                       ptr()->length_, ptr()->type_arguments_, ptr()->data(),
-                       as_reference);
+                       length_, type_arguments_, data(), as_reference);
 }
 
 void ImmutableArrayLayout::WriteTo(SnapshotWriter* writer,
@@ -1053,8 +1050,8 @@
                                    Snapshot::Kind kind,
                                    bool as_reference) {
   writer->ArrayWriteTo(object_id, kImmutableArrayCid,
-                       writer->GetObjectTags(this), ptr()->length_,
-                       ptr()->type_arguments_, ptr()->data(), as_reference);
+                       writer->GetObjectTags(this), length_, type_arguments_,
+                       data(), as_reference);
 }
 
 GrowableObjectArrayPtr GrowableObjectArray::ReadFrom(SnapshotReader* reader,
@@ -1099,13 +1096,13 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out the type arguments field.
-  writer->WriteObjectImpl(ptr()->type_arguments_, kAsInlinedObject);
+  writer->WriteObjectImpl(type_arguments_, kAsInlinedObject);
 
   // Write out the used length field.
-  writer->Write<ObjectPtr>(ptr()->length_);
+  writer->Write<ObjectPtr>(length_);
 
   // Write out the Array object.
-  writer->WriteObjectImpl(ptr()->data_, kAsReference);
+  writer->WriteObjectImpl(data_, kAsReference);
 }
 
 LinkedHashMapPtr LinkedHashMap::ReadFrom(SnapshotReader* reader,
@@ -1170,18 +1167,18 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out the type arguments.
-  writer->WriteObjectImpl(ptr()->type_arguments_, kAsInlinedObject);
+  writer->WriteObjectImpl(type_arguments_, kAsInlinedObject);
 
-  const intptr_t used_data = Smi::Value(ptr()->used_data_);
+  const intptr_t used_data = Smi::Value(used_data_);
   ASSERT((used_data & 1) == 0);  // Keys + values, so must be even.
-  const intptr_t deleted_keys = Smi::Value(ptr()->deleted_keys_);
+  const intptr_t deleted_keys = Smi::Value(deleted_keys_);
 
   // Write out the number of (not deleted) key/value pairs that will follow.
   writer->Write<ObjectPtr>(Smi::New((used_data >> 1) - deleted_keys));
 
   // Write out the keys and values.
   const bool write_as_reference = this->IsCanonical() ? false : true;
-  ArrayPtr data_array = ptr()->data_;
+  ArrayPtr data_array = data_;
   ObjectPtr* data_elements = data_array->ptr()->data();
   ASSERT(used_data <= Smi::Value(data_array->ptr()->length_));
 #if defined(DEBUG)
@@ -1235,10 +1232,10 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out the float values.
-  writer->Write<float>(ptr()->value_[0]);
-  writer->Write<float>(ptr()->value_[1]);
-  writer->Write<float>(ptr()->value_[2]);
-  writer->Write<float>(ptr()->value_[3]);
+  writer->Write<float>(value_[0]);
+  writer->Write<float>(value_[1]);
+  writer->Write<float>(value_[2]);
+  writer->Write<float>(value_[3]);
 }
 
 Int32x4Ptr Int32x4::ReadFrom(SnapshotReader* reader,
@@ -1274,10 +1271,10 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out the mask values.
-  writer->Write<uint32_t>(ptr()->value_[0]);
-  writer->Write<uint32_t>(ptr()->value_[1]);
-  writer->Write<uint32_t>(ptr()->value_[2]);
-  writer->Write<uint32_t>(ptr()->value_[3]);
+  writer->Write<uint32_t>(value_[0]);
+  writer->Write<uint32_t>(value_[1]);
+  writer->Write<uint32_t>(value_[2]);
+  writer->Write<uint32_t>(value_[3]);
 }
 
 Float64x2Ptr Float64x2::ReadFrom(SnapshotReader* reader,
@@ -1311,8 +1308,8 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out the float values.
-  writer->Write<double>(ptr()->value_[0]);
-  writer->Write<double>(ptr()->value_[1]);
+  writer->Write<double>(value_[0]);
+  writer->Write<double>(value_[1]);
 }
 
 TypedDataPtr TypedData::ReadFrom(SnapshotReader* reader,
@@ -1387,7 +1384,7 @@
                               bool as_reference) {
   ASSERT(writer != NULL);
   intptr_t cid = this->GetClassId();
-  intptr_t length = Smi::Value(ptr()->length_);  // In elements.
+  intptr_t length = Smi::Value(length_);  // In elements.
   intptr_t external_cid;
   intptr_t bytes;
   switch (cid) {
@@ -1461,8 +1458,8 @@
     // Write as external.
     writer->WriteIndexedObject(external_cid);
     writer->WriteTags(writer->GetObjectTags(this));
-    writer->Write<ObjectPtr>(ptr()->length_);
-    uint8_t* data = reinterpret_cast<uint8_t*>(ptr()->data());
+    writer->Write<ObjectPtr>(length_);
+    uint8_t* data = reinterpret_cast<uint8_t*>(this->data());
     void* passed_data = malloc(bytes);
     if (passed_data == NULL) {
       OUT_OF_MEMORY();
@@ -1477,8 +1474,8 @@
     // Write as internal.
     writer->WriteIndexedObject(cid);
     writer->WriteTags(writer->GetObjectTags(this));
-    writer->Write<ObjectPtr>(ptr()->length_);
-    uint8_t* data = reinterpret_cast<uint8_t*>(ptr()->data());
+    writer->Write<ObjectPtr>(length_);
+    uint8_t* data = reinterpret_cast<uint8_t*>(this->data());
     writer->Align(Zone::kAlignment);
     writer->WriteBytes(data, bytes);
   }
@@ -1490,7 +1487,7 @@
                                       bool as_reference) {
   ASSERT(writer != NULL);
   intptr_t cid = this->GetClassId();
-  intptr_t length = Smi::Value(ptr()->length_);  // In elements.
+  intptr_t length = Smi::Value(length_);  // In elements.
   intptr_t bytes;
   switch (cid) {
     case kExternalTypedDataInt8ArrayCid:
@@ -1546,8 +1543,8 @@
   // Write as external.
   writer->WriteIndexedObject(cid);
   writer->WriteTags(writer->GetObjectTags(this));
-  writer->Write<ObjectPtr>(ptr()->length_);
-  uint8_t* data = reinterpret_cast<uint8_t*>(ptr()->data_);
+  writer->Write<ObjectPtr>(length_);
+  uint8_t* data = reinterpret_cast<uint8_t*>(data_);
   void* passed_data = malloc(bytes);
   if (passed_data == NULL) {
     OUT_OF_MEMORY();
@@ -1565,7 +1562,7 @@
                                   Snapshot::Kind kind,
                                   bool as_reference) {
   // Views have always a backing store.
-  ASSERT(ptr()->typed_data_ != Object::null());
+  ASSERT(typed_data_ != Object::null());
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -1575,9 +1572,9 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write members.
-  writer->Write<ObjectPtr>(ptr()->offset_in_bytes_);
-  writer->Write<ObjectPtr>(ptr()->length_);
-  writer->WriteObjectImpl(ptr()->typed_data_, as_reference);
+  writer->Write<ObjectPtr>(offset_in_bytes_);
+  writer->Write<ObjectPtr>(length_);
+  writer->WriteObjectImpl(typed_data_, as_reference);
 }
 
 TypedDataViewPtr TypedDataView::ReadFrom(SnapshotReader* reader,
@@ -1624,7 +1621,7 @@
   writer->WriteIndexedObject(kCapabilityCid);
   writer->WriteTags(writer->GetObjectTags(this));
 
-  writer->Write<uint64_t>(ptr()->id_);
+  writer->Write<uint64_t>(id_);
 }
 
 SendPortPtr SendPort::ReadFrom(SnapshotReader* reader,
@@ -1654,8 +1651,8 @@
   writer->WriteIndexedObject(kSendPortCid);
   writer->WriteTags(writer->GetObjectTags(this));
 
-  writer->Write<uint64_t>(ptr()->id_);
-  writer->Write<uint64_t>(ptr()->origin_id_);
+  writer->Write<uint64_t>(id_);
+  writer->Write<uint64_t>(origin_id_);
 }
 
 TransferableTypedDataPtr TransferableTypedData::ReadFrom(SnapshotReader* reader,
@@ -1769,11 +1766,11 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out all the other fields.
-  writer->Write<ObjectPtr>(ptr()->num_bracket_expressions_);
-  writer->WriteObjectImpl(ptr()->pattern_, kAsInlinedObject);
-  writer->Write<int32_t>(ptr()->num_one_byte_registers_);
-  writer->Write<int32_t>(ptr()->num_two_byte_registers_);
-  writer->Write<int8_t>(ptr()->type_flags_);
+  writer->Write<ObjectPtr>(num_bracket_expressions_);
+  writer->WriteObjectImpl(pattern_, kAsInlinedObject);
+  writer->Write<int32_t>(num_one_byte_registers_);
+  writer->Write<int32_t>(num_two_byte_registers_);
+  writer->Write<int8_t>(type_flags_);
 }
 
 WeakPropertyPtr WeakProperty::ReadFrom(SnapshotReader* reader,
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 457832a..b957bc7 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1424,7 +1424,7 @@
 streamId | event types provided
 -------- | -----------
 VM | VMUpdate, VMFlagUpdate
-Isolate | IsolateStart, IsolateRunnable, IsolateExit, IsolateUpdate, IsolateReload, IsolateSpawn, ServiceExtensionAdded
+Isolate | IsolateStart, IsolateRunnable, IsolateExit, IsolateUpdate, IsolateReload, ServiceExtensionAdded
 Debug | PauseStart, PauseExit, PauseBreakpoint, PauseInterrupted, PauseException, PausePostRequest, Resume, BreakpointAdded, BreakpointResolved, BreakpointRemoved, Inspect, None
 GC | GC
 Extension | Extension
@@ -2043,7 +2043,6 @@
   // The status (success or failure) related to the event.
   // This is provided for the event kinds:
   //   IsolateReloaded
-  //   IsolateSpawn
   string status [optional];
 
   // LogRecord data.
diff --git a/runtime/vm/service_event.cc b/runtime/vm/service_event.cc
index 4233863..a96fd6e 100644
--- a/runtime/vm/service_event.cc
+++ b/runtime/vm/service_event.cc
@@ -69,8 +69,6 @@
       return "ServiceExtensionAdded";
     case kIsolateReload:
       return "IsolateReload";
-    case kIsolateSpawn:
-      return "IsolateSpawn";
     case kPauseStart:
       return "PauseStart";
     case kPauseExit:
@@ -126,7 +124,6 @@
     case kIsolateExit:
     case kIsolateUpdate:
     case kIsolateReload:
-    case kIsolateSpawn:
     case kServiceExtensionAdded:
       return &Service::isolate_stream;
 
@@ -195,16 +192,6 @@
       jsobj.AddProperty("reloadError", *(reload_error()));
     }
   }
-  if (kind() == kIsolateSpawn) {
-    ASSERT(spawn_token() != NULL);
-    jsobj.AddPropertyStr("spawnToken", *(spawn_token()));
-    if (spawn_error_ == NULL) {
-      jsobj.AddProperty("status", "success");
-    } else {
-      jsobj.AddProperty("status", "failure");
-      jsobj.AddPropertyStr("spawnError", *(spawn_error()));
-    }
-  }
   if (kind() == kServiceExtensionAdded) {
     ASSERT(extension_rpc_ != NULL);
     jsobj.AddProperty("extensionRPC", extension_rpc_->ToCString());
diff --git a/runtime/vm/service_event.h b/runtime/vm/service_event.h
index c60e1d2..f2aedde 100644
--- a/runtime/vm/service_event.h
+++ b/runtime/vm/service_event.h
@@ -30,7 +30,6 @@
     kIsolateExit,            // Isolate has exited
     kIsolateUpdate,          // Isolate identity information has changed
     kIsolateReload,          // Result of a reload request
-    kIsolateSpawn,           // Result of an isolate spawn request
     kServiceExtensionAdded,  // A service extension was registered
 
     kPauseStart,  // --pause-isolates-on-start
@@ -155,24 +154,6 @@
     reload_error_ = error;
   }
 
-  const String* spawn_token() const {
-    ASSERT(kind_ == kIsolateSpawn);
-    return spawn_token_;
-  }
-  void set_spawn_token(const String* error) {
-    ASSERT(kind_ == kIsolateSpawn);
-    spawn_token_ = error;
-  }
-
-  const String* spawn_error() const {
-    ASSERT(kind_ == kIsolateSpawn);
-    return spawn_error_;
-  }
-  void set_spawn_error(const String* error) {
-    ASSERT(kind_ == kIsolateSpawn);
-    spawn_error_ = error;
-  }
-
   bool at_async_jump() const { return at_async_jump_; }
   void set_at_async_jump(bool value) { at_async_jump_ = value; }
 
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 7f100bb..1faa561 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -259,7 +259,7 @@
 }
 
 SmiPtr BaseReader::ReadAsSmi() {
-  SmiPtr value = Read<SmiPtr>();
+  SmiPtr value = static_cast<SmiPtr>(Read<intptr_t>());
   ASSERT((static_cast<uword>(value) & kSmiTagMask) == kSmiTag);
   return value;
 }
@@ -1297,14 +1297,14 @@
 
 void SnapshotWriter::WriteClassId(ClassLayout* cls) {
   ASSERT(!Snapshot::IsFull(kind_));
-  int class_id = cls->ptr()->id_;
+  int class_id = cls->id_;
   ASSERT(!IsSingletonClassId(class_id) && !IsBootstrapedClassId(class_id));
 
   // Write out the library url and class name.
-  LibraryPtr library = cls->ptr()->library_;
+  LibraryPtr library = cls->library_;
   ASSERT(library != Library::null());
   WriteObjectImpl(library->ptr()->url_, kAsInlinedObject);
-  WriteObjectImpl(cls->ptr()->name_, kAsInlinedObject);
+  WriteObjectImpl(cls->name_, kAsInlinedObject);
 }
 
 void SnapshotWriter::WriteStaticImplicitClosure(intptr_t object_id,
diff --git a/runtime/vm/uri.cc b/runtime/vm/uri.cc
index 5e75ef1..74046e9 100644
--- a/runtime/vm/uri.cc
+++ b/runtime/vm/uri.cc
@@ -369,10 +369,7 @@
   buffer[truncated_base_len] = '/';
 
   // Copy the ref_path.
-  strncpy((buffer + truncated_base_len + 1), ref_path, ref_path_len);
-
-  // Add the trailing '\0'.
-  buffer[len] = '\0';
+  strncpy((buffer + truncated_base_len + 1), ref_path, ref_path_len + 1);
 
   return buffer;
 }
diff --git a/runtime/vm/v8_snapshot_writer.cc b/runtime/vm/v8_snapshot_writer.cc
index 1a79e0c..7d22307 100644
--- a/runtime/vm/v8_snapshot_writer.cc
+++ b/runtime/vm/v8_snapshot_writer.cc
@@ -53,7 +53,7 @@
     info->name = EnsureString(name);
   } else {
     info->name =
-        EnsureString(OS::SCreate(zone_, "Unnamed [%s] %s", type, name));
+        EnsureString(OS::SCreate(zone_, "Unnamed [%s] %s", type, "(nil)"));
   }
 }
 
diff --git a/runtime/vm/zone.cc b/runtime/vm/zone.cc
index b6d3727..7859112 100644
--- a/runtime/vm/zone.cc
+++ b/runtime/vm/zone.cc
@@ -40,7 +40,7 @@
   void* alignment_;
 
   // Computes the address of the nth byte in this segment.
-  uword address(int n) { return reinterpret_cast<uword>(this) + n; }
+  uword address(intptr_t n) { return reinterpret_cast<uword>(this) + n; }
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(Segment);
 };
@@ -195,6 +195,7 @@
 #endif
   position_ = initial_buffer_.start();
   limit_ = initial_buffer_.end();
+  small_segment_capacity_ = 0;
   head_ = NULL;
   large_segments_ = NULL;
   previous_ = NULL;
@@ -252,8 +253,22 @@
     return AllocateLargeSegment(size);
   }
 
+  const intptr_t kSuperPageSize = 2 * MB;
+  intptr_t next_size;
+  if (small_segment_capacity_ < kSuperPageSize) {
+    // When the Zone is small, grow linearly to reduce size and use the segment
+    // cache to avoid expensive mmap calls.
+    next_size = kSegmentSize;
+  } else {
+    // When the Zone is large, grow geometrically to avoid Page Table Entry
+    // exhaustion. Using 1.125 ratio.
+    next_size = Utils::RoundUp(small_segment_capacity_ >> 3, kSuperPageSize);
+  }
+  ASSERT(next_size >= kSegmentSize);
+
   // Allocate another segment and chain it up.
-  head_ = Segment::New(kSegmentSize, head_);
+  head_ = Segment::New(next_size, head_);
+  small_segment_capacity_ += next_size;
 
   // Recompute 'position' and 'limit' based on the new head segment.
   uword result = Utils::RoundUp(head_->start(), kAlignment);
diff --git a/runtime/vm/zone.h b/runtime/vm/zone.h
index 7115cc71..548708d 100644
--- a/runtime/vm/zone.h
+++ b/runtime/vm/zone.h
@@ -155,6 +155,9 @@
   // implementation is in zone.cc.
   class Segment;
 
+  // Total size of all segments in [head_].
+  intptr_t small_segment_capacity_ = 0;
+
   // The current head segment; may be NULL.
   Segment* head_;
 
diff --git a/runtime/vm/zone_text_buffer.h b/runtime/vm/zone_text_buffer.h
index f4e2f31..1b7fef3 100644
--- a/runtime/vm/zone_text_buffer.h
+++ b/runtime/vm/zone_text_buffer.h
@@ -26,7 +26,7 @@
   void AddString(const String& s);
 
   char* buffer() { return buffer_; }
-  intptr_t length() { return length_; }
+  intptr_t length() const { return length_; }
 
   void Clear();
 
diff --git a/sdk/lib/_internal/js_dev_runtime/patch/convert_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/convert_patch.dart
index 6b85e67..cdc7370 100644
--- a/sdk/lib/_internal/js_dev_runtime/patch/convert_patch.dart
+++ b/sdk/lib/_internal/js_dev_runtime/patch/convert_patch.dart
@@ -500,11 +500,17 @@
 }
 
 @patch
-int _scanOneByteCharacters(List<int> units, int from, int endIndex) {
-  final to = endIndex;
-  for (var i = from; i < to; i++) {
-    final unit = units[i];
-    if ((unit & _ONE_BYTE_LIMIT) != unit) return i - from;
+class _Utf8Decoder {
+  @patch
+  _Utf8Decoder(this.allowMalformed) : _state = beforeBom;
+
+  @patch
+  String convertSingle(List<int> codeUnits, int start, int maybeEnd) {
+    return convertGeneral(codeUnits, start, maybeEnd, true);
   }
-  return to - from;
+
+  @patch
+  String convertChunked(List<int> codeUnits, int start, int maybeEnd) {
+    return convertGeneral(codeUnits, start, maybeEnd, false);
+  }
 }
diff --git a/sdk/lib/_internal/js_runtime/lib/convert_patch.dart b/sdk/lib/_internal/js_runtime/lib/convert_patch.dart
index 421fd51..c2dc264 100644
--- a/sdk/lib/_internal/js_runtime/lib/convert_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/convert_patch.dart
@@ -494,11 +494,17 @@
 }
 
 @patch
-int _scanOneByteCharacters(List<int> units, int from, int endIndex) {
-  final to = endIndex;
-  for (var i = from; i < to; i++) {
-    final unit = units[i];
-    if ((unit & _ONE_BYTE_LIMIT) != unit) return i - from;
+class _Utf8Decoder {
+  @patch
+  _Utf8Decoder(this.allowMalformed) : _state = beforeBom;
+
+  @patch
+  String convertSingle(List<int> codeUnits, int start, int maybeEnd) {
+    return convertGeneral(codeUnits, start, maybeEnd, true);
   }
-  return to - from;
+
+  @patch
+  String convertChunked(List<int> codeUnits, int start, int maybeEnd) {
+    return convertGeneral(codeUnits, start, maybeEnd, false);
+  }
 }
diff --git a/sdk/lib/_internal/vm/bin/builtin.dart b/sdk/lib/_internal/vm/bin/builtin.dart
index b79755e..129d1fc 100644
--- a/sdk/lib/_internal/vm/bin/builtin.dart
+++ b/sdk/lib/_internal/vm/bin/builtin.dart
@@ -11,6 +11,7 @@
 import 'dart:collection' hide LinkedList, LinkedListEntry;
 import 'dart:_internal' hide Symbol;
 import 'dart:io';
+import 'dart:convert';
 import 'dart:isolate';
 import 'dart:typed_data';
 
@@ -130,11 +131,12 @@
     _log('Resolving package with uri path: ${uri.path}');
   }
   var resolvedUri;
-  if (_packageError != null) {
+  final error = _packageError;
+  if (error != null) {
     if (_traceLoading) {
-      _log("Resolving package with pending resolution error: $_packageError");
+      _log("Resolving package with pending resolution error: $error");
     }
-    throw _packageError;
+    throw error;
   } else {
     if (packageNameEnd < 0) {
       // Package URIs must have a path after the package name, even if it's
@@ -143,7 +145,7 @@
           "'package:${uri.path}/', not 'package:${uri.path}'";
     }
     var packageName = uri.path.substring(0, packageNameEnd);
-    var mapping = _packageMap[packageName];
+    final mapping = _packageMap[packageName];
     if (_traceLoading) {
       _log("Mapped '$packageName' package to '$mapping'");
     }
@@ -204,281 +206,185 @@
   }
 }
 
-// Handling of packages requests. Finding and parsing of .packages file or
-// packages/ directories.
-const _LF = 0x0A;
-const _CR = 0x0D;
-const _SPACE = 0x20;
-const _HASH = 0x23;
-const _DOT = 0x2E;
-const _COLON = 0x3A;
-const _DEL = 0x7F;
+// The values go from ' ' to DEL and `x` means disallowed.
+const String _invalidPackageNameChars =
+    'x.xx.x.........x..........x.x.xx...........................xxxx.x..........................xxx.x';
 
-const _invalidPackageNameChars = const [
-  true, //  space
-  false, // !
-  true, //  "
-  true, //  #
-  false, // $
-  true, //  %
-  false, // &
-  false, // '
-  false, // (
-  false, // )
-  false, // *
-  false, // +
-  false, // ,
-  false, // -
-  false, // .
-  true, //  /
-  false, // 0
-  false, // 1
-  false, // 2
-  false, // 3
-  false, // 4
-  false, // 5
-  false, // 6
-  false, // 7
-  false, // 8
-  false, // 9
-  true, //  :
-  false, // ;
-  true, //  <
-  false, // =
-  true, //  >
-  true, //  ?
-  false, // @
-  false, // A
-  false, // B
-  false, // C
-  false, // D
-  false, // E
-  false, // F
-  false, // G
-  false, // H
-  false, // I
-  false, // J
-  false, // K
-  false, // L
-  false, // M
-  false, // N
-  false, // O
-  false, // P
-  false, // Q
-  false, // R
-  false, // S
-  false, // T
-  false, // U
-  false, // V
-  false, // W
-  false, // X
-  false, // Y
-  false, // Z
-  true, //  [
-  true, //  \
-  true, //  ]
-  true, //  ^
-  false, // _
-  true, //  `
-  false, // a
-  false, // b
-  false, // c
-  false, // d
-  false, // e
-  false, // f
-  false, // g
-  false, // h
-  false, // i
-  false, // j
-  false, // k
-  false, // l
-  false, // m
-  false, // n
-  false, // o
-  false, // p
-  false, // q
-  false, // r
-  false, // s
-  false, // t
-  false, // u
-  false, // v
-  false, // w
-  false, // x
-  false, // y
-  false, // z
-  true, //  {
-  true, //  |
-  true, //  }
-  false, // ~
-  true, //  DEL
-];
+bool _isValidPackageName(String packageName) {
+  const space = 0x20;
+  const del = 0x7F;
+  const dot = 0x2e;
+  const lowerX = 0x78;
+  for (int i = 0; i < packageName.length; ++i) {
+    final int char = packageName.codeUnitAt(i);
+    if (char < space || del < char) {
+      return false;
+    }
+    final int allowed = _invalidPackageNameChars.codeUnitAt(char - space);
+    assert(allowed == dot || allowed == lowerX);
+    if (allowed == lowerX) {
+      return false;
+    }
+  }
+  return true;
+}
 
-_parsePackagesFile(bool traceLoading, Uri packagesFile, List<int> data) {
+_parsePackagesFile(bool traceLoading, Uri packagesFile, String data) {
   // The first entry contains the location of the identified .packages file
   // instead of a mapping.
-  var result = [packagesFile.toString(), null];
-  var index = 0;
-  var len = data.length;
-  while (index < len) {
-    var start = index;
-    var char = data[index];
-    if ((char == _CR) || (char == _LF)) {
-      // Skipping empty lines.
-      index++;
+  final List result = [packagesFile.toString(), null];
+
+  final lines = LineSplitter.split(data);
+  for (String line in lines) {
+    final hashIndex = line.indexOf('#');
+    if (hashIndex == 0) {
+      continue;
+    }
+    if (hashIndex > 0) {
+      line = line.substring(0, hashIndex);
+    }
+    line = line.trimRight();
+    if (line.isEmpty) {
       continue;
     }
 
-    // Identify split within the line and end of the line.
-    var separator = -1;
-    var end = len;
-    // Verifying validity of package name while scanning the line.
-    var nonDot = false;
-    var invalidPackageName = false;
-
-    // Scan to the end of the line or data.
-    while (index < len) {
-      char = data[index++];
-      // If we have not reached the separator yet, determine whether we are
-      // scanning legal package name characters.
-      if (separator == -1) {
-        if ((char == _COLON)) {
-          // The first colon on a line is the separator between package name and
-          // related URI.
-          separator = index - 1;
-        } else {
-          // Still scanning the package name part. Check for the validity of
-          // the characters.
-          nonDot = nonDot || (char != _DOT);
-          invalidPackageName = invalidPackageName ||
-              (char < _SPACE) ||
-              (char > _DEL) ||
-              _invalidPackageNameChars[char - _SPACE];
-        }
-      }
-      // Identify end of line.
-      if ((char == _CR) || (char == _LF)) {
-        end = index - 1;
-        break;
-      }
+    final colonIndex = line.indexOf(':');
+    if (colonIndex <= 0) {
+      return 'Line in "$packagesFile" should be of the format '
+          '`<package-name>:<path>" but was: "$line"';
+    }
+    final packageName = line.substring(0, colonIndex);
+    if (!_isValidPackageName(packageName)) {
+      return 'Package name in $packagesFile contains disallowed characters ('
+          'was: "$packageName")';
     }
 
-    // No further handling needed for comment lines.
-    if (data[start] == _HASH) {
-      if (traceLoading) {
-        _log("Skipping comment in $packagesFile:\n"
-            "${new String.fromCharCodes(data, start, end)}");
-      }
-      continue;
-    }
-
-    // Check for a badly formatted line, starting with a ':'.
-    if (separator == start) {
-      var line = new String.fromCharCodes(data, start, end);
-      if (traceLoading) {
-        _log("Line starts with ':' in $packagesFile:\n"
-            "$line");
-      }
-      return "Missing package name in $packagesFile:\n"
-          "$line";
-    }
-
-    // Ensure there is a separator on the line.
-    if (separator == -1) {
-      var line = new String.fromCharCodes(data, start, end);
-      if (traceLoading) {
-        _log("Line has no ':' in $packagesFile:\n"
-            "$line");
-      }
-      return "Missing ':' separator in $packagesFile:\n"
-          "$line";
-    }
-
-    var packageName = new String.fromCharCodes(data, start, separator);
-
-    // Check for valid package name.
-    if (invalidPackageName || !nonDot) {
-      var line = new String.fromCharCodes(data, start, end);
-      if (traceLoading) {
-        _log("Invalid package name $packageName in $packagesFile");
-      }
-      return "Invalid package name '$packageName' in $packagesFile:\n"
-          "$line";
-    }
-
+    String packageUri = line.substring(colonIndex + 1);
     if (traceLoading) {
       _log("packageName: $packageName");
-    }
-    var packageUri = new String.fromCharCodes(data, separator + 1, end);
-    if (traceLoading) {
-      _log("original packageUri: $packageUri");
+      _log("packageUri: $packageUri");
     }
     // Ensure the package uri ends with a /.
-    if (!packageUri.endsWith("/")) {
-      packageUri = "$packageUri/";
+    if (!packageUri.endsWith('/')) {
+      packageUri += '/';
     }
-    packageUri = packagesFile.resolve(packageUri).toString();
+    final resolvedPackageUri = packagesFile.resolve(packageUri).toString();
     if (traceLoading) {
-      _log("mapping: $packageName -> $packageUri");
+      _log("mapping: $packageName -> $resolvedPackageUri");
     }
     result.add(packageName);
-    result.add(packageUri);
+    result.add(resolvedPackageUri);
   }
-
   if (traceLoading) {
     _log("Parsed packages file at $packagesFile. Sending:\n$result");
   }
   return result;
 }
 
-_loadPackagesFile(bool traceLoading, Uri packagesFile) {
-  try {
-    var data = new File.fromUri(packagesFile).readAsBytesSync();
-    if (traceLoading) {
-      _log("Loaded packages file from $packagesFile:\n"
-          "${new String.fromCharCodes(data)}");
-    }
-    return _parsePackagesFile(traceLoading, packagesFile, data);
-  } catch (e, s) {
-    if (traceLoading) {
-      _log("Error loading packages: $e\n$s");
-    }
-    return "Uncaught error ($e) loading packages file.";
+// The .dart_tool/package_config.json format is described in
+//
+// https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md
+//
+// The returned list has the format:
+//
+//    [0] Location of package_config.json file.
+//    [1] null
+//    [n*2] Name of n-th package
+//    [n*2 + 1] Location of n-th package's sources (as a String)
+//
+List _parsePackageConfig(bool traceLoading, Uri packageConfig, String data) {
+  final Map packageJson = json.decode(data);
+  final version = packageJson['configVersion'];
+  if (version != 2) {
+    throw 'The package configuration file has an unsupported version.';
   }
+  // The first entry contains the location of the identified
+  // .dart_tool/package_config.json file instead of a mapping.
+  final result = <dynamic>[packageConfig.toString(), null];
+  final List packages = packageJson['packages'] ?? [];
+  for (final Map package in packages) {
+    String rootUri = package['rootUri'];
+    if (!rootUri.endsWith('/')) rootUri += '/';
+    final String packageName = package['name'];
+    final String packageUri = package['packageUri'];
+    final Uri resolvedRootUri = packageConfig.resolve(rootUri);
+    final Uri resolvedPackageUri = packageUri != null
+        ? resolvedRootUri.resolve(packageUri)
+        : resolvedRootUri;
+    if (packageUri != null &&
+        !'$resolvedPackageUri'.contains('$resolvedRootUri')) {
+      throw 'The resolved "packageUri" is not a subdirectory of the "rootUri".';
+    }
+    if (!_isValidPackageName(packageName)) {
+      throw 'Package name in $packageConfig contains disallowed characters ('
+          'was: "$packageName")';
+    }
+    result.add(packageName);
+    result.add(resolvedPackageUri.toString());
+    if (traceLoading) {
+      _log('Resolved package "$packageName" to be at $resolvedPackageUri');
+    }
+  }
+  return result;
 }
 
-_findPackagesFile(bool traceLoading, Uri base) {
+_findPackagesConfiguration(bool traceLoading, Uri base) {
   try {
-    // Walk up the directory hierarchy to check for the existence of
-    // .packages files in parent directories and for the existence of a
-    // packages/ directory on the first iteration.
-    var dir = new File.fromUri(base).parent;
-    var prev = null;
-    // Keep searching until we reach the root.
-    while ((prev == null) || (prev.path != dir.path)) {
-      // Check for the existence of a .packages file and if it exists try to
-      // load and parse it.
-      var dirUri = dir.uri;
-      var packagesFile = dirUri.resolve(".packages");
+    // Walk up the directory hierarchy to check for the existence of either one
+    // of
+    //   - .packages (preferred)
+    //   - .dart_tool/package_config.json
+    var currentDir = new File.fromUri(base).parent;
+    while (true) {
+      final dirUri = currentDir.uri;
+
+      // We prefer using `.packages` over `.dart_tool/package_config.json` so
+      // old users of `Isolate.packageConfig` which cannot handle the new format
+      // will continue to work (see https://github.com/dart-lang/sdk/issues/41748).
+      final packagesFile = dirUri.resolve(".packages");
       if (traceLoading) {
         _log("Checking for $packagesFile file.");
       }
-      var exists = new File.fromUri(packagesFile).existsSync();
+      File file = File.fromUri(packagesFile);
+      bool exists = file.existsSync();
       if (traceLoading) {
         _log("$packagesFile exists: $exists");
       }
       if (exists) {
-        return _loadPackagesFile(traceLoading, packagesFile);
+        final String data = utf8.decode(file.readAsBytesSync());
+        if (traceLoading) {
+          _log("Loaded packages file from $packagesFile:\n$data");
+        }
+        return _parsePackagesFile(traceLoading, packagesFile, data);
       }
-      // Move up one level.
-      prev = dir;
-      dir = dir.parent;
+
+      // We fallback to using `.dart_tool/package_config.json` if it exists.
+      final packageConfig = dirUri.resolve(".dart_tool/package_config.json");
+      if (traceLoading) {
+        _log("Checking for $packageConfig file.");
+      }
+      file = File.fromUri(packageConfig);
+      exists = file.existsSync();
+      if (traceLoading) {
+        _log("$packageConfig exists: $exists");
+      }
+      if (exists) {
+        final data = utf8.decode(file.readAsBytesSync());
+        if (traceLoading) {
+          _log("Loaded package config file from $packageConfig:$data\n");
+        }
+        return _parsePackageConfig(traceLoading, packageConfig, data);
+      }
+
+      final parentDir = currentDir.parent;
+      if (dirUri == parentDir.uri) break;
+      currentDir = parentDir;
     }
 
-    // No .packages file was found.
     if (traceLoading) {
-      _log("Could not resolve a package location from $base");
+      _log("Could not resolve a package configuration from $base");
     }
-    return "Could not resolve a package location for base at $base";
+    return "Could not resolve a package configuration for base at $base";
   } catch (e, s) {
     if (traceLoading) {
       _log("Error loading packages: $e\n$s");
@@ -487,29 +393,62 @@
   }
 }
 
-_loadPackagesData(traceLoading, resource) {
-  try {
-    var data = resource.data;
-    var mime = data.mimeType;
-    if (mime != "text/plain") {
-      throw "MIME-type must be text/plain: $mime given.";
+int _indexOfFirstNonWhitespaceCharacter(String data) {
+  // Whitespace characters ignored in JSON spec:
+  // https://tools.ietf.org/html/rfc7159
+  const tab = 0x09;
+  const lf = 0x0A;
+  const cr = 0x0D;
+  const space = 0x20;
+
+  int index = 0;
+  while (index < data.length) {
+    final int char = data.codeUnitAt(index);
+    if (char != lf && char != cr && char != space && char != tab) {
+      break;
     }
-    var charset = data.charset;
-    if ((charset != "utf-8") && (charset != "US-ASCII")) {
-      // The C++ portion of the embedder assumes UTF-8.
-      throw "Only utf-8 or US-ASCII encodings are supported: $charset given.";
-    }
-    return _parsePackagesFile(traceLoading, resource, data.contentAsBytes());
-  } catch (e) {
-    return "Uncaught error ($e) loading packages data.";
+    index++;
   }
+  return index;
+}
+
+bool _canBeValidJson(String data) {
+  const int openCurly = 0x7B;
+  final int index = _indexOfFirstNonWhitespaceCharacter(data);
+  return index < data.length && data.codeUnitAt(index) == openCurly;
+}
+
+_parsePackageConfiguration(bool traceLoading, Uri resource, Uint8List bytes) {
+  try {
+    final data = utf8.decode(bytes);
+    if (_canBeValidJson(data)) {
+      return _parsePackageConfig(traceLoading, resource, data);
+    } else {
+      return _parsePackagesFile(traceLoading, resource, data);
+    }
+  } catch (e) {
+    return "The resource '$resource' is neither a valid '.packages' file nor "
+        "a valid '.dart_tool/package_config.json' file.";
+  }
+}
+
+bool _isValidUtf8DataUrl(UriData data) {
+  final mime = data.mimeType;
+  if (mime != "text/plain") {
+    return false;
+  }
+  final charset = data.charset;
+  if (charset != "utf-8" && charset != "US-ASCII") {
+    return false;
+  }
+  return true;
 }
 
 _handlePackagesRequest(bool traceLoading, int tag, Uri resource) {
   try {
     if (tag == -1) {
       if (resource.scheme == '' || resource.scheme == 'file') {
-        return _findPackagesFile(traceLoading, resource);
+        return _findPackagesConfiguration(traceLoading, resource);
       } else {
         return "Unsupported scheme used to locate .packages file:'$resource'.";
       }
@@ -517,19 +456,25 @@
       if (traceLoading) {
         _log("Handling load of packages map: '$resource'.");
       }
+      Uint8List bytes;
       if (resource.scheme == '' || resource.scheme == 'file') {
-        var exists = new File.fromUri(resource).existsSync();
-        if (exists) {
-          return _loadPackagesFile(traceLoading, resource);
-        } else {
-          return "Packages file '$resource' not found.";
+        final file = File.fromUri(resource);
+        if (!file.existsSync()) {
+          return "Packages file '$resource' does not exit.";
         }
+        bytes = file.readAsBytesSync();
       } else if (resource.scheme == 'data') {
-        return _loadPackagesData(traceLoading, resource);
+        final uriData = resource.data;
+        if (!_isValidUtf8DataUrl(uriData)) {
+          return "The data resource '$resource' must have a 'text/plain' mime "
+              "type and a 'utf-8' or 'US-ASCII' charset.";
+        }
+        bytes = uriData.contentAsBytes();
       } else {
         return "Unknown scheme (${resource.scheme}) for package file at "
             "'$resource'.";
       }
+      return _parsePackageConfiguration(traceLoading, resource, bytes);
     } else {
       return "Unknown packages request tag: $tag for '$resource'.";
     }
@@ -580,6 +525,9 @@
 }
 
 // Embedder Entrypoint:
+// The embedder calls this method with the value of the --packages command line
+// option. It can point to a ".packages" or a ".dart_tool/package_config.json"
+// file.
 @pragma("vm:entry-point")
 String _setPackagesMap(String packagesParam) {
   if (!_setupCompleted) {
@@ -677,7 +625,7 @@
     resolvedUri = _resolvePackageUri(packageUri);
   } catch (e, s) {
     if (_traceLoading) {
-      _log("Exception when resolving package URI: $packageUri");
+      _log("Exception when resolving package URI: $packageUri:\n$e\n$s");
     }
     resolvedUri = null;
   }
diff --git a/sdk/lib/_internal/vm/lib/convert_patch.dart b/sdk/lib/_internal/vm/lib/convert_patch.dart
index f1e46cf..33215c7 100644
--- a/sdk/lib/_internal/vm/lib/convert_patch.dart
+++ b/sdk/lib/_internal/vm/lib/convert_patch.dart
@@ -1498,267 +1498,17 @@
   }
 }
 
-class _Utf8StringBuffer {
-  static const int INITIAL_CAPACITY = 32;
-  // Partial state encoding.
-  static const int MASK_TWO_BIT = 0x03;
-  static const int MASK_SIZE = MASK_TWO_BIT;
-  static const int SHIFT_MISSING = 2;
-  static const int SHIFT_VALUE = 4;
-  static const int NO_PARTIAL = 0;
-
-  // UTF-8 encoding and limits.
-  static const int MAX_ASCII = 127;
-  static const int MAX_TWO_BYTE = 0x7ff;
-  static const int MAX_THREE_BYTE = 0xffff;
-  static const int MAX_UNICODE = 0X10ffff;
-  static const int MASK_TWO_BYTE = 0x1f;
-  static const int MASK_THREE_BYTE = 0x0f;
-  static const int MASK_FOUR_BYTE = 0x07;
-  static const int MASK_CONTINUE_TAG = 0xC0;
-  static const int MASK_CONTINUE_VALUE = 0x3f;
-  static const int CONTINUE_TAG = 0x80;
-
-  // UTF-16 surrogate encoding.
-  static const int LEAD_SURROGATE = 0xD800;
-  static const int TAIL_SURROGATE = 0xDC00;
-  static const int SHIFT_HIGH_SURROGATE = 10;
-  static const int MASK_LOW_SURROGATE = 0x3ff;
-
-  // The internal buffer starts as Uint8List, but may change to Uint16List
-  // if the string contains non-Latin-1 characters.
-  List<int> buffer = new Uint8List(INITIAL_CAPACITY);
-  // Number of elements in buffer.
-  int length = 0;
-  // Partial decoding state, for cases where an UTF-8 sequences is split
-  // between chunks.
-  int partialState = NO_PARTIAL;
-  // Whether all characters so far have been Latin-1 (and the buffer is
-  // still a Uint8List). Set to false when the first non-Latin-1 character
-  // is encountered, and the buffer is then also converted to a Uint16List.
-  bool isLatin1 = true;
-  // If allowing malformed, invalid UTF-8 sequences are converted to
-  // U+FFFD.
-  bool allowMalformed;
-
-  _Utf8StringBuffer(this.allowMalformed);
-
-  /**
-   * Parse the continuation of a multi-byte UTF-8 sequence.
-   *
-   * Parse [utf8] from [position] to [end]. If the sequence extends beyond
-   * `end`, store the partial state in [partialState], and continue from there
-   * on the next added slice.
-   *
-   * The [size] is the number of expected continuation bytes total,
-   * and [missing] is the number of remaining continuation bytes.
-   * The [size] is used to detect overlong encodings.
-   * The [value] is the value collected so far.
-   *
-   * When called after seeing the first multi-byte marker, the [size] and
-   * [missing] values are always the same, but they may differ if continuing
-   * after a partial sequence.
-   */
-  int addContinuation(
-      List<int> utf8, int position, int end, int size, int missing, int value) {
-    int codeEnd = position + missing;
-    do {
-      if (position == end) {
-        missing = codeEnd - position;
-        partialState =
-            size | (missing << SHIFT_MISSING) | (value << SHIFT_VALUE);
-        return end;
-      }
-      int char = utf8[position];
-      if ((char & MASK_CONTINUE_TAG) != CONTINUE_TAG) {
-        if (allowMalformed) {
-          addCharCode(0xFFFD);
-          return position;
-        }
-        throw new FormatException(
-            "Expected UTF-8 continuation byte, "
-            "found $char",
-            utf8,
-            position);
-      }
-      value = 64 * value + (char & MASK_CONTINUE_VALUE);
-      position++;
-    } while (position < codeEnd);
-    if (value <= const [0, MAX_ASCII, MAX_TWO_BYTE, MAX_THREE_BYTE][size]) {
-      // Over-long encoding.
-      if (allowMalformed) {
-        value = 0xFFFD;
-      } else {
-        throw new FormatException(
-            "Invalid encoding: U+${value.toRadixString(16).padLeft(4, '0')}"
-            " encoded in ${size + 1} bytes.",
-            utf8,
-            position - 1);
-      }
-    }
-    addCharCode(value);
-    return position;
-  }
-
-  void addCharCode(int char) {
-    assert(char >= 0);
-    assert(char <= MAX_UNICODE);
-    if (partialState != NO_PARTIAL) {
-      if (allowMalformed) {
-        partialState = NO_PARTIAL;
-        addCharCode(0xFFFD);
-      } else {
-        throw new FormatException("Incomplete UTF-8 sequence");
-      }
-    }
-    if (isLatin1 && char > 0xff) {
-      _to16Bit(); // Also grows a little if close to full.
-    }
-    int length = this.length;
-    if (char <= MAX_THREE_BYTE) {
-      if (length == buffer.length) _grow();
-      buffer[length] = char;
-      this.length = length + 1;
-      return;
-    }
-    if (length + 2 > buffer.length) _grow();
-    int bits = char - 0x10000;
-    buffer[length] = LEAD_SURROGATE | (bits >> SHIFT_HIGH_SURROGATE);
-    buffer[length + 1] = TAIL_SURROGATE | (bits & MASK_LOW_SURROGATE);
-    this.length = length + 2;
-  }
-
-  void _to16Bit() {
-    assert(isLatin1);
-    Uint16List newBuffer;
-    if ((length + INITIAL_CAPACITY) * 2 <= buffer.length) {
-      // Reuse existing buffer if it's big enough.
-      newBuffer = new Uint16List.view((buffer as Uint8List).buffer);
-    } else {
-      int newCapacity = buffer.length;
-      if (newCapacity - length < INITIAL_CAPACITY) {
-        newCapacity = length + INITIAL_CAPACITY;
-      }
-      newBuffer = new Uint16List(newCapacity);
-    }
-    newBuffer.setRange(0, length, buffer);
-    buffer = newBuffer;
-    isLatin1 = false;
-  }
-
-  void _grow() {
-    int newCapacity = buffer.length * 2;
-    List newBuffer;
-    if (isLatin1) {
-      newBuffer = new Uint8List(newCapacity);
-    } else {
-      newBuffer = new Uint16List(newCapacity);
-    }
-    newBuffer.setRange(0, length, buffer);
-    buffer = newBuffer;
-  }
-
-  void addSlice(List<int> utf8, int position, int end) {
-    assert(position < end);
-    if (partialState > 0) {
-      int continueByteCount = (partialState & MASK_TWO_BIT);
-      int missing = (partialState >> SHIFT_MISSING) & MASK_TWO_BIT;
-      int value = partialState >> SHIFT_VALUE;
-      partialState = NO_PARTIAL;
-      position = addContinuation(
-          utf8, position, end, continueByteCount, missing, value);
-      if (position == end) return;
-    }
-    // Keep index and capacity in local variables while looping over
-    // ASCII characters.
-    int index = length;
-    int capacity = buffer.length;
-    while (position < end) {
-      int char = utf8[position];
-      if (char <= MAX_ASCII) {
-        if (index == capacity) {
-          length = index;
-          _grow();
-          capacity = buffer.length;
-        }
-        buffer[index++] = char;
-        position++;
-        continue;
-      }
-      length = index;
-      if ((char & MASK_CONTINUE_TAG) == CONTINUE_TAG) {
-        if (allowMalformed) {
-          addCharCode(0xFFFD);
-          position++;
-        } else {
-          throw new FormatException(
-              "Unexpected UTF-8 continuation byte", utf8, position);
-        }
-      } else if (char < 0xE0) {
-        // C0-DF
-        // Two-byte.
-        position = addContinuation(
-            utf8, position + 1, end, 1, 1, char & MASK_TWO_BYTE);
-      } else if (char < 0xF0) {
-        // E0-EF
-        // Three-byte.
-        position = addContinuation(
-            utf8, position + 1, end, 2, 2, char & MASK_THREE_BYTE);
-      } else if (char < 0xF8) {
-        // F0-F7
-        // Four-byte.
-        position = addContinuation(
-            utf8, position + 1, end, 3, 3, char & MASK_FOUR_BYTE);
-      } else {
-        if (allowMalformed) {
-          addCharCode(0xFFFD);
-          position++;
-        } else {
-          throw new FormatException(
-              "Invalid UTF-8 byte: $char", utf8, position);
-        }
-      }
-      index = length;
-      capacity = buffer.length;
-    }
-    length = index;
-  }
-
-  String toString() {
-    if (partialState != NO_PARTIAL) {
-      if (allowMalformed) {
-        partialState = NO_PARTIAL;
-        addCharCode(0xFFFD);
-      } else {
-        int continueByteCount = (partialState & MASK_TWO_BIT);
-        int missing = (partialState >> SHIFT_MISSING) & MASK_TWO_BIT;
-        int value = partialState >> SHIFT_VALUE;
-        int seenByteCount = continueByteCount - missing + 1;
-        List source = new Uint8List(seenByteCount);
-        while (seenByteCount > 1) {
-          seenByteCount--;
-          source[seenByteCount] = CONTINUE_TAG | (value & MASK_CONTINUE_VALUE);
-          value >>= 6;
-        }
-        source[0] = value | (0x3c0 >> (continueByteCount - 1));
-        throw new FormatException(
-            "Incomplete UTF-8 sequence", source, source.length);
-      }
-    }
-    return new String.fromCharCodes(buffer, 0, length);
-  }
-}
-
 /**
  * Chunked JSON parser that parses UTF-8 chunks.
  */
 class _JsonUtf8Parser extends _ChunkedJsonParser<List<int>> {
-  final bool allowMalformed;
+  final _Utf8Decoder decoder;
   List<int> chunk;
   int chunkEnd;
 
-  _JsonUtf8Parser(_JsonListener listener, this.allowMalformed)
-      : super(listener) {
+  _JsonUtf8Parser(_JsonListener listener, bool allowMalformed)
+      : decoder = new _Utf8Decoder(allowMalformed),
+        super(listener) {
     // Starts out checking for an optional BOM (KWD_BOM, count = 0).
     partialState =
         _ChunkedJsonParser.PARTIAL_KEYWORD | _ChunkedJsonParser.KWD_BOM;
@@ -1778,21 +1528,24 @@
   }
 
   void beginString() {
-    this.buffer = new _Utf8StringBuffer(allowMalformed);
+    decoder.reset();
+    this.buffer = new StringBuffer();
   }
 
   void addSliceToString(int start, int end) {
-    _Utf8StringBuffer buffer = this.buffer;
-    buffer.addSlice(chunk, start, end);
+    final StringBuffer buffer = this.buffer;
+    buffer.write(decoder.convertChunked(chunk, start, end));
   }
 
   void addCharToString(int charCode) {
-    _Utf8StringBuffer buffer = this.buffer;
-    buffer.addCharCode(charCode);
+    final StringBuffer buffer = this.buffer;
+    decoder.flush(buffer);
+    buffer.writeCharCode(charCode);
   }
 
   String endString() {
-    _Utf8StringBuffer buffer = this.buffer;
+    final StringBuffer buffer = this.buffer;
+    decoder.flush(buffer);
     this.buffer = null;
     return buffer.toString();
   }
@@ -1855,24 +1608,424 @@
 }
 
 @patch
-int _scanOneByteCharacters(List<int> units, int from, int endIndex) {
-  final to = endIndex;
+class _Utf8Decoder {
+  /// Flags indicating presence of the various kinds of bytes in the input.
+  int _scanFlags = 0;
 
-  // Special case for _Uint8ArrayView.
-  if (units is Uint8List) {
-    if (from >= 0 && to >= 0 && to <= units.length) {
-      for (int i = from; i < to; i++) {
-        final unit = units[i];
-        if ((unit & _ONE_BYTE_LIMIT) != unit) return i - from;
-      }
-      return to - from;
+  /// How many bytes of the BOM have been read so far. Set to -1 when the BOM
+  /// has been skipped (or was not present).
+  int _bomIndex = 0;
+
+  // Table for the scanning phase, which quickly scans through the input.
+  //
+  // Each input byte is looked up in the table, providing a size and some flags.
+  // The sizes are summed, and the flags are or'ed together.
+  //
+  // The resulting size and flags indicate:
+  // A) How many UTF-16 code units will be emitted by the decoding of this
+  //    input. This can be used to allocate a string of the correct length up
+  //    front.
+  // B) Which decoder and resulting string representation is appropriate. There
+  //    are three cases:
+  //    1) Pure ASCII (flags == 0): The input can simply be put into a
+  //       OneByteString without further decoding.
+  //    2) Latin1 (flags == (flagLatin1 | flagExtension)): The result can be
+  //       represented by a OneByteString, and the decoder can assume that only
+  //       Latin1 characters are present.
+  //    3) Arbitrary input (otherwise): Needs a full-featured decoder. Output
+  //       can be represented by a TwoByteString.
+
+  static const int sizeMask = 0x03;
+  static const int flagsMask = 0x3C;
+
+  static const int flagExtension = 1 << 2;
+  static const int flagLatin1 = 1 << 3;
+  static const int flagNonLatin1 = 1 << 4;
+  static const int flagIllegal = 1 << 5;
+
+  // ASCII     'A' = 64 + (1);
+  // Extension 'D' = 64 + (0 | flagExtension);
+  // Latin1    'I' = 64 + (1 | flagLatin1);
+  // BMP       'Q' = 64 + (1 | flagNonLatin1);
+  // Non-BMP   'R' = 64 + (2 | flagNonLatin1);
+  // Illegal   'a' = 64 + (1 | flagIllegal);
+  // Illegal   'b' = 64 + (2 | flagIllegal);
+  static const String scanTable = ""
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 00-1F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 20-3F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 40-5F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 60-7F
+      "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" // 80-9F
+      "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" // A0-BF
+      "aaIIQQQQQQQQQQQQQQQQQQQQQQQQQQQQ" // C0-DF
+      "QQQQQQQQQQQQQQQQRRRRRbbbbbbbbbbb" // E0-FF
+      ;
+
+  /// Reset the decoder to a state where it is ready to decode a new string but
+  /// will not skip a leading BOM. Used by the fused UTF-8 / JSON decoder.
+  void reset() {
+    _state = initial;
+    _bomIndex = -1;
+  }
+
+  // The VM decoder handles BOM explicitly instead of via the state machine.
+  @patch
+  _Utf8Decoder(this.allowMalformed) : _state = initial;
+
+  @patch
+  String convertSingle(List<int> codeUnits, int start, int maybeEnd) {
+    int end = RangeError.checkValidRange(start, maybeEnd, codeUnits.length);
+
+    // Have bytes as Uint8List.
+    Uint8List bytes;
+    int errorOffset;
+    if (codeUnits is Uint8List) {
+      bytes = codeUnits;
+      errorOffset = 0;
+    } else {
+      bytes = _makeUint8List(codeUnits, start, end);
+      errorOffset = start;
+      end -= start;
+      start = 0;
     }
+
+    // Skip initial BOM.
+    start = skipBomSingle(bytes, start, end);
+
+    // Special case empty input.
+    if (start == end) return "";
+
+    // Scan input to determine size and appropriate decoder.
+    int size = scan(bytes, start, end);
+    int flags = _scanFlags;
+
+    if (flags == 0) {
+      // Pure ASCII.
+      assert(size == end - start);
+      // TODO(dartbug.com/41703): String.fromCharCodes has a lot of overhead
+      // checking types and ranges, which is redundant in this case. Find a
+      // more direct way to do the conversion.
+      return String.fromCharCodes(bytes, start, end);
+    }
+
+    String result;
+    if (flags == (flagLatin1 | flagExtension)) {
+      // Latin1.
+      result = decode8(bytes, start, end, size);
+    } else {
+      // Arbitrary Unicode.
+      result = decode16(bytes, start, end, size);
+    }
+    if (_state == accept) {
+      return result;
+    }
+
+    if (!allowMalformed) {
+      if (!isErrorState(_state)) {
+        // Unfinished sequence.
+        _state = errorUnfinished;
+        _charOrIndex = end;
+      }
+      final String message = errorDescription(_state);
+      throw FormatException(message, codeUnits, errorOffset + _charOrIndex);
+    }
+
+    // Start over on slow path.
+    _state = initial;
+    result = decodeGeneral(bytes, start, end, true);
+    assert(!isErrorState(_state));
+    return result;
   }
 
-  // Fall through to normal case.
-  for (var i = from; i < to; i++) {
-    final unit = units[i];
-    if ((unit & _ONE_BYTE_LIMIT) != unit) return i - from;
+  @patch
+  String convertChunked(List<int> codeUnits, int start, int maybeEnd) {
+    int end = RangeError.checkValidRange(start, maybeEnd, codeUnits.length);
+
+    // Have bytes as Uint8List.
+    Uint8List bytes;
+    int errorOffset;
+    if (codeUnits is Uint8List) {
+      bytes = codeUnits;
+      errorOffset = 0;
+    } else {
+      bytes = _makeUint8List(codeUnits, start, end);
+      errorOffset = start;
+      end -= start;
+      start = 0;
+    }
+
+    // Skip initial BOM.
+    start = skipBomChunked(bytes, start, end);
+
+    // Special case empty input.
+    if (start == end) return "";
+
+    // Scan input to determine size and appropriate decoder.
+    int size = scan(bytes, start, end);
+    int flags = _scanFlags;
+
+    // Adjust scan flags and size based on carry-over state.
+    switch (_state) {
+      case IA:
+        break;
+      case X1:
+        flags |= _charOrIndex < (0x100 >> 6) ? flagLatin1 : flagNonLatin1;
+        if (end - start >= 1) {
+          size += _charOrIndex < (0x10000 >> 6) ? 1 : 2;
+        }
+        break;
+      case X2:
+        flags |= flagNonLatin1;
+        if (end - start >= 2) {
+          size += _charOrIndex < (0x10000 >> 12) ? 1 : 2;
+        }
+        break;
+      case TO:
+      case TS:
+        flags |= flagNonLatin1;
+        if (end - start >= 2) size += 1;
+        break;
+      case X3:
+      case QO:
+      case QR:
+        flags |= flagNonLatin1;
+        if (end - start >= 3) size += 2;
+        break;
+    }
+
+    if (flags == 0) {
+      // Pure ASCII.
+      assert(_state == accept);
+      assert(size == end - start);
+      // TODO(dartbug.com/41703): String.fromCharCodes has a lot of overhead
+      // checking types and ranges, which is redundant in this case. Find a
+      // more direct way to do the conversion.
+      return String.fromCharCodes(bytes, start, end);
+    }
+
+    // Do not include any final, incomplete character in size.
+    int extensionCount = 0;
+    int i = end - 1;
+    while (i >= start && (bytes[i] & 0xC0) == 0x80) {
+      extensionCount++;
+      i--;
+    }
+    if (i >= start && bytes[i] >= ((~0x3F >> extensionCount) & 0xFF)) {
+      size -= bytes[i] >= 0xF0 ? 2 : 1;
+    }
+
+    final int carryOverState = _state;
+    final int carryOverChar = _charOrIndex;
+    String result;
+    if (flags == (flagLatin1 | flagExtension)) {
+      // Latin1.
+      result = decode8(bytes, start, end, size);
+    } else {
+      // Arbitrary Unicode.
+      result = decode16(bytes, start, end, size);
+    }
+    if (!isErrorState(_state)) {
+      return result;
+    }
+    assert(_bomIndex == -1);
+
+    if (!allowMalformed) {
+      final String message = errorDescription(_state);
+      _state = initial; // Ready for more input.
+      throw FormatException(message, codeUnits, errorOffset + _charOrIndex);
+    }
+
+    // Start over on slow path.
+    _state = carryOverState;
+    _charOrIndex = carryOverChar;
+    result = decodeGeneral(bytes, start, end, false);
+    assert(!isErrorState(_state));
+    return result;
   }
-  return to - from;
+
+  @pragma("vm:prefer-inline")
+  int skipBomSingle(Uint8List bytes, int start, int end) {
+    if (end - start >= 3 &&
+        bytes[start] == 0xEF &&
+        bytes[start + 1] == 0xBB &&
+        bytes[start + 2] == 0xBF) {
+      return start + 3;
+    }
+    return start;
+  }
+
+  @pragma("vm:prefer-inline")
+  int skipBomChunked(Uint8List bytes, int start, int end) {
+    assert(start <= end);
+    int bomIndex = _bomIndex;
+    // Already skipped?
+    if (bomIndex == -1) return start;
+
+    const bomValues = <int>[0xEF, 0xBB, 0xBF];
+    int i = start;
+    while (bomIndex < 3) {
+      if (i == end) {
+        // Unfinished BOM.
+        _bomIndex = bomIndex;
+        return start;
+      }
+      if (bytes[i++] != bomValues[bomIndex++]) {
+        // No BOM.
+        _bomIndex = -1;
+        return start;
+      }
+    }
+    // Complete BOM.
+    _bomIndex = -1;
+    _state = initial;
+    return i;
+  }
+
+  // Scanning functions to compute the size of the resulting string and flags
+  // (written to _scanFlags) indicating which decoder to use.
+  // TODO(dartbug.com/41702): Intrinsify this function.
+  int scan(Uint8List bytes, int start, int end) {
+    _scanFlags = 0;
+    for (int i = start; i < end; i++) {
+      if (bytes[i] > 127) return i - start + scan2(bytes, i, end);
+    }
+    return end - start;
+  }
+
+  int scan2(Uint8List bytes, int start, int end) {
+    final String scanTable = _Utf8Decoder.scanTable;
+    int size = 0;
+    int flags = 0;
+    for (int i = start; i < end; i++) {
+      int t = scanTable.codeUnitAt(bytes[i]);
+      size += t & sizeMask;
+      flags |= t;
+    }
+    _scanFlags = flags & flagsMask;
+    return size;
+  }
+
+  String decode8(Uint8List bytes, int start, int end, int size) {
+    assert(start < end);
+    // TODO(dartbug.com/41704): Allocate an uninitialized _OneByteString and
+    // write characters to it using _setAt.
+    Uint8List chars = Uint8List(size);
+    int i = start;
+    int j = 0;
+    if (_state == X1) {
+      // Half-way though 2-byte sequence
+      assert(_charOrIndex == 2 || _charOrIndex == 3);
+      final int e = bytes[i++] ^ 0x80;
+      if (e >= 0x40) {
+        _state = errorMissingExtension;
+        _charOrIndex = i - 1;
+        return "";
+      }
+      chars[j++] = (_charOrIndex << 6) | e;
+      _state = accept;
+    }
+    assert(_state == accept);
+    while (i < end) {
+      int byte = bytes[i++];
+      if (byte >= 0x80) {
+        if (byte < 0xC0) {
+          _state = errorUnexpectedExtension;
+          _charOrIndex = i - 1;
+          return "";
+        }
+        assert(byte == 0xC2 || byte == 0xC3);
+        if (i == end) {
+          _state = X1;
+          _charOrIndex = byte & 0x1F;
+          break;
+        }
+        final int e = bytes[i++] ^ 0x80;
+        if (e >= 0x40) {
+          _state = errorMissingExtension;
+          _charOrIndex = i - 1;
+          return "";
+        }
+        byte = (byte << 6) | e;
+      }
+      chars[j++] = byte;
+    }
+    // Output size must match, unless we are doing single conversion and are
+    // inside an unfinished sequence (which will trigger an error later).
+    assert(_bomIndex == 0 && _state != accept
+        ? (j == size - 1 || j == size - 2)
+        : (j == size));
+    return String.fromCharCodes(chars);
+  }
+
+  String decode16(Uint8List bytes, int start, int end, int size) {
+    assert(start < end);
+    final String typeTable = _Utf8Decoder.typeTable;
+    final String transitionTable = _Utf8Decoder.transitionTable;
+    // TODO(dartbug.com/41704): Allocate an uninitialized _TwoByteString and
+    // write characters to it using _setAt.
+    Uint16List chars = Uint16List(size);
+    int i = start;
+    int j = 0;
+    int state = _state;
+    int char;
+
+    // First byte
+    assert(!isErrorState(state));
+    final int byte = bytes[i++];
+    final int type = typeTable.codeUnitAt(byte) & typeMask;
+    if (state == accept) {
+      char = byte & (shiftedByteMask >> type);
+      state = transitionTable.codeUnitAt(type);
+    } else {
+      char = (byte & 0x3F) | (_charOrIndex << 6);
+      state = transitionTable.codeUnitAt(state + type);
+    }
+
+    while (i < end) {
+      final int byte = bytes[i++];
+      final int type = typeTable.codeUnitAt(byte) & typeMask;
+      if (state == accept) {
+        if (char >= 0x10000) {
+          assert(char < 0x110000);
+          chars[j++] = 0xD7C0 + (char >> 10);
+          chars[j++] = 0xDC00 + (char & 0x3FF);
+        } else {
+          chars[j++] = char;
+        }
+        char = byte & (shiftedByteMask >> type);
+        state = transitionTable.codeUnitAt(type);
+      } else if (isErrorState(state)) {
+        _state = state;
+        _charOrIndex = i - 2;
+        return "";
+      } else {
+        char = (byte & 0x3F) | (char << 6);
+        state = transitionTable.codeUnitAt(state + type);
+      }
+    }
+
+    // Final write?
+    if (state == accept) {
+      if (char >= 0x10000) {
+        assert(char < 0x110000);
+        chars[j++] = 0xD7C0 + (char >> 10);
+        chars[j++] = 0xDC00 + (char & 0x3FF);
+      } else {
+        chars[j++] = char;
+      }
+    } else if (isErrorState(state)) {
+      _state = state;
+      _charOrIndex = end - 1;
+      return "";
+    }
+
+    _state = state;
+    _charOrIndex = char;
+    // Output size must match, unless we are doing single conversion and are
+    // inside an unfinished sequence (which will trigger an error later).
+    assert(_bomIndex == 0 && _state != accept
+        ? (j == size - 1 || j == size - 2)
+        : (j == size));
+    return String.fromCharCodes(chars);
+  }
 }
diff --git a/sdk/lib/_internal/vm/lib/internal_patch.dart b/sdk/lib/_internal/vm/lib/internal_patch.dart
index 6accfc3..76a8a88 100644
--- a/sdk/lib/_internal/vm/lib/internal_patch.dart
+++ b/sdk/lib/_internal/vm/lib/internal_patch.dart
@@ -48,7 +48,6 @@
   // Implementation of package root/map provision.
   static var packageRootString;
   static var packageConfigString;
-  static var packageRootUriFuture;
   static var packageConfigUriFuture;
   static var resolvePackageUriFuture;
 
diff --git a/sdk/lib/_internal/vm/lib/isolate_patch.dart b/sdk/lib/_internal/vm/lib/isolate_patch.dart
index e17c1de..e357b8a 100644
--- a/sdk/lib/_internal/vm/lib/isolate_patch.dart
+++ b/sdk/lib/_internal/vm/lib/isolate_patch.dart
@@ -267,21 +267,21 @@
   // The control port (aka the main isolate port) does not handle any messages.
   if (controlPort != null) {
     controlPort.handler = (_) {}; // Nobody home on the control port.
-  }
 
-  if (parentPort != null) {
-    // Build a message to our parent isolate providing access to the
-    // current isolate's control port and capabilities.
-    //
-    // TODO(floitsch): Send an error message if we can't find the entry point.
-    var readyMessage = new List(2);
-    readyMessage[0] = controlPort.sendPort;
-    readyMessage[1] = capabilities;
+    if (parentPort != null) {
+      // Build a message to our parent isolate providing access to the
+      // current isolate's control port and capabilities.
+      //
+      // TODO(floitsch): Send an error message if we can't find the entry point.
+      final readyMessage = List(2);
+      readyMessage[0] = controlPort.sendPort;
+      readyMessage[1] = capabilities;
 
-    // Out of an excess of paranoia we clear the capabilities from the
-    // stack.  Not really necessary.
-    capabilities = null;
-    parentPort.send(readyMessage);
+      // Out of an excess of paranoia we clear the capabilities from the
+      // stack.  Not really necessary.
+      capabilities = null;
+      parentPort.send(readyMessage);
+    }
   }
   assert(capabilities == null);
 
@@ -343,7 +343,6 @@
   }
 
   static bool _packageSupported() =>
-      (VMLibraryHooks.packageRootUriFuture != null) &&
       (VMLibraryHooks.packageConfigUriFuture != null) &&
       (VMLibraryHooks.resolvePackageUriFuture != null);
 
@@ -355,46 +354,33 @@
       SendPort onError,
       String debugName}) async {
     // `paused` isn't handled yet.
-    RawReceivePort readyPort;
+    // Check for the type of `entryPoint` on the spawning isolate to make
+    // error-handling easier.
+    if (entryPoint is! _UnaryFunction) {
+      throw new ArgumentError(entryPoint);
+    }
+    // The VM will invoke [_startIsolate] with entryPoint as argument.
+
+    // We do not inherit the package config settings from the parent isolate,
+    // instead we use the values that were set on the command line.
+    var packageConfig = VMLibraryHooks.packageConfigString;
+    var script = VMLibraryHooks.platformScript;
+    if (script == null) {
+      // We do not have enough information to support spawning the new
+      // isolate.
+      throw new UnsupportedError("Isolate.spawn");
+    }
+    if (script.isScheme("package")) {
+      script = await Isolate.resolvePackageUri(script);
+    }
+
+    final RawReceivePort readyPort = new RawReceivePort();
     try {
-      // Check for the type of `entryPoint` on the spawning isolate to make
-      // error-handling easier.
-      if (entryPoint is! _UnaryFunction) {
-        throw new ArgumentError(entryPoint);
-      }
-      // The VM will invoke [_startIsolate] with entryPoint as argument.
-      readyPort = new RawReceivePort();
-
-      // We do not inherit the package config settings from the parent isolate,
-      // instead we use the values that were set on the command line.
-      var packageConfig = VMLibraryHooks.packageConfigString;
-      var script = VMLibraryHooks.platformScript;
-      if (script == null) {
-        // We do not have enough information to support spawning the new
-        // isolate.
-        throw new UnsupportedError("Isolate.spawn");
-      }
-      if (script.scheme == "package") {
-        script = await Isolate.resolvePackageUri(script);
-      }
-
-      _spawnFunction(
-          readyPort.sendPort,
-          script.toString(),
-          entryPoint,
-          message,
-          paused,
-          errorsAreFatal,
-          onExit,
-          onError,
-          null,
-          packageConfig,
-          debugName);
+      _spawnFunction(readyPort.sendPort, script.toString(), entryPoint, message,
+          paused, errorsAreFatal, onExit, onError, packageConfig, debugName);
       return await _spawnCommon(readyPort);
     } catch (e, st) {
-      if (readyPort != null) {
-        readyPort.close();
-      }
+      readyPort.close();
       return await new Future<Isolate>.error(e, st);
     }
   }
@@ -411,7 +397,6 @@
       Uri packageConfig,
       bool automaticPackageResolution: false,
       String debugName}) async {
-    RawReceivePort readyPort;
     if (environment != null) {
       throw new UnimplementedError("environment");
     }
@@ -434,38 +419,30 @@
             "packageRoot and a packageConfig.");
       }
     }
+    // Resolve the uri against the current isolate's root Uri first.
+    final Uri spawnedUri = _rootUri.resolveUri(uri);
+
+    // Inherit this isolate's package resolution setup if not overridden.
+    if (!automaticPackageResolution && packageConfig == null) {
+      if (Isolate._packageSupported()) {
+        packageConfig = await Isolate.packageConfig;
+      }
+    }
+
+    // Ensure to resolve package: URIs being handed in as parameters.
+    if (packageConfig != null) {
+      // Avoid calling resolvePackageUri if not strictly necessary in case
+      // the API is not supported.
+      if (packageConfig.isScheme("package")) {
+        packageConfig = await Isolate.resolvePackageUri(packageConfig);
+      }
+    }
+
+    // The VM will invoke [_startIsolate] and not `main`.
+    final packageConfigString = packageConfig?.toString();
+
+    final RawReceivePort readyPort = new RawReceivePort();
     try {
-      // Resolve the uri against the current isolate's root Uri first.
-      var spawnedUri = _rootUri.resolveUri(uri);
-
-      // Inherit this isolate's package resolution setup if not overridden.
-      if (!automaticPackageResolution &&
-          (packageRoot == null) &&
-          (packageConfig == null)) {
-        if (Isolate._packageSupported()) {
-          packageRoot = await Isolate.packageRoot;
-          packageConfig = await Isolate.packageConfig;
-        }
-      }
-
-      // Ensure to resolve package: URIs being handed in as parameters.
-      if (packageRoot != null) {
-        // `packages/` directory is no longer supported. Force it null.
-        // TODO(mfairhurst) Should this throw an exception?
-        packageRoot = null;
-      } else if (packageConfig != null) {
-        // Avoid calling resolvePackageUri if not strictly necessary in case
-        // the API is not supported.
-        if (packageConfig.scheme == "package") {
-          packageConfig = await Isolate.resolvePackageUri(packageConfig);
-        }
-      }
-
-      // The VM will invoke [_startIsolate] and not `main`.
-      readyPort = new RawReceivePort();
-      var packageRootString = packageRoot?.toString();
-      var packageConfigString = packageConfig?.toString();
-
       _spawnUri(
           readyPort.sendPort,
           spawnedUri.toString(),
@@ -478,20 +455,17 @@
           checked,
           null,
           /* environment */
-          packageRootString,
           packageConfigString,
           debugName);
       return await _spawnCommon(readyPort);
     } catch (e) {
-      if (readyPort != null) {
-        readyPort.close();
-      }
+      readyPort.close();
       rethrow;
     }
   }
 
   static Future<Isolate> _spawnCommon(RawReceivePort readyPort) {
-    Completer completer = new Completer<Isolate>.sync();
+    final completer = new Completer<Isolate>.sync();
     readyPort.handler = (readyMessage) {
       readyPort.close();
       if (readyMessage is List && readyMessage.length == 2) {
@@ -536,7 +510,6 @@
       bool errorsAreFatal,
       SendPort onExit,
       SendPort onError,
-      String packageRoot,
       String packageConfig,
       String debugName) native "Isolate_spawnFunction";
 
@@ -551,7 +524,6 @@
       bool errorsAreFatal,
       bool checked,
       List environment,
-      String packageRoot,
       String packageConfig,
       String debugName) native "Isolate_spawnUri";
 
diff --git a/sdk/lib/convert/json.dart b/sdk/lib/convert/json.dart
index 5aa14b2..fc55abc 100644
--- a/sdk/lib/convert/json.dart
+++ b/sdk/lib/convert/json.dart
@@ -535,11 +535,16 @@
   static const int char_0 = 0x30;
   static const int backslash = 0x5c;
   static const int char_b = 0x62;
+  static const int char_d = 0x64;
   static const int char_f = 0x66;
   static const int char_n = 0x6e;
   static const int char_r = 0x72;
   static const int char_t = 0x74;
   static const int char_u = 0x75;
+  static const int surrogateMin = 0xd800;
+  static const int surrogateMask = 0xfc00;
+  static const int surrogateLead = 0xd800;
+  static const int surrogateTrail = 0xdc00;
 
   /// List of objects currently being traversed. Used to detect cycles.
   final List _seen = [];
@@ -573,7 +578,30 @@
     final length = s.length;
     for (var i = 0; i < length; i++) {
       var charCode = s.codeUnitAt(i);
-      if (charCode > backslash) continue;
+      if (charCode > backslash) {
+        if (charCode >= surrogateMin) {
+          // Possible surrogate. Check if it is unpaired.
+          if (((charCode & surrogateMask) == surrogateLead &&
+                  !(i + 1 < length &&
+                      (s.codeUnitAt(i + 1) & surrogateMask) ==
+                          surrogateTrail)) ||
+              ((charCode & surrogateMask) == surrogateTrail &&
+                  !(i - 1 >= 0 &&
+                      (s.codeUnitAt(i - 1) & surrogateMask) ==
+                          surrogateLead))) {
+            // Lone surrogate.
+            if (i > offset) writeStringSlice(s, offset, i);
+            offset = i + 1;
+            writeCharCode(backslash);
+            writeCharCode(char_u);
+            writeCharCode(char_d);
+            writeCharCode(hexDigit((charCode >> 8) & 0xf));
+            writeCharCode(hexDigit((charCode >> 4) & 0xf));
+            writeCharCode(hexDigit(charCode & 0xf));
+          }
+        }
+        continue;
+      }
       if (charCode < 32) {
         if (i > offset) writeStringSlice(s, offset, i);
         offset = i + 1;
@@ -953,16 +981,22 @@
       if (char <= 0x7f) {
         writeByte(char);
       } else {
-        if ((char & 0xFC00) == 0xD800 && i + 1 < end) {
-          // Lead surrogate.
-          var nextChar = string.codeUnitAt(i + 1);
-          if ((nextChar & 0xFC00) == 0xDC00) {
-            // Tail surrogate.
-            char = 0x10000 + ((char & 0x3ff) << 10) + (nextChar & 0x3ff);
-            writeFourByteCharCode(char);
-            i++;
-            continue;
+        if ((char & 0xF800) == 0xD800) {
+          // Surrogate.
+          if (char < 0xDC00 && i + 1 < end) {
+            // Lead surrogate.
+            var nextChar = string.codeUnitAt(i + 1);
+            if ((nextChar & 0xFC00) == 0xDC00) {
+              // Tail surrogate.
+              char = 0x10000 + ((char & 0x3ff) << 10) + (nextChar & 0x3ff);
+              writeFourByteCharCode(char);
+              i++;
+              continue;
+            }
           }
+          // Unpaired surrogate.
+          writeMultiByteCharCode(unicodeReplacementCharacterRune);
+          continue;
         }
         writeMultiByteCharCode(char);
       }
diff --git a/sdk/lib/convert/string_conversion.dart b/sdk/lib/convert/string_conversion.dart
index 086ed79..6c7d965 100644
--- a/sdk/lib/convert/string_conversion.dart
+++ b/sdk/lib/convert/string_conversion.dart
@@ -256,12 +256,13 @@
 class _Utf8StringSinkAdapter extends ByteConversionSink {
   final _Utf8Decoder _decoder;
   final Sink _sink;
+  final StringSink _stringSink;
 
-  _Utf8StringSinkAdapter(this._sink, StringSink stringSink, bool allowMalformed)
-      : _decoder = _Utf8Decoder(stringSink, allowMalformed);
+  _Utf8StringSinkAdapter(this._sink, this._stringSink, bool allowMalformed)
+      : _decoder = _Utf8Decoder(allowMalformed);
 
   void close() {
-    _decoder.close();
+    _decoder.flush(_stringSink);
     if (_sink != null) _sink.close();
   }
 
@@ -271,7 +272,7 @@
 
   void addSlice(
       List<int> codeUnits, int startIndex, int endIndex, bool isLast) {
-    _decoder.convert(codeUnits, startIndex, endIndex);
+    _stringSink.write(_decoder.convertChunked(codeUnits, startIndex, endIndex));
     if (isLast) close();
   }
 }
@@ -289,11 +290,11 @@
 
   _Utf8ConversionSink._(
       this._chunkedSink, StringBuffer stringBuffer, bool allowMalformed)
-      : _decoder = _Utf8Decoder(stringBuffer, allowMalformed),
+      : _decoder = _Utf8Decoder(allowMalformed),
         _buffer = stringBuffer;
 
   void close() {
-    _decoder.close();
+    _decoder.flush(_buffer);
     if (_buffer.isNotEmpty) {
       var accumulated = _buffer.toString();
       _buffer.clear();
@@ -308,7 +309,7 @@
   }
 
   void addSlice(List<int> chunk, int startIndex, int endIndex, bool isLast) {
-    _decoder.convert(chunk, startIndex, endIndex);
+    _buffer.write(_decoder.convertChunked(chunk, startIndex, endIndex));
     if (_buffer.isNotEmpty) {
       var accumulated = _buffer.toString();
       _chunkedSink.addSlice(accumulated, 0, accumulated.length, isLast);
diff --git a/sdk/lib/convert/utf.dart b/sdk/lib/convert/utf.dart
index a614f39..3d08ad7 100644
--- a/sdk/lib/convert/utf.dart
+++ b/sdk/lib/convert/utf.dart
@@ -58,12 +58,19 @@
   /// was used to instantiate `this`.
   String decode(List<int> codeUnits, {bool allowMalformed}) {
     allowMalformed ??= _allowMalformed;
-    return Utf8Decoder(allowMalformed: allowMalformed).convert(codeUnits);
+    // Switch between const objects to avoid allocation.
+    Utf8Decoder decoder = allowMalformed
+        ? const Utf8Decoder(allowMalformed: true)
+        : const Utf8Decoder(allowMalformed: false);
+    return decoder.convert(codeUnits);
   }
 
   Utf8Encoder get encoder => const Utf8Encoder();
   Utf8Decoder get decoder {
-    return Utf8Decoder(allowMalformed: _allowMalformed);
+    // Switch between const objects to avoid allocation.
+    return _allowMalformed
+        ? const Utf8Decoder(allowMalformed: true)
+        : const Utf8Decoder(allowMalformed: false);
   }
 }
 
@@ -131,6 +138,13 @@
   /// Allow an implementation to pick the most efficient way of storing bytes.
   static Uint8List _createBuffer(int size) => Uint8List(size);
 
+  /// Write a replacement character (U+FFFD). Used for unpaired surrogates.
+  void _writeReplacementCharacter() {
+    _buffer[_bufferIndex++] = 0xEF;
+    _buffer[_bufferIndex++] = 0xBF;
+    _buffer[_bufferIndex++] = 0xBD;
+  }
+
   /// Tries to combine the given [leadingSurrogate] with the [nextCodeUnit] and
   /// writes it to [_buffer].
   ///
@@ -138,8 +152,8 @@
   /// [leadingSurrogate]. If it wasn't then nextCodeUnit was not a trailing
   /// surrogate and has not been written yet.
   ///
-  /// It is safe to pass 0 for [nextCodeUnit] in which case only the leading
-  /// surrogate is written.
+  /// It is safe to pass 0 for [nextCodeUnit] in which case a replacement
+  /// character is written to represent the unpaired lead surrogate.
   bool _writeSurrogate(int leadingSurrogate, int nextCodeUnit) {
     if (_isTailSurrogate(nextCodeUnit)) {
       var rune = _combineSurrogatePair(leadingSurrogate, nextCodeUnit);
@@ -153,14 +167,8 @@
       _buffer[_bufferIndex++] = 0x80 | (rune & 0x3f);
       return true;
     } else {
-      // TODO(floitsch): allow to throw on malformed strings.
-      // Encode the half-surrogate directly into UTF-8. This yields
-      // invalid UTF-8, but we started out with invalid UTF-16.
-
-      // Surrogates are always encoded in 3 bytes in UTF-8.
-      _buffer[_bufferIndex++] = 0xE0 | (leadingSurrogate >> 12);
-      _buffer[_bufferIndex++] = 0x80 | ((leadingSurrogate >> 6) & 0x3f);
-      _buffer[_bufferIndex++] = 0x80 | (leadingSurrogate & 0x3f);
+      // Unpaired lead surrogate.
+      _writeReplacementCharacter();
       return false;
     }
   }
@@ -186,12 +194,16 @@
         if (_bufferIndex >= _buffer.length) break;
         _buffer[_bufferIndex++] = codeUnit;
       } else if (_isLeadSurrogate(codeUnit)) {
-        if (_bufferIndex + 3 >= _buffer.length) break;
+        if (_bufferIndex + 4 > _buffer.length) break;
         // Note that it is safe to read the next code unit. We decremented
         // [end] above when the last valid code unit was a leading surrogate.
         var nextCodeUnit = str.codeUnitAt(stringIndex + 1);
         var wasCombined = _writeSurrogate(codeUnit, nextCodeUnit);
         if (wasCombined) stringIndex++;
+      } else if (_isTailSurrogate(codeUnit)) {
+        if (_bufferIndex + 3 > _buffer.length) break;
+        // Unpaired tail surrogate.
+        _writeReplacementCharacter();
       } else {
         var rune = codeUnit;
         if (rune <= _TWO_BYTE_LIMIT) {
@@ -306,29 +318,7 @@
       return result;
     }
 
-    var length = codeUnits.length;
-    end = RangeError.checkValidRange(start, end, length);
-
-    // Fast case for ASCII strings avoids StringBuffer/_Utf8Decoder.
-    int oneBytes = _scanOneByteCharacters(codeUnits, start, end);
-    StringBuffer buffer;
-    bool isFirstCharacter = true;
-    if (oneBytes > 0) {
-      var firstPart = String.fromCharCodes(codeUnits, start, start + oneBytes);
-      start += oneBytes;
-      if (start == end) {
-        return firstPart;
-      }
-      buffer = StringBuffer(firstPart);
-      isFirstCharacter = false;
-    }
-
-    buffer ??= StringBuffer();
-    var decoder = _Utf8Decoder(buffer, _allowMalformed);
-    decoder._isFirstCharacter = isFirstCharacter;
-    decoder.convert(codeUnits, start, end);
-    decoder.flush(codeUnits, end);
-    return buffer.toString();
+    return _Utf8Decoder(_allowMalformed).convertSingle(codeUnits, start, end);
   }
 
   /// Starts a chunked conversion.
@@ -374,185 +364,314 @@
     0x10000 + ((lead & _SURROGATE_VALUE_MASK) << 10) |
     (tail & _SURROGATE_VALUE_MASK);
 
-/// Decodes UTF-8.
-///
-/// The decoder handles chunked input.
-// TODO(floitsch): make this class public.
 class _Utf8Decoder {
-  final bool _allowMalformed;
-  final StringSink _stringSink;
-  bool _isFirstCharacter = true;
-  int _value = 0;
-  int _expectedUnits = 0;
-  int _extraUnits = 0;
+  /// Decode malformed UTF-8 as replacement characters (instead of throwing)?
+  final bool allowMalformed;
 
-  _Utf8Decoder(this._stringSink, this._allowMalformed);
+  /// Decoder DFA state.
+  int _state;
 
-  bool get hasPartialInput => _expectedUnits > 0;
+  /// Partially decoded character. Meaning depends on state. Not used when in
+  /// the initial/accept state. When in an error state, contains the index into
+  /// the input of the error.
+  int _charOrIndex = 0;
 
-  // Limits of one through four byte encodings.
-  static const List<int> _LIMITS = <int>[
-    _ONE_BYTE_LIMIT,
-    _TWO_BYTE_LIMIT,
-    _THREE_BYTE_LIMIT,
-    _FOUR_BYTE_LIMIT
-  ];
+  // State machine for UTF-8 decoding, based on this decoder by Björn Höhrmann:
+  // https://bjoern.hoehrmann.de/utf-8/decoder/dfa/
+  //
+  // One iteration in the state machine proceeds as:
+  //
+  // type = typeTable[byte];
+  // char = (state != accept)
+  //     ? (byte & 0x3F) | (char << 6)
+  //     : byte & (shiftedByteMask >> type);
+  // state = transitionTable[state + type];
+  //
+  // After each iteration, if state == accept, char is output as a character.
 
-  void close() {
-    flush();
+  // Mask to and on the type read from the table.
+  static const int typeMask = 0x1F;
+  // Mask shifted right by byte type to mask first byte of sequence.
+  static const int shiftedByteMask = 0xF0FE;
+
+  // Byte types.
+  // 'A' = ASCII, 00-7F
+  // 'B' = 2-byte, C2-DF
+  // 'C' = 3-byte, E1-EC, EE
+  // 'D' = 3-byte (possibly surrogate), ED
+  // 'E' = Illegal, C0-C1, F5+
+  // 'F' = Low extension, 80-8F
+  // 'G' = Mid extension, 90-9F
+  // 'H' = High extension, A0-BA, BC-BE
+  // 'I' = Second byte of BOM, BB
+  // 'J' = Third byte of BOM, BF
+  // 'K' = 3-byte (possibly overlong), E0
+  // 'L' = First byte of BOM, EF
+  // 'M' = 4-byte (possibly out-of-range), F4
+  // 'N' = 4-byte, F1-F3
+  // 'O' = 4-byte (possibly overlong), F0
+  static const String typeTable = ""
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 00-1F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 20-3F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 40-5F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 60-7F
+      "FFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGG" // 80-9F
+      "HHHHHHHHHHHHHHHHHHHHHHHHHHHIHHHJ" // A0-BF
+      "EEBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" // C0-DF
+      "KCCCCCCCCCCCCDCLONNNMEEEEEEEEEEE" // E0-FF
+      ;
+
+  // States (offsets into transition table).
+  static const int IA = 0x00; // Initial / Accept
+  static const int BB = 0x10; // Before BOM
+  static const int AB = 0x20; // After BOM
+  static const int X1 = 0x30; // Expecting one extension byte
+  static const int X2 = 0x3A; // Expecting two extension bytes
+  static const int X3 = 0x44; // Expecting three extension bytes
+  static const int TO = 0x4E; // Possibly overlong 3-byte
+  static const int TS = 0x58; // Possibly surrogate
+  static const int QO = 0x62; // Possibly overlong 4-byte
+  static const int QR = 0x6C; // Possibly out-of-range 4-byte
+  static const int B1 = 0x76; // One byte into BOM
+  static const int B2 = 0x80; // Two bytes into BOM
+  static const int E1 = 0x41; // Error: Missing extension byte
+  static const int E2 = 0x43; // Error: Unexpected extension byte
+  static const int E3 = 0x45; // Error: Invalid byte
+  static const int E4 = 0x47; // Error: Overlong encoding
+  static const int E5 = 0x49; // Error: Out of range
+  static const int E6 = 0x4B; // Error: Surrogate
+  static const int E7 = 0x4D; // Error: Unfinished
+
+  // Character equivalents for states.
+  static const String _IA = '\u0000';
+  static const String _BB = '\u0010';
+  static const String _AB = '\u0020';
+  static const String _X1 = '\u0030';
+  static const String _X2 = '\u003A';
+  static const String _X3 = '\u0044';
+  static const String _TO = '\u004E';
+  static const String _TS = '\u0058';
+  static const String _QO = '\u0062';
+  static const String _QR = '\u006C';
+  static const String _B1 = '\u0076';
+  static const String _B2 = '\u0080';
+  static const String _E1 = '\u0041';
+  static const String _E2 = '\u0043';
+  static const String _E3 = '\u0045';
+  static const String _E4 = '\u0047';
+  static const String _E5 = '\u0049';
+  static const String _E6 = '\u004B';
+  static const String _E7 = '\u004D';
+
+  // Transition table of the state machine. Maps state and byte type
+  // to next state.
+  static const String transitionTable = " "
+      // A   B   C   D   E   F   G   H   I   J   K   L   M   N   O
+      "$_IA$_X1$_X2$_TS$_E3$_E2$_E2$_E2$_E2$_E2$_TO$_X2$_QR$_X3$_QO " // IA
+      "$_IA$_X1$_X2$_TS$_E3$_E2$_E2$_E2$_E2$_E2$_TO$_B1$_QR$_X3$_QO " // BB
+      "$_IA$_X1$_X2$_TS$_E3$_E2$_E2$_E2$_E2$_E2$_TO$_X2$_QR$_X3$_QO " // AB
+      "$_E1$_E1$_E1$_E1$_E1$_IA$_IA$_IA$_IA$_IA" // Overlap 5 E1s        X1
+      "$_E1$_E1$_E1$_E1$_E1$_X1$_X1$_X1$_X1$_X1" // Overlap 5 E1s        X2
+      "$_E1$_E1$_E1$_E1$_E1$_X2$_X2$_X2$_X2$_X2" // Overlap 5 E1s        X3
+      "$_E1$_E1$_E1$_E1$_E1$_E4$_E4$_X1$_X1$_X1" // Overlap 5 E1s        TO
+      "$_E1$_E1$_E1$_E1$_E1$_X1$_X1$_E6$_E6$_E6" // Overlap 5 E1s        TS
+      "$_E1$_E1$_E1$_E1$_E1$_E4$_X2$_X2$_X2$_X2" // Overlap 5 E1s        QO
+      "$_E1$_E1$_E1$_E1$_E1$_X2$_E5$_E5$_E5$_E5" // Overlap 5 E1s        QR
+      "$_E1$_E1$_E1$_E1$_E1$_X1$_X1$_X1$_B2$_X1" // Overlap 5 E1s        B1
+      "$_E1$_E1$_E1$_E1$_E1$_IA$_IA$_IA$_IA$_AB$_E1$_E1$_E1$_E1$_E1" //  B2
+      ;
+
+  // Aliases for states.
+  static const int initial = IA;
+  static const int accept = IA;
+  static const int beforeBom = BB;
+  static const int afterBom = AB;
+  static const int errorMissingExtension = E1;
+  static const int errorUnexpectedExtension = E2;
+  static const int errorInvalid = E3;
+  static const int errorOverlong = E4;
+  static const int errorOutOfRange = E5;
+  static const int errorSurrogate = E6;
+  static const int errorUnfinished = E7;
+
+  static bool isErrorState(int state) => (state & 1) != 0;
+
+  static String errorDescription(int state) {
+    switch (state) {
+      case errorMissingExtension:
+        return "Missing extension byte";
+      case errorUnexpectedExtension:
+        return "Unexpected extension byte";
+      case errorInvalid:
+        return "Invalid UTF-8 byte";
+      case errorOverlong:
+        return "Overlong encoding";
+      case errorOutOfRange:
+        return "Out of unicode range";
+      case errorSurrogate:
+        return "Encoded surrogate";
+      case errorUnfinished:
+        return "Unfinished UTF-8 octet sequence";
+      default:
+        return "";
+    }
+  }
+
+  external _Utf8Decoder(bool allowMalformed);
+
+  external String convertSingle(List<int> codeUnits, int start, int maybeEnd);
+
+  external String convertChunked(List<int> codeUnits, int start, int maybeEnd);
+
+  String convertGeneral(
+      List<int> codeUnits, int start, int maybeEnd, bool single) {
+    int end = RangeError.checkValidRange(start, maybeEnd, codeUnits.length);
+
+    if (start == end) return "";
+
+    // Have bytes as Uint8List.
+    Uint8List bytes;
+    int errorOffset;
+    if (codeUnits is Uint8List) {
+      bytes = codeUnits;
+      errorOffset = 0;
+    } else {
+      bytes = _makeUint8List(codeUnits, start, end);
+      errorOffset = start;
+      end -= start;
+      start = 0;
+    }
+
+    String result = decodeGeneral(bytes, start, end, single);
+    if (isErrorState(_state)) {
+      String message = errorDescription(_state);
+      _state = initial; // Ready for more input.
+      throw FormatException(message, codeUnits, errorOffset + _charOrIndex);
+    }
+    return result;
   }
 
   /// Flushes this decoder as if closed.
   ///
   /// This method throws if the input was partial and the decoder was
   /// constructed with `allowMalformed` set to `false`.
-  ///
-  /// The [source] and [offset] of the current position may be provided,
-  /// and are included in the exception if one is thrown.
-  void flush([List<int> source, int offset]) {
-    if (hasPartialInput) {
-      if (!_allowMalformed) {
-        throw FormatException(
-            "Unfinished UTF-8 octet sequence", source, offset);
-      }
-      _stringSink.writeCharCode(unicodeReplacementCharacterRune);
-      _value = 0;
-      _expectedUnits = 0;
-      _extraUnits = 0;
+  void flush(StringSink sink) {
+    final int state = _state;
+    _state = initial;
+    if (state <= afterBom) {
+      return;
+    }
+    // Unfinished sequence.
+    if (allowMalformed) {
+      sink.writeCharCode(unicodeReplacementCharacterRune);
+    } else {
+      throw FormatException(errorDescription(errorUnfinished), null, null);
     }
   }
 
-  void convert(List<int> codeUnits, int startIndex, int endIndex) {
-    var value = _value;
-    var expectedUnits = _expectedUnits;
-    var extraUnits = _extraUnits;
-    _value = 0;
-    _expectedUnits = 0;
-    _extraUnits = 0;
-
-    var i = startIndex;
+  String decodeGeneral(Uint8List bytes, int start, int end, bool single) {
+    final String typeTable = _Utf8Decoder.typeTable;
+    final String transitionTable = _Utf8Decoder.transitionTable;
+    int state = _state;
+    int char = _charOrIndex;
+    final StringBuffer buffer = StringBuffer();
+    int i = start;
+    int byte = bytes[i++];
     loop:
     while (true) {
       multibyte:
-      if (expectedUnits > 0) {
-        do {
-          if (i == endIndex) {
-            break loop;
-          }
-          var unit = codeUnits[i];
-          if ((unit & 0xC0) != 0x80) {
-            expectedUnits = 0;
-            if (!_allowMalformed) {
-              throw FormatException(
-                  "Bad UTF-8 encoding 0x${unit.toRadixString(16)}",
-                  codeUnits,
-                  i);
+      while (true) {
+        int type = typeTable.codeUnitAt(byte) & typeMask;
+        char = (state <= afterBom)
+            ? byte & (shiftedByteMask >> type)
+            : (byte & 0x3F) | (char << 6);
+        state = transitionTable.codeUnitAt(state + type);
+        if (state == accept) {
+          buffer.writeCharCode(char);
+          if (i == end) break loop;
+          break multibyte;
+        } else if (isErrorState(state)) {
+          if (allowMalformed) {
+            switch (state) {
+              case errorInvalid:
+              case errorUnexpectedExtension:
+                // A single byte that can't start a sequence.
+                buffer.writeCharCode(unicodeReplacementCharacterRune);
+                break;
+              case errorMissingExtension:
+                // Unfinished sequence followed by a byte that can start a
+                // sequence.
+                buffer.writeCharCode(unicodeReplacementCharacterRune);
+                // Re-parse offending byte.
+                i -= 1;
+                break;
+              default:
+                // Unfinished sequence followed by a byte that can't start a
+                // sequence.
+                buffer.writeCharCode(unicodeReplacementCharacterRune);
+                buffer.writeCharCode(unicodeReplacementCharacterRune);
+                break;
             }
-            _isFirstCharacter = false;
-            _stringSink.writeCharCode(unicodeReplacementCharacterRune);
-            break multibyte;
+            state = initial;
           } else {
-            value = (value << 6) | (unit & 0x3f);
-            expectedUnits--;
-            i++;
+            _state = state;
+            _charOrIndex = i - 1;
+            return "";
           }
-        } while (expectedUnits > 0);
-        if (value <= _LIMITS[extraUnits - 1]) {
-          // Overly long encoding. The value could be encoded with a shorter
-          // encoding.
-          if (!_allowMalformed) {
-            throw FormatException(
-                "Overlong encoding of 0x${value.toRadixString(16)}",
-                codeUnits,
-                i - extraUnits - 1);
-          }
-          expectedUnits = extraUnits = 0;
-          value = unicodeReplacementCharacterRune;
         }
-        if (value > _FOUR_BYTE_LIMIT) {
-          if (!_allowMalformed) {
-            throw FormatException(
-                "Character outside valid Unicode range: "
-                "0x${value.toRadixString(16)}",
-                codeUnits,
-                i - extraUnits - 1);
-          }
-          value = unicodeReplacementCharacterRune;
-        }
-        if (!_isFirstCharacter || value != unicodeBomCharacterRune) {
-          _stringSink.writeCharCode(value);
-        }
-        _isFirstCharacter = false;
+        if (i == end) break loop;
+        byte = bytes[i++];
       }
 
-      while (i < endIndex) {
-        var oneBytes = _scanOneByteCharacters(codeUnits, i, endIndex);
-        if (oneBytes > 0) {
-          _isFirstCharacter = false;
-          assert(i + oneBytes <= endIndex);
-          _stringSink.write(String.fromCharCodes(codeUnits, i, i + oneBytes));
-
-          i += oneBytes;
-          if (i == endIndex) break;
-        }
-        var unit = codeUnits[i++];
-        // TODO(floitsch): the way we test we could potentially allow
-        // units that are too large, if they happen to have the
-        // right bit-pattern. (Same is true for the multibyte loop above).
-        // TODO(floitsch): optimize this loop. See:
-        // https://codereview.chromium.org/22929022/diff/1/sdk/lib/convert/utf.dart?column_width=80
-        if (unit < 0) {
-          // TODO(floitsch): should this be unit <= 0 ?
-          if (!_allowMalformed) {
-            throw FormatException(
-                "Negative UTF-8 code unit: -0x${(-unit).toRadixString(16)}",
-                codeUnits,
-                i - 1);
+      final int markStart = i;
+      byte = bytes[i++];
+      if (byte < 128) {
+        int markEnd = end;
+        while (i < end) {
+          byte = bytes[i++];
+          if (byte >= 128) {
+            markEnd = i - 1;
+            break;
           }
-          _stringSink.writeCharCode(unicodeReplacementCharacterRune);
+        }
+        assert(markStart < markEnd);
+        if (markEnd - markStart < 20) {
+          for (int m = markStart; m < markEnd; m++) {
+            buffer.writeCharCode(bytes[m]);
+          }
         } else {
-          assert(unit > _ONE_BYTE_LIMIT);
-          if ((unit & 0xE0) == 0xC0) {
-            value = unit & 0x1F;
-            expectedUnits = extraUnits = 1;
-            continue loop;
-          }
-          if ((unit & 0xF0) == 0xE0) {
-            value = unit & 0x0F;
-            expectedUnits = extraUnits = 2;
-            continue loop;
-          }
-          // 0xF5, 0xF6 ... 0xFF never appear in valid UTF-8 sequences.
-          if ((unit & 0xF8) == 0xF0 && unit < 0xF5) {
-            value = unit & 0x07;
-            expectedUnits = extraUnits = 3;
-            continue loop;
-          }
-          if (!_allowMalformed) {
-            throw FormatException(
-                "Bad UTF-8 encoding 0x${unit.toRadixString(16)}",
-                codeUnits,
-                i - 1);
-          }
-          value = unicodeReplacementCharacterRune;
-          expectedUnits = extraUnits = 0;
-          _isFirstCharacter = false;
-          _stringSink.writeCharCode(value);
+          buffer.write(String.fromCharCodes(bytes, markStart, markEnd));
         }
+        if (markEnd == end) break loop;
       }
-      break loop;
     }
-    if (expectedUnits > 0) {
-      _value = value;
-      _expectedUnits = expectedUnits;
-      _extraUnits = extraUnits;
+
+    if (single && state > afterBom) {
+      // Unfinished sequence.
+      if (allowMalformed) {
+        buffer.writeCharCode(unicodeReplacementCharacterRune);
+      } else {
+        _state = errorUnfinished;
+        _charOrIndex = end;
+        return "";
+      }
     }
+    _state = state;
+    _charOrIndex = char;
+    return buffer.toString();
+  }
+
+  static Uint8List _makeUint8List(List<int> codeUnits, int start, int end) {
+    final int length = end - start;
+    final Uint8List bytes = Uint8List(length);
+    for (int i = 0; i < length; i++) {
+      int b = codeUnits[start + i];
+      if ((b & ~0xFF) != 0) {
+        // Replace invalid byte values by FF, which is also invalid.
+        b = 0xFF;
+      }
+      bytes[i] = b;
+    }
+    return bytes;
   }
 }
-
-// Returns the number of bytes in [units] starting at offset [from] which have
-// the leftmost bit set to 0.
-//
-// To increase performance of this critical method we have a special variant of
-// it implemented in the VM's patch files, which is why we make it external.
-external int _scanOneByteCharacters(List<int> units, int from, int endIndex);
diff --git a/sdk/lib/internal/internal.dart b/sdk/lib/internal/internal.dart
index b3ecbe7..d044b03 100644
--- a/sdk/lib/internal/internal.dart
+++ b/sdk/lib/internal/internal.dart
@@ -20,16 +20,17 @@
 import 'dart:core' hide Symbol;
 import 'dart:core' as core;
 import 'dart:math' show Random;
+import 'dart:typed_data' show Uint8List;
 
 part 'async_cast.dart';
 part 'cast.dart';
 part 'errors.dart';
 part 'iterable.dart';
 part 'list.dart';
+part 'linked_list.dart';
 part 'print.dart';
 part 'sort.dart';
 part 'symbol.dart';
-part 'linked_list.dart';
 
 // Powers of 10 up to 10^22 are representable as doubles.
 // Powers of 10 above that are only approximate due to lack of precission.
diff --git a/sdk/lib/vmservice/vmservice.dart b/sdk/lib/vmservice/vmservice.dart
index 82ef7c2..bfbdaf8 100644
--- a/sdk/lib/vmservice/vmservice.dart
+++ b/sdk/lib/vmservice/vmservice.dart
@@ -714,45 +714,6 @@
         details: "Unknown service: ${message.method}");
   }
 
-  Future<String> _spawnUri(Message message) async {
-    var token = message.params['token'];
-    if (token == null) {
-      return encodeMissingParamError(message, 'token');
-    }
-    if (token is! String) {
-      return encodeInvalidParamError(message, 'token');
-    }
-    var uri = message.params['uri'];
-    if (uri == null) {
-      return encodeMissingParamError(message, 'uri');
-    }
-    if (uri is! String) {
-      return encodeInvalidParamError(message, 'uri');
-    }
-    var args = message.params['args'];
-    var argsOfString = new List<String>();
-    if (args != null) {
-      if (args is! List) {
-        return encodeInvalidParamError(message, 'args');
-      }
-      for (var arg in args) {
-        if (arg is! String) {
-          return encodeInvalidParamError(message, 'args');
-        }
-        argsOfString.add(arg);
-      }
-    }
-    var msg = message.params['message'];
-
-    Isolate.spawnUri(Uri.parse(uri), argsOfString, msg).then((isolate) {
-      _spawnUriNotify(isolate.controlPort, token);
-    }).catchError((e) {
-      _spawnUriNotify(e.toString(), token);
-    });
-
-    return encodeSuccess(message);
-  }
-
   Future<Response> routeRequest(VMService _, Message message) async {
     final response = await _routeRequestImpl(message);
     if (response == null) {
@@ -780,9 +741,6 @@
       if (message.method == 'registerService') {
         return await _registerService(message);
       }
-      if (message.method == '_spawnUri') {
-        return await _spawnUri(message);
-      }
       if (message.method == 'setClientName') {
         return _setClientName(message);
       }
@@ -848,6 +806,3 @@
 
 /// Get the bytes to the tar archive.
 Uint8List _requestAssets() native "VMService_RequestAssets";
-
-/// Notify the vm service that an isolate has been spawned via rpc.
-void _spawnUriNotify(obj, String token) native "VMService_spawnUriNotify";
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/convert_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/convert_patch.dart
index a17be68..1b79fe8 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/convert_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/convert_patch.dart
@@ -496,11 +496,17 @@
 }
 
 @patch
-int _scanOneByteCharacters(List<int> units, int from, int endIndex) {
-  final to = endIndex;
-  for (var i = from; i < to; i++) {
-    final unit = units[i];
-    if ((unit & _ONE_BYTE_LIMIT) != unit) return i - from;
+class _Utf8Decoder {
+  @patch
+  _Utf8Decoder(this.allowMalformed) : _state = beforeBom;
+
+  @patch
+  String convertSingle(List<int> codeUnits, int start, int? maybeEnd) {
+    return convertGeneral(codeUnits, start, maybeEnd, true);
   }
-  return to - from;
+
+  @patch
+  String convertChunked(List<int> codeUnits, int start, int? maybeEnd) {
+    return convertGeneral(codeUnits, start, maybeEnd, false);
+  }
 }
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/convert_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/convert_patch.dart
index 44e8ab3..070946a 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/convert_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/convert_patch.dart
@@ -494,11 +494,17 @@
 }
 
 @patch
-int _scanOneByteCharacters(List<int> units, int from, int endIndex) {
-  final to = endIndex;
-  for (var i = from; i < to; i++) {
-    final unit = units[i];
-    if ((unit & _ONE_BYTE_LIMIT) != unit) return i - from;
+class _Utf8Decoder {
+  @patch
+  _Utf8Decoder(this.allowMalformed) : _state = beforeBom;
+
+  @patch
+  String convertSingle(List<int> codeUnits, int start, int? maybeEnd) {
+    return convertGeneral(codeUnits, start, maybeEnd, true);
   }
-  return to - from;
+
+  @patch
+  String convertChunked(List<int> codeUnits, int start, int? maybeEnd) {
+    return convertGeneral(codeUnits, start, maybeEnd, false);
+  }
 }
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/linked_hash_map.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/linked_hash_map.dart
index f79a5d3..70882d8 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/linked_hash_map.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/linked_hash_map.dart
@@ -97,12 +97,12 @@
     if (_isStringKey(key)) {
       var strings = _strings;
       if (strings == null) return null;
-      LinkedHashMapCell cell = _getTableCell(strings, key);
+      LinkedHashMapCell? cell = _getTableCell(strings, key);
       return JS('', '#', cell == null ? null : cell.hashMapCellValue);
     } else if (_isNumericKey(key)) {
       var nums = _nums;
       if (nums == null) return null;
-      LinkedHashMapCell cell = _getTableCell(nums, key);
+      LinkedHashMapCell? cell = _getTableCell(nums, key);
       return JS('', '#', cell == null ? null : cell.hashMapCellValue);
     } else {
       return internalGet(key);
@@ -221,7 +221,7 @@
 
   V? _removeHashTableEntry(var table, Object? key) {
     if (table == null) return null;
-    LinkedHashMapCell cell = _getTableCell(table, key);
+    LinkedHashMapCell? cell = _getTableCell(table, key);
     if (cell == null) return null;
     _unlinkCell(cell);
     _deleteTableEntry(table, key);
@@ -289,7 +289,7 @@
     return JS('int', '# & 0x3ffffff', key.hashCode);
   }
 
-  List<LinkedHashMapCell> _getBucket(var table, var key) {
+  List<LinkedHashMapCell>? _getBucket(var table, var key) {
     var hash = internalComputeHashCode(key);
     return _getTableBucket(table, hash);
   }
@@ -306,11 +306,11 @@
 
   String toString() => MapBase.mapToString(this);
 
-  LinkedHashMapCell _getTableCell(var table, var key) {
+  LinkedHashMapCell? _getTableCell(var table, var key) {
     return JS('var', '#[#]', table, key);
   }
 
-  List<LinkedHashMapCell> _getTableBucket(var table, var key) {
+  List<LinkedHashMapCell>? _getTableBucket(var table, var key) {
     return JS('var', '#[#]', table, key);
   }
 
@@ -324,7 +324,7 @@
   }
 
   bool _containsTableEntry(var table, var key) {
-    LinkedHashMapCell cell = _getTableCell(table, key);
+    LinkedHashMapCell? cell = _getTableCell(table, key);
     return cell != null;
   }
 
@@ -344,12 +344,12 @@
 
 class Es6LinkedHashMap<K, V> extends JsLinkedHashMap<K, V> {
   @override
-  LinkedHashMapCell _getTableCell(var table, var key) {
+  LinkedHashMapCell? _getTableCell(var table, var key) {
     return JS('var', '#.get(#)', table, key);
   }
 
   @override
-  List<LinkedHashMapCell> _getTableBucket(var table, var key) {
+  List<LinkedHashMapCell>? _getTableBucket(var table, var key) {
     return JS('var', '#.get(#)', table, key);
   }
 
diff --git a/sdk_nnbd/lib/_internal/vm/bin/builtin.dart b/sdk_nnbd/lib/_internal/vm/bin/builtin.dart
index e186a81..bc8f8e5 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/builtin.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/builtin.dart
@@ -9,6 +9,7 @@
 import 'dart:collection' hide LinkedList, LinkedListEntry;
 import 'dart:_internal' hide Symbol;
 import 'dart:io';
+import 'dart:convert';
 import 'dart:isolate';
 import 'dart:typed_data';
 
@@ -164,7 +165,7 @@
 }
 
 void _requestPackagesMap(Uri? packageConfig) {
-  var msg = null;
+  dynamic msg = null;
   if (packageConfig != null) {
     // Explicitly specified .packages path.
     msg = _handlePackagesRequest(_traceLoading, -2, packageConfig);
@@ -204,281 +205,185 @@
   }
 }
 
-// Handling of packages requests. Finding and parsing of .packages file or
-// packages/ directories.
-const _LF = 0x0A;
-const _CR = 0x0D;
-const _SPACE = 0x20;
-const _HASH = 0x23;
-const _DOT = 0x2E;
-const _COLON = 0x3A;
-const _DEL = 0x7F;
+// The values go from ' ' to DEL and `x` means disallowed.
+const String _invalidPackageNameChars =
+    'x.xx.x.........x..........x.x.xx...........................xxxx.x..........................xxx.x';
 
-const _invalidPackageNameChars = const [
-  true, //  space
-  false, // !
-  true, //  "
-  true, //  #
-  false, // $
-  true, //  %
-  false, // &
-  false, // '
-  false, // (
-  false, // )
-  false, // *
-  false, // +
-  false, // ,
-  false, // -
-  false, // .
-  true, //  /
-  false, // 0
-  false, // 1
-  false, // 2
-  false, // 3
-  false, // 4
-  false, // 5
-  false, // 6
-  false, // 7
-  false, // 8
-  false, // 9
-  true, //  :
-  false, // ;
-  true, //  <
-  false, // =
-  true, //  >
-  true, //  ?
-  false, // @
-  false, // A
-  false, // B
-  false, // C
-  false, // D
-  false, // E
-  false, // F
-  false, // G
-  false, // H
-  false, // I
-  false, // J
-  false, // K
-  false, // L
-  false, // M
-  false, // N
-  false, // O
-  false, // P
-  false, // Q
-  false, // R
-  false, // S
-  false, // T
-  false, // U
-  false, // V
-  false, // W
-  false, // X
-  false, // Y
-  false, // Z
-  true, //  [
-  true, //  \
-  true, //  ]
-  true, //  ^
-  false, // _
-  true, //  `
-  false, // a
-  false, // b
-  false, // c
-  false, // d
-  false, // e
-  false, // f
-  false, // g
-  false, // h
-  false, // i
-  false, // j
-  false, // k
-  false, // l
-  false, // m
-  false, // n
-  false, // o
-  false, // p
-  false, // q
-  false, // r
-  false, // s
-  false, // t
-  false, // u
-  false, // v
-  false, // w
-  false, // x
-  false, // y
-  false, // z
-  true, //  {
-  true, //  |
-  true, //  }
-  false, // ~
-  true, //  DEL
-];
+bool _isValidPackageName(String packageName) {
+  const space = 0x20;
+  const del = 0x7F;
+  const dot = 0x2e;
+  const lowerX = 0x78;
+  for (int i = 0; i < packageName.length; ++i) {
+    final int char = packageName.codeUnitAt(i);
+    if (char < space || del < char) {
+      return false;
+    }
+    final int allowed = _invalidPackageNameChars.codeUnitAt(char - space);
+    assert(allowed == dot || allowed == lowerX);
+    if (allowed == lowerX) {
+      return false;
+    }
+  }
+  return true;
+}
 
-_parsePackagesFile(bool traceLoading, Uri packagesFile, List<int> data) {
+_parsePackagesFile(bool traceLoading, Uri packagesFile, String data) {
   // The first entry contains the location of the identified .packages file
   // instead of a mapping.
-  var result = [packagesFile.toString(), null];
-  var index = 0;
-  var len = data.length;
-  while (index < len) {
-    var start = index;
-    var char = data[index];
-    if ((char == _CR) || (char == _LF)) {
-      // Skipping empty lines.
-      index++;
+  final List result = [packagesFile.toString(), null];
+
+  final lines = LineSplitter.split(data);
+  for (String line in lines) {
+    final hashIndex = line.indexOf('#');
+    if (hashIndex == 0) {
+      continue;
+    }
+    if (hashIndex > 0) {
+      line = line.substring(0, hashIndex);
+    }
+    line = line.trimRight();
+    if (line.isEmpty) {
       continue;
     }
 
-    // Identify split within the line and end of the line.
-    var separator = -1;
-    var end = len;
-    // Verifying validity of package name while scanning the line.
-    var nonDot = false;
-    var invalidPackageName = false;
-
-    // Scan to the end of the line or data.
-    while (index < len) {
-      char = data[index++];
-      // If we have not reached the separator yet, determine whether we are
-      // scanning legal package name characters.
-      if (separator == -1) {
-        if ((char == _COLON)) {
-          // The first colon on a line is the separator between package name and
-          // related URI.
-          separator = index - 1;
-        } else {
-          // Still scanning the package name part. Check for the validity of
-          // the characters.
-          nonDot = nonDot || (char != _DOT);
-          invalidPackageName = invalidPackageName ||
-              (char < _SPACE) ||
-              (char > _DEL) ||
-              _invalidPackageNameChars[char - _SPACE];
-        }
-      }
-      // Identify end of line.
-      if ((char == _CR) || (char == _LF)) {
-        end = index - 1;
-        break;
-      }
+    final colonIndex = line.indexOf(':');
+    if (colonIndex <= 0) {
+      return 'Line in "$packagesFile" should be of the format '
+          '`<package-name>:<path>" but was: "$line"';
+    }
+    final packageName = line.substring(0, colonIndex);
+    if (!_isValidPackageName(packageName)) {
+      return 'Package name in $packagesFile contains disallowed characters ('
+          'was: "$packageName")';
     }
 
-    // No further handling needed for comment lines.
-    if (data[start] == _HASH) {
-      if (traceLoading) {
-        _log("Skipping comment in $packagesFile:\n"
-            "${new String.fromCharCodes(data, start, end)}");
-      }
-      continue;
-    }
-
-    // Check for a badly formatted line, starting with a ':'.
-    if (separator == start) {
-      var line = new String.fromCharCodes(data, start, end);
-      if (traceLoading) {
-        _log("Line starts with ':' in $packagesFile:\n"
-            "$line");
-      }
-      return "Missing package name in $packagesFile:\n"
-          "$line";
-    }
-
-    // Ensure there is a separator on the line.
-    if (separator == -1) {
-      var line = new String.fromCharCodes(data, start, end);
-      if (traceLoading) {
-        _log("Line has no ':' in $packagesFile:\n"
-            "$line");
-      }
-      return "Missing ':' separator in $packagesFile:\n"
-          "$line";
-    }
-
-    var packageName = new String.fromCharCodes(data, start, separator);
-
-    // Check for valid package name.
-    if (invalidPackageName || !nonDot) {
-      var line = new String.fromCharCodes(data, start, end);
-      if (traceLoading) {
-        _log("Invalid package name $packageName in $packagesFile");
-      }
-      return "Invalid package name '$packageName' in $packagesFile:\n"
-          "$line";
-    }
-
+    String packageUri = line.substring(colonIndex + 1);
     if (traceLoading) {
       _log("packageName: $packageName");
-    }
-    var packageUri = new String.fromCharCodes(data, separator + 1, end);
-    if (traceLoading) {
-      _log("original packageUri: $packageUri");
+      _log("packageUri: $packageUri");
     }
     // Ensure the package uri ends with a /.
-    if (!packageUri.endsWith("/")) {
-      packageUri = "$packageUri/";
+    if (!packageUri.endsWith('/')) {
+      packageUri += '/';
     }
-    packageUri = packagesFile.resolve(packageUri).toString();
+    final resolvedPackageUri = packagesFile.resolve(packageUri).toString();
     if (traceLoading) {
-      _log("mapping: $packageName -> $packageUri");
+      _log("mapping: $packageName -> $resolvedPackageUri");
     }
     result.add(packageName);
-    result.add(packageUri);
+    result.add(resolvedPackageUri);
   }
-
   if (traceLoading) {
     _log("Parsed packages file at $packagesFile. Sending:\n$result");
   }
   return result;
 }
 
-_loadPackagesFile(bool traceLoading, Uri packagesFile) {
-  try {
-    var data = new File.fromUri(packagesFile).readAsBytesSync();
-    if (traceLoading) {
-      _log("Loaded packages file from $packagesFile:\n"
-          "${new String.fromCharCodes(data)}");
-    }
-    return _parsePackagesFile(traceLoading, packagesFile, data);
-  } catch (e, s) {
-    if (traceLoading) {
-      _log("Error loading packages: $e\n$s");
-    }
-    return "Uncaught error ($e) loading packages file.";
+// The .dart_tool/package_config.json format is described in
+//
+// https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md
+//
+// The returned list has the format:
+//
+//    [0] Location of package_config.json file.
+//    [1] null
+//    [n*2] Name of n-th package
+//    [n*2 + 1] Location of n-th package's sources (as a String)
+//
+List _parsePackageConfig(bool traceLoading, Uri packageConfig, String data) {
+  final Map packageJson = json.decode(data);
+  final version = packageJson['configVersion'];
+  if (version != 2) {
+    throw 'The package configuration file has an unsupported version.';
   }
+  // The first entry contains the location of the identified
+  // .dart_tool/package_config.json file instead of a mapping.
+  final result = <dynamic>[packageConfig.toString(), null];
+  final List packages = packageJson['packages'] ?? [];
+  for (final Map package in packages) {
+    String rootUri = package['rootUri'];
+    if (!rootUri.endsWith('/')) rootUri += '/';
+    final String packageName = package['name'];
+    final String? packageUri = package['packageUri'];
+    final Uri resolvedRootUri = packageConfig.resolve(rootUri);
+    final Uri resolvedPackageUri = packageUri != null
+        ? resolvedRootUri.resolve(packageUri)
+        : resolvedRootUri;
+    if (packageUri != null &&
+        !'$resolvedPackageUri'.contains('$resolvedRootUri')) {
+      throw 'The resolved "packageUri" is not a subdirectory of the "rootUri".';
+    }
+    if (!_isValidPackageName(packageName)) {
+      throw 'Package name in $packageConfig contains disallowed characters ('
+          'was: "$packageName")';
+    }
+    result.add(packageName);
+    result.add(resolvedPackageUri.toString());
+    if (traceLoading) {
+      _log('Resolved package "$packageName" to be at $resolvedPackageUri');
+    }
+  }
+  return result;
 }
 
-_findPackagesFile(bool traceLoading, Uri base) {
+_findPackagesConfiguration(bool traceLoading, Uri base) {
   try {
-    // Walk up the directory hierarchy to check for the existence of
-    // .packages files in parent directories and for the existence of a
-    // packages/ directory on the first iteration.
-    var dir = new File.fromUri(base).parent;
-    var prev = null;
-    // Keep searching until we reach the root.
-    while ((prev == null) || (prev.path != dir.path)) {
-      // Check for the existence of a .packages file and if it exists try to
-      // load and parse it.
-      var dirUri = dir.uri;
-      var packagesFile = dirUri.resolve(".packages");
+    // Walk up the directory hierarchy to check for the existence of either one
+    // of
+    //   - .packages (preferred)
+    //   - .dart_tool/package_config.json
+    var currentDir = new File.fromUri(base).parent;
+    while (true) {
+      final dirUri = currentDir.uri;
+
+      // We prefer using `.packages` over `.dart_tool/package_config.json` so
+      // old users of `Isolate.packageConfig` which cannot handle the new format
+      // will continue to work (see https://github.com/dart-lang/sdk/issues/41748).
+      final packagesFile = dirUri.resolve(".packages");
       if (traceLoading) {
         _log("Checking for $packagesFile file.");
       }
-      var exists = new File.fromUri(packagesFile).existsSync();
+      File file = File.fromUri(packagesFile);
+      bool exists = file.existsSync();
       if (traceLoading) {
         _log("$packagesFile exists: $exists");
       }
       if (exists) {
-        return _loadPackagesFile(traceLoading, packagesFile);
+        final String data = utf8.decode(file.readAsBytesSync());
+        if (traceLoading) {
+          _log("Loaded packages file from $packagesFile:\n$data");
+        }
+        return _parsePackagesFile(traceLoading, packagesFile, data);
       }
-      // Move up one level.
-      prev = dir;
-      dir = dir.parent;
+
+      // We fallback to using `.dart_tool/package_config.json` if it exists.
+      final packageConfig = dirUri.resolve(".dart_tool/package_config.json");
+      if (traceLoading) {
+        _log("Checking for $packageConfig file.");
+      }
+      file = File.fromUri(packageConfig);
+      exists = file.existsSync();
+      if (traceLoading) {
+        _log("$packageConfig exists: $exists");
+      }
+      if (exists) {
+        final data = utf8.decode(file.readAsBytesSync());
+        if (traceLoading) {
+          _log("Loaded package config file from $packageConfig:$data\n");
+        }
+        return _parsePackageConfig(traceLoading, packageConfig, data);
+      }
+
+      final parentDir = currentDir.parent;
+      if (dirUri == parentDir.uri) break;
+      currentDir = parentDir;
     }
 
-    // No .packages file was found.
     if (traceLoading) {
-      _log("Could not resolve a package location from $base");
+      _log("Could not resolve a package configuration from $base");
     }
-    return "Could not resolve a package location for base at $base";
+    return "Could not resolve a package configuration for base at $base";
   } catch (e, s) {
     if (traceLoading) {
       _log("Error loading packages: $e\n$s");
@@ -487,29 +392,62 @@
   }
 }
 
-_loadPackagesData(traceLoading, resource) {
-  try {
-    var data = resource.data;
-    var mime = data.mimeType;
-    if (mime != "text/plain") {
-      throw "MIME-type must be text/plain: $mime given.";
+int _indexOfFirstNonWhitespaceCharacter(String data) {
+  // Whitespace characters ignored in JSON spec:
+  // https://tools.ietf.org/html/rfc7159
+  const tab = 0x09;
+  const lf = 0x0A;
+  const cr = 0x0D;
+  const space = 0x20;
+
+  int index = 0;
+  while (index < data.length) {
+    final int char = data.codeUnitAt(index);
+    if (char != lf && char != cr && char != space && char != tab) {
+      break;
     }
-    var charset = data.charset;
-    if ((charset != "utf-8") && (charset != "US-ASCII")) {
-      // The C++ portion of the embedder assumes UTF-8.
-      throw "Only utf-8 or US-ASCII encodings are supported: $charset given.";
-    }
-    return _parsePackagesFile(traceLoading, resource, data.contentAsBytes());
-  } catch (e) {
-    return "Uncaught error ($e) loading packages data.";
+    index++;
   }
+  return index;
+}
+
+bool _canBeValidJson(String data) {
+  const int openCurly = 0x7B;
+  final int index = _indexOfFirstNonWhitespaceCharacter(data);
+  return index < data.length && data.codeUnitAt(index) == openCurly;
+}
+
+_parsePackageConfiguration(bool traceLoading, Uri resource, Uint8List bytes) {
+  try {
+    final data = utf8.decode(bytes);
+    if (_canBeValidJson(data)) {
+      return _parsePackageConfig(traceLoading, resource, data);
+    } else {
+      return _parsePackagesFile(traceLoading, resource, data);
+    }
+  } catch (e) {
+    return "The resource '$resource' is neither a valid '.packages' file nor "
+        "a valid '.dart_tool/package_config.json' file.";
+  }
+}
+
+bool _isValidUtf8DataUrl(UriData data) {
+  final mime = data.mimeType;
+  if (mime != "text/plain") {
+    return false;
+  }
+  final charset = data.charset;
+  if (charset != "utf-8" && charset != "US-ASCII") {
+    return false;
+  }
+  return true;
 }
 
 _handlePackagesRequest(bool traceLoading, int tag, Uri resource) {
   try {
     if (tag == -1) {
       if (resource.scheme == '' || resource.scheme == 'file') {
-        return _findPackagesFile(traceLoading, resource);
+        return _findPackagesConfiguration(traceLoading, resource);
       } else {
         return "Unsupported scheme used to locate .packages file:'$resource'.";
       }
@@ -517,19 +455,25 @@
       if (traceLoading) {
         _log("Handling load of packages map: '$resource'.");
       }
+      late Uint8List bytes;
       if (resource.scheme == '' || resource.scheme == 'file') {
-        var exists = new File.fromUri(resource).existsSync();
-        if (exists) {
-          return _loadPackagesFile(traceLoading, resource);
-        } else {
-          return "Packages file '$resource' not found.";
+        final file = File.fromUri(resource);
+        if (!file.existsSync()) {
+          return "Packages file '$resource' does not exit.";
         }
+        bytes = file.readAsBytesSync();
       } else if (resource.scheme == 'data') {
-        return _loadPackagesData(traceLoading, resource);
+        final uriData = resource.data!;
+        if (!_isValidUtf8DataUrl(uriData)) {
+          return "The data resource '$resource' must have a 'text/plain' mime "
+              "type and a 'utf-8' or 'US-ASCII' charset.";
+        }
+        bytes = uriData.contentAsBytes();
       } else {
         return "Unknown scheme (${resource.scheme}) for package file at "
             "'$resource'.";
       }
+      return _parsePackageConfiguration(traceLoading, resource, bytes);
     } else {
       return "Unknown packages request tag: $tag for '$resource'.";
     }
@@ -580,6 +524,9 @@
 }
 
 // Embedder Entrypoint:
+// The embedder calls this method with the value of the --packages command line
+// option. It can point to a ".packages" or a ".dart_tool/package_config.json"
+// file.
 @pragma("vm:entry-point")
 String _setPackagesMap(String packagesParam) {
   if (!_setupCompleted) {
@@ -671,7 +618,7 @@
     resolvedUri = _resolvePackageUri(packageUri);
   } catch (e, s) {
     if (_traceLoading) {
-      _log("Exception when resolving package URI: $packageUri");
+      _log("Exception when resolving package URI: $packageUri:\n$e\n$s");
     }
     resolvedUri = null;
   }
diff --git a/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart
index 374221c..e4302cc 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart
@@ -1498,269 +1498,19 @@
   }
 }
 
-class _Utf8StringBuffer {
-  static const int INITIAL_CAPACITY = 32;
-  // Partial state encoding.
-  static const int MASK_TWO_BIT = 0x03;
-  static const int MASK_SIZE = MASK_TWO_BIT;
-  static const int SHIFT_MISSING = 2;
-  static const int SHIFT_VALUE = 4;
-  static const int NO_PARTIAL = 0;
-
-  // UTF-8 encoding and limits.
-  static const int MAX_ASCII = 127;
-  static const int MAX_TWO_BYTE = 0x7ff;
-  static const int MAX_THREE_BYTE = 0xffff;
-  static const int MAX_UNICODE = 0X10ffff;
-  static const int MASK_TWO_BYTE = 0x1f;
-  static const int MASK_THREE_BYTE = 0x0f;
-  static const int MASK_FOUR_BYTE = 0x07;
-  static const int MASK_CONTINUE_TAG = 0xC0;
-  static const int MASK_CONTINUE_VALUE = 0x3f;
-  static const int CONTINUE_TAG = 0x80;
-
-  // UTF-16 surrogate encoding.
-  static const int LEAD_SURROGATE = 0xD800;
-  static const int TAIL_SURROGATE = 0xDC00;
-  static const int SHIFT_HIGH_SURROGATE = 10;
-  static const int MASK_LOW_SURROGATE = 0x3ff;
-
-  // The internal buffer starts as Uint8List, but may change to Uint16List
-  // if the string contains non-Latin-1 characters.
-  List<int> buffer = new Uint8List(INITIAL_CAPACITY);
-  // Number of elements in buffer.
-  int length = 0;
-  // Partial decoding state, for cases where an UTF-8 sequences is split
-  // between chunks.
-  int partialState = NO_PARTIAL;
-  // Whether all characters so far have been Latin-1 (and the buffer is
-  // still a Uint8List). Set to false when the first non-Latin-1 character
-  // is encountered, and the buffer is then also converted to a Uint16List.
-  bool isLatin1 = true;
-  // If allowing malformed, invalid UTF-8 sequences are converted to
-  // U+FFFD.
-  bool allowMalformed;
-
-  _Utf8StringBuffer(this.allowMalformed);
-
-  /**
-   * Parse the continuation of a multi-byte UTF-8 sequence.
-   *
-   * Parse [utf8] from [position] to [end]. If the sequence extends beyond
-   * `end`, store the partial state in [partialState], and continue from there
-   * on the next added slice.
-   *
-   * The [size] is the number of expected continuation bytes total,
-   * and [missing] is the number of remaining continuation bytes.
-   * The [size] is used to detect overlong encodings.
-   * The [value] is the value collected so far.
-   *
-   * When called after seeing the first multi-byte marker, the [size] and
-   * [missing] values are always the same, but they may differ if continuing
-   * after a partial sequence.
-   */
-  int addContinuation(
-      List<int> utf8, int position, int end, int size, int missing, int value) {
-    int codeEnd = position + missing;
-    do {
-      if (position == end) {
-        missing = codeEnd - position;
-        partialState =
-            size | (missing << SHIFT_MISSING) | (value << SHIFT_VALUE);
-        return end;
-      }
-      int char = utf8[position];
-      if ((char & MASK_CONTINUE_TAG) != CONTINUE_TAG) {
-        if (allowMalformed) {
-          addCharCode(0xFFFD);
-          return position;
-        }
-        throw new FormatException(
-            "Expected UTF-8 continuation byte, "
-            "found $char",
-            utf8,
-            position);
-      }
-      value = 64 * value + (char & MASK_CONTINUE_VALUE);
-      position++;
-    } while (position < codeEnd);
-    if (value <= const [0, MAX_ASCII, MAX_TWO_BYTE, MAX_THREE_BYTE][size]) {
-      // Over-long encoding.
-      if (allowMalformed) {
-        value = 0xFFFD;
-      } else {
-        throw new FormatException(
-            "Invalid encoding: U+${value.toRadixString(16).padLeft(4, '0')}"
-            " encoded in ${size + 1} bytes.",
-            utf8,
-            position - 1);
-      }
-    }
-    addCharCode(value);
-    return position;
-  }
-
-  void addCharCode(int char) {
-    assert(char >= 0);
-    assert(char <= MAX_UNICODE);
-    if (partialState != NO_PARTIAL) {
-      if (allowMalformed) {
-        partialState = NO_PARTIAL;
-        addCharCode(0xFFFD);
-      } else {
-        throw new FormatException("Incomplete UTF-8 sequence");
-      }
-    }
-    if (isLatin1 && char > 0xff) {
-      _to16Bit(); // Also grows a little if close to full.
-    }
-    int length = this.length;
-    if (char <= MAX_THREE_BYTE) {
-      if (length == buffer.length) _grow();
-      buffer[length] = char;
-      this.length = length + 1;
-      return;
-    }
-    if (length + 2 > buffer.length) _grow();
-    int bits = char - 0x10000;
-    buffer[length] = LEAD_SURROGATE | (bits >> SHIFT_HIGH_SURROGATE);
-    buffer[length + 1] = TAIL_SURROGATE | (bits & MASK_LOW_SURROGATE);
-    this.length = length + 2;
-  }
-
-  void _to16Bit() {
-    assert(isLatin1);
-    Uint16List newBuffer;
-    if ((length + INITIAL_CAPACITY) * 2 <= buffer.length) {
-      // Reuse existing buffer if it's big enough.
-      newBuffer = new Uint16List.view((buffer as Uint8List).buffer);
-    } else {
-      int newCapacity = buffer.length;
-      if (newCapacity - length < INITIAL_CAPACITY) {
-        newCapacity = length + INITIAL_CAPACITY;
-      }
-      newBuffer = new Uint16List(newCapacity);
-    }
-    newBuffer.setRange(0, length, buffer);
-    buffer = newBuffer;
-    isLatin1 = false;
-  }
-
-  void _grow() {
-    int newCapacity = buffer.length * 2;
-    List<int> newBuffer;
-    if (isLatin1) {
-      newBuffer = new Uint8List(newCapacity);
-    } else {
-      newBuffer = new Uint16List(newCapacity);
-    }
-    newBuffer.setRange(0, length, buffer);
-    buffer = newBuffer;
-  }
-
-  void addSlice(List<int> utf8, int position, int end) {
-    assert(position < end);
-    if (partialState > 0) {
-      int continueByteCount = (partialState & MASK_TWO_BIT);
-      int missing = (partialState >> SHIFT_MISSING) & MASK_TWO_BIT;
-      int value = partialState >> SHIFT_VALUE;
-      partialState = NO_PARTIAL;
-      position = addContinuation(
-          utf8, position, end, continueByteCount, missing, value);
-      if (position == end) return;
-    }
-    // Keep index and capacity in local variables while looping over
-    // ASCII characters.
-    int index = length;
-    int capacity = buffer.length;
-    while (position < end) {
-      int char = utf8[position];
-      if (char <= MAX_ASCII) {
-        if (index == capacity) {
-          length = index;
-          _grow();
-          capacity = buffer.length;
-        }
-        buffer[index++] = char;
-        position++;
-        continue;
-      }
-      length = index;
-      if ((char & MASK_CONTINUE_TAG) == CONTINUE_TAG) {
-        if (allowMalformed) {
-          addCharCode(0xFFFD);
-          position++;
-        } else {
-          throw new FormatException(
-              "Unexpected UTF-8 continuation byte", utf8, position);
-        }
-      } else if (char < 0xE0) {
-        // C0-DF
-        // Two-byte.
-        position = addContinuation(
-            utf8, position + 1, end, 1, 1, char & MASK_TWO_BYTE);
-      } else if (char < 0xF0) {
-        // E0-EF
-        // Three-byte.
-        position = addContinuation(
-            utf8, position + 1, end, 2, 2, char & MASK_THREE_BYTE);
-      } else if (char < 0xF8) {
-        // F0-F7
-        // Four-byte.
-        position = addContinuation(
-            utf8, position + 1, end, 3, 3, char & MASK_FOUR_BYTE);
-      } else {
-        if (allowMalformed) {
-          addCharCode(0xFFFD);
-          position++;
-        } else {
-          throw new FormatException(
-              "Invalid UTF-8 byte: $char", utf8, position);
-        }
-      }
-      index = length;
-      capacity = buffer.length;
-    }
-    length = index;
-  }
-
-  String toString() {
-    if (partialState != NO_PARTIAL) {
-      if (allowMalformed) {
-        partialState = NO_PARTIAL;
-        addCharCode(0xFFFD);
-      } else {
-        int continueByteCount = (partialState & MASK_TWO_BIT);
-        int missing = (partialState >> SHIFT_MISSING) & MASK_TWO_BIT;
-        int value = partialState >> SHIFT_VALUE;
-        int seenByteCount = continueByteCount - missing + 1;
-        List source = new Uint8List(seenByteCount);
-        while (seenByteCount > 1) {
-          seenByteCount--;
-          source[seenByteCount] = CONTINUE_TAG | (value & MASK_CONTINUE_VALUE);
-          value >>= 6;
-        }
-        source[0] = value | (0x3c0 >> (continueByteCount - 1));
-        throw new FormatException(
-            "Incomplete UTF-8 sequence", source, source.length);
-      }
-    }
-    return new String.fromCharCodes(buffer, 0, length);
-  }
-}
-
 /**
  * Chunked JSON parser that parses UTF-8 chunks.
  */
 class _JsonUtf8Parser extends _ChunkedJsonParser<List<int>> {
   static final Uint8List emptyChunk = Uint8List(0);
 
-  final bool allowMalformed;
+  final _Utf8Decoder decoder;
   List<int> chunk = emptyChunk;
   int chunkEnd = 0;
 
-  _JsonUtf8Parser(_JsonListener listener, this.allowMalformed)
-      : super(listener) {
+  _JsonUtf8Parser(_JsonListener listener, bool allowMalformed)
+      : decoder = new _Utf8Decoder(allowMalformed),
+        super(listener) {
     // Starts out checking for an optional BOM (KWD_BOM, count = 0).
     partialState =
         _ChunkedJsonParser.PARTIAL_KEYWORD | _ChunkedJsonParser.KWD_BOM;
@@ -1780,21 +1530,24 @@
   }
 
   void beginString() {
-    this.buffer = new _Utf8StringBuffer(allowMalformed);
+    decoder.reset();
+    this.buffer = new StringBuffer();
   }
 
   void addSliceToString(int start, int end) {
-    _Utf8StringBuffer buffer = this.buffer;
-    buffer.addSlice(chunk, start, end);
+    final StringBuffer buffer = this.buffer;
+    buffer.write(decoder.convertChunked(chunk, start, end));
   }
 
   void addCharToString(int charCode) {
-    _Utf8StringBuffer buffer = this.buffer;
-    buffer.addCharCode(charCode);
+    final StringBuffer buffer = this.buffer;
+    decoder.flush(buffer);
+    buffer.writeCharCode(charCode);
   }
 
   String endString() {
-    _Utf8StringBuffer buffer = this.buffer;
+    final StringBuffer buffer = this.buffer;
+    decoder.flush(buffer);
     this.buffer = null;
     return buffer.toString();
   }
@@ -1859,24 +1612,424 @@
 }
 
 @patch
-int _scanOneByteCharacters(List<int> units, int from, int endIndex) {
-  final to = endIndex;
+class _Utf8Decoder {
+  /// Flags indicating presence of the various kinds of bytes in the input.
+  int _scanFlags = 0;
 
-  // Special case for _Uint8ArrayView.
-  if (units is Uint8List) {
-    if (from >= 0 && to >= 0 && to <= units.length) {
-      for (int i = from; i < to; i++) {
-        final unit = units[i];
-        if ((unit & _ONE_BYTE_LIMIT) != unit) return i - from;
-      }
-      return to - from;
+  /// How many bytes of the BOM have been read so far. Set to -1 when the BOM
+  /// has been skipped (or was not present).
+  int _bomIndex = 0;
+
+  // Table for the scanning phase, which quickly scans through the input.
+  //
+  // Each input byte is looked up in the table, providing a size and some flags.
+  // The sizes are summed, and the flags are or'ed together.
+  //
+  // The resulting size and flags indicate:
+  // A) How many UTF-16 code units will be emitted by the decoding of this
+  //    input. This can be used to allocate a string of the correct length up
+  //    front.
+  // B) Which decoder and resulting string representation is appropriate. There
+  //    are three cases:
+  //    1) Pure ASCII (flags == 0): The input can simply be put into a
+  //       OneByteString without further decoding.
+  //    2) Latin1 (flags == (flagLatin1 | flagExtension)): The result can be
+  //       represented by a OneByteString, and the decoder can assume that only
+  //       Latin1 characters are present.
+  //    3) Arbitrary input (otherwise): Needs a full-featured decoder. Output
+  //       can be represented by a TwoByteString.
+
+  static const int sizeMask = 0x03;
+  static const int flagsMask = 0x3C;
+
+  static const int flagExtension = 1 << 2;
+  static const int flagLatin1 = 1 << 3;
+  static const int flagNonLatin1 = 1 << 4;
+  static const int flagIllegal = 1 << 5;
+
+  // ASCII     'A' = 64 + (1);
+  // Extension 'D' = 64 + (0 | flagExtension);
+  // Latin1    'I' = 64 + (1 | flagLatin1);
+  // BMP       'Q' = 64 + (1 | flagNonLatin1);
+  // Non-BMP   'R' = 64 + (2 | flagNonLatin1);
+  // Illegal   'a' = 64 + (1 | flagIllegal);
+  // Illegal   'b' = 64 + (2 | flagIllegal);
+  static const String scanTable = ""
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 00-1F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 20-3F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 40-5F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 60-7F
+      "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" // 80-9F
+      "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" // A0-BF
+      "aaIIQQQQQQQQQQQQQQQQQQQQQQQQQQQQ" // C0-DF
+      "QQQQQQQQQQQQQQQQRRRRRbbbbbbbbbbb" // E0-FF
+      ;
+
+  /// Reset the decoder to a state where it is ready to decode a new string but
+  /// will not skip a leading BOM. Used by the fused UTF-8 / JSON decoder.
+  void reset() {
+    _state = initial;
+    _bomIndex = -1;
+  }
+
+  // The VM decoder handles BOM explicitly instead of via the state machine.
+  @patch
+  _Utf8Decoder(this.allowMalformed) : _state = initial;
+
+  @patch
+  String convertSingle(List<int> codeUnits, int start, int? maybeEnd) {
+    int end = RangeError.checkValidRange(start, maybeEnd, codeUnits.length);
+
+    // Have bytes as Uint8List.
+    Uint8List bytes;
+    int errorOffset;
+    if (codeUnits is Uint8List) {
+      bytes = codeUnits;
+      errorOffset = 0;
+    } else {
+      bytes = _makeUint8List(codeUnits, start, end);
+      errorOffset = start;
+      end -= start;
+      start = 0;
     }
+
+    // Skip initial BOM.
+    start = skipBomSingle(bytes, start, end);
+
+    // Special case empty input.
+    if (start == end) return "";
+
+    // Scan input to determine size and appropriate decoder.
+    int size = scan(bytes, start, end);
+    int flags = _scanFlags;
+
+    if (flags == 0) {
+      // Pure ASCII.
+      assert(size == end - start);
+      // TODO(dartbug.com/41703): String.fromCharCodes has a lot of overhead
+      // checking types and ranges, which is redundant in this case. Find a
+      // more direct way to do the conversion.
+      return String.fromCharCodes(bytes, start, end);
+    }
+
+    String result;
+    if (flags == (flagLatin1 | flagExtension)) {
+      // Latin1.
+      result = decode8(bytes, start, end, size);
+    } else {
+      // Arbitrary Unicode.
+      result = decode16(bytes, start, end, size);
+    }
+    if (_state == accept) {
+      return result;
+    }
+
+    if (!allowMalformed) {
+      if (!isErrorState(_state)) {
+        // Unfinished sequence.
+        _state = errorUnfinished;
+        _charOrIndex = end;
+      }
+      final String message = errorDescription(_state);
+      throw FormatException(message, codeUnits, errorOffset + _charOrIndex);
+    }
+
+    // Start over on slow path.
+    _state = initial;
+    result = decodeGeneral(bytes, start, end, true);
+    assert(!isErrorState(_state));
+    return result;
   }
 
-  // Fall through to normal case.
-  for (var i = from; i < to; i++) {
-    final unit = units[i];
-    if ((unit & _ONE_BYTE_LIMIT) != unit) return i - from;
+  @patch
+  String convertChunked(List<int> codeUnits, int start, int? maybeEnd) {
+    int end = RangeError.checkValidRange(start, maybeEnd, codeUnits.length);
+
+    // Have bytes as Uint8List.
+    Uint8List bytes;
+    int errorOffset;
+    if (codeUnits is Uint8List) {
+      bytes = codeUnits;
+      errorOffset = 0;
+    } else {
+      bytes = _makeUint8List(codeUnits, start, end);
+      errorOffset = start;
+      end -= start;
+      start = 0;
+    }
+
+    // Skip initial BOM.
+    start = skipBomChunked(bytes, start, end);
+
+    // Special case empty input.
+    if (start == end) return "";
+
+    // Scan input to determine size and appropriate decoder.
+    int size = scan(bytes, start, end);
+    int flags = _scanFlags;
+
+    // Adjust scan flags and size based on carry-over state.
+    switch (_state) {
+      case IA:
+        break;
+      case X1:
+        flags |= _charOrIndex < (0x100 >> 6) ? flagLatin1 : flagNonLatin1;
+        if (end - start >= 1) {
+          size += _charOrIndex < (0x10000 >> 6) ? 1 : 2;
+        }
+        break;
+      case X2:
+        flags |= flagNonLatin1;
+        if (end - start >= 2) {
+          size += _charOrIndex < (0x10000 >> 12) ? 1 : 2;
+        }
+        break;
+      case TO:
+      case TS:
+        flags |= flagNonLatin1;
+        if (end - start >= 2) size += 1;
+        break;
+      case X3:
+      case QO:
+      case QR:
+        flags |= flagNonLatin1;
+        if (end - start >= 3) size += 2;
+        break;
+    }
+
+    if (flags == 0) {
+      // Pure ASCII.
+      assert(_state == accept);
+      assert(size == end - start);
+      // TODO(dartbug.com/41703): String.fromCharCodes has a lot of overhead
+      // checking types and ranges, which is redundant in this case. Find a
+      // more direct way to do the conversion.
+      return String.fromCharCodes(bytes, start, end);
+    }
+
+    // Do not include any final, incomplete character in size.
+    int extensionCount = 0;
+    int i = end - 1;
+    while (i >= start && (bytes[i] & 0xC0) == 0x80) {
+      extensionCount++;
+      i--;
+    }
+    if (i >= start && bytes[i] >= ((~0x3F >> extensionCount) & 0xFF)) {
+      size -= bytes[i] >= 0xF0 ? 2 : 1;
+    }
+
+    final int carryOverState = _state;
+    final int carryOverChar = _charOrIndex;
+    String result;
+    if (flags == (flagLatin1 | flagExtension)) {
+      // Latin1.
+      result = decode8(bytes, start, end, size);
+    } else {
+      // Arbitrary Unicode.
+      result = decode16(bytes, start, end, size);
+    }
+    if (!isErrorState(_state)) {
+      return result;
+    }
+    assert(_bomIndex == -1);
+
+    if (!allowMalformed) {
+      final String message = errorDescription(_state);
+      _state = initial; // Ready for more input.
+      throw FormatException(message, codeUnits, errorOffset + _charOrIndex);
+    }
+
+    // Start over on slow path.
+    _state = carryOverState;
+    _charOrIndex = carryOverChar;
+    result = decodeGeneral(bytes, start, end, false);
+    assert(!isErrorState(_state));
+    return result;
   }
-  return to - from;
+
+  @pragma("vm:prefer-inline")
+  int skipBomSingle(Uint8List bytes, int start, int end) {
+    if (end - start >= 3 &&
+        bytes[start] == 0xEF &&
+        bytes[start + 1] == 0xBB &&
+        bytes[start + 2] == 0xBF) {
+      return start + 3;
+    }
+    return start;
+  }
+
+  @pragma("vm:prefer-inline")
+  int skipBomChunked(Uint8List bytes, int start, int end) {
+    assert(start <= end);
+    int bomIndex = _bomIndex;
+    // Already skipped?
+    if (bomIndex == -1) return start;
+
+    const bomValues = <int>[0xEF, 0xBB, 0xBF];
+    int i = start;
+    while (bomIndex < 3) {
+      if (i == end) {
+        // Unfinished BOM.
+        _bomIndex = bomIndex;
+        return start;
+      }
+      if (bytes[i++] != bomValues[bomIndex++]) {
+        // No BOM.
+        _bomIndex = -1;
+        return start;
+      }
+    }
+    // Complete BOM.
+    _bomIndex = -1;
+    _state = initial;
+    return i;
+  }
+
+  // Scanning functions to compute the size of the resulting string and flags
+  // (written to _scanFlags) indicating which decoder to use.
+  // TODO(dartbug.com/41702): Intrinsify this function.
+  int scan(Uint8List bytes, int start, int end) {
+    _scanFlags = 0;
+    for (int i = start; i < end; i++) {
+      if (bytes[i] > 127) return i - start + scan2(bytes, i, end);
+    }
+    return end - start;
+  }
+
+  int scan2(Uint8List bytes, int start, int end) {
+    final String scanTable = _Utf8Decoder.scanTable;
+    int size = 0;
+    int flags = 0;
+    for (int i = start; i < end; i++) {
+      int t = scanTable.codeUnitAt(bytes[i]);
+      size += t & sizeMask;
+      flags |= t;
+    }
+    _scanFlags = flags & flagsMask;
+    return size;
+  }
+
+  String decode8(Uint8List bytes, int start, int end, int size) {
+    assert(start < end);
+    // TODO(dartbug.com/41704): Allocate an uninitialized _OneByteString and
+    // write characters to it using _setAt.
+    Uint8List chars = Uint8List(size);
+    int i = start;
+    int j = 0;
+    if (_state == X1) {
+      // Half-way though 2-byte sequence
+      assert(_charOrIndex == 2 || _charOrIndex == 3);
+      final int e = bytes[i++] ^ 0x80;
+      if (e >= 0x40) {
+        _state = errorMissingExtension;
+        _charOrIndex = i - 1;
+        return "";
+      }
+      chars[j++] = (_charOrIndex << 6) | e;
+      _state = accept;
+    }
+    assert(_state == accept);
+    while (i < end) {
+      int byte = bytes[i++];
+      if (byte >= 0x80) {
+        if (byte < 0xC0) {
+          _state = errorUnexpectedExtension;
+          _charOrIndex = i - 1;
+          return "";
+        }
+        assert(byte == 0xC2 || byte == 0xC3);
+        if (i == end) {
+          _state = X1;
+          _charOrIndex = byte & 0x1F;
+          break;
+        }
+        final int e = bytes[i++] ^ 0x80;
+        if (e >= 0x40) {
+          _state = errorMissingExtension;
+          _charOrIndex = i - 1;
+          return "";
+        }
+        byte = (byte << 6) | e;
+      }
+      chars[j++] = byte;
+    }
+    // Output size must match, unless we are doing single conversion and are
+    // inside an unfinished sequence (which will trigger an error later).
+    assert(_bomIndex == 0 && _state != accept
+        ? (j == size - 1 || j == size - 2)
+        : (j == size));
+    return String.fromCharCodes(chars);
+  }
+
+  String decode16(Uint8List bytes, int start, int end, int size) {
+    assert(start < end);
+    final String typeTable = _Utf8Decoder.typeTable;
+    final String transitionTable = _Utf8Decoder.transitionTable;
+    // TODO(dartbug.com/41704): Allocate an uninitialized _TwoByteString and
+    // write characters to it using _setAt.
+    Uint16List chars = Uint16List(size);
+    int i = start;
+    int j = 0;
+    int state = _state;
+    int char;
+
+    // First byte
+    assert(!isErrorState(state));
+    final int byte = bytes[i++];
+    final int type = typeTable.codeUnitAt(byte) & typeMask;
+    if (state == accept) {
+      char = byte & (shiftedByteMask >> type);
+      state = transitionTable.codeUnitAt(type);
+    } else {
+      char = (byte & 0x3F) | (_charOrIndex << 6);
+      state = transitionTable.codeUnitAt(state + type);
+    }
+
+    while (i < end) {
+      final int byte = bytes[i++];
+      final int type = typeTable.codeUnitAt(byte) & typeMask;
+      if (state == accept) {
+        if (char >= 0x10000) {
+          assert(char < 0x110000);
+          chars[j++] = 0xD7C0 + (char >> 10);
+          chars[j++] = 0xDC00 + (char & 0x3FF);
+        } else {
+          chars[j++] = char;
+        }
+        char = byte & (shiftedByteMask >> type);
+        state = transitionTable.codeUnitAt(type);
+      } else if (isErrorState(state)) {
+        _state = state;
+        _charOrIndex = i - 2;
+        return "";
+      } else {
+        char = (byte & 0x3F) | (char << 6);
+        state = transitionTable.codeUnitAt(state + type);
+      }
+    }
+
+    // Final write?
+    if (state == accept) {
+      if (char >= 0x10000) {
+        assert(char < 0x110000);
+        chars[j++] = 0xD7C0 + (char >> 10);
+        chars[j++] = 0xDC00 + (char & 0x3FF);
+      } else {
+        chars[j++] = char;
+      }
+    } else if (isErrorState(state)) {
+      _state = state;
+      _charOrIndex = end - 1;
+      return "";
+    }
+
+    _state = state;
+    _charOrIndex = char;
+    // Output size must match, unless we are doing single conversion and are
+    // inside an unfinished sequence (which will trigger an error later).
+    assert(_bomIndex == 0 && _state != accept
+        ? (j == size - 1 || j == size - 2)
+        : (j == size));
+    return String.fromCharCodes(chars);
+  }
 }
diff --git a/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
index b484a2c..2faf799 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
@@ -52,7 +52,6 @@
   // Implementation of package root/map provision.
   static var packageRootString;
   static var packageConfigString;
-  static var packageRootUriFuture;
   static var packageConfigUriFuture;
   static var resolvePackageUriFuture;
 
diff --git a/sdk_nnbd/lib/_internal/vm/lib/isolate_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/isolate_patch.dart
index dca8156..1f97131 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/isolate_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/isolate_patch.dart
@@ -272,7 +272,7 @@
       // current isolate's control port and capabilities.
       //
       // TODO(floitsch): Send an error message if we can't find the entry point.
-      var readyMessage = new List<Object?>.filled(2, null);
+      final readyMessage = List<Object?>.filled(2, null);
       readyMessage[0] = controlPort.sendPort;
       readyMessage[1] = capabilities;
 
@@ -342,7 +342,6 @@
   }
 
   static bool _packageSupported() =>
-      (VMLibraryHooks.packageRootUriFuture != null) &&
       (VMLibraryHooks.packageConfigUriFuture != null) &&
       (VMLibraryHooks.resolvePackageUriFuture != null);
 
@@ -376,18 +375,8 @@
 
     final RawReceivePort readyPort = new RawReceivePort();
     try {
-      _spawnFunction(
-          readyPort.sendPort,
-          script.toString(),
-          entryPoint,
-          message,
-          paused,
-          errorsAreFatal,
-          onExit,
-          onError,
-          null,
-          packageConfig,
-          debugName);
+      _spawnFunction(readyPort.sendPort, script.toString(), entryPoint, message,
+          paused, errorsAreFatal, onExit, onError, packageConfig, debugName);
       return await _spawnCommon(readyPort);
     } catch (e, st) {
       readyPort.close();
@@ -430,24 +419,17 @@
       }
     }
     // Resolve the uri against the current isolate's root Uri first.
-    var spawnedUri = _rootUri!.resolveUri(uri);
+    final Uri spawnedUri = _rootUri!.resolveUri(uri);
 
     // Inherit this isolate's package resolution setup if not overridden.
-    if (!automaticPackageResolution &&
-        (packageRoot == null) &&
-        (packageConfig == null)) {
+    if (!automaticPackageResolution && packageConfig == null) {
       if (Isolate._packageSupported()) {
-        packageRoot = await Isolate.packageRoot;
         packageConfig = await Isolate.packageConfig;
       }
     }
 
     // Ensure to resolve package: URIs being handed in as parameters.
-    if (packageRoot != null) {
-      // `packages/` directory is no longer supported. Force it null.
-      // TODO(mfairhurst) Should this throw an exception?
-      packageRoot = null;
-    } else if (packageConfig != null) {
+    if (packageConfig != null) {
       // Avoid calling resolvePackageUri if not strictly necessary in case
       // the API is not supported.
       if (packageConfig.isScheme("package")) {
@@ -456,8 +438,7 @@
     }
 
     // The VM will invoke [_startIsolate] and not `main`.
-    var packageRootString = packageRoot?.toString();
-    var packageConfigString = packageConfig?.toString();
+    final packageConfigString = packageConfig?.toString();
 
     final RawReceivePort readyPort = new RawReceivePort();
     try {
@@ -473,7 +454,6 @@
           checked,
           null,
           /* environment */
-          packageRootString,
           packageConfigString,
           debugName);
       return await _spawnCommon(readyPort);
@@ -529,7 +509,6 @@
       bool errorsAreFatal,
       SendPort? onExit,
       SendPort? onError,
-      String? packageRoot,
       String? packageConfig,
       String? debugName) native "Isolate_spawnFunction";
 
@@ -544,7 +523,6 @@
       bool errorsAreFatal,
       bool? checked,
       List? environment,
-      String? packageRoot,
       String? packageConfig,
       String? debugName) native "Isolate_spawnUri";
 
diff --git a/sdk_nnbd/lib/convert/json.dart b/sdk_nnbd/lib/convert/json.dart
index e932223..6d897a0 100644
--- a/sdk_nnbd/lib/convert/json.dart
+++ b/sdk_nnbd/lib/convert/json.dart
@@ -535,11 +535,16 @@
   static const int char_0 = 0x30;
   static const int backslash = 0x5c;
   static const int char_b = 0x62;
+  static const int char_d = 0x64;
   static const int char_f = 0x66;
   static const int char_n = 0x6e;
   static const int char_r = 0x72;
   static const int char_t = 0x74;
   static const int char_u = 0x75;
+  static const int surrogateMin = 0xd800;
+  static const int surrogateMask = 0xfc00;
+  static const int surrogateLead = 0xd800;
+  static const int surrogateTrail = 0xdc00;
 
   /// List of objects currently being traversed. Used to detect cycles.
   final List _seen = [];
@@ -573,7 +578,30 @@
     final length = s.length;
     for (var i = 0; i < length; i++) {
       var charCode = s.codeUnitAt(i);
-      if (charCode > backslash) continue;
+      if (charCode > backslash) {
+        if (charCode >= surrogateMin) {
+          // Possible surrogate. Check if it is unpaired.
+          if (((charCode & surrogateMask) == surrogateLead &&
+                  !(i + 1 < length &&
+                      (s.codeUnitAt(i + 1) & surrogateMask) ==
+                          surrogateTrail)) ||
+              ((charCode & surrogateMask) == surrogateTrail &&
+                  !(i - 1 >= 0 &&
+                      (s.codeUnitAt(i - 1) & surrogateMask) ==
+                          surrogateLead))) {
+            // Lone surrogate.
+            if (i > offset) writeStringSlice(s, offset, i);
+            offset = i + 1;
+            writeCharCode(backslash);
+            writeCharCode(char_u);
+            writeCharCode(char_d);
+            writeCharCode(hexDigit((charCode >> 8) & 0xf));
+            writeCharCode(hexDigit((charCode >> 4) & 0xf));
+            writeCharCode(hexDigit(charCode & 0xf));
+          }
+        }
+        continue;
+      }
       if (charCode < 32) {
         if (i > offset) writeStringSlice(s, offset, i);
         offset = i + 1;
@@ -961,16 +989,22 @@
       if (char <= 0x7f) {
         writeByte(char);
       } else {
-        if ((char & 0xFC00) == 0xD800 && i + 1 < end) {
-          // Lead surrogate.
-          var nextChar = string.codeUnitAt(i + 1);
-          if ((nextChar & 0xFC00) == 0xDC00) {
-            // Tail surrogate.
-            char = 0x10000 + ((char & 0x3ff) << 10) + (nextChar & 0x3ff);
-            writeFourByteCharCode(char);
-            i++;
-            continue;
+        if ((char & 0xF800) == 0xD800) {
+          // Surrogate.
+          if (char < 0xDC00 && i + 1 < end) {
+            // Lead surrogate.
+            var nextChar = string.codeUnitAt(i + 1);
+            if ((nextChar & 0xFC00) == 0xDC00) {
+              // Tail surrogate.
+              char = 0x10000 + ((char & 0x3ff) << 10) + (nextChar & 0x3ff);
+              writeFourByteCharCode(char);
+              i++;
+              continue;
+            }
           }
+          // Unpaired surrogate.
+          writeMultiByteCharCode(unicodeReplacementCharacterRune);
+          continue;
         }
         writeMultiByteCharCode(char);
       }
diff --git a/sdk_nnbd/lib/convert/string_conversion.dart b/sdk_nnbd/lib/convert/string_conversion.dart
index 1d5f038..2315330 100644
--- a/sdk_nnbd/lib/convert/string_conversion.dart
+++ b/sdk_nnbd/lib/convert/string_conversion.dart
@@ -258,12 +258,13 @@
 class _Utf8StringSinkAdapter extends ByteConversionSink {
   final _Utf8Decoder _decoder;
   final Sink<Object?> _sink;
+  final StringSink _stringSink;
 
-  _Utf8StringSinkAdapter(this._sink, StringSink stringSink, bool allowMalformed)
-      : _decoder = _Utf8Decoder(stringSink, allowMalformed);
+  _Utf8StringSinkAdapter(this._sink, this._stringSink, bool allowMalformed)
+      : _decoder = _Utf8Decoder(allowMalformed);
 
   void close() {
-    _decoder.close();
+    _decoder.flush(_stringSink);
     _sink.close();
   }
 
@@ -273,7 +274,7 @@
 
   void addSlice(
       List<int> codeUnits, int startIndex, int endIndex, bool isLast) {
-    _decoder.convert(codeUnits, startIndex, endIndex);
+    _stringSink.write(_decoder.convertChunked(codeUnits, startIndex, endIndex));
     if (isLast) close();
   }
 }
@@ -291,11 +292,11 @@
 
   _Utf8ConversionSink._(
       this._chunkedSink, StringBuffer stringBuffer, bool allowMalformed)
-      : _decoder = _Utf8Decoder(stringBuffer, allowMalformed),
+      : _decoder = _Utf8Decoder(allowMalformed),
         _buffer = stringBuffer;
 
   void close() {
-    _decoder.close();
+    _decoder.flush(_buffer);
     if (_buffer.isNotEmpty) {
       var accumulated = _buffer.toString();
       _buffer.clear();
@@ -310,7 +311,7 @@
   }
 
   void addSlice(List<int> chunk, int startIndex, int endIndex, bool isLast) {
-    _decoder.convert(chunk, startIndex, endIndex);
+    _buffer.write(_decoder.convertChunked(chunk, startIndex, endIndex));
     if (_buffer.isNotEmpty) {
       var accumulated = _buffer.toString();
       _chunkedSink.addSlice(accumulated, 0, accumulated.length, isLast);
diff --git a/sdk_nnbd/lib/convert/utf.dart b/sdk_nnbd/lib/convert/utf.dart
index d9324f6..f495ac0 100644
--- a/sdk_nnbd/lib/convert/utf.dart
+++ b/sdk_nnbd/lib/convert/utf.dart
@@ -55,13 +55,19 @@
   /// If [allowMalformed] is not given, it defaults to the `allowMalformed` that
   /// was used to instantiate `this`.
   String decode(List<int> codeUnits, {bool? allowMalformed}) {
-    return Utf8Decoder(allowMalformed: allowMalformed ?? _allowMalformed)
-        .convert(codeUnits);
+    // Switch between const objects to avoid allocation.
+    Utf8Decoder decoder = allowMalformed ?? _allowMalformed
+        ? const Utf8Decoder(allowMalformed: true)
+        : const Utf8Decoder(allowMalformed: false);
+    return decoder.convert(codeUnits);
   }
 
   Utf8Encoder get encoder => const Utf8Encoder();
   Utf8Decoder get decoder {
-    return Utf8Decoder(allowMalformed: _allowMalformed);
+    // Switch between const objects to avoid allocation.
+    return _allowMalformed
+        ? const Utf8Decoder(allowMalformed: true)
+        : const Utf8Decoder(allowMalformed: false);
   }
 }
 
@@ -133,6 +139,13 @@
   /// Allow an implementation to pick the most efficient way of storing bytes.
   static Uint8List _createBuffer(int size) => Uint8List(size);
 
+  /// Write a replacement character (U+FFFD). Used for unpaired surrogates.
+  void _writeReplacementCharacter() {
+    _buffer[_bufferIndex++] = 0xEF;
+    _buffer[_bufferIndex++] = 0xBF;
+    _buffer[_bufferIndex++] = 0xBD;
+  }
+
   /// Tries to combine the given [leadingSurrogate] with the [nextCodeUnit] and
   /// writes it to [_buffer].
   ///
@@ -140,8 +153,8 @@
   /// [leadingSurrogate]. If it wasn't then nextCodeUnit was not a trailing
   /// surrogate and has not been written yet.
   ///
-  /// It is safe to pass 0 for [nextCodeUnit] in which case only the leading
-  /// surrogate is written.
+  /// It is safe to pass 0 for [nextCodeUnit] in which case a replacement
+  /// character is written to represent the unpaired lead surrogate.
   bool _writeSurrogate(int leadingSurrogate, int nextCodeUnit) {
     if (_isTailSurrogate(nextCodeUnit)) {
       var rune = _combineSurrogatePair(leadingSurrogate, nextCodeUnit);
@@ -155,14 +168,8 @@
       _buffer[_bufferIndex++] = 0x80 | (rune & 0x3f);
       return true;
     } else {
-      // TODO(floitsch): allow to throw on malformed strings.
-      // Encode the half-surrogate directly into UTF-8. This yields
-      // invalid UTF-8, but we started out with invalid UTF-16.
-
-      // Surrogates are always encoded in 3 bytes in UTF-8.
-      _buffer[_bufferIndex++] = 0xE0 | (leadingSurrogate >> 12);
-      _buffer[_bufferIndex++] = 0x80 | ((leadingSurrogate >> 6) & 0x3f);
-      _buffer[_bufferIndex++] = 0x80 | (leadingSurrogate & 0x3f);
+      // Unpaired lead surrogate.
+      _writeReplacementCharacter();
       return false;
     }
   }
@@ -188,12 +195,16 @@
         if (_bufferIndex >= _buffer.length) break;
         _buffer[_bufferIndex++] = codeUnit;
       } else if (_isLeadSurrogate(codeUnit)) {
-        if (_bufferIndex + 3 >= _buffer.length) break;
+        if (_bufferIndex + 4 > _buffer.length) break;
         // Note that it is safe to read the next code unit. We decremented
         // [end] above when the last valid code unit was a leading surrogate.
         var nextCodeUnit = str.codeUnitAt(stringIndex + 1);
         var wasCombined = _writeSurrogate(codeUnit, nextCodeUnit);
         if (wasCombined) stringIndex++;
+      } else if (_isTailSurrogate(codeUnit)) {
+        if (_bufferIndex + 3 > _buffer.length) break;
+        // Unpaired tail surrogate.
+        _writeReplacementCharacter();
       } else {
         var rune = codeUnit;
         if (rune <= _TWO_BYTE_LIMIT) {
@@ -308,33 +319,7 @@
       return result;
     }
 
-    var length = codeUnits.length;
-    end = RangeError.checkValidRange(start, end, length);
-    // TODO(38725): Remove workaround when assignment promotion is implemented
-    if (end == null) {
-      throw RangeError("Invalid range");
-    }
-
-    // Fast case for ASCII strings avoids StringBuffer/_Utf8Decoder.
-    int oneBytes = _scanOneByteCharacters(codeUnits, start, end);
-    StringBuffer buffer;
-    bool isFirstCharacter = true;
-    if (oneBytes > 0) {
-      var firstPart = String.fromCharCodes(codeUnits, start, start + oneBytes);
-      start += oneBytes;
-      if (start == end) {
-        return firstPart;
-      }
-      buffer = StringBuffer(firstPart);
-      isFirstCharacter = false;
-    } else {
-      buffer = StringBuffer();
-    }
-    var decoder = _Utf8Decoder(buffer, _allowMalformed);
-    decoder._isFirstCharacter = isFirstCharacter;
-    decoder.convert(codeUnits, start, end);
-    decoder.flush(codeUnits, end);
-    return buffer.toString();
+    return _Utf8Decoder(_allowMalformed).convertSingle(codeUnits, start, end);
   }
 
   /// Starts a chunked conversion.
@@ -380,185 +365,314 @@
     0x10000 + ((lead & _SURROGATE_VALUE_MASK) << 10) |
     (tail & _SURROGATE_VALUE_MASK);
 
-/// Decodes UTF-8.
-///
-/// The decoder handles chunked input.
-// TODO(floitsch): make this class public.
 class _Utf8Decoder {
-  final bool _allowMalformed;
-  final StringSink _stringSink;
-  bool _isFirstCharacter = true;
-  int _value = 0;
-  int _expectedUnits = 0;
-  int _extraUnits = 0;
+  /// Decode malformed UTF-8 as replacement characters (instead of throwing)?
+  final bool allowMalformed;
 
-  _Utf8Decoder(this._stringSink, this._allowMalformed);
+  /// Decoder DFA state.
+  int _state;
 
-  bool get hasPartialInput => _expectedUnits > 0;
+  /// Partially decoded character. Meaning depends on state. Not used when in
+  /// the initial/accept state. When in an error state, contains the index into
+  /// the input of the error.
+  int _charOrIndex = 0;
 
-  // Limits of one through four byte encodings.
-  static const List<int> _LIMITS = <int>[
-    _ONE_BYTE_LIMIT,
-    _TWO_BYTE_LIMIT,
-    _THREE_BYTE_LIMIT,
-    _FOUR_BYTE_LIMIT
-  ];
+  // State machine for UTF-8 decoding, based on this decoder by Björn Höhrmann:
+  // https://bjoern.hoehrmann.de/utf-8/decoder/dfa/
+  //
+  // One iteration in the state machine proceeds as:
+  //
+  // type = typeTable[byte];
+  // char = (state != accept)
+  //     ? (byte & 0x3F) | (char << 6)
+  //     : byte & (shiftedByteMask >> type);
+  // state = transitionTable[state + type];
+  //
+  // After each iteration, if state == accept, char is output as a character.
 
-  void close() {
-    flush();
+  // Mask to and on the type read from the table.
+  static const int typeMask = 0x1F;
+  // Mask shifted right by byte type to mask first byte of sequence.
+  static const int shiftedByteMask = 0xF0FE;
+
+  // Byte types.
+  // 'A' = ASCII, 00-7F
+  // 'B' = 2-byte, C2-DF
+  // 'C' = 3-byte, E1-EC, EE
+  // 'D' = 3-byte (possibly surrogate), ED
+  // 'E' = Illegal, C0-C1, F5+
+  // 'F' = Low extension, 80-8F
+  // 'G' = Mid extension, 90-9F
+  // 'H' = High extension, A0-BA, BC-BE
+  // 'I' = Second byte of BOM, BB
+  // 'J' = Third byte of BOM, BF
+  // 'K' = 3-byte (possibly overlong), E0
+  // 'L' = First byte of BOM, EF
+  // 'M' = 4-byte (possibly out-of-range), F4
+  // 'N' = 4-byte, F1-F3
+  // 'O' = 4-byte (possibly overlong), F0
+  static const String typeTable = ""
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 00-1F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 20-3F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 40-5F
+      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 60-7F
+      "FFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGG" // 80-9F
+      "HHHHHHHHHHHHHHHHHHHHHHHHHHHIHHHJ" // A0-BF
+      "EEBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" // C0-DF
+      "KCCCCCCCCCCCCDCLONNNMEEEEEEEEEEE" // E0-FF
+      ;
+
+  // States (offsets into transition table).
+  static const int IA = 0x00; // Initial / Accept
+  static const int BB = 0x10; // Before BOM
+  static const int AB = 0x20; // After BOM
+  static const int X1 = 0x30; // Expecting one extension byte
+  static const int X2 = 0x3A; // Expecting two extension bytes
+  static const int X3 = 0x44; // Expecting three extension bytes
+  static const int TO = 0x4E; // Possibly overlong 3-byte
+  static const int TS = 0x58; // Possibly surrogate
+  static const int QO = 0x62; // Possibly overlong 4-byte
+  static const int QR = 0x6C; // Possibly out-of-range 4-byte
+  static const int B1 = 0x76; // One byte into BOM
+  static const int B2 = 0x80; // Two bytes into BOM
+  static const int E1 = 0x41; // Error: Missing extension byte
+  static const int E2 = 0x43; // Error: Unexpected extension byte
+  static const int E3 = 0x45; // Error: Invalid byte
+  static const int E4 = 0x47; // Error: Overlong encoding
+  static const int E5 = 0x49; // Error: Out of range
+  static const int E6 = 0x4B; // Error: Surrogate
+  static const int E7 = 0x4D; // Error: Unfinished
+
+  // Character equivalents for states.
+  static const String _IA = '\u0000';
+  static const String _BB = '\u0010';
+  static const String _AB = '\u0020';
+  static const String _X1 = '\u0030';
+  static const String _X2 = '\u003A';
+  static const String _X3 = '\u0044';
+  static const String _TO = '\u004E';
+  static const String _TS = '\u0058';
+  static const String _QO = '\u0062';
+  static const String _QR = '\u006C';
+  static const String _B1 = '\u0076';
+  static const String _B2 = '\u0080';
+  static const String _E1 = '\u0041';
+  static const String _E2 = '\u0043';
+  static const String _E3 = '\u0045';
+  static const String _E4 = '\u0047';
+  static const String _E5 = '\u0049';
+  static const String _E6 = '\u004B';
+  static const String _E7 = '\u004D';
+
+  // Transition table of the state machine. Maps state and byte type
+  // to next state.
+  static const String transitionTable = " "
+      // A   B   C   D   E   F   G   H   I   J   K   L   M   N   O
+      "$_IA$_X1$_X2$_TS$_E3$_E2$_E2$_E2$_E2$_E2$_TO$_X2$_QR$_X3$_QO " // IA
+      "$_IA$_X1$_X2$_TS$_E3$_E2$_E2$_E2$_E2$_E2$_TO$_B1$_QR$_X3$_QO " // BB
+      "$_IA$_X1$_X2$_TS$_E3$_E2$_E2$_E2$_E2$_E2$_TO$_X2$_QR$_X3$_QO " // AB
+      "$_E1$_E1$_E1$_E1$_E1$_IA$_IA$_IA$_IA$_IA" // Overlap 5 E1s        X1
+      "$_E1$_E1$_E1$_E1$_E1$_X1$_X1$_X1$_X1$_X1" // Overlap 5 E1s        X2
+      "$_E1$_E1$_E1$_E1$_E1$_X2$_X2$_X2$_X2$_X2" // Overlap 5 E1s        X3
+      "$_E1$_E1$_E1$_E1$_E1$_E4$_E4$_X1$_X1$_X1" // Overlap 5 E1s        TO
+      "$_E1$_E1$_E1$_E1$_E1$_X1$_X1$_E6$_E6$_E6" // Overlap 5 E1s        TS
+      "$_E1$_E1$_E1$_E1$_E1$_E4$_X2$_X2$_X2$_X2" // Overlap 5 E1s        QO
+      "$_E1$_E1$_E1$_E1$_E1$_X2$_E5$_E5$_E5$_E5" // Overlap 5 E1s        QR
+      "$_E1$_E1$_E1$_E1$_E1$_X1$_X1$_X1$_B2$_X1" // Overlap 5 E1s        B1
+      "$_E1$_E1$_E1$_E1$_E1$_IA$_IA$_IA$_IA$_AB$_E1$_E1$_E1$_E1$_E1" //  B2
+      ;
+
+  // Aliases for states.
+  static const int initial = IA;
+  static const int accept = IA;
+  static const int beforeBom = BB;
+  static const int afterBom = AB;
+  static const int errorMissingExtension = E1;
+  static const int errorUnexpectedExtension = E2;
+  static const int errorInvalid = E3;
+  static const int errorOverlong = E4;
+  static const int errorOutOfRange = E5;
+  static const int errorSurrogate = E6;
+  static const int errorUnfinished = E7;
+
+  static bool isErrorState(int state) => (state & 1) != 0;
+
+  static String errorDescription(int state) {
+    switch (state) {
+      case errorMissingExtension:
+        return "Missing extension byte";
+      case errorUnexpectedExtension:
+        return "Unexpected extension byte";
+      case errorInvalid:
+        return "Invalid UTF-8 byte";
+      case errorOverlong:
+        return "Overlong encoding";
+      case errorOutOfRange:
+        return "Out of unicode range";
+      case errorSurrogate:
+        return "Encoded surrogate";
+      case errorUnfinished:
+        return "Unfinished UTF-8 octet sequence";
+      default:
+        return "";
+    }
+  }
+
+  external _Utf8Decoder(bool allowMalformed);
+
+  external String convertSingle(List<int> codeUnits, int start, int? maybeEnd);
+
+  external String convertChunked(List<int> codeUnits, int start, int? maybeEnd);
+
+  String convertGeneral(
+      List<int> codeUnits, int start, int? maybeEnd, bool single) {
+    int end = RangeError.checkValidRange(start, maybeEnd, codeUnits.length);
+
+    if (start == end) return "";
+
+    // Have bytes as Uint8List.
+    Uint8List bytes;
+    int errorOffset;
+    if (codeUnits is Uint8List) {
+      bytes = codeUnits;
+      errorOffset = 0;
+    } else {
+      bytes = _makeUint8List(codeUnits, start, end);
+      errorOffset = start;
+      end -= start;
+      start = 0;
+    }
+
+    String result = decodeGeneral(bytes, start, end, single);
+    if (isErrorState(_state)) {
+      String message = errorDescription(_state);
+      _state = initial; // Ready for more input.
+      throw FormatException(message, codeUnits, errorOffset + _charOrIndex);
+    }
+    return result;
   }
 
   /// Flushes this decoder as if closed.
   ///
   /// This method throws if the input was partial and the decoder was
   /// constructed with `allowMalformed` set to `false`.
-  ///
-  /// The [source] and [offset] of the current position may be provided,
-  /// and are included in the exception if one is thrown.
-  void flush([List<int>? source, int? offset]) {
-    if (hasPartialInput) {
-      if (!_allowMalformed) {
-        throw FormatException(
-            "Unfinished UTF-8 octet sequence", source, offset);
-      }
-      _stringSink.writeCharCode(unicodeReplacementCharacterRune);
-      _value = 0;
-      _expectedUnits = 0;
-      _extraUnits = 0;
+  void flush(StringSink sink) {
+    final int state = _state;
+    _state = initial;
+    if (state <= afterBom) {
+      return;
+    }
+    // Unfinished sequence.
+    if (allowMalformed) {
+      sink.writeCharCode(unicodeReplacementCharacterRune);
+    } else {
+      throw FormatException(errorDescription(errorUnfinished), null, null);
     }
   }
 
-  void convert(List<int> codeUnits, int startIndex, int endIndex) {
-    var value = _value;
-    var expectedUnits = _expectedUnits;
-    var extraUnits = _extraUnits;
-    _value = 0;
-    _expectedUnits = 0;
-    _extraUnits = 0;
-
-    var i = startIndex;
+  String decodeGeneral(Uint8List bytes, int start, int end, bool single) {
+    final String typeTable = _Utf8Decoder.typeTable;
+    final String transitionTable = _Utf8Decoder.transitionTable;
+    int state = _state;
+    int char = _charOrIndex;
+    final StringBuffer buffer = StringBuffer();
+    int i = start;
+    int byte = bytes[i++];
     loop:
     while (true) {
       multibyte:
-      if (expectedUnits > 0) {
-        do {
-          if (i == endIndex) {
-            break loop;
-          }
-          var unit = codeUnits[i];
-          if ((unit & 0xC0) != 0x80) {
-            expectedUnits = 0;
-            if (!_allowMalformed) {
-              throw FormatException(
-                  "Bad UTF-8 encoding 0x${unit.toRadixString(16)}",
-                  codeUnits,
-                  i);
+      while (true) {
+        int type = typeTable.codeUnitAt(byte) & typeMask;
+        char = (state <= afterBom)
+            ? byte & (shiftedByteMask >> type)
+            : (byte & 0x3F) | (char << 6);
+        state = transitionTable.codeUnitAt(state + type);
+        if (state == accept) {
+          buffer.writeCharCode(char);
+          if (i == end) break loop;
+          break multibyte;
+        } else if (isErrorState(state)) {
+          if (allowMalformed) {
+            switch (state) {
+              case errorInvalid:
+              case errorUnexpectedExtension:
+                // A single byte that can't start a sequence.
+                buffer.writeCharCode(unicodeReplacementCharacterRune);
+                break;
+              case errorMissingExtension:
+                // Unfinished sequence followed by a byte that can start a
+                // sequence.
+                buffer.writeCharCode(unicodeReplacementCharacterRune);
+                // Re-parse offending byte.
+                i -= 1;
+                break;
+              default:
+                // Unfinished sequence followed by a byte that can't start a
+                // sequence.
+                buffer.writeCharCode(unicodeReplacementCharacterRune);
+                buffer.writeCharCode(unicodeReplacementCharacterRune);
+                break;
             }
-            _isFirstCharacter = false;
-            _stringSink.writeCharCode(unicodeReplacementCharacterRune);
-            break multibyte;
+            state = initial;
           } else {
-            value = (value << 6) | (unit & 0x3f);
-            expectedUnits--;
-            i++;
+            _state = state;
+            _charOrIndex = i - 1;
+            return "";
           }
-        } while (expectedUnits > 0);
-        if (value <= _LIMITS[extraUnits - 1]) {
-          // Overly long encoding. The value could be encoded with a shorter
-          // encoding.
-          if (!_allowMalformed) {
-            throw FormatException(
-                "Overlong encoding of 0x${value.toRadixString(16)}",
-                codeUnits,
-                i - extraUnits - 1);
-          }
-          expectedUnits = extraUnits = 0;
-          value = unicodeReplacementCharacterRune;
         }
-        if (value > _FOUR_BYTE_LIMIT) {
-          if (!_allowMalformed) {
-            throw FormatException(
-                "Character outside valid Unicode range: "
-                "0x${value.toRadixString(16)}",
-                codeUnits,
-                i - extraUnits - 1);
-          }
-          value = unicodeReplacementCharacterRune;
-        }
-        if (!_isFirstCharacter || value != unicodeBomCharacterRune) {
-          _stringSink.writeCharCode(value);
-        }
-        _isFirstCharacter = false;
+        if (i == end) break loop;
+        byte = bytes[i++];
       }
 
-      while (i < endIndex) {
-        var oneBytes = _scanOneByteCharacters(codeUnits, i, endIndex);
-        if (oneBytes > 0) {
-          _isFirstCharacter = false;
-          assert(i + oneBytes <= endIndex);
-          _stringSink.write(String.fromCharCodes(codeUnits, i, i + oneBytes));
-
-          i += oneBytes;
-          if (i == endIndex) break;
-        }
-        var unit = codeUnits[i++];
-        // TODO(floitsch): the way we test we could potentially allow
-        // units that are too large, if they happen to have the
-        // right bit-pattern. (Same is true for the multibyte loop above).
-        // TODO(floitsch): optimize this loop. See:
-        // https://codereview.chromium.org/22929022/diff/1/sdk/lib/convert/utf.dart?column_width=80
-        if (unit < 0) {
-          // TODO(floitsch): should this be unit <= 0 ?
-          if (!_allowMalformed) {
-            throw FormatException(
-                "Negative UTF-8 code unit: -0x${(-unit).toRadixString(16)}",
-                codeUnits,
-                i - 1);
+      final int markStart = i;
+      byte = bytes[i++];
+      if (byte < 128) {
+        int markEnd = end;
+        while (i < end) {
+          byte = bytes[i++];
+          if (byte >= 128) {
+            markEnd = i - 1;
+            break;
           }
-          _stringSink.writeCharCode(unicodeReplacementCharacterRune);
+        }
+        assert(markStart < markEnd);
+        if (markEnd - markStart < 20) {
+          for (int m = markStart; m < markEnd; m++) {
+            buffer.writeCharCode(bytes[m]);
+          }
         } else {
-          assert(unit > _ONE_BYTE_LIMIT);
-          if ((unit & 0xE0) == 0xC0) {
-            value = unit & 0x1F;
-            expectedUnits = extraUnits = 1;
-            continue loop;
-          }
-          if ((unit & 0xF0) == 0xE0) {
-            value = unit & 0x0F;
-            expectedUnits = extraUnits = 2;
-            continue loop;
-          }
-          // 0xF5, 0xF6 ... 0xFF never appear in valid UTF-8 sequences.
-          if ((unit & 0xF8) == 0xF0 && unit < 0xF5) {
-            value = unit & 0x07;
-            expectedUnits = extraUnits = 3;
-            continue loop;
-          }
-          if (!_allowMalformed) {
-            throw FormatException(
-                "Bad UTF-8 encoding 0x${unit.toRadixString(16)}",
-                codeUnits,
-                i - 1);
-          }
-          value = unicodeReplacementCharacterRune;
-          expectedUnits = extraUnits = 0;
-          _isFirstCharacter = false;
-          _stringSink.writeCharCode(value);
+          buffer.write(String.fromCharCodes(bytes, markStart, markEnd));
         }
+        if (markEnd == end) break loop;
       }
-      break loop;
     }
-    if (expectedUnits > 0) {
-      _value = value;
-      _expectedUnits = expectedUnits;
-      _extraUnits = extraUnits;
+
+    if (single && state > afterBom) {
+      // Unfinished sequence.
+      if (allowMalformed) {
+        buffer.writeCharCode(unicodeReplacementCharacterRune);
+      } else {
+        _state = errorUnfinished;
+        _charOrIndex = end;
+        return "";
+      }
     }
+    _state = state;
+    _charOrIndex = char;
+    return buffer.toString();
+  }
+
+  static Uint8List _makeUint8List(List<int> codeUnits, int start, int end) {
+    final int length = end - start;
+    final Uint8List bytes = Uint8List(length);
+    for (int i = 0; i < length; i++) {
+      int b = codeUnits[start + i];
+      if ((b & ~0xFF) != 0) {
+        // Replace invalid byte values by FF, which is also invalid.
+        b = 0xFF;
+      }
+      bytes[i] = b;
+    }
+    return bytes;
   }
 }
-
-// Returns the number of bytes in [units] starting at offset [from] which have
-// the leftmost bit set to 0.
-//
-// To increase performance of this critical method we have a special variant of
-// it implemented in the VM's patch files, which is why we make it external.
-external int _scanOneByteCharacters(List<int> units, int from, int endIndex);
diff --git a/sdk_nnbd/lib/internal/internal.dart b/sdk_nnbd/lib/internal/internal.dart
index bec8b0c..dad3b05 100644
--- a/sdk_nnbd/lib/internal/internal.dart
+++ b/sdk_nnbd/lib/internal/internal.dart
@@ -18,16 +18,17 @@
 import 'dart:core' hide Symbol;
 import 'dart:core' as core show Symbol;
 import 'dart:math' show Random;
+import 'dart:typed_data' show Uint8List;
 
 part 'async_cast.dart';
 part 'cast.dart';
 part 'errors.dart';
 part 'iterable.dart';
 part 'list.dart';
+part 'linked_list.dart';
 part 'print.dart';
 part 'sort.dart';
 part 'symbol.dart';
-part 'linked_list.dart';
 
 // Returns true iff `null as T` will succeed based on the
 // execution mode.
diff --git a/sdk_nnbd/lib/vmservice/vmservice.dart b/sdk_nnbd/lib/vmservice/vmservice.dart
index 5b0ad91..4b2988a 100644
--- a/sdk_nnbd/lib/vmservice/vmservice.dart
+++ b/sdk_nnbd/lib/vmservice/vmservice.dart
@@ -706,45 +706,6 @@
         details: 'Unknown service: ${message.method}');
   }
 
-  Future<String> _spawnUri(Message message) async {
-    final token = message.params['token'];
-    if (token == null) {
-      return encodeMissingParamError(message, 'token');
-    }
-    if (token is! String) {
-      return encodeInvalidParamError(message, 'token');
-    }
-    final uri = message.params['uri'];
-    if (uri == null) {
-      return encodeMissingParamError(message, 'uri');
-    }
-    if (uri is! String) {
-      return encodeInvalidParamError(message, 'uri');
-    }
-    final args = message.params['args'];
-    final argsOfString = <String>[];
-    if (args != null) {
-      if (args is! List) {
-        return encodeInvalidParamError(message, 'args');
-      }
-      for (final arg in args) {
-        if (arg is! String) {
-          return encodeInvalidParamError(message, 'args');
-        }
-        argsOfString.add(arg);
-      }
-    }
-    final msg = message.params['message'];
-
-    Isolate.spawnUri(Uri.parse(uri), argsOfString, msg).then((isolate) {
-      _spawnUriNotify(isolate.controlPort, token);
-    }).catchError((e) {
-      _spawnUriNotify(e.toString(), token);
-    });
-
-    return encodeSuccess(message);
-  }
-
   Future<Response?> routeRequest(VMService _, Message message) async {
     final response = await _routeRequestImpl(message);
     if (response == null) {
@@ -772,9 +733,6 @@
       if (message.method == 'registerService') {
         return await _registerService(message);
       }
-      if (message.method == '_spawnUri') {
-        return await _spawnUri(message);
-      }
       if (message.method == 'setClientName') {
         return _setClientName(message);
       }
@@ -839,6 +797,3 @@
 
 /// Get the bytes to the tar archive.
 Uint8List _requestAssets() native 'VMService_RequestAssets';
-
-/// Notify the vm service that an isolate has been spawned via rpc.
-void _spawnUriNotify(obj, String token) native 'VMService_spawnUriNotify';
diff --git a/tests/compiler/dart2js/codegen/model_test.dart b/tests/compiler/dart2js/codegen/model_test.dart
index 95dedea..9e694ee 100644
--- a/tests/compiler/dart2js/codegen/model_test.dart
+++ b/tests/compiler/dart2js/codegen/model_test.dart
@@ -53,7 +53,7 @@
 
   @override
   DataInterpreter<Features> get dataValidator =>
-      const FeaturesDataInterpreter();
+      const FeaturesDataInterpreter(wildcard: '*');
 }
 
 class Tags {
diff --git a/tests/compiler/dart2js/impact/data/as.dart b/tests/compiler/dart2js/impact/data/as.dart
index 0efa63a..b4c3f2d 100644
--- a/tests/compiler/dart2js/impact/data/as.dart
+++ b/tests/compiler/dart2js/impact/data/as.dart
@@ -11,7 +11,7 @@
   promoted(null);
 }
 
-/*member: explicitAs:
+/*spec:nnbd-off.member: explicitAs:
  dynamic=[String.length],
  static=[
   Rti._bind(1),
@@ -51,13 +51,56 @@
   inst:JSBool,
   param:String]
 */
+/*spec:nnbd-sdk.member: explicitAs:
+ dynamic=[String.length],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:String*]
+*/
 explicitAs(String i) {
   i.length;
   // ignore: unnecessary_cast
   return i as String;
 }
 
-/*member: implicitAs:
+/*spec:nnbd-off.member: implicitAs:
  dynamic=[String.length],
  static=[
   Rti._bind(1),
@@ -97,6 +140,49 @@
   inst:JSBool,
   param:String]
 */
+/*spec:nnbd-sdk.member: implicitAs:
+ dynamic=[String.length],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:String*]
+*/
 String implicitAs(String i) {
   dynamic j = i;
   i.length;
@@ -104,7 +190,7 @@
   return j;
 }
 
-/*member: promoted:
+/*spec:nnbd-off.member: promoted:
  dynamic=[String.length],
  static=[
   Rti._bind(1),
@@ -145,6 +231,50 @@
   inst:JSNull,
   is:String]
 */
+/*spec:nnbd-sdk.member: promoted:
+ dynamic=[String.length],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:String*]
+*/
 String promoted(dynamic i) {
   if (i is! String) return null;
   i.length;
diff --git a/tests/compiler/dart2js/impact/data/async.dart b/tests/compiler/dart2js/impact/data/async.dart
index af7463f..70738c5 100644
--- a/tests/compiler/dart2js/impact/data/async.dart
+++ b/tests/compiler/dart2js/impact/data/async.dart
@@ -219,7 +219,7 @@
   return () async* {};
 }
 
-/*member: testAsyncForIn:
+/*spec:nnbd-off.member: testAsyncForIn:
  dynamic=[
   _StreamIterator.cancel(0),
   _StreamIterator.current,
@@ -271,12 +271,67 @@
   inst:JSNull,
   inst:Null]
 */
+/*spec:nnbd-sdk.member: testAsyncForIn:
+ dynamic=[
+  _StreamIterator.cancel(0),
+  _StreamIterator.current,
+  _StreamIterator.moveNext(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  StreamIterator.(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _asyncAwait(2),
+  _asyncRethrow(2),
+  _asyncReturn(2),
+  _asyncStartSync(2),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  _makeAsyncAwaitCompleter<dynamic>(0),
+  _wrapJsFunctionForAsync(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:Stream<dynamic>*,
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  inst:Null]
+*/
 testAsyncForIn(o) async {
   // ignore: UNUSED_LOCAL_VARIABLE
   await for (var e in o) {}
 }
 
-/*member: testAsyncForInTyped:
+/*spec:nnbd-off.member: testAsyncForInTyped:
  dynamic=[
   _StreamIterator.cancel(0),
   _StreamIterator.current,
@@ -329,6 +384,62 @@
   inst:JSNull,
   inst:Null]
 */
+/*spec:nnbd-sdk.member: testAsyncForInTyped:
+ dynamic=[
+  _StreamIterator.cancel(0),
+  _StreamIterator.current,
+  _StreamIterator.moveNext(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  StreamIterator.(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _asyncAwait(2),
+  _asyncRethrow(2),
+  _asyncReturn(2),
+  _asyncStartSync(2),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  _makeAsyncAwaitCompleter<dynamic>(0),
+  _wrapJsFunctionForAsync(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:Stream<dynamic>*,
+  impl:int*,
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  inst:Null]
+*/
 testAsyncForInTyped(o) async {
   // ignore: UNUSED_LOCAL_VARIABLE
   await for (int e in o) {}
diff --git a/tests/compiler/dart2js/impact/data/classes.dart b/tests/compiler/dart2js/impact/data/classes.dart
index 443975a..4e7ab2c 100644
--- a/tests/compiler/dart2js/impact/data/classes.dart
+++ b/tests/compiler/dart2js/impact/data/classes.dart
@@ -139,7 +139,7 @@
 testForwardingConstructor() => new ForwardingConstructorClass(null);
 
 class ForwardingConstructorTypedSuperClass {
-  /*member: ForwardingConstructorTypedSuperClass.:
+  /*spec:nnbd-off.member: ForwardingConstructorTypedSuperClass.:
    static=[
     Object.(0),
     Rti._bind(1),
@@ -179,6 +179,49 @@
     inst:JSBool,
     param:int]
   */
+  /*spec:nnbd-sdk.member: ForwardingConstructorTypedSuperClass.:
+   static=[
+    Object.(0),
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    param:int*]
+  */
   ForwardingConstructorTypedSuperClass(int arg);
 }
 
@@ -192,7 +235,7 @@
 testForwardingConstructorTyped() => new ForwardingConstructorTypedClass(null);
 
 class ForwardingConstructorGenericSuperClass<T> {
-  /*member: ForwardingConstructorGenericSuperClass.:
+  /*spec:nnbd-off.member: ForwardingConstructorGenericSuperClass.:
    static=[
     Object.(0),
     Rti._bind(1),
@@ -244,6 +287,61 @@
     inst:JSUnmodifiableArray<dynamic>,
     param:ForwardingConstructorGenericSuperClass.T]
   */
+  /*spec:nnbd-sdk.member: ForwardingConstructorGenericSuperClass.:
+   static=[
+    Object.(0),
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    checkSubtypeOfRuntimeType(2),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:ForwardingConstructorGenericSuperClass.T*]
+  */
   ForwardingConstructorGenericSuperClass(T arg);
 }
 
@@ -273,7 +371,7 @@
 */
 testEnum() => Enum.A;
 
-/*member: staticGenericMethod:
+/*spec:nnbd-off.member: staticGenericMethod:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -326,17 +424,85 @@
   param:Object,
   param:staticGenericMethod.T]
 */
+/*spec:nnbd-sdk.member: staticGenericMethod:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  checkSubtypeOfRuntimeType(2),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  inst:List<staticGenericMethod.T*>,
+  param:Object*,
+  param:staticGenericMethod.T*]
+*/
 List<T> staticGenericMethod<T>(T arg) => [arg];
 
-/*member: testStaticGenericMethod:
+/*spec:nnbd-off.member: testStaticGenericMethod:
   static=[staticGenericMethod<bool>(1)],
   type=[inst:JSBool]
 */
+/*spec:nnbd-sdk.member: testStaticGenericMethod:
+ static=[staticGenericMethod<bool*>(1)],
+ type=[inst:JSBool]
+*/
 testStaticGenericMethod() {
   staticGenericMethod<bool>(true);
 }
 
-/*member: testInstanceGenericMethod:dynamic=[exact:GenericClass.genericMethod<bool>(1)],static=[GenericClass.generative(0),checkTypeBound(4),throwTypeError(1)],type=[inst:JSBool]*/
+/*spec:nnbd-off.member: testInstanceGenericMethod:dynamic=[exact:GenericClass.genericMethod<bool>(1)],static=[GenericClass.generative(0),checkTypeBound(4),throwTypeError(1)],type=[inst:JSBool]*/
+/*spec:nnbd-sdk.member: testInstanceGenericMethod:
+ dynamic=[exact:GenericClass.genericMethod<bool*>(1)],
+ static=[
+  GenericClass.generative(0),
+  checkTypeBound(4),
+  throwTypeError(1)],
+ type=[inst:JSBool]
+*/
 testInstanceGenericMethod() {
   new GenericClass<int, String>.generative().genericMethod<bool>(false);
 }
@@ -372,7 +538,7 @@
 class GenericClass<X, Y> {
   const GenericClass.generative();
 
-  /*member: GenericClass.genericMethod:
+  /*spec:nnbd-off.member: GenericClass.genericMethod:
    static=[
     Rti._bind(1),
     Rti._eval(1),
@@ -426,6 +592,63 @@
     param:Object,
     param:genericMethod.T]
   */
+  /*spec:nnbd-sdk.member: GenericClass.genericMethod:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    checkSubtypeOfRuntimeType(2),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSNull,
+    inst:JSUnmodifiableArray<dynamic>,
+    inst:Map<GenericClass.X*,genericMethod.T*>,
+    param:Object*,
+    param:genericMethod.T*]
+  */
   Map<X, T> genericMethod<T>(T arg) => {null: arg};
 }
 
diff --git a/tests/compiler/dart2js/impact/data/constants/lib.dart b/tests/compiler/dart2js/impact/data/constants/lib.dart
index 47c5760..964ffcb 100644
--- a/tests/compiler/dart2js/impact/data/constants/lib.dart
+++ b/tests/compiler/dart2js/impact/data/constants/lib.dart
@@ -44,7 +44,7 @@
 
 const typeLiteralField = String;
 
-/*member: id:
+/*spec:nnbd-off.member: id:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -96,6 +96,61 @@
   param:Object,
   param:id.T]
 */
+/*spec:nnbd-sdk.member: id:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  checkSubtypeOfRuntimeType(2),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Object*,
+  param:id.T*]
+*/
 T id<T>(T t) => t;
 
 const int Function(int) _instantiation = id;
diff --git a/tests/compiler/dart2js/impact/data/constants/main.dart b/tests/compiler/dart2js/impact/data/constants/main.dart
index 1b959de..3a80aee 100644
--- a/tests/compiler/dart2js/impact/data/constants/main.dart
+++ b/tests/compiler/dart2js/impact/data/constants/main.dart
@@ -7,7 +7,7 @@
 import 'lib.dart';
 import 'lib.dart' deferred as defer;
 
-/*member: main:static=**/
+/*member: main:static=%*/
 main() {
   nullLiteral();
   boolLiteral();
@@ -91,7 +91,10 @@
 /*member: symbolLiteral:static=[Symbol.(1)],type=[inst:Symbol]*/
 symbolLiteral() => #foo;
 
-/*member: listLiteral:type=[inst:JSBool,inst:List<bool>]*/
+/*spec:nnbd-off.member: listLiteral:type=[inst:JSBool,inst:List<bool>]*/
+/*spec:nnbd-sdk.member: listLiteral:type=[
+  inst:JSBool,
+  inst:List<bool*>]*/
 listLiteral() => const [true, false];
 
 /*member: mapLiteral:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
@@ -109,7 +112,16 @@
 */
 instanceConstant() => const Class(true, false);
 
-/*member: typeLiteral:static=[createRuntimeType(1),typeLiteral(1)],type=[inst:Type,inst:_Type,lit:String]*/
+/*spec:nnbd-off.member: typeLiteral:static=[createRuntimeType(1),typeLiteral(1)],type=[inst:Type,inst:_Type,lit:String]*/
+/*spec:nnbd-sdk.member: typeLiteral:
+ static=[
+  createRuntimeType(1),
+  typeLiteral(1)],
+ type=[
+  inst:Type,
+  inst:_Type,
+  lit:String*]
+*/
 typeLiteral() {
   const dynamic local = String;
   return local;
@@ -151,7 +163,10 @@
 /*member: symbolLiteralRef:static=[Symbol.(1)],type=[inst:Symbol]*/
 symbolLiteralRef() => symbolLiteralField;
 
-/*member: listLiteralRef:type=[inst:JSBool,inst:List<bool>]*/
+/*spec:nnbd-off.member: listLiteralRef:type=[inst:JSBool,inst:List<bool>]*/
+/*spec:nnbd-sdk.member: listLiteralRef:type=[
+  inst:JSBool,
+  inst:List<bool*>]*/
 listLiteralRef() => listLiteralField;
 
 /*member: mapLiteralRef:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
@@ -169,7 +184,16 @@
 */
 instanceConstantRef() => instanceConstantField;
 
-/*member: typeLiteralRef:static=[createRuntimeType(1),typeLiteral(1)],type=[inst:Type,inst:_Type,lit:String]*/
+/*spec:nnbd-off.member: typeLiteralRef:static=[createRuntimeType(1),typeLiteral(1)],type=[inst:Type,inst:_Type,lit:String]*/
+/*spec:nnbd-sdk.member: typeLiteralRef:
+ static=[
+  createRuntimeType(1),
+  typeLiteral(1)],
+ type=[
+  inst:Type,
+  inst:_Type,
+  lit:String*]
+*/
 typeLiteralRef() => typeLiteralField;
 
 /*member: instantiationRef:static=[closureFunctionType(1),id,instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
@@ -201,7 +225,10 @@
 symbolLiteralDeferred() => defer.symbolLiteralField;
 
 // TODO(johnniwinther): Should we record that this is deferred?
-/*member: listLiteralDeferred:type=[inst:JSBool,inst:List<bool>]*/
+/*spec:nnbd-off.member: listLiteralDeferred:type=[inst:JSBool,inst:List<bool>]*/
+/*spec:nnbd-sdk.member: listLiteralDeferred:type=[
+  inst:JSBool,
+  inst:List<bool*>]*/
 listLiteralDeferred() => defer.listLiteralField;
 
 // TODO(johnniwinther): Should we record that this is deferred?
@@ -222,7 +249,16 @@
 */
 instanceConstantDeferred() => defer.instanceConstantField;
 
-/*member: typeLiteralDeferred:static=[createRuntimeType(1),typeLiteral(1)],type=[inst:Type,inst:_Type,lit:String{defer}]*/
+/*spec:nnbd-off.member: typeLiteralDeferred:static=[createRuntimeType(1),typeLiteral(1)],type=[inst:Type,inst:_Type,lit:String{defer}]*/
+/*spec:nnbd-sdk.member: typeLiteralDeferred:
+ static=[
+  createRuntimeType(1),
+  typeLiteral(1)],
+ type=[
+  inst:Type,
+  inst:_Type,
+  lit:String*{defer}]
+*/
 typeLiteralDeferred() => defer.typeLiteralField;
 
 /*member: instantiationDeferred:static=[closureFunctionType(1),id{defer},instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
diff --git a/tests/compiler/dart2js/impact/data/constructors.dart b/tests/compiler/dart2js/impact/data/constructors.dart
index fc06869..cba8812 100644
--- a/tests/compiler/dart2js/impact/data/constructors.dart
+++ b/tests/compiler/dart2js/impact/data/constructors.dart
@@ -111,7 +111,8 @@
   const Class.redirect();
 }
 
-/*member: testConstRedirectingFactoryInvokeGeneric:type=[const:GenericClass<int,String>]*/
+/*spec:nnbd-off.member: testConstRedirectingFactoryInvokeGeneric:type=[const:GenericClass<int,String>]*/
+/*spec:nnbd-sdk.member: testConstRedirectingFactoryInvokeGeneric:type=[const:GenericClass<int*,String*>]*/
 testConstRedirectingFactoryInvokeGeneric() {
   const GenericClass<int, String>.redirect();
 }
@@ -154,7 +155,7 @@
   /*member: GenericClass.generative:static=[Object.(0)]*/
   const GenericClass.generative();
 
-  /*member: GenericClass.fact:
+  /*spec:nnbd-off.member: GenericClass.fact:
    static=[
     Rti._bind(1),
     Rti._eval(1),
@@ -194,6 +195,49 @@
     inst:JSNull,
     param:Object]
   */
+  /*spec:nnbd-sdk.member: GenericClass.fact:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    inst:JSNull,
+    param:Object*]
+  */
   factory GenericClass.fact() => null;
 
   const factory GenericClass.redirect() = GenericClass<X, Y>.generative;
diff --git a/tests/compiler/dart2js/impact/data/effectively_final.dart b/tests/compiler/dart2js/impact/data/effectively_final.dart
index 71b9cc5..ffb98ea 100644
--- a/tests/compiler/dart2js/impact/data/effectively_final.dart
+++ b/tests/compiler/dart2js/impact/data/effectively_final.dart
@@ -69,7 +69,7 @@
 /*member: _method1:type=[inst:JSNull]*/
 num _method1() => null;
 
-/*member: effectivelyFinalPromoted:
+/*spec:nnbd-off.member: effectivelyFinalPromoted:
  dynamic=[
   int.+,
   num.+],
@@ -118,6 +118,58 @@
   inst:JSUInt32,
   is:int]
 */
+/*spec:nnbd-sdk.member: effectivelyFinalPromoted:
+ dynamic=[
+  int.+,
+  num.+],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  _method1(0),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSUInt31,
+  inst:JSUInt32,
+  is:int*]
+*/
 effectivelyFinalPromoted() {
   dynamic c = _method1();
   c + 0;
@@ -129,7 +181,7 @@
 /*member: _method2:type=[inst:JSNull]*/
 String _method2() => null;
 
-/*member: effectivelyFinalPromotedInvalid:
+/*spec:nnbd-off.member: effectivelyFinalPromotedInvalid:
  dynamic=[
   String.+,
   int.+],
@@ -179,6 +231,59 @@
   inst:JSUInt32,
   is:int]
 */
+/*spec:nnbd-sdk.member: effectivelyFinalPromotedInvalid:
+ dynamic=[
+  String.+,
+  int.+],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  _method2(0),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSString,
+  inst:JSUInt31,
+  inst:JSUInt32,
+  is:int*]
+*/
 effectivelyFinalPromotedInvalid() {
   dynamic c = _method2();
   c + '';
diff --git a/tests/compiler/dart2js/impact/data/expressions.dart b/tests/compiler/dart2js/impact/data/expressions.dart
index 513f538..153a7bf 100644
--- a/tests/compiler/dart2js/impact/data/expressions.dart
+++ b/tests/compiler/dart2js/impact/data/expressions.dart
@@ -107,7 +107,7 @@
 */
 testPreDec(o) => --o;
 
-/*member: testIs:
+/*spec:nnbd-off.member: testIs:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -147,9 +147,52 @@
   inst:JSNull,
   is:Class]
 */
+/*spec:nnbd-sdk.member: testIs:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:Class*]
+*/
 testIs() => null is Class;
 
-/*member: testIsGeneric:
+/*spec:nnbd-off.member: testIsGeneric:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -200,9 +243,63 @@
   inst:JSUnmodifiableArray<dynamic>,
   is:GenericClass<int,String>]
 */
+/*spec:nnbd-sdk.member: testIsGeneric:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:GenericClass<int*,String*>*]
+*/
 testIsGeneric() => null is GenericClass<int, String>;
 
-/*member: testIsGenericRaw:
+/*spec:nnbd-off.member: testIsGenericRaw:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -242,9 +339,52 @@
   inst:JSNull,
   is:GenericClass<dynamic,dynamic>]
 */
+/*spec:nnbd-sdk.member: testIsGenericRaw:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:GenericClass<dynamic,dynamic>*]
+*/
 testIsGenericRaw() => null is GenericClass;
 
-/*member: testIsGenericDynamic:
+/*spec:nnbd-off.member: testIsGenericDynamic:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -284,9 +424,52 @@
   inst:JSNull,
   is:GenericClass<dynamic,dynamic>]
 */
+/*spec:nnbd-sdk.member: testIsGenericDynamic:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:GenericClass<dynamic,dynamic>*]
+*/
 testIsGenericDynamic() => null is GenericClass<dynamic, dynamic>;
 
-/*member: testIsNot:
+/*spec:nnbd-off.member: testIsNot:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -326,9 +509,52 @@
   inst:JSNull,
   is:Class]
 */
+/*spec:nnbd-sdk.member: testIsNot:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:Class*]
+*/
 testIsNot() => null is! Class;
 
-/*member: testIsNotGeneric:
+/*spec:nnbd-off.member: testIsNotGeneric:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -379,9 +605,63 @@
   inst:JSUnmodifiableArray<dynamic>,
   is:GenericClass<int,String>]
 */
+/*spec:nnbd-sdk.member: testIsNotGeneric:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:GenericClass<int*,String*>*]
+*/
 testIsNotGeneric() => null is! GenericClass<int, String>;
 
-/*member: testIsNotGenericRaw:
+/*spec:nnbd-off.member: testIsNotGenericRaw:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -421,9 +701,52 @@
   inst:JSNull,
   is:GenericClass<dynamic,dynamic>]
 */
+/*spec:nnbd-sdk.member: testIsNotGenericRaw:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:GenericClass<dynamic,dynamic>*]
+*/
 testIsNotGenericRaw() => null is! GenericClass;
 
-/*member: testIsNotGenericDynamic:
+/*spec:nnbd-off.member: testIsNotGenericDynamic:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -463,9 +786,52 @@
   inst:JSNull,
   is:GenericClass<dynamic,dynamic>]
 */
+/*spec:nnbd-sdk.member: testIsNotGenericDynamic:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:GenericClass<dynamic,dynamic>*]
+*/
 testIsNotGenericDynamic() => null is! GenericClass<dynamic, dynamic>;
 
-/*member: testIsTypedef:
+/*spec:nnbd-off.member: testIsTypedef:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -516,9 +882,63 @@
   inst:JSUnmodifiableArray<dynamic>,
   is:dynamic Function()]
 */
+/*spec:nnbd-sdk.member: testIsTypedef:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:dynamic Function()*]
+*/
 testIsTypedef() => null is Typedef;
 
-/*member: testIsTypedefGeneric:
+/*spec:nnbd-off.member: testIsTypedefGeneric:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -569,9 +989,63 @@
   inst:JSUnmodifiableArray<dynamic>,
   is:int Function(String)]
 */
+/*spec:nnbd-sdk.member: testIsTypedefGeneric:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:int* Function(String*)*]
+*/
 testIsTypedefGeneric() => null is GenericTypedef<int, String>;
 
-/*member: testIsTypedefGenericRaw:
+/*spec:nnbd-off.member: testIsTypedefGenericRaw:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -622,9 +1096,63 @@
   inst:JSUnmodifiableArray<dynamic>,
   is:dynamic Function(dynamic)]
 */
+/*spec:nnbd-sdk.member: testIsTypedefGenericRaw:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:dynamic Function(dynamic)*]
+*/
 testIsTypedefGenericRaw() => null is GenericTypedef;
 
-/*member: testIsTypedefGenericDynamic:
+/*spec:nnbd-off.member: testIsTypedefGenericDynamic:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -675,9 +1203,63 @@
   inst:JSUnmodifiableArray<dynamic>,
   is:dynamic Function(dynamic)]
 */
+/*spec:nnbd-sdk.member: testIsTypedefGenericDynamic:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:dynamic Function(dynamic)*]
+*/
 testIsTypedefGenericDynamic() => null is GenericTypedef<dynamic, dynamic>;
 
-/*member: testIsTypedefDeep:
+/*spec:nnbd-off.member: testIsTypedefDeep:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -728,9 +1310,63 @@
   inst:JSUnmodifiableArray<dynamic>,
   is:List<int Function(dynamic Function(dynamic))>]
 */
+/*spec:nnbd-sdk.member: testIsTypedefDeep:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:List<int* Function(dynamic Function(dynamic)*)*>*]
+*/
 testIsTypedefDeep() => null is List<GenericTypedef<int, GenericTypedef>>;
 
-/*member: testAs:
+/*spec:nnbd-off.member: testAs:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -770,10 +1406,53 @@
   inst:Closure,
   inst:JSBool]
 */
+/*spec:nnbd-sdk.member: testAs:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1),
+  throwRuntimeError(1)],
+ type=[
+  as:Class*,
+  inst:Closure,
+  inst:JSBool]
+*/
 // ignore: UNNECESSARY_CAST
 testAs(dynamic o) => o as Class;
 
-/*member: testAsGeneric:
+/*spec:nnbd-off.member: testAsGeneric:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -824,10 +1503,64 @@
   inst:JSMutableArray<dynamic>,
   inst:JSUnmodifiableArray<dynamic>]
 */
+/*spec:nnbd-sdk.member: testAsGeneric:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2),
+  throwRuntimeError(1)],
+ type=[
+  as:GenericClass<int*,String*>*,
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>]
+*/
 // ignore: UNNECESSARY_CAST
 testAsGeneric(dynamic o) => o as GenericClass<int, String>;
 
-/*member: testAsGenericRaw:
+/*spec:nnbd-off.member: testAsGenericRaw:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -867,10 +1600,53 @@
   inst:Closure,
   inst:JSBool]
 */
+/*spec:nnbd-sdk.member: testAsGenericRaw:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1),
+  throwRuntimeError(1)],
+ type=[
+  as:GenericClass<dynamic,dynamic>*,
+  inst:Closure,
+  inst:JSBool]
+*/
 // ignore: UNNECESSARY_CAST
 testAsGenericRaw(dynamic o) => o as GenericClass;
 
-/*member: testAsGenericDynamic:
+/*spec:nnbd-off.member: testAsGenericDynamic:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -910,6 +1686,49 @@
   inst:Closure,
   inst:JSBool]
 */
+/*spec:nnbd-sdk.member: testAsGenericDynamic:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1),
+  throwRuntimeError(1)],
+ type=[
+  as:GenericClass<dynamic,dynamic>*,
+  inst:Closure,
+  inst:JSBool]
+*/
 // ignore: UNNECESSARY_CAST
 testAsGenericDynamic(dynamic o) => o as GenericClass<dynamic, dynamic>;
 
@@ -921,7 +1740,7 @@
 /*member: testIfNotNull:dynamic=[Object.==,foo],type=[inst:JSNull]*/
 testIfNotNull(o) => o?.foo;
 
-/*member: testTypedIfNotNull:
+/*spec:nnbd-off.member: testTypedIfNotNull:
  dynamic=[
   Class.==,
   Class.field],
@@ -964,6 +1783,52 @@
   inst:JSNull,
   param:Class]
 */
+/*spec:nnbd-sdk.member: testTypedIfNotNull:
+ dynamic=[
+  Class.==,
+  Class.field],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class*]
+*/
 testTypedIfNotNull(Class o) => o?.field;
 
 /*member: testIfNotNullSet:dynamic=[Object.==,foo=],type=[inst:JSBool,inst:JSNull]*/
diff --git a/tests/compiler/dart2js/impact/data/extract_type_arguments.dart b/tests/compiler/dart2js/impact/data/extract_type_arguments.dart
index 78bcadf..ac1d171 100644
--- a/tests/compiler/dart2js/impact/data/extract_type_arguments.dart
+++ b/tests/compiler/dart2js/impact/data/extract_type_arguments.dart
@@ -14,7 +14,7 @@
 /*member: C.:static=[Object.(0)]*/
 class C implements A<int>, B<String, bool> {}
 
-/*member: testA:
+/*spec:nnbd-off.member: testA:
  dynamic=[call<A.T>(0)],
  static=[
   Rti._bind(1),
@@ -68,9 +68,66 @@
   inst:JSUnmodifiableArray<dynamic>,
   is:A<A.T>]
 */
+/*spec:nnbd-sdk.member: testA:
+ dynamic=[call<A.T>(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  extractTypeArguments<A<dynamic>*>(2),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  impl:A<dynamic>*,
+  impl:Function,
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:A<A.T>]
+*/
 testA(c, f) => extractTypeArguments<A>(c, f);
 
-/*member: testB:
+/*spec:nnbd-off.member: testB:
  dynamic=[call<B.S,B.U>(0)],
  static=[
   Rti._bind(1),
@@ -124,6 +181,63 @@
   inst:JSUnmodifiableArray<dynamic>,
   is:B<B.S,B.U>]
 */
+/*spec:nnbd-sdk.member: testB:
+ dynamic=[call<B.S,B.U>(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  extractTypeArguments<B<dynamic,dynamic>*>(2),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  impl:B<dynamic,dynamic>*,
+  impl:Function,
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:B<B.S,B.U>]
+*/
 testB(c, f) => extractTypeArguments<B>(c, f);
 
 /*member: main:static=[C.(0),testA(2),testB(2)],type=[inst:JSNull]*/
diff --git a/tests/compiler/dart2js/impact/data/future_or.dart b/tests/compiler/dart2js/impact/data/future_or.dart
index 336fdef..0e51f38 100644
--- a/tests/compiler/dart2js/impact/data/future_or.dart
+++ b/tests/compiler/dart2js/impact/data/future_or.dart
@@ -6,7 +6,23 @@
 
 import "dart:async";
 
-/*member: main:dynamic=[runtimeType],runtimeType=[unknown:FutureOr<int>],static=[Future.value(1),checkTypeBound(4),print(1),throwTypeError(1)],type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*spec:nnbd-off.member: main:dynamic=[runtimeType],runtimeType=[unknown:FutureOr<int>],static=[Future.value(1),checkTypeBound(4),print(1),throwTypeError(1)],type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*spec:nnbd-sdk.member: main:
+ dynamic=[runtimeType],
+ runtimeType=[unknown:FutureOr<int*>*],
+ static=[
+  Future.value(1),
+  checkTypeBound(4),
+  print(1),
+  throwTypeError(1)],
+ type=[
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSUInt31,
+  inst:JSUInt32]
+*/
 @pragma('dart2js:disableFinal')
 void main() {
   FutureOr<int> i = new Future<int>.value(0);
diff --git a/tests/compiler/dart2js/impact/data/initializers.dart b/tests/compiler/dart2js/impact/data/initializers.dart
index 3a7c734..36e9210 100644
--- a/tests/compiler/dart2js/impact/data/initializers.dart
+++ b/tests/compiler/dart2js/impact/data/initializers.dart
@@ -30,7 +30,7 @@
   testGenericClass();
 }
 
-/*member: testDefaultValuesPositional:
+/*spec:nnbd-off.member: testDefaultValuesPositional:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -69,9 +69,51 @@
   inst:JSBool,
   param:bool]
 */
+/*spec:nnbd-sdk.member: testDefaultValuesPositional:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:bool*]
+*/
 testDefaultValuesPositional([bool value = false]) {}
 
-/*member: testDefaultValuesNamed:
+/*spec:nnbd-off.member: testDefaultValuesNamed:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -110,6 +152,48 @@
   inst:JSBool,
   param:bool]
 */
+/*spec:nnbd-sdk.member: testDefaultValuesNamed:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:bool*]
+*/
 testDefaultValuesNamed({bool value: false}) {}
 
 class ClassFieldInitializer1 {
@@ -162,7 +246,7 @@
 
 /*member: ClassInstanceFieldWithInitializer.:static=[Object.(0)]*/
 class ClassInstanceFieldWithInitializer {
-  /*member: ClassInstanceFieldWithInitializer.field:
+  /*spec:nnbd-off.member: ClassInstanceFieldWithInitializer.field:
    static=[
     Rti._bind(1),
     Rti._eval(1),
@@ -201,6 +285,48 @@
     inst:JSBool,
     param:bool]
   */
+  /*spec:nnbd-sdk.member: ClassInstanceFieldWithInitializer.field:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    param:bool*]
+  */
   var field = false;
 }
 
@@ -209,7 +335,7 @@
 
 /*member: ClassInstanceFieldTyped.:static=[Object.(0)]*/
 class ClassInstanceFieldTyped {
-  /*member: ClassInstanceFieldTyped.field:
+  /*spec:nnbd-off.member: ClassInstanceFieldTyped.field:
    static=[
     Rti._bind(1),
     Rti._eval(1),
@@ -249,6 +375,49 @@
     inst:JSNull,
     param:int]
   */
+  /*spec:nnbd-sdk.member: ClassInstanceFieldTyped.field:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    inst:JSNull,
+    param:int*]
+  */
   int field;
 }
 
@@ -275,7 +444,7 @@
 testSuperInitializer() => new ClassSuperInitializer();
 
 class ClassGeneric<T> {
-  /*member: ClassGeneric.:
+  /*spec:nnbd-off.member: ClassGeneric.:
    static=[
     Object.(0),
     Rti._bind(1),
@@ -327,6 +496,61 @@
     inst:JSUnmodifiableArray<dynamic>,
     param:ClassGeneric.T]
   */
+  /*spec:nnbd-sdk.member: ClassGeneric.:
+   static=[
+    Object.(0),
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    checkSubtypeOfRuntimeType(2),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:ClassGeneric.T*]
+  */
   ClassGeneric(T arg);
 }
 
diff --git a/tests/compiler/dart2js/impact/data/injected_cast.dart b/tests/compiler/dart2js/impact/data/injected_cast.dart
index 3ebf374..6c2a678 100644
--- a/tests/compiler/dart2js/impact/data/injected_cast.dart
+++ b/tests/compiler/dart2js/impact/data/injected_cast.dart
@@ -16,7 +16,7 @@
 
 /*member: Class1.:static=[Object.(0)]*/
 class Class1 {
-  /*member: Class1.field1:
+  /*spec:nnbd-off.member: Class1.field1:
    static=[
     Rti._bind(1),
     Rti._eval(1),
@@ -56,10 +56,53 @@
     inst:JSNull,
     param:A]
   */
+  /*spec:nnbd-sdk.member: Class1.field1:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    inst:JSNull,
+    param:A*]
+  */
   A field1;
 }
 
-/*member: method1:
+/*spec:nnbd-off.member: method1:
  dynamic=[Class1.field1=],
  static=[
   Rti._bind(1),
@@ -100,6 +143,50 @@
   inst:JSBool,
   is:Class1]
 */
+/*spec:nnbd-sdk.member: method1:
+ dynamic=[Class1.field1=],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:A*,
+  inst:Closure,
+  inst:JSBool,
+  is:Class1*]
+*/
 method1(dynamic o, dynamic value) {
   if (o is! Class1) return;
   o.field1 = value;
@@ -107,21 +194,131 @@
 
 /*member: Class2.:static=[Object.(0)]*/
 class Class2<T> {
-  /*member: Class2.field2:
-   static=*,
-   type=[inst:*,param:Class2.T]
+  /*spec:nnbd-off.member: Class2.field2:
+   static=%,
+   type=[inst:%,param:Class2.T]
    */
+  /*spec:nnbd-sdk.member: Class2.field2:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    checkSubtypeOfRuntimeType(2),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSNull,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:Class2.T*]
+  */
   T field2;
 }
 
-/*member: method2:
+/*spec:nnbd-off.member: method2:
  dynamic=[Class2.field2=],
- static=*,
+ static=%,
  type=[
   impl:A,
-  inst:*,
+  inst:%,
   is:Class2<A>]
 */
+/*spec:nnbd-sdk.member: method2:
+ dynamic=[Class2.field2=],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  impl:A*,
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:Class2<A*>*]
+*/
 method2(dynamic o, dynamic value) {
   if (o is! Class2<A>) return;
   o.field2 = value;
@@ -129,7 +326,7 @@
 
 /*member: Class3.:static=[Object.(0)]*/
 class Class3 {
-  /*member: Class3.method3:
+  /*spec:nnbd-off.member: Class3.method3:
    static=[
     Rti._bind(1),
     Rti._eval(1),
@@ -171,10 +368,55 @@
     param:B,
     param:C]
   */
+  /*spec:nnbd-sdk.member: Class3.method3:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    inst:JSNull,
+    param:A*,
+    param:B*,
+    param:C*]
+  */
   method3(A a, [B b, C c]) {}
 }
 
-/*member: method3:
+/*spec:nnbd-off.member: method3:
  dynamic=[Class3.method3(3)],
  static=[
   Rti._bind(1),
@@ -217,6 +459,52 @@
   is:Class3,
   param:B]
 */
+/*spec:nnbd-sdk.member: method3:
+ dynamic=[Class3.method3(3)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:A*,
+  impl:C*,
+  inst:Closure,
+  inst:JSBool,
+  is:Class3*,
+  param:B*]
+*/
 method3(dynamic o, dynamic a, B b, dynamic c) {
   if (o is! Class3) return;
   o.method3(a, b, c);
@@ -224,7 +512,7 @@
 
 /*member: Class4.:static=[Object.(0)]*/
 class Class4 {
-  /*member: Class4.method4:
+  /*spec:nnbd-off.member: Class4.method4:
    static=[
     Rti._bind(1),
     Rti._eval(1),
@@ -266,10 +554,55 @@
     param:B,
     param:C]
   */
+  /*spec:nnbd-sdk.member: Class4.method4:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    inst:JSNull,
+    param:A*,
+    param:B*,
+    param:C*]
+  */
   method4(A a, {B b, C c}) {}
 }
 
-/*member: method4:
+/*spec:nnbd-off.member: method4:
  dynamic=[Class4.method4(1,b,c)],
  static=[
   Rti._bind(1),
@@ -312,6 +645,52 @@
   is:Class4,
   param:B]
 */
+/*spec:nnbd-sdk.member: method4:
+ dynamic=[Class4.method4(1,b,c)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:A*,
+  impl:C*,
+  inst:Closure,
+  inst:JSBool,
+  is:Class4*,
+  param:B*]
+*/
 method4(dynamic o, dynamic a, B b, dynamic c) {
   if (o is! Class4) return;
   o.method4(a, c: c, b: b);
@@ -319,10 +698,10 @@
 
 /*member: Class5.:static=[Object.(0)]*/
 class Class5<T1, T2> {
-  /*member: Class5.method5:
-   static=*,
+  /*spec:nnbd-off.member: Class5.method5:
+   static=%,
    type=[
-    inst:*,
+    inst:%,
     param:C,
     param:Class5.T1,
     param:Class5.T2,
@@ -330,21 +709,140 @@
     param:method5.S1,
     param:method5.S2]
   */
+  /*spec:nnbd-sdk.member: Class5.method5:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    checkSubtypeOfRuntimeType(2),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSNull,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:C*,
+    param:Class5.T1*,
+    param:Class5.T2*,
+    param:Object*,
+    param:method5.S1*,
+    param:method5.S2*]
+  */
   method5<S1, S2>(T1 a, [T2 b, C c, S1 d, S2 e]) {}
 }
 
-/*member: method5:
+/*spec:nnbd-off.member: method5:
  dynamic=[Class5.method5<D,E>(5)],
- static=*,
+ static=%,
  type=[
   impl:A,
   impl:D,
-  inst:*,
+  inst:%,
   is:Class5<A,B>,
   param:B,
   param:C,
   param:E]
 */
+/*spec:nnbd-sdk.member: method5:
+ dynamic=[Class5.method5<D*,E*>(5)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  impl:A*,
+  impl:D*,
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:Class5<A*,B*>*,
+  param:B*,
+  param:C*,
+  param:E*]
+*/
 method5(dynamic o, dynamic a, B b, C c, dynamic d, E e) {
   if (o is! Class5<A, B>) return;
   o.method5<D, E>(a, b, c, d, e);
@@ -352,10 +850,10 @@
 
 /*member: Class6.:static=[Object.(0)]*/
 class Class6<T1, T2> {
-  /*member: Class6.method6:
-   static=*,
+  /*spec:nnbd-off.member: Class6.method6:
+   static=%,
    type=[
-    inst:*,
+    inst:%,
     param:C,
     param:Class6.T1,
     param:Class6.T2,
@@ -363,21 +861,140 @@
     param:method6.S1,
     param:method6.S2]
   */
+  /*spec:nnbd-sdk.member: Class6.method6:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    checkSubtypeOfRuntimeType(2),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSNull,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:C*,
+    param:Class6.T1*,
+    param:Class6.T2*,
+    param:Object*,
+    param:method6.S1*,
+    param:method6.S2*]
+  */
   method6<S1, S2>(T1 a, {T2 b, C c, S1 d, S2 e}) {}
 }
 
-/*member: method6:
+/*spec:nnbd-off.member: method6:
  dynamic=[Class6.method6<D,E>(1,b,c,d,e)],
- static=*,
+ static=%,
  type=[
   impl:A,
   impl:D,
-  inst:*,
+  inst:%,
   is:Class6<A,B>,
   param:B,
   param:C,
   param:E]
 */
+/*spec:nnbd-sdk.member: method6:
+ dynamic=[Class6.method6<D*,E*>(1,b,c,d,e)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  impl:A*,
+  impl:D*,
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:Class6<A*,B*>*,
+  param:B*,
+  param:C*,
+  param:E*]
+*/
 method6(dynamic o, dynamic a, B b, C c, dynamic d, E e) {
   if (o is! Class6<A, B>) return;
   o.method6<D, E>(a, d: d, b: b, e: e, c: c);
@@ -389,7 +1006,7 @@
   A Function(A) get f => null;
 }
 
-/*member: method7:
+/*spec:nnbd-off.member: method7:
  dynamic=[
   Class7.f(1),
   call(1)],
@@ -432,6 +1049,52 @@
   inst:JSBool,
   is:Class7]
 */
+/*spec:nnbd-sdk.member: method7:
+ dynamic=[
+  Class7.f(1),
+  call(1)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:A*,
+  inst:Closure,
+  inst:JSBool,
+  is:Class7*]
+*/
 method7(dynamic o, dynamic a) {
   if (o is! Class7) return;
   o.f(a);
@@ -439,27 +1102,193 @@
 
 /*member: F.:static=[Object.(0)]*/
 class F<T> {
-  /*member: F.method:static=*,type=[inst:*,param:List<F.T>]*/
+  /*spec:nnbd-off.member: F.method:static=%,type=[inst:%,param:List<F.T>]*/
+  /*spec:nnbd-sdk.member: F.method:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSNull,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:List<F.T*>*]
+  */
   T method(List<T> list) => null;
 
-  /*member: F.field:static=*,type=[inst:*,param:F.T]*/
+  /*spec:nnbd-off.member: F.field:static=%,type=[inst:%,param:F.T]*/
+  /*spec:nnbd-sdk.member: F.field:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    checkSubtypeOfRuntimeType(2),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSNull,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:F.T*]
+  */
   T field;
 }
 
 /*member: G.:static=[F.(0)]*/
 class G extends F<int> {}
 
-/*member: method8:
+/*spec:nnbd-off.member: method8:
  dynamic=[G.method(1)],
- static=*,
- type=[impl:List<int>,inst:*,is:G,param:Iterable<int>]
+ static=%,
+ type=[impl:List<int>,inst:%,is:G,param:Iterable<int>]
+*/
+/*spec:nnbd-sdk.member: method8:
+ dynamic=[G.method(1)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  impl:List<int*>*,
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  is:G*,
+  param:Iterable<int*>*]
 */
 method8(dynamic g, Iterable<int> iterable) {
   if (g is! G) return null;
   return g.method(iterable);
 }
 
-/*member: method9:
+/*spec:nnbd-off.member: method9:
  dynamic=[G.field=],
  static=[
   Rti._bind(1),
@@ -502,12 +1331,58 @@
   is:G,
   param:num]
 */
+/*spec:nnbd-sdk.member: method9:
+ dynamic=[G.field=],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:int*,
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  is:G*,
+  param:num*]
+*/
 method9(dynamic g, num value) {
   if (g is! G) return null;
   return g.field = value;
 }
 
-/*member: main:**/
+/*member: main:%*/
 main() {
   method1(new Class1(), null);
   method2(new Class2<A>(), null);
diff --git a/tests/compiler/dart2js/impact/data/invokes.dart b/tests/compiler/dart2js/impact/data/invokes.dart
index 045a41c..3e7d4b4 100644
--- a/tests/compiler/dart2js/impact/data/invokes.dart
+++ b/tests/compiler/dart2js/impact/data/invokes.dart
@@ -117,7 +117,7 @@
   topLevelFunction3(15, c: 16, b: 17);
 }
 
-/*member: topLevelFunction1Typed:
+/*spec:nnbd-off.member: topLevelFunction1Typed:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -156,9 +156,51 @@
   inst:JSBool,
   param:int]
 */
+/*spec:nnbd-sdk.member: topLevelFunction1Typed:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:int*]
+*/
 void topLevelFunction1Typed(int a) {}
 
-/*member: topLevelFunction2Typed:
+/*spec:nnbd-off.member: topLevelFunction2Typed:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -200,9 +242,54 @@
   param:double,
   param:num]
 */
+/*spec:nnbd-sdk.member: topLevelFunction2Typed:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:String*,
+  param:double*,
+  param:num*]
+*/
 int topLevelFunction2Typed(String a, [num b, double c]) => null;
 
-/*member: topLevelFunction3Typed:
+/*spec:nnbd-off.member: topLevelFunction3Typed:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -255,11 +342,67 @@
   param:Map<String,bool>,
   param:bool]
 */
+/*spec:nnbd-sdk.member: topLevelFunction3Typed:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:List<int*>*,
+  param:Map<String*,bool*>*,
+  param:bool*]
+*/
 double topLevelFunction3Typed(bool a, {List<int> b, Map<String, bool> c}) {
   return null;
 }
 
-/*member: testTopLevelInvokeTyped:
+/*spec:nnbd-off.member: testTopLevelInvokeTyped:
  static=[
   topLevelFunction1Typed(1),
   topLevelFunction2Typed(1),
@@ -283,6 +426,30 @@
   inst:List<int>,
   inst:Map<String,bool>]
 */
+/*spec:nnbd-sdk.member: testTopLevelInvokeTyped:
+ static=[
+  topLevelFunction1Typed(1),
+  topLevelFunction2Typed(1),
+  topLevelFunction2Typed(2),
+  topLevelFunction2Typed(3),
+  topLevelFunction3Typed(1),
+  topLevelFunction3Typed(1,b),
+  topLevelFunction3Typed(1,b,c),
+  topLevelFunction3Typed(1,b,c),
+  topLevelFunction3Typed(1,c)],
+ type=[
+  inst:JSBool,
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNull,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSString,
+  inst:JSUInt31,
+  inst:JSUInt32,
+  inst:List<int*>,
+  inst:Map<String*,bool*>]
+*/
 testTopLevelInvokeTyped() {
   topLevelFunction1Typed(0);
   topLevelFunction2Typed('1');
@@ -295,7 +462,7 @@
   topLevelFunction3Typed(false, c: {'16': false}, b: [17]);
 }
 
-/*member: topLevelFunctionTyped1:
+/*spec:nnbd-off.member: topLevelFunctionTyped1:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -345,9 +512,62 @@
   inst:JSUnmodifiableArray<dynamic>,
   param:void Function(num)]
 */
+/*spec:nnbd-sdk.member: topLevelFunctionTyped1:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:void Function(num*)*]
+*/
 topLevelFunctionTyped1(void a(num b)) {}
 
-/*member: topLevelFunctionTyped2:
+/*spec:nnbd-off.member: topLevelFunctionTyped2:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -397,9 +617,62 @@
   inst:JSUnmodifiableArray<dynamic>,
   param:void Function(num,[String])]
 */
+/*spec:nnbd-sdk.member: topLevelFunctionTyped2:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:void Function(num*,[String*])*]
+*/
 topLevelFunctionTyped2(void a(num b, [String c])) {}
 
-/*member: topLevelFunctionTyped3:
+/*spec:nnbd-off.member: topLevelFunctionTyped3:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -449,9 +722,62 @@
   inst:JSUnmodifiableArray<dynamic>,
   param:void Function(num,{String c,int d})]
 */
+/*spec:nnbd-sdk.member: topLevelFunctionTyped3:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:void Function(num*,{String* c,int* d})*]
+*/
 topLevelFunctionTyped3(void a(num b, {String c, int d})) {}
 
-/*member: topLevelFunctionTyped4:
+/*spec:nnbd-off.member: topLevelFunctionTyped4:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -501,6 +827,59 @@
   inst:JSUnmodifiableArray<dynamic>,
   param:void Function(num,{int c,String d})]
 */
+/*spec:nnbd-sdk.member: topLevelFunctionTyped4:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:void Function(num*,{int* c,String* d})*]
+*/
 topLevelFunctionTyped4(void a(num b, {String d, int c})) {}
 
 /*member: testTopLevelFunctionTyped:
@@ -539,7 +918,7 @@
 /*member: testTopLevelSetterSet:static=[set:topLevelSetter],type=[inst:JSNull]*/
 testTopLevelSetterSet() => topLevelSetter = null;
 
-/*member: topLevelSetterTyped=:
+/*spec:nnbd-off.member: topLevelSetterTyped=:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -578,6 +957,48 @@
   inst:JSBool,
   param:int]
 */
+/*spec:nnbd-sdk.member: topLevelSetterTyped=:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:int*]
+*/
 void set topLevelSetterTyped(int value) {}
 
 /*member: testTopLevelSetterSetTyped:static=[set:topLevelSetterTyped],type=[inst:JSNull]*/
@@ -606,7 +1027,7 @@
 /*member: testTopLevelFieldFinal:static=[topLevelFieldFinal]*/
 testTopLevelFieldFinal() => topLevelFieldFinal;
 
-/*member: topLevelFieldTyped:
+/*spec:nnbd-off.member: topLevelFieldTyped:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -646,12 +1067,55 @@
   inst:JSNull,
   param:int]
 */
+/*spec:nnbd-sdk.member: topLevelFieldTyped:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:int*]
+*/
 int topLevelFieldTyped;
 
 /*member: testTopLevelFieldTyped:static=[topLevelFieldTyped]*/
 testTopLevelFieldTyped() => topLevelFieldTyped;
 
-/*member: topLevelFieldGeneric1:
+/*spec:nnbd-off.member: topLevelFieldGeneric1:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -691,12 +1155,55 @@
   inst:JSNull,
   param:GenericClass<dynamic,dynamic>]
 */
+/*spec:nnbd-sdk.member: topLevelFieldGeneric1:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:GenericClass<dynamic,dynamic>*]
+*/
 GenericClass topLevelFieldGeneric1;
 
 /*member: testTopLevelFieldGeneric1:static=[topLevelFieldGeneric1]*/
 testTopLevelFieldGeneric1() => topLevelFieldGeneric1;
 
-/*member: topLevelFieldGeneric2:
+/*spec:nnbd-off.member: topLevelFieldGeneric2:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -736,12 +1243,55 @@
   inst:JSNull,
   param:GenericClass<dynamic,dynamic>]
 */
+/*spec:nnbd-sdk.member: topLevelFieldGeneric2:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:GenericClass<dynamic,dynamic>*]
+*/
 GenericClass<dynamic, dynamic> topLevelFieldGeneric2;
 
 /*member: testTopLevelFieldGeneric2:static=[topLevelFieldGeneric2]*/
 testTopLevelFieldGeneric2() => topLevelFieldGeneric2;
 
-/*member: topLevelFieldGeneric3:
+/*spec:nnbd-off.member: topLevelFieldGeneric3:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -792,6 +1342,60 @@
   inst:JSUnmodifiableArray<dynamic>,
   param:GenericClass<int,String>]
 */
+/*spec:nnbd-sdk.member: topLevelFieldGeneric3:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:GenericClass<int*,String*>*]
+*/
 GenericClass<int, String> topLevelFieldGeneric3;
 
 /*member: testTopLevelFieldGeneric3:static=[topLevelFieldGeneric3]*/
@@ -916,7 +1520,7 @@
   localFunction() {}
 }
 
-/*member: testLocalFunctionTyped:
+/*spec:nnbd-off.member: testLocalFunctionTyped:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -967,6 +1571,60 @@
   inst:JSUnmodifiableArray<dynamic>,
   param:String]
 */
+/*spec:nnbd-sdk.member: testLocalFunctionTyped:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  computeSignature(3),
+  def:localFunction,
+  findType(1),
+  getRuntimeTypeArguments(3),
+  getRuntimeTypeInfo(1),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:Function,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:String*]
+*/
 testLocalFunctionTyped() {
   // ignore: UNUSED_ELEMENT
   int localFunction(String a) => null;
diff --git a/tests/compiler/dart2js/impact/data/jsinterop.dart b/tests/compiler/dart2js/impact/data/jsinterop.dart
index b997a3e..c5581aa 100644
--- a/tests/compiler/dart2js/impact/data/jsinterop.dart
+++ b/tests/compiler/dart2js/impact/data/jsinterop.dart
@@ -61,7 +61,7 @@
 /*member: GenericClass.:static=[JavaScriptObject.(0)]*/
 @JS()
 class GenericClass<T> {
-  /*member: GenericClass.method:
+  /*spec:nnbd-off.member: GenericClass.method:
    static=[
     Rti._bind(1),
     Rti._eval(1),
@@ -112,6 +112,60 @@
     inst:JSUnmodifiableArray<dynamic>,
     param:void Function(GenericClass.T)]
   */
+  /*spec:nnbd-sdk.member: GenericClass.method:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    checkSubtype(4),
+    findType(1),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    instanceType(1),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:Closure,
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSNull,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:void Function(GenericClass.T*)*]
+  */
   external GenericClass method([Callback<T> callback]);
 }
 
diff --git a/tests/compiler/dart2js/impact/data/jsinterop_setter1.dart b/tests/compiler/dart2js/impact/data/jsinterop_setter1.dart
index 3f78563..d0dfa5c 100644
--- a/tests/compiler/dart2js/impact/data/jsinterop_setter1.dart
+++ b/tests/compiler/dart2js/impact/data/jsinterop_setter1.dart
@@ -11,7 +11,7 @@
 
 import 'package:js/js.dart';
 
-/*member: foo=:
+/*spec:nnbd-off.member: foo=:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -61,10 +61,63 @@
   native:SqlError,
   param:Function]
 */
+/*spec:nnbd-sdk.member: foo=:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  native:ApplicationCacheErrorEvent,
+  native:DomError,
+  native:DomException,
+  native:ErrorEvent,
+  native:MediaError,
+  native:NavigatorUserMediaError,
+  native:OverconstrainedError,
+  native:PositionError,
+  native:SensorErrorEvent,
+  native:SpeechRecognitionError,
+  native:SqlError,
+  param:Function*]
+*/
 @JS()
 external set foo(Function f);
 
-/*member: _doStuff:
+/*spec:nnbd-off.member: _doStuff:
  dynamic=[
   File.==,
   File.name],
@@ -111,6 +164,56 @@
   param:File,
   param:String]
 */
+/*spec:nnbd-sdk.member: _doStuff:
+ dynamic=[
+  File.==,
+  File.name],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  defineProperty(3),
+  findType(1),
+  instanceType(1),
+  print(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  inst:JSString,
+  param:File*,
+  param:String*]
+*/
 void _doStuff(String name, File file) {
   if (file == null) {
     print('OK');
@@ -118,12 +221,16 @@
   print(file.name);
 }
 
-/*member: main:
+/*spec:nnbd-off.member: main:
  static=[
  _doStuff,
  allowInterop<Function>(1),
  set:foo]
 */
+/*spec:nnbd-sdk.member: main:static=[
+  _doStuff,
+  allowInterop<Function*>(1),
+  set:foo]*/
 void main() {
   foo = allowInterop(_doStuff);
 }
diff --git a/tests/compiler/dart2js/impact/data/jsinterop_setter2.dart b/tests/compiler/dart2js/impact/data/jsinterop_setter2.dart
index 8ece87e..b52a2ad 100644
--- a/tests/compiler/dart2js/impact/data/jsinterop_setter2.dart
+++ b/tests/compiler/dart2js/impact/data/jsinterop_setter2.dart
@@ -11,7 +11,7 @@
 
 import 'package:js/js.dart';
 
-/*member: foo=:
+/*spec:nnbd-off.member: foo=:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -73,10 +73,75 @@
   native:SqlError,
   param:void Function(String,File)]
 */
+/*spec:nnbd-sdk.member: foo=:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  native:ApplicationCacheErrorEvent,
+  native:DomError,
+  native:DomException,
+  native:ErrorEvent,
+  native:File,
+  native:MediaError,
+  native:NavigatorUserMediaError,
+  native:OverconstrainedError,
+  native:PositionError,
+  native:SensorErrorEvent,
+  native:SpeechRecognitionError,
+  native:SqlError,
+  param:void Function(String*,File*)*]
+*/
 @JS()
 external set foo(void Function(String, File) f);
 
-/*member: _doStuff:
+/*spec:nnbd-off.member: _doStuff:
  dynamic=[
   File.==,
   File.name],
@@ -123,6 +188,56 @@
   param:File,
   param:String]
 */
+/*spec:nnbd-sdk.member: _doStuff:
+ dynamic=[
+  File.==,
+  File.name],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  defineProperty(3),
+  findType(1),
+  instanceType(1),
+  print(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  inst:JSString,
+  param:File*,
+  param:String*]
+*/
 void _doStuff(String name, File file) {
   if (file == null) {
     print('OK');
@@ -130,12 +245,16 @@
   print(file.name);
 }
 
-/*member: main:
+/*spec:nnbd-off.member: main:
  static=[
   _doStuff,
   allowInterop<void Function(String,File)>(1),
   set:foo]
 */
+/*spec:nnbd-sdk.member: main:static=[
+  _doStuff,
+  allowInterop<void Function(String*,File*)*>(1),
+  set:foo]*/
 void main() {
   foo = allowInterop(_doStuff);
 }
diff --git a/tests/compiler/dart2js/impact/data/literals.dart b/tests/compiler/dart2js/impact/data/literals.dart
index 4edd315..9c0bcfa 100644
--- a/tests/compiler/dart2js/impact/data/literals.dart
+++ b/tests/compiler/dart2js/impact/data/literals.dart
@@ -131,7 +131,16 @@
 /*member: testIfNullConstSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
 testIfNullConstSymbol() => const Symbol(null ?? 'foo');
 
-/*member: testTypeLiteral:static=[createRuntimeType(1),typeLiteral(1)],type=[inst:Type,inst:_Type,lit:Object]*/
+/*spec:nnbd-off.member: testTypeLiteral:static=[createRuntimeType(1),typeLiteral(1)],type=[inst:Type,inst:_Type,lit:Object]*/
+/*spec:nnbd-sdk.member: testTypeLiteral:
+ static=[
+  createRuntimeType(1),
+  typeLiteral(1)],
+ type=[
+  inst:Type,
+  inst:_Type,
+  lit:Object*]
+*/
 testTypeLiteral() => Object;
 
 /*member: testBoolFromEnvironment:type=[inst:JSBool]*/
@@ -143,13 +152,17 @@
 /*member: testEmptyListLiteralDynamic:type=[inst:List<dynamic>]*/
 testEmptyListLiteralDynamic() => <dynamic>[];
 
-/*member: testEmptyListLiteralTyped:type=[inst:List<String>]*/
+/*spec:nnbd-off.member: testEmptyListLiteralTyped:type=[inst:List<String>]*/
+/*spec:nnbd-sdk.member: testEmptyListLiteralTyped:type=[inst:List<String*>]*/
 testEmptyListLiteralTyped() => <String>[];
 
 /*member: testEmptyListLiteralConstant:type=[inst:List<dynamic>]*/
 testEmptyListLiteralConstant() => const [];
 
-/*member: testNonEmptyListLiteral:type=[inst:JSBool,inst:List<bool>]*/
+/*spec:nnbd-off.member: testNonEmptyListLiteral:type=[inst:JSBool,inst:List<bool>]*/
+/*spec:nnbd-sdk.member: testNonEmptyListLiteral:type=[
+  inst:JSBool,
+  inst:List<bool*>]*/
 testNonEmptyListLiteral() => [true];
 
 /*member: testEmptyMapLiteral:type=[inst:Map<dynamic,dynamic>]*/
@@ -158,7 +171,8 @@
 /*member: testEmptyMapLiteralDynamic:type=[inst:Map<dynamic,dynamic>]*/
 testEmptyMapLiteralDynamic() => <dynamic, dynamic>{};
 
-/*member: testEmptyMapLiteralTyped:type=[inst:Map<String,int>]*/
+/*spec:nnbd-off.member: testEmptyMapLiteralTyped:type=[inst:Map<String,int>]*/
+/*spec:nnbd-sdk.member: testEmptyMapLiteralTyped:type=[inst:Map<String*,int*>]*/
 testEmptyMapLiteralTyped() => <String, int>{};
 
 /*member: testEmptyMapLiteralConstant:
@@ -170,7 +184,11 @@
 */
 testEmptyMapLiteralConstant() => const {};
 
-/*member: testNonEmptyMapLiteral:type=[inst:JSBool,inst:JSNull,inst:Map<Null,bool>]*/
+/*spec:nnbd-off.member: testNonEmptyMapLiteral:type=[inst:JSBool,inst:JSNull,inst:Map<Null,bool>]*/
+/*spec:nnbd-sdk.member: testNonEmptyMapLiteral:type=[
+  inst:JSBool,
+  inst:JSNull,
+  inst:Map<Null,bool*>]*/
 testNonEmptyMapLiteral() => {null: true};
 
 class GenericClass<X, Y> {
diff --git a/tests/compiler/dart2js/impact/data/native.dart b/tests/compiler/dart2js/impact/data/native.dart
index 3909b77..a923095 100644
--- a/tests/compiler/dart2js/impact/data/native.dart
+++ b/tests/compiler/dart2js/impact/data/native.dart
@@ -47,18 +47,18 @@
 testNativeMethodCreates() native;
 
 // This will trigger native instantiation and therefore include type use
-// `native:X` for all native types. This is truncated to `type=[*]` to avoid
+// `native:X` for all native types. This is truncated to `type=[%]` to avoid
 // dependency on the particular types. If `testNativeMethodReturns` was not
 // called `testNativeMethodCreates` would instead trigger the native
 // instantiations, so the blame is a bit arbitrary.
-/*member: testNativeMethodReturns:type=[*]*/
+/*member: testNativeMethodReturns:type=[%]*/
 @Returns('String|Null|JSArray')
 // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
 testNativeMethodReturns() native;
 
 @Native("NativeClass")
 class NativeClass {
-  /*member: NativeClass.field:
+  /*spec:nnbd-off.member: NativeClass.field:
    static=[
     Rti._bind(1),
     Rti._eval(1),
@@ -104,6 +104,55 @@
     native:int,
     param:Object]
   */
+  /*spec:nnbd-sdk.member: NativeClass.field:
+   static=[
+    Rti._bind(1),
+    Rti._eval(1),
+    _arrayInstanceType(1),
+    _asBool(1),
+    _asBoolQ(1),
+    _asBoolS(1),
+    _asDouble(1),
+    _asDoubleQ(1),
+    _asDoubleS(1),
+    _asInt(1),
+    _asIntQ(1),
+    _asIntS(1),
+    _asNum(1),
+    _asNumQ(1),
+    _asNumS(1),
+    _asObject(1),
+    _asString(1),
+    _asStringQ(1),
+    _asStringS(1),
+    _asTop(1),
+    _generalAsCheckImplementation(1),
+    _generalIsTestImplementation(1),
+    _generalNullableAsCheckImplementation(1),
+    _generalNullableIsTestImplementation(1),
+    _installSpecializedAsCheck(1),
+    _installSpecializedIsTest(1),
+    _instanceType(1),
+    _isBool(1),
+    _isInt(1),
+    _isNum(1),
+    _isObject(1),
+    _isString(1),
+    _isTop(1),
+    findType(1),
+    instanceType(1)],
+   type=[
+    inst:Closure,
+    inst:JSBool,
+    inst:JSNull,
+    native:JSExtendableArray<JSExtendableArray.E>,
+    native:Object,
+    native:String,
+    native:bool,
+    native:double,
+    native:int,
+    param:Object*]
+  */
   @annotation_Creates_SerializedScriptValue
   final Object field;
 
@@ -112,7 +161,7 @@
   }
 }
 
-/*member: testNativeField:
+/*spec:nnbd-off.member: testNativeField:
  dynamic=[NativeClass.field],
  static=[
   Rti._bind(1),
@@ -153,4 +202,48 @@
   inst:JSBool,
   param:NativeClass]
 */
+/*spec:nnbd-sdk.member: testNativeField:
+ dynamic=[NativeClass.field],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  defineProperty(3),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:NativeClass*]
+*/
 testNativeField(NativeClass c) => c.field;
diff --git a/tests/compiler/dart2js/impact/data/promotion.dart b/tests/compiler/dart2js/impact/data/promotion.dart
index 9341be1..fe2a60d 100644
--- a/tests/compiler/dart2js/impact/data/promotion.dart
+++ b/tests/compiler/dart2js/impact/data/promotion.dart
@@ -39,7 +39,7 @@
   dynamicToNoSuchMethodTearOff(null);
 }
 
-/*member: positiveTyped:
+/*spec:nnbd-off.member: positiveTyped:
  dynamic=[SubClass.method(0)],
  static=[
   Rti._bind(1),
@@ -80,11 +80,55 @@
   is:SubClass,
   param:Class]
 */
+/*spec:nnbd-sdk.member: positiveTyped:
+ dynamic=[SubClass.method(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  is:SubClass*,
+  param:Class*]
+*/
 positiveTyped(Class cls) {
   if (cls is SubClass) cls.method();
 }
 
-/*member: positiveDynamic:
+/*spec:nnbd-off.member: positiveDynamic:
  dynamic=[SubClass.method(0)],
  static=[
   Rti._bind(1),
@@ -124,11 +168,54 @@
   inst:JSBool,
   is:SubClass]
 */
+/*spec:nnbd-sdk.member: positiveDynamic:
+ dynamic=[SubClass.method(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  is:SubClass*]
+*/
 positiveDynamic(dynamic cls) {
   if (cls is SubClass) cls.method();
 }
 
-/*member: negativeDynamic:
+/*spec:nnbd-off.member: negativeDynamic:
  dynamic=[SubClass.method(0)],
  static=[
   Rti._bind(1),
@@ -168,6 +255,49 @@
   inst:JSBool,
   is:SubClass]
 */
+/*spec:nnbd-sdk.member: negativeDynamic:
+ dynamic=[SubClass.method(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  is:SubClass*]
+*/
 negativeDynamic(dynamic cls) {
   if (cls is! SubClass) return;
   cls.method();
diff --git a/tests/compiler/dart2js/impact/data/runtime_type.dart b/tests/compiler/dart2js/impact/data/runtime_type.dart
index bb1703f..e9cdb53 100644
--- a/tests/compiler/dart2js/impact/data/runtime_type.dart
+++ b/tests/compiler/dart2js/impact/data/runtime_type.dart
@@ -6,9 +6,16 @@
 
 /*member: Class1a.:static=[Object.(0)]*/
 class Class1a<T> {
-  /*member: Class1a.==:
+  /*spec:nnbd-off.member: Class1a.==:
    dynamic=[this:Class1a.runtimeType,Object.runtimeType,Type.==],
-   runtimeType=[equals:Class1a<Class1a.T>/Object]
+   runtimeType=[equals:Class1a<Class1a.T>==Object]
+  */
+  /*spec:nnbd-sdk.member: Class1a.==:
+   dynamic=[
+    Object.runtimeType,
+    Type.==,
+    this:Class1a.runtimeType],
+   runtimeType=[equals:Class1a<Class1a.T*>*==Object]
   */
   bool operator ==(other) {
     return runtimeType == other.runtimeType;
@@ -17,9 +24,19 @@
 
 /*member: Class1b.:static=[Class1a.(0)]*/
 class Class1b<T> extends Class1a<T> {
-  /*member: Class1b.==:
-   dynamic=[this:Class1b.runtimeType,Object.runtimeType,Type.==],
-   runtimeType=[equals:Object/Class1b<Class1b.T>]
+  /*spec:nnbd-off.member: Class1b.==:
+   dynamic=[
+    Object.runtimeType,
+    Type.==,
+    this:Class1b.runtimeType],
+   runtimeType=[equals:Object==Class1b<Class1b.T>]
+  */
+  /*spec:nnbd-sdk.member: Class1b.==:
+   dynamic=[
+    Object.runtimeType,
+    Type.==,
+    this:Class1b.runtimeType],
+   runtimeType=[equals:Object==Class1b<Class1b.T*>*]
   */
   bool operator ==(other) {
     return other.runtimeType == runtimeType;
@@ -28,9 +45,22 @@
 
 /*member: Class1c.:static=[Object.(0)]*/
 class Class1c<T> implements Class1a<T> {
-  /*member: Class1c.==:
-   dynamic=[this:Class1c.runtimeType,Object.==,Object.runtimeType,Type.==],
-   runtimeType=[equals:Class1c<Class1c.T>/Object],
+  /*spec:nnbd-off.member: Class1c.==:
+   dynamic=[
+    Object.==,
+    Object.runtimeType,
+    Type.==,
+    this:Class1c.runtimeType],
+   runtimeType=[equals:Class1c<Class1c.T>==Object],
+   type=[inst:JSNull]
+  */
+  /*spec:nnbd-sdk.member: Class1c.==:
+   dynamic=[
+    Object.==,
+    Object.runtimeType,
+    Type.==,
+    this:Class1c.runtimeType],
+   runtimeType=[equals:Class1c<Class1c.T*>*==Object],
    type=[inst:JSNull]
   */
   bool operator ==(other) {
@@ -40,9 +70,22 @@
 
 /*member: Class1d.:static=[Object.(0)]*/
 class Class1d<T> implements Class1a<T> {
-  /*member: Class1d.==:
-   dynamic=[this:Class1d.runtimeType,Object.==,Object.runtimeType,Type.==],
-   runtimeType=[equals:Object/Class1d<Class1d.T>],
+  /*spec:nnbd-off.member: Class1d.==:
+   dynamic=[
+    Object.==,
+    Object.runtimeType,
+    Type.==,
+    this:Class1d.runtimeType],
+   runtimeType=[equals:Object==Class1d<Class1d.T>],
+   type=[inst:JSNull]
+  */
+  /*spec:nnbd-sdk.member: Class1d.==:
+   dynamic=[
+    Object.==,
+    Object.runtimeType,
+    Type.==,
+    this:Class1d.runtimeType],
+   runtimeType=[equals:Object==Class1d<Class1d.T*>*],
    type=[inst:JSNull]
   */
   bool operator ==(other) {
@@ -62,7 +105,7 @@
 /*member: Class4.:static=[Object.(0)]*/
 class Class4 {}
 
-/*member: toString1:
+/*spec:nnbd-off.member: toString1:
  dynamic=[
   Class2.runtimeType,
   toString(0)],
@@ -118,9 +161,68 @@
   inst:JSUnmodifiableArray<dynamic>,
   param:Class2<int>]
 */
+/*spec:nnbd-sdk.member: toString1:
+ dynamic=[
+  Class2.runtimeType,
+  toString(0)],
+ runtimeType=[string:Class2<int*>*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  S(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSString,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class2<int*>*]
+*/
 toString1(Class2<int> c) => '${c.runtimeType}';
 
-/*member: toString2:
+/*spec:nnbd-off.member: toString2:
  dynamic=[
   Class2.==,
   Class2.runtimeType,
@@ -178,9 +280,70 @@
   inst:JSUnmodifiableArray<dynamic>,
   param:Class2<int>]
 */
+/*spec:nnbd-sdk.member: toString2:
+ dynamic=[
+  Class2.==,
+  Class2.runtimeType,
+  toString(0)],
+ runtimeType=[string:Class2<int*>*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  S(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSString,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class2<int*>*]
+*/
 toString2(Class2<int> c) => '${c?.runtimeType}';
 
-/*member: toString3:
+/*spec:nnbd-off.member: toString3:
  dynamic=[
   Class2.runtimeType,
   Type.toString(0)],
@@ -234,9 +397,66 @@
   inst:JSUnmodifiableArray<dynamic>,
   param:Class2<int>]
 */
+/*spec:nnbd-sdk.member: toString3:
+ dynamic=[
+  Class2.runtimeType,
+  Type.toString(0)],
+ runtimeType=[string:Class2<int*>*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class2<int*>*]
+*/
 toString3(Class2<int> c) => c.runtimeType.toString();
 
-/*member: toString4:
+/*spec:nnbd-off.member: toString4:
  dynamic=[
   Class2.runtimeType,
   Type.==,
@@ -292,9 +512,68 @@
   inst:JSUnmodifiableArray<dynamic>,
   param:Class2<int>]
 */
+/*spec:nnbd-sdk.member: toString4:
+ dynamic=[
+  Class2.runtimeType,
+  Type.==,
+  Type.toString(0)],
+ runtimeType=[string:Class2<int*>*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class2<int*>*]
+*/
 toString4(Class2<int> c) => c.runtimeType?.toString();
 
-/*member: toString5:
+/*spec:nnbd-off.member: toString5:
  dynamic=[
   Class2.==,
   Class2.runtimeType,
@@ -351,9 +630,69 @@
   inst:JSUnmodifiableArray<dynamic>,
   param:Class2<int>]
 */
+/*spec:nnbd-sdk.member: toString5:
+ dynamic=[
+  Class2.==,
+  Class2.runtimeType,
+  Type.==,
+  Type.toString(0)],
+ runtimeType=[string:Class2<int*>*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class2<int*>*]
+*/
 toString5(Class2<int> c) => c?.runtimeType?.toString();
 
-/*member: toString6:
+/*spec:nnbd-off.member: toString6:
  dynamic=[
   Class2.==,
   Class2.runtimeType,
@@ -409,9 +748,68 @@
   inst:JSUnmodifiableArray<dynamic>,
   param:Class2<int>]
 */
+/*spec:nnbd-sdk.member: toString6:
+ dynamic=[
+  Class2.==,
+  Class2.runtimeType,
+  Type.toString(0)],
+ runtimeType=[string:Class2<int*>*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class2<int*>*]
+*/
 toString6(Class2<int> c) => c?.runtimeType.toString();
 
-/*member: unknown:
+/*spec:nnbd-off.member: unknown:
  dynamic=[Class2.runtimeType],
  runtimeType=[unknown:Class2<int>],
  static=[
@@ -463,16 +861,71 @@
   inst:JSUnmodifiableArray<dynamic>,
   param:Class2<int>]
 */
+/*spec:nnbd-sdk.member: unknown:
+ dynamic=[Class2.runtimeType],
+ runtimeType=[unknown:Class2<int*>*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class2<int*>*]
+*/
 unknown(Class2<int> c) => c.runtimeType;
 
-/*member: equals1:
+/*spec:nnbd-off.member: equals1:
  dynamic=[
   Class1a.==,
   Class1a.runtimeType,
   Class1d.==,
   Class1d.runtimeType,
   Type.==],
- runtimeType=[equals:Class1a<int>/Class1d<int>],
+ runtimeType=[equals:Class1a<int>==Class1d<int>],
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -524,9 +977,71 @@
   param:Class1a<int>,
   param:Class1d<int>]
 */
+/*spec:nnbd-sdk.member: equals1:
+ dynamic=[
+  Class1a.==,
+  Class1a.runtimeType,
+  Class1d.==,
+  Class1d.runtimeType,
+  Type.==],
+ runtimeType=[equals:Class1a<int*>*==Class1d<int*>*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkSubtype(4),
+  findType(1),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  instanceType(1),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:Closure,
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:Class1a<int*>*,
+  param:Class1d<int*>*]
+*/
 equals1(Class1a<int> a, Class1d<int> b) => a?.runtimeType == b?.runtimeType;
 
-/*member: almostEquals1:
+/*spec:nnbd-off.member: almostEquals1:
  dynamic=[
   Class3.runtimeType,
   Type.==],
@@ -570,9 +1085,56 @@
   inst:JSNull,
   param:Class3]
 */
+/*spec:nnbd-sdk.member: almostEquals1:
+ dynamic=[
+  Class3.runtimeType,
+  Type.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostEquals1(Class3 a) => a.runtimeType == null;
 
-/*member: almostEquals2:
+/*spec:nnbd-off.member: almostEquals2:
  dynamic=[
   Class3.==,
   Class3.runtimeType,
@@ -617,9 +1179,57 @@
   inst:JSNull,
   param:Class3]
 */
+/*spec:nnbd-sdk.member: almostEquals2:
+ dynamic=[
+  Class3.==,
+  Class3.runtimeType,
+  Type.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostEquals2(Class3 a) => a?.runtimeType == null;
 
-/*member: almostEquals3:
+/*spec:nnbd-off.member: almostEquals3:
  dynamic=[
   Class3.runtimeType,
   Null.==],
@@ -663,9 +1273,56 @@
   inst:JSNull,
   param:Class3]
 */
+/*spec:nnbd-sdk.member: almostEquals3:
+ dynamic=[
+  Class3.runtimeType,
+  Null.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostEquals3(Class3 a) => null == a.runtimeType;
 
-/*member: almostEquals4:
+/*spec:nnbd-off.member: almostEquals4:
  dynamic=[
   Class3.==,
   Class3.runtimeType,
@@ -710,9 +1367,57 @@
   inst:JSNull,
   param:Class3]
 */
+/*spec:nnbd-sdk.member: almostEquals4:
+ dynamic=[
+  Class3.==,
+  Class3.runtimeType,
+  Null.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostEquals4(Class3 a) => null == a?.runtimeType;
 
-/*member: almostEquals5:
+/*spec:nnbd-off.member: almostEquals5:
  dynamic=[
   Class3.field,
   Class3.runtimeType,
@@ -756,9 +1461,56 @@
   inst:JSBool,
   param:Class3]
 */
+/*spec:nnbd-sdk.member: almostEquals5:
+ dynamic=[
+  Class3.field,
+  Class3.runtimeType,
+  Type.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:Class3*]
+*/
 almostEquals5(Class3 a) => a.runtimeType == a.field;
 
-/*member: almostEquals6:
+/*spec:nnbd-off.member: almostEquals6:
  dynamic=[
   Class3.==,
   Class3.field,
@@ -804,9 +1556,58 @@
   inst:JSNull,
   param:Class3]
 */
+/*spec:nnbd-sdk.member: almostEquals6:
+ dynamic=[
+  Class3.==,
+  Class3.field,
+  Class3.runtimeType,
+  Type.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostEquals6(Class3 a) => a?.runtimeType == a.field;
 
-/*member: almostEquals7:
+/*spec:nnbd-off.member: almostEquals7:
  dynamic=[
   Class3.==,
   Class3.field,
@@ -852,9 +1653,58 @@
   inst:JSNull,
   param:Class3]
 */
+/*spec:nnbd-sdk.member: almostEquals7:
+ dynamic=[
+  Class3.==,
+  Class3.field,
+  Class3.runtimeType,
+  Type.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostEquals7(Class3 a) => a.runtimeType == a?.field;
 
-/*member: almostEquals8:
+/*spec:nnbd-off.member: almostEquals8:
  dynamic=[
   Class3.==,
   Class3.field,
@@ -900,9 +1750,58 @@
   inst:JSNull,
   param:Class3]
 */
+/*spec:nnbd-sdk.member: almostEquals8:
+ dynamic=[
+  Class3.==,
+  Class3.field,
+  Class3.runtimeType,
+  Type.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostEquals8(Class3 a) => a?.runtimeType == a?.field;
 
-/*member: almostEquals9:
+/*spec:nnbd-off.member: almostEquals9:
  dynamic=[
   Class3.field,
   Class3.runtimeType,
@@ -946,9 +1845,56 @@
   inst:JSBool,
   param:Class3]
 */
+/*spec:nnbd-sdk.member: almostEquals9:
+ dynamic=[
+  Class3.field,
+  Class3.runtimeType,
+  Object.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:Class3*]
+*/
 almostEquals9(Class3 a) => a.field == a.runtimeType;
 
-/*member: almostEquals10:
+/*spec:nnbd-off.member: almostEquals10:
  dynamic=[
   Class3.==,
   Class3.field,
@@ -994,9 +1940,58 @@
   inst:JSNull,
   param:Class3]
 */
+/*spec:nnbd-sdk.member: almostEquals10:
+ dynamic=[
+  Class3.==,
+  Class3.field,
+  Class3.runtimeType,
+  Object.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostEquals10(Class3 a) => a?.field == a.runtimeType;
 
-/*member: almostEquals11:
+/*spec:nnbd-off.member: almostEquals11:
  dynamic=[
   Class3.==,
   Class3.field,
@@ -1042,9 +2037,58 @@
   inst:JSNull,
   param:Class3]
 */
+/*spec:nnbd-sdk.member: almostEquals11:
+ dynamic=[
+  Class3.==,
+  Class3.field,
+  Class3.runtimeType,
+  Object.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostEquals11(Class3 a) => a.field == a?.runtimeType;
 
-/*member: almostEquals12:
+/*spec:nnbd-off.member: almostEquals12:
  dynamic=[
   Class3.==,
   Class3.field,
@@ -1090,9 +2134,58 @@
   inst:JSNull,
   param:Class3]
 */
+/*spec:nnbd-sdk.member: almostEquals12:
+ dynamic=[
+  Class3.==,
+  Class3.field,
+  Class3.runtimeType,
+  Object.==],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostEquals12(Class3 a) => a?.field == a?.runtimeType;
 
-/*member: almostToString1:
+/*spec:nnbd-off.member: almostToString1:
  dynamic=[
   Class3.runtimeType,
   Type.toString],
@@ -1135,9 +2228,55 @@
   inst:JSBool,
   param:Class3]
 */
+/*spec:nnbd-sdk.member: almostToString1:
+ dynamic=[
+  Class3.runtimeType,
+  Type.toString],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:Class3*]
+*/
 almostToString1(Class3 a) => a.runtimeType.toString;
 
-/*member: almostToString2:
+/*spec:nnbd-off.member: almostToString2:
  dynamic=[
   Class3.==,
   Class3.runtimeType,
@@ -1183,9 +2322,58 @@
   inst:JSNull,
   param:Class3]
 */
+/*spec:nnbd-sdk.member: almostToString2:
+ dynamic=[
+  Class3.==,
+  Class3.runtimeType,
+  Type.==,
+  Type.toString],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostToString2(Class3 a) => a?.runtimeType?.toString;
 
-/*member: almostToString3:
+/*spec:nnbd-off.member: almostToString3:
  dynamic=[
   Class3.runtimeType,
   Type.noSuchMethod(1)],
@@ -1229,9 +2417,56 @@
   inst:JSNull,
   param:Class3]
 */
+/*spec:nnbd-sdk.member: almostToString3:
+ dynamic=[
+  Class3.runtimeType,
+  Type.noSuchMethod(1)],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostToString3(Class3 a) => a.runtimeType.noSuchMethod(null);
 
-/*member: almostToString4:
+/*spec:nnbd-off.member: almostToString4:
  dynamic=[
   Class3.==,
   Class3.runtimeType,
@@ -1276,14 +2511,62 @@
   inst:JSNull,
   param:Class3]
 */
+/*spec:nnbd-sdk.member: almostToString4:
+ dynamic=[
+  Class3.==,
+  Class3.runtimeType,
+  Type.noSuchMethod(1)],
+ runtimeType=[unknown:Class3*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*]
+*/
 almostToString4(Class3 a) => a?.runtimeType.noSuchMethod(null);
 
-/*member: notEquals1:
+/*spec:nnbd-off.member: notEquals1:
  dynamic=[
   Class3.runtimeType,
   Class4.runtimeType,
   Type.==],
- runtimeType=[equals:Class3/Class4],
+ runtimeType=[equals:Class3==Class4],
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -1323,15 +2606,63 @@
   param:Class3,
   param:Class4]
 */
+/*spec:nnbd-sdk.member: notEquals1:
+ dynamic=[
+  Class3.runtimeType,
+  Class4.runtimeType,
+  Type.==],
+ runtimeType=[equals:Class3*==Class4*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  param:Class3*,
+  param:Class4*]
+*/
 notEquals1(Class3 a, Class4 b) => a.runtimeType != b.runtimeType;
 
-/*member: notEquals2:
+/*spec:nnbd-off.member: notEquals2:
  dynamic=[
   Class3.==,
   Class3.runtimeType,
   Class4.runtimeType,
   Type.==],
- runtimeType=[equals:Class3/Class4],
+ runtimeType=[equals:Class3==Class4],
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -1372,15 +2703,65 @@
   param:Class3,
   param:Class4]
 */
+/*spec:nnbd-sdk.member: notEquals2:
+ dynamic=[
+  Class3.==,
+  Class3.runtimeType,
+  Class4.runtimeType,
+  Type.==],
+ runtimeType=[equals:Class3*==Class4*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*,
+  param:Class4*]
+*/
 notEquals2(Class3 a, Class4 b) => a?.runtimeType != b.runtimeType;
 
-/*member: notEquals3:
+/*spec:nnbd-off.member: notEquals3:
  dynamic=[
   Class3.runtimeType,
   Class4.==,
   Class4.runtimeType,
   Type.==],
- runtimeType=[equals:Class3/Class4],
+ runtimeType=[equals:Class3==Class4],
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -1421,16 +2802,66 @@
   param:Class3,
   param:Class4]
 */
+/*spec:nnbd-sdk.member: notEquals3:
+ dynamic=[
+  Class3.runtimeType,
+  Class4.==,
+  Class4.runtimeType,
+  Type.==],
+ runtimeType=[equals:Class3*==Class4*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*,
+  param:Class4*]
+*/
 notEquals3(Class3 a, Class4 b) => a.runtimeType != b?.runtimeType;
 
-/*member: notEquals4:
+/*spec:nnbd-off.member: notEquals4:
  dynamic=[
   Class3.==,
   Class3.runtimeType,
   Class4.==,
   Class4.runtimeType,
   Type.==],
- runtimeType=[equals:Class3/Class4],
+ runtimeType=[equals:Class3==Class4],
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -1471,6 +2902,57 @@
   param:Class3,
   param:Class4]
 */
+/*spec:nnbd-sdk.member: notEquals4:
+ dynamic=[
+  Class3.==,
+  Class3.runtimeType,
+  Class4.==,
+  Class4.runtimeType,
+  Type.==],
+ runtimeType=[equals:Class3*==Class4*],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1)],
+ type=[
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  param:Class3*,
+  param:Class4*]
+*/
 notEquals4(Class3 a, Class4 b) => a?.runtimeType != b?.runtimeType;
 
 /*member: main:dynamic=[exact:Class1a.==],static=[Class1a.(0),Class1b.(0),Class1c.(0),Class1d.(0),Class2.(0),Class3.(0),Class4.(0),almostEquals1(1),almostEquals10(1),almostEquals11(1),almostEquals12(1),almostEquals2(1),almostEquals3(1),almostEquals4(1),almostEquals5(1),almostEquals6(1),almostEquals7(1),almostEquals8(1),almostEquals9(1),almostToString1(1),almostToString2(1),almostToString3(1),almostToString4(1),checkTypeBound(4),equals1(2),notEquals1(2),notEquals2(2),notEquals3(2),notEquals4(2),print(1),throwTypeError(1),toString1(1),toString2(1),toString3(1),toString4(1),toString5(1),toString6(1),unknown(1)]*/
diff --git a/tests/compiler/dart2js/impact/data/statements.dart b/tests/compiler/dart2js/impact/data/statements.dart
index 4d94691..e0ab8fb 100644
--- a/tests/compiler/dart2js/impact/data/statements.dart
+++ b/tests/compiler/dart2js/impact/data/statements.dart
@@ -67,7 +67,7 @@
     return 1;
 }
 
-/*member: testForIn:
+/*spec:nnbd-off.member: testForIn:
  dynamic=[
   Iterator.current,
   Iterator.iterator,
@@ -113,12 +113,61 @@
   inst:JSNull,
   inst:Null]
 */
+/*spec:nnbd-sdk.member: testForIn:
+ dynamic=[
+  Iterator.current,
+  Iterator.iterator,
+  Iterator.moveNext(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkConcurrentModificationError(2),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:Iterable<dynamic>*,
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  inst:Null]
+*/
 testForIn(o) {
   // ignore: UNUSED_LOCAL_VARIABLE
   for (var e in o) {}
 }
 
-/*member: testForInTyped:
+/*spec:nnbd-off.member: testForInTyped:
  dynamic=[
   Iterator.current,
   Iterator.iterator,
@@ -165,6 +214,56 @@
   inst:JSNull,
   inst:Null]
 */
+/*spec:nnbd-sdk.member: testForInTyped:
+ dynamic=[
+  Iterator.current,
+  Iterator.iterator,
+  Iterator.moveNext(0)],
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  checkConcurrentModificationError(2),
+  findType(1),
+  instanceType(1)],
+ type=[
+  impl:Iterable<dynamic>*,
+  impl:int*,
+  inst:Closure,
+  inst:JSBool,
+  inst:JSNull,
+  inst:Null]
+*/
 testForInTyped(o) {
   // ignore: UNUSED_LOCAL_VARIABLE
   for (int e in o) {}
@@ -180,7 +279,7 @@
   try {} catch (e) {}
 }
 
-/*member: testTryCatchOn:
+/*spec:nnbd-off.member: testTryCatchOn:
  static=[
   Rti._bind(1),
   Rti._eval(1),
@@ -222,6 +321,51 @@
   inst:PlainJavaScriptObject,
   inst:UnknownJavaScriptObject]
 */
+/*spec:nnbd-sdk.member: testTryCatchOn:
+ static=[
+  Rti._bind(1),
+  Rti._eval(1),
+  _arrayInstanceType(1),
+  _asBool(1),
+  _asBoolQ(1),
+  _asBoolS(1),
+  _asDouble(1),
+  _asDoubleQ(1),
+  _asDoubleS(1),
+  _asInt(1),
+  _asIntQ(1),
+  _asIntS(1),
+  _asNum(1),
+  _asNumQ(1),
+  _asNumS(1),
+  _asObject(1),
+  _asString(1),
+  _asStringQ(1),
+  _asStringS(1),
+  _asTop(1),
+  _generalAsCheckImplementation(1),
+  _generalIsTestImplementation(1),
+  _generalNullableAsCheckImplementation(1),
+  _generalNullableIsTestImplementation(1),
+  _installSpecializedAsCheck(1),
+  _installSpecializedIsTest(1),
+  _instanceType(1),
+  _isBool(1),
+  _isInt(1),
+  _isNum(1),
+  _isObject(1),
+  _isString(1),
+  _isTop(1),
+  findType(1),
+  instanceType(1),
+  unwrapException(1)],
+ type=[
+  catch:String*,
+  inst:Closure,
+  inst:JSBool,
+  inst:PlainJavaScriptObject,
+  inst:UnknownJavaScriptObject]
+*/
 testTryCatchOn() {
   // ignore: UNUSED_CATCH_CLAUSE
   try {} on String catch (e) {}
diff --git a/tests/compiler/dart2js/impact/impact_test.dart b/tests/compiler/dart2js/impact/impact_test.dart
index 315b9ac..c3ff87b 100644
--- a/tests/compiler/dart2js/impact/impact_test.dart
+++ b/tests/compiler/dart2js/impact/impact_test.dart
@@ -46,6 +46,8 @@
 class ImpactDataComputer extends DataComputer<Features> {
   const ImpactDataComputer();
 
+  static const String wildcard = '%';
+
   @override
   void computeMemberData(Compiler compiler, MemberEntity member,
       Map<Id, ActualData<Features>> actualMap,
@@ -55,14 +57,14 @@
     ir.Member node = frontendStrategy.elementMap.getMemberNode(member);
     Features features = new Features();
     if (impact.typeUses.length > 50) {
-      features.addElement(Tags.typeUse, '*');
+      features.addElement(Tags.typeUse, wildcard);
     } else {
       for (TypeUse use in impact.typeUses) {
         features.addElement(Tags.typeUse, use.shortText);
       }
     }
     if (impact.staticUses.length > 50) {
-      features.addElement(Tags.staticUse, '*');
+      features.addElement(Tags.staticUse, wildcard);
     } else {
       for (StaticUse use in impact.staticUses) {
         features.addElement(Tags.staticUse, use.shortText);
@@ -92,5 +94,5 @@
 
   @override
   DataInterpreter<Features> get dataValidator =>
-      const FeaturesDataInterpreter();
+      const FeaturesDataInterpreter(wildcard: wildcard);
 }
diff --git a/tests/compiler/dart2js_extra/rti/required_named_parameters_test.dart b/tests/compiler/dart2js_extra/rti/required_named_parameters_test.dart
new file mode 100644
index 0000000..309a381
--- /dev/null
+++ b/tests/compiler/dart2js_extra/rti/required_named_parameters_test.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2020, 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.
+
+// Requirements=nnbd
+
+import 'dart:_rti' as rti;
+import 'dart:_foreign_helper' show JS;
+import "package:expect/expect.dart";
+
+const typeRulesJson = r'''
+{
+  "B": {"A": []},
+  "C": {"B": []}
+}
+''';
+final typeRules = JS('=Object', 'JSON.parse(#)', typeRulesJson);
+
+main() {
+  var universe = rti.testingCreateUniverse();
+  rti.testingAddRules(universe, typeRules);
+
+  // Recipe is properly parsed
+  var rti1 = rti.testingUniverseEval(universe, "@(B,{a!B,b:B,c!B})");
+
+  // Subtype must be contravariant in its named parameter types
+  var rti2 = rti.testingUniverseEval(universe, "@(B,{a!A,b:B,c!B})");
+  Expect.isTrue(rti.testingIsSubtype(universe, rti2, rti1));
+  rti2 = rti.testingUniverseEval(universe, "@(B,{a!B,b:A,c!B})");
+  Expect.isTrue(rti.testingIsSubtype(universe, rti2, rti1));
+  rti2 = rti.testingUniverseEval(universe, "@(B,{a!C,b:B,c!B})");
+  Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1));
+  rti2 = rti.testingUniverseEval(universe, "@(B,{a!B,b:C,c!B})");
+  Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1));
+
+  // Subtype may not omit optional named parameters
+  rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,c!A})");
+  Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1));
+
+  // Subtype may not omit required named parameters
+  rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,b:A})");
+  Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1));
+
+  // Subtype may contain additional named optional parameters
+  rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,b:A,c!A,d:A})");
+  Expect.isTrue(rti.testingIsSubtype(universe, rti2, rti1));
+
+  // Subtype may redeclare required parameters as optional.
+  rti2 = rti.testingUniverseEval(universe, "@(A,{a:A,b:A,c:A})");
+  Expect.isTrue(rti.testingIsSubtype(universe, rti2, rti1));
+
+  // Subtype may not redeclare optional parameters as required
+  rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,b!A,c!A})");
+  Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1));
+
+  // Subtype may not declare new required named parameters
+  rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,b:A,c!A,d!A})");
+  Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1));
+
+  // Rti.toString() appears as expected
+  Expect.equals('(B, {required B a, B b, required B c}) => dynamic',
+      rti.testingRtiToString(rti1));
+
+  // Rti debug string properly annotates all required parameters
+  Expect.equals(
+      2, 'required'.allMatches(rti.testingRtiToDebugString(rti1)).length);
+}
diff --git a/tests/corelib/list_map_test.dart b/tests/corelib/list_map_test.dart
index 19ce07e..cf27a37 100644
--- a/tests/corelib/list_map_test.dart
+++ b/tests/corelib/list_map_test.dart
@@ -115,7 +115,7 @@
     testOp((i) => i.every((n) => n < 5), "every<5");
     testOp((i) => i.every((n) => n < 10), "every<10");
     testOp((i) => i.reduce((a, b) => a + b), "reduce-sum");
-    testOp((i) => i.fold/*<int>*/(0, (a, b) => a + b), "fold-sum");
+    testOp((i) => i.fold<int>(0, (a, b) => a + b), "fold-sum");
     testOp((i) => i.join("-"), "join-");
     testOp((i) => i.join(""), "join");
     testOp((i) => i.join(), "join-null");
diff --git a/tests/corelib/list_reversed_test.dart b/tests/corelib/list_reversed_test.dart
index e331f8c..e26e731 100644
--- a/tests/corelib/list_reversed_test.dart
+++ b/tests/corelib/list_reversed_test.dart
@@ -106,7 +106,7 @@
     testOp((i) => i.every((n) => n < 5), "every<5");
     testOp((i) => i.every((n) => n < 10), "every<10");
     testOp((i) => i.reduce((a, b) => a + b), "reduce-sum");
-    testOp((i) => i.fold/*<int>*/(0, (a, b) => a + b), "fold-sum");
+    testOp((i) => i.fold<int>(0, (a, b) => a + b), "fold-sum");
     testOp((i) => i.join("-"), "join-");
     testOp((i) => i.join(""), "join");
     testOp((i) => i.join(), "join-null");
diff --git a/tests/language/function_type/function_type0_test.dart b/tests/language/function_type/function_type0_test.dart
new file mode 100644
index 0000000..d2134ef
--- /dev/null
+++ b/tests/language/function_type/function_type0_test.dart
@@ -0,0 +1,923 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int x);
+typedef F1<T> = Function Function(List<T> x);
+typedef F2<T> = core.List<core.int> Function(int y, {List<Function> x});
+typedef F3<T> = Function(int, {Function x});
+typedef F4<T> = Function Function<A>(int x);
+typedef F5<T> = int Function(int, {int x}) Function();
+typedef F6<T> = int Function([core.List<core.int> x]) Function();
+typedef F7<T> = Function Function(int y, [int x]) Function();
+typedef F8<T> = Function Function(int, [List<Function>]) Function();
+typedef F9<T> = Function Function(int, {List<T> x}) Function();
+typedef F10<T> = List<Function> Function(List<Function> x) Function();
+typedef F11<T> = List<Function> Function(int y, [List<T> x]) Function();
+typedef F12<T> = core.List<core.int> Function([Function]) Function();
+typedef F13<T> = core.List<core.int> Function({core.List<core.int> x})
+    Function();
+typedef F14<T> = List<T> Function(int y, {int x}) Function();
+typedef F15<T> = List<T> Function(int, [core.List<core.int> x]) Function();
+typedef F16<T> = Function(int) Function();
+typedef F17<T> = Function(int x, [List<Function>]) Function();
+typedef F18<T> = Function(int y, {List<T> x}) Function();
+typedef F19<T> = void Function([List<Function> x]) Function();
+typedef F20<T> = void Function(List<T>) Function();
+typedef F21<T> = List<Function> Function<A>(Function x) Function();
+typedef F22<T> = Function<A>(List<Function> x) Function();
+typedef F23<T> = void Function<A>(core.List<core.int> x) Function();
+
+int f0(int x) => throw 'uncalled';
+Function f1(List<int> x) => throw 'uncalled';
+core.List<core.int> f2(int y, {List<Function> x = const []}) =>
+    throw 'uncalled';
+f3(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+Function f4<A>(int x) => throw 'uncalled';
+int Function(int, {int x}) f5() => throw 'uncalled';
+int Function([core.List<core.int> x]) f6() => throw 'uncalled';
+Function Function(int y, [int x]) f7() => throw 'uncalled';
+Function Function(int, [List<Function>]) f8() => throw 'uncalled';
+Function Function(int, {List<int> x}) f9() => throw 'uncalled';
+List<Function> Function(List<Function> x) f10() => throw 'uncalled';
+List<Function> Function(int y, [List<int> x]) f11() => throw 'uncalled';
+core.List<core.int> Function([Function]) f12() => throw 'uncalled';
+core.List<core.int> Function({core.List<core.int> x}) f13() => throw 'uncalled';
+List<int> Function(int y, {int x}) f14() => throw 'uncalled';
+List<int> Function(int, [core.List<core.int> x]) f15() => throw 'uncalled';
+Function(int) f16() => throw 'uncalled';
+Function(int x, [List<Function>]) f17() => throw 'uncalled';
+Function(int y, {List<int> x}) f18() => throw 'uncalled';
+void Function([List<Function> x]) f19() => throw 'uncalled';
+void Function(List<int>) f20() => throw 'uncalled';
+List<Function> Function<A>(Function x) f21() => throw 'uncalled';
+Function<A>(List<Function> x) f22() => throw 'uncalled';
+void Function<A>(core.List<core.int> x) f23() => throw 'uncalled';
+
+class U0<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int x) x0;
+  late Function Function(List<T> x) x1;
+  late core.List<core.int> Function(int y, {List<Function> x}) x2;
+  late Function(int, {Function x}) x3;
+  late Function Function<A>(int x) x4;
+  late int Function(int, {int x}) Function() x5;
+  late int Function([core.List<core.int> x]) Function() x6;
+  late Function Function(int y, [int x]) Function() x7;
+  late Function Function(int, [List<Function>]) Function() x8;
+  late Function Function(int, {List<T> x}) Function() x9;
+  late List<Function> Function(List<Function> x) Function() x10;
+  late List<Function> Function(int y, [List<T> x]) Function() x11;
+  late core.List<core.int> Function([Function]) Function() x12;
+  late core.List<core.int> Function({core.List<core.int> x}) Function() x13;
+  late List<T> Function(int y, {int x}) Function() x14;
+  late List<T> Function(int, [core.List<core.int> x]) Function() x15;
+  late Function(int) Function() x16;
+  late Function(int x, [List<Function>]) Function() x17;
+  late Function(int y, {List<T> x}) Function() x18;
+  late void Function([List<Function> x]) Function() x19;
+  late void Function(List<T>) Function() x20;
+  late List<Function> Function<A>(Function x) Function() x21;
+  late Function<A>(List<Function> x) Function() x22;
+  late void Function<A>(core.List<core.int> x) Function() x23;
+
+  U0({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x) => throw 'uncalled';
+  Function m1(List<T> x) => throw 'uncalled';
+  core.List<core.int> m2(int y, {List<Function> x = const []}) =>
+      throw 'uncalled';
+  m3(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+  Function m4<A>(int x) => throw 'uncalled';
+  int Function(int, {int x}) m5() => throw 'uncalled';
+  int Function([core.List<core.int> x]) m6() => throw 'uncalled';
+  Function Function(int y, [int x]) m7() => throw 'uncalled';
+  Function Function(int, [List<Function>]) m8() => throw 'uncalled';
+  Function Function(int, {List<T> x}) m9() => throw 'uncalled';
+  List<Function> Function(List<Function> x) m10() => throw 'uncalled';
+  List<Function> Function(int y, [List<T> x]) m11() => throw 'uncalled';
+  core.List<core.int> Function([Function]) m12() => throw 'uncalled';
+  core.List<core.int> Function({core.List<core.int> x}) m13() =>
+      throw 'uncalled';
+  List<T> Function(int y, {int x}) m14() => throw 'uncalled';
+  List<T> Function(int, [core.List<core.int> x]) m15() => throw 'uncalled';
+  Function(int) m16() => throw 'uncalled';
+  Function(int x, [List<Function>]) m17() => throw 'uncalled';
+  Function(int y, {List<T> x}) m18() => throw 'uncalled';
+  void Function([List<Function> x]) m19() => throw 'uncalled';
+  void Function(List<T>) m20() => throw 'uncalled';
+  List<Function> Function<A>(Function x) m21() => throw 'uncalled';
+  Function<A>(List<Function> x) m22() => throw 'uncalled';
+  void Function<A>(core.List<core.int> x) m23() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int x)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int x) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int x));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function(List<T> x)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<T> x) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function(List<T> x));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int y, {List<Function> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {List<Function> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(
+        m2 is core.List<core.int> Function(int y, {List<Function> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function(int, {Function x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int, {Function x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int, {Function x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function Function<A>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function Function<A>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {int x}) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {int x}) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, {int x}) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([core.List<core.int> x]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([core.List<core.int> x]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, [int x]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [int x]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, [int x]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<Function>]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<Function>]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [List<Function>]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function(int, {List<T> x}) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {List<T> x}) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function(int, {List<T> x}) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+    // The static function has its T always set to int.
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isFalse(f9 is F9<bool>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    Expect.isFalse(confuse(f9) is F9<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        x9 = confuse(f9);
+      });
+      Expect.throws(() {
+        l9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        l9 = confuse(f9);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m9 is F9<int>);
+      Expect.equals(tIsBool, m9 is F9<bool>);
+      Expect.equals(tIsInt, confuse(m9) is F9<int>);
+      Expect.equals(tIsBool, confuse(m9) is F9<bool>);
+    }
+  }
+
+  /// List<Function> Function(List<Function> x) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<Function> x) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(List<Function> x) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int y, [List<T> x]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [List<T> x]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is List<Function> Function(int y, [List<T> x]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function([Function]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([Function]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([Function]) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function({core.List<core.int> x}) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({core.List<core.int> x}) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function({core.List<core.int> x})
+        Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(int y, {int x}) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {int x}) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, {int x}) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [core.List<core.int> x]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [core.List<core.int> x]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int, [core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [List<Function>]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [List<Function>]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int x, [List<Function>]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// Function(int y, {List<T> x}) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {List<T> x}) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is Function(int y, {List<T> x}) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+    // The static function has its T always set to int.
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isFalse(f18 is F18<bool>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    Expect.isFalse(confuse(f18) is F18<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x18 = (f18 as dynamic);
+      });
+      Expect.throws(() {
+        x18 = confuse(f18);
+      });
+      Expect.throws(() {
+        l18 = (f18 as dynamic);
+      });
+      Expect.throws(() {
+        l18 = confuse(f18);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m18 is F18<int>);
+      Expect.equals(tIsBool, m18 is F18<bool>);
+      Expect.equals(tIsInt, confuse(m18) is F18<int>);
+      Expect.equals(tIsBool, confuse(m18) is F18<bool>);
+    }
+  }
+
+  /// void Function([List<Function> x]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<Function> x]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([List<Function> x]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(List<T>) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(List<T>) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(List<T>) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(Function x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(Function x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(Function x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<Function> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<Function> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(List<Function> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(core.List<core.int> x) Function()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(core.List<core.int> x) Function() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U0().runTests();
+  new U0<int>(tIsInt: true).runTests();
+  new U0<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type10_test.dart b/tests/language/function_type/function_type10_test.dart
new file mode 100644
index 0000000..fc803d6
--- /dev/null
+++ b/tests/language/function_type/function_type10_test.dart
@@ -0,0 +1,948 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int y, {int x});
+typedef F1<T> = Function Function(int y, {List<T> x});
+typedef F2<T> = core.List<core.int> Function(int, {core.List<core.int> x});
+typedef F3<T> = Function({List<Function> x});
+typedef F4<T> = List<Function> Function<A>(List<Function> x);
+typedef F5<T> = int Function(Function x) Function<B extends core.int>();
+typedef F6<T> = int Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F7<T> = Function Function([int]) Function<B extends core.int>();
+typedef F8<T> = Function Function({List<Function> x})
+    Function<B extends core.int>();
+typedef F9<T> = Function Function() Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int, [List<Function> x])
+    Function<B extends core.int>();
+typedef F11<T> = List<Function> Function([List<T>])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int x, [Function])
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function([Function x]) Function<B extends core.int>();
+typedef F15<T> = List<T> Function(core.List<core.int>)
+    Function<B extends core.int>();
+typedef F16<T> = Function(int, [int]) Function<B extends core.int>();
+typedef F17<T> = Function(int, {List<Function> x})
+    Function<B extends core.int>();
+typedef F18<T> = void Function(int x) Function<B extends core.int>();
+typedef F19<T> = void Function(int y, [List<Function> x])
+    Function<B extends core.int>();
+typedef F20<T> = void Function(int, [List<T>]) Function<B extends core.int>();
+typedef F21<T> = List<Function> Function<A>(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F22<T> = Function<A>(List<T> x) Function<B extends core.int>();
+typedef F23<T> = void Function<A>() Function<B extends core.int>();
+
+int f0(int y, {int x = -1}) => throw 'uncalled';
+Function f1(int y, {List<int> x = const []}) => throw 'uncalled';
+core.List<core.int> f2(int x0, {core.List<core.int> x = const []}) =>
+    throw 'uncalled';
+f3({List<Function> x = const []}) => throw 'uncalled';
+List<Function> f4<A>(List<Function> x) => throw 'uncalled';
+int Function(Function x) f5<B extends core.int>() => throw 'uncalled';
+int Function(int y, [core.List<core.int> x]) f6<B extends core.int>() =>
+    throw 'uncalled';
+Function Function([int]) f7<B extends core.int>() => throw 'uncalled';
+Function Function({List<Function> x}) f8<B extends core.int>() =>
+    throw 'uncalled';
+Function Function() f9<B extends core.int>() => throw 'uncalled';
+List<Function> Function(int, [List<Function> x]) f10<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function([List<int>]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int x, [Function]) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, {core.List<core.int> x})
+    f13<B extends core.int>() => throw 'uncalled';
+List<int> Function([Function x]) f14<B extends core.int>() => throw 'uncalled';
+List<int> Function(core.List<core.int>) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function(int, [int]) f16<B extends core.int>() => throw 'uncalled';
+Function(int, {List<Function> x}) f17<B extends core.int>() => throw 'uncalled';
+void Function(int x) f18<B extends core.int>() => throw 'uncalled';
+void Function(int y, [List<Function> x]) f19<B extends core.int>() =>
+    throw 'uncalled';
+void Function(int, [List<int>]) f20<B extends core.int>() => throw 'uncalled';
+List<Function> Function<A>(core.List<core.int> x) f21<B extends core.int>() =>
+    throw 'uncalled';
+Function<A>(List<int> x) f22<B extends core.int>() => throw 'uncalled';
+void Function<A>() f23<B extends core.int>() => throw 'uncalled';
+
+class U10<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int y, {int x}) x0;
+  late Function Function(int y, {List<T> x}) x1;
+  late core.List<core.int> Function(int, {core.List<core.int> x}) x2;
+  late Function({List<Function> x}) x3;
+  late List<Function> Function<A>(List<Function> x) x4;
+  late int Function(Function x) Function<B extends core.int>() x5;
+  late int Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>() x6;
+  late Function Function([int]) Function<B extends core.int>() x7;
+  late Function Function({List<Function> x}) Function<B extends core.int>() x8;
+  late Function Function() Function<B extends core.int>() x9;
+  late List<Function> Function(int, [List<Function> x])
+      Function<B extends core.int>() x10;
+  late List<Function> Function([List<T>]) Function<B extends core.int>() x11;
+  late core.List<core.int> Function(int x, [Function])
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>() x13;
+  late List<T> Function([Function x]) Function<B extends core.int>() x14;
+  late List<T> Function(core.List<core.int>) Function<B extends core.int>() x15;
+  late Function(int, [int]) Function<B extends core.int>() x16;
+  late Function(int, {List<Function> x}) Function<B extends core.int>() x17;
+  late void Function(int x) Function<B extends core.int>() x18;
+  late void Function(int y, [List<Function> x]) Function<B extends core.int>()
+      x19;
+  late void Function(int, [List<T>]) Function<B extends core.int>() x20;
+  late List<Function> Function<A>(core.List<core.int> x)
+      Function<B extends core.int>() x21;
+  late Function<A>(List<T> x) Function<B extends core.int>() x22;
+  late void Function<A>() Function<B extends core.int>() x23;
+
+  U10({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int y, {int x = -1}) => throw 'uncalled';
+  Function m1(int y, {List<T> x = const []}) => throw 'uncalled';
+  core.List<core.int> m2(int x0, {core.List<core.int> x = const []}) =>
+      throw 'uncalled';
+  m3({List<Function> x = const []}) => throw 'uncalled';
+  List<Function> m4<A>(List<Function> x) => throw 'uncalled';
+  int Function(Function x) m5<B extends core.int>() => throw 'uncalled';
+  int Function(int y, [core.List<core.int> x]) m6<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function([int]) m7<B extends core.int>() => throw 'uncalled';
+  Function Function({List<Function> x}) m8<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function() m9<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(int, [List<Function> x]) m10<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function([List<T>]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x, [Function]) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {core.List<core.int> x})
+      m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function([Function x]) m14<B extends core.int>() => throw 'uncalled';
+  List<T> Function(core.List<core.int>) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int, [int]) m16<B extends core.int>() => throw 'uncalled';
+  Function(int, {List<Function> x}) m17<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int x) m18<B extends core.int>() => throw 'uncalled';
+  void Function(int y, [List<Function> x]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int, [List<T>]) m20<B extends core.int>() => throw 'uncalled';
+  List<Function> Function<A>(core.List<core.int> x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  Function<A>(List<T> x) m22<B extends core.int>() => throw 'uncalled';
+  void Function<A>() m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int y, {int x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {int x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int y, {int x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function(int y, {List<T> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {List<T> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function(int y, {List<T> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, {core.List<core.int> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {core.List<core.int> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(
+        m2 is core.List<core.int> Function(int, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function({List<Function> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function({List<Function> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function({List<Function> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<Function> Function<A>(List<Function> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<Function> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<Function> Function<A>(List<Function> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(Function x) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(Function x) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [core.List<core.int> x]) Function<B extends core.int>()
+        l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([int]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([int]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function([int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({List<Function> x}) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({List<Function> x}) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function({List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function() Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function() Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function() Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<Function> x]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<Function> x])
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function([List<T>]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<T>]) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function([List<T>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int x, [Function]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [Function])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int x, [Function])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int y,
+            {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function([Function x]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([Function x]) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function([Function x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(core.List<core.int>) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(core.List<core.int>) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(core.List<core.int>)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [int]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [int]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {List<Function> x}) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {List<Function> x}) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int x) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [List<Function> x]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [List<Function> x]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int, [List<T>]) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<T>]) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is void Function(int, [List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(core.List<core.int> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<T> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<T> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+
+  /// void Function<A>() Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>() Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>() Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U10().runTests();
+  new U10<int>(tIsInt: true).runTests();
+  new U10<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type11_test.dart b/tests/language/function_type/function_type11_test.dart
new file mode 100644
index 0000000..5499988
--- /dev/null
+++ b/tests/language/function_type/function_type11_test.dart
@@ -0,0 +1,948 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(Function x);
+typedef F1<T> = Function Function();
+typedef F2<T> = core.List<core.int> Function(int y, {core.List<core.int> x});
+typedef F3<T> = Function(int, {List<Function> x});
+typedef F4<T> = List<Function> Function<A>(core.List<core.int> x);
+typedef F5<T> = int Function(Function x) Function<B extends core.int>(int x);
+typedef F6<T> = int Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F7<T> = Function Function([int]) Function<B extends core.int>(int x);
+typedef F8<T> = Function Function({List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F9<T> = Function Function() Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(int, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F11<T> = List<Function> Function([List<T>])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int x, [Function])
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function([Function x]) Function<B extends core.int>(
+    int x);
+typedef F15<T> = List<T> Function(core.List<core.int>)
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function(int, [int]) Function<B extends core.int>(int x);
+typedef F17<T> = Function(int, {List<Function> x}) Function<B extends core.int>(
+    int x);
+typedef F18<T> = void Function(int x) Function<B extends core.int>(int x);
+typedef F19<T> = void Function(int y, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F20<T> = void Function(int, [List<T>]) Function<B extends core.int>(
+    int x);
+typedef F21<T> = List<Function> Function<A>(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = Function<A>(List<T> x) Function<B extends core.int>(int x);
+typedef F23<T> = void Function<A>() Function<B extends core.int>(int x);
+
+int f0(Function x) => throw 'uncalled';
+Function f1() => throw 'uncalled';
+core.List<core.int> f2(int y, {core.List<core.int> x = const []}) =>
+    throw 'uncalled';
+f3(int x0, {List<Function> x = const []}) => throw 'uncalled';
+List<Function> f4<A>(core.List<core.int> x) => throw 'uncalled';
+int Function(Function x) f5<B extends core.int>(int x) => throw 'uncalled';
+int Function(int y, [core.List<core.int> x]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function([int]) f7<B extends core.int>(int x) => throw 'uncalled';
+Function Function({List<Function> x}) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function() f9<B extends core.int>(int x) => throw 'uncalled';
+List<Function> Function(int, [List<Function> x]) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<Function> Function([List<int>]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int x, [Function]) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, {core.List<core.int> x})
+    f13<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function([Function x]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(core.List<core.int>) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int, [int]) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(int, {List<Function> x}) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int x) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(int y, [List<Function> x]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int, [List<int>]) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function<A>(core.List<core.int> x) f21<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+Function<A>(List<int> x) f22<B extends core.int>(int x) => throw 'uncalled';
+void Function<A>() f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U11<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(Function x) x0;
+  late Function Function() x1;
+  late core.List<core.int> Function(int y, {core.List<core.int> x}) x2;
+  late Function(int, {List<Function> x}) x3;
+  late List<Function> Function<A>(core.List<core.int> x) x4;
+  late int Function(Function x) Function<B extends core.int>(int x) x5;
+  late int Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>(int x) x6;
+  late Function Function([int]) Function<B extends core.int>(int x) x7;
+  late Function Function({List<Function> x}) Function<B extends core.int>(int x)
+      x8;
+  late Function Function() Function<B extends core.int>(int x) x9;
+  late List<Function> Function(int, [List<Function> x])
+      Function<B extends core.int>(int x) x10;
+  late List<Function> Function([List<T>]) Function<B extends core.int>(int x)
+      x11;
+  late core.List<core.int> Function(int x, [Function])
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>(int x) x13;
+  late List<T> Function([Function x]) Function<B extends core.int>(int x) x14;
+  late List<T> Function(core.List<core.int>) Function<B extends core.int>(int x)
+      x15;
+  late Function(int, [int]) Function<B extends core.int>(int x) x16;
+  late Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+      x17;
+  late void Function(int x) Function<B extends core.int>(int x) x18;
+  late void Function(int y, [List<Function> x]) Function<B extends core.int>(
+      int x) x19;
+  late void Function(int, [List<T>]) Function<B extends core.int>(int x) x20;
+  late List<Function> Function<A>(core.List<core.int> x)
+      Function<B extends core.int>(int x) x21;
+  late Function<A>(List<T> x) Function<B extends core.int>(int x) x22;
+  late void Function<A>() Function<B extends core.int>(int x) x23;
+
+  U11({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(Function x) => throw 'uncalled';
+  Function m1() => throw 'uncalled';
+  core.List<core.int> m2(int y, {core.List<core.int> x = const []}) =>
+      throw 'uncalled';
+  m3(int x0, {List<Function> x = const []}) => throw 'uncalled';
+  List<Function> m4<A>(core.List<core.int> x) => throw 'uncalled';
+  int Function(Function x) m5<B extends core.int>(int x) => throw 'uncalled';
+  int Function(int y, [core.List<core.int> x]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function([int]) m7<B extends core.int>(int x) => throw 'uncalled';
+  Function Function({List<Function> x}) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function() m9<B extends core.int>(int x) => throw 'uncalled';
+  List<Function> Function(int, [List<Function> x]) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<Function> Function([List<T>]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x, [Function]) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {core.List<core.int> x})
+      m13<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function([Function x]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(core.List<core.int>) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int, [int]) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(int, {List<Function> x}) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int x) m18<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int y, [List<Function> x]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int, [List<T>]) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function<A>(core.List<core.int> x) m21<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  Function<A>(List<T> x) m22<B extends core.int>(int x) => throw 'uncalled';
+  void Function<A>() m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(Function x)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(Function x) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(Function x));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function()
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function() l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function());
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function(int y, {core.List<core.int> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {core.List<core.int> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(
+        m2 is core.List<core.int> Function(int y, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function(int, {List<Function> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int, {List<Function> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int, {List<Function> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<Function> Function<A>(core.List<core.int> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(core.List<core.int> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<Function> Function<A>(core.List<core.int> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(Function x) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(Function x) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(Function x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [core.List<core.int> x]) Function<B extends core.int>(
+        int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([int]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([int]) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function([int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({List<Function> x}) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({List<Function> x}) Function<B extends core.int>(int x)
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function({List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function() Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function() Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is Function Function() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<Function> x])
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function([List<T>]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<T>]) Function<B extends core.int>(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function([List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int x, [Function]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [Function])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int x, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int y,
+            {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function([Function x]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([Function x]) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(core.List<core.int>) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(core.List<core.int>) Function<B extends core.int>(int x)
+        l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(core.List<core.int>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [int]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [int]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int, [int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {List<Function> x}) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int x) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [List<Function> x]) Function<B extends core.int>(int x)
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int, [List<T>]) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<T>]) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<T> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<T> x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is Function<A>(List<T> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+
+  /// void Function<A>() Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>() Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is void Function<A>() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U11().runTests();
+  new U11<int>(tIsInt: true).runTests();
+  new U11<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type12_test.dart b/tests/language/function_type/function_type12_test.dart
new file mode 100644
index 0000000..2bb14fc
--- /dev/null
+++ b/tests/language/function_type/function_type12_test.dart
@@ -0,0 +1,941 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function([Function x]);
+typedef F1<T> = List<Function> Function(int x);
+typedef F2<T> = core.List<core.int> Function(List<T> x);
+typedef F3<T> = Function(int y, {List<Function> x});
+typedef F4<T> = List<Function> Function<A>(List<T> x);
+typedef F5<T> = int Function([Function x]) Function();
+typedef F6<T> = int Function(core.List<core.int>) Function();
+typedef F7<T> = Function Function(int, [int]) Function();
+typedef F8<T> = Function Function(int, {List<Function> x}) Function();
+typedef F9<T> = List<Function> Function(int x) Function();
+typedef F10<T> = List<Function> Function(int y, [List<Function> x]) Function();
+typedef F11<T> = List<Function> Function(int, [List<T>]) Function();
+typedef F12<T> = core.List<core.int> Function({Function x}) Function();
+typedef F13<T> = core.List<core.int> Function(List<T> x) Function();
+typedef F14<T> = List<T> Function(int, [Function x]) Function();
+typedef F15<T> = List<T> Function([core.List<core.int>]) Function();
+typedef F16<T> = Function(int x, [int]) Function();
+typedef F17<T> = Function(int y, {List<Function> x}) Function();
+typedef F18<T> = void Function([int x]) Function();
+typedef F19<T> = void Function(List<Function>) Function();
+typedef F20<T> = void Function(int x, [List<T>]) Function();
+typedef F21<T> = List<Function> Function<A>(List<T> x) Function();
+typedef F22<T> = Function<A>() Function();
+typedef F23<T> = void Function<A>(A x) Function();
+
+int f0([Function x = _voidFunction]) => throw 'uncalled';
+List<Function> f1(int x) => throw 'uncalled';
+core.List<core.int> f2(List<int> x) => throw 'uncalled';
+f3(int y, {List<Function> x = const []}) => throw 'uncalled';
+List<Function> f4<A>(List<int> x) => throw 'uncalled';
+int Function([Function x]) f5() => throw 'uncalled';
+int Function(core.List<core.int>) f6() => throw 'uncalled';
+Function Function(int, [int]) f7() => throw 'uncalled';
+Function Function(int, {List<Function> x}) f8() => throw 'uncalled';
+List<Function> Function(int x) f9() => throw 'uncalled';
+List<Function> Function(int y, [List<Function> x]) f10() => throw 'uncalled';
+List<Function> Function(int, [List<int>]) f11() => throw 'uncalled';
+core.List<core.int> Function({Function x}) f12() => throw 'uncalled';
+core.List<core.int> Function(List<int> x) f13() => throw 'uncalled';
+List<int> Function(int, [Function x]) f14() => throw 'uncalled';
+List<int> Function([core.List<core.int>]) f15() => throw 'uncalled';
+Function(int x, [int]) f16() => throw 'uncalled';
+Function(int y, {List<Function> x}) f17() => throw 'uncalled';
+void Function([int x]) f18() => throw 'uncalled';
+void Function(List<Function>) f19() => throw 'uncalled';
+void Function(int x, [List<int>]) f20() => throw 'uncalled';
+List<Function> Function<A>(List<int> x) f21() => throw 'uncalled';
+Function<A>() f22() => throw 'uncalled';
+void Function<A>(A x) f23() => throw 'uncalled';
+
+class U12<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function([Function x]) x0;
+  late List<Function> Function(int x) x1;
+  late core.List<core.int> Function(List<T> x) x2;
+  late Function(int y, {List<Function> x}) x3;
+  late List<Function> Function<A>(List<T> x) x4;
+  late int Function([Function x]) Function() x5;
+  late int Function(core.List<core.int>) Function() x6;
+  late Function Function(int, [int]) Function() x7;
+  late Function Function(int, {List<Function> x}) Function() x8;
+  late List<Function> Function(int x) Function() x9;
+  late List<Function> Function(int y, [List<Function> x]) Function() x10;
+  late List<Function> Function(int, [List<T>]) Function() x11;
+  late core.List<core.int> Function({Function x}) Function() x12;
+  late core.List<core.int> Function(List<T> x) Function() x13;
+  late List<T> Function(int, [Function x]) Function() x14;
+  late List<T> Function([core.List<core.int>]) Function() x15;
+  late Function(int x, [int]) Function() x16;
+  late Function(int y, {List<Function> x}) Function() x17;
+  late void Function([int x]) Function() x18;
+  late void Function(List<Function>) Function() x19;
+  late void Function(int x, [List<T>]) Function() x20;
+  late List<Function> Function<A>(List<T> x) Function() x21;
+  late Function<A>() Function() x22;
+  late void Function<A>(A x) Function() x23;
+
+  U12({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0([Function x = _voidFunction]) => throw 'uncalled';
+  List<Function> m1(int x) => throw 'uncalled';
+  core.List<core.int> m2(List<T> x) => throw 'uncalled';
+  m3(int y, {List<Function> x = const []}) => throw 'uncalled';
+  List<Function> m4<A>(List<T> x) => throw 'uncalled';
+  int Function([Function x]) m5() => throw 'uncalled';
+  int Function(core.List<core.int>) m6() => throw 'uncalled';
+  Function Function(int, [int]) m7() => throw 'uncalled';
+  Function Function(int, {List<Function> x}) m8() => throw 'uncalled';
+  List<Function> Function(int x) m9() => throw 'uncalled';
+  List<Function> Function(int y, [List<Function> x]) m10() => throw 'uncalled';
+  List<Function> Function(int, [List<T>]) m11() => throw 'uncalled';
+  core.List<core.int> Function({Function x}) m12() => throw 'uncalled';
+  core.List<core.int> Function(List<T> x) m13() => throw 'uncalled';
+  List<T> Function(int, [Function x]) m14() => throw 'uncalled';
+  List<T> Function([core.List<core.int>]) m15() => throw 'uncalled';
+  Function(int x, [int]) m16() => throw 'uncalled';
+  Function(int y, {List<Function> x}) m17() => throw 'uncalled';
+  void Function([int x]) m18() => throw 'uncalled';
+  void Function(List<Function>) m19() => throw 'uncalled';
+  void Function(int x, [List<T>]) m20() => throw 'uncalled';
+  List<Function> Function<A>(List<T> x) m21() => throw 'uncalled';
+  Function<A>() m22() => throw 'uncalled';
+  void Function<A>(A x) m23() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function([Function x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function([Function x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function([Function x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int x)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int x));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function(List<T> x)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<T> x) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function(List<T> x));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int y, {List<Function> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {List<Function> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int y, {List<Function> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<Function> Function<A>(List<T> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<T> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<Function> Function<A>(List<T> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m4 is F4<int>);
+      Expect.equals(true, m4 is F4<bool>);
+      Expect.equals(true, confuse(m4) is F4<int>);
+      Expect.equals(true, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function([Function x]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([Function x]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function([Function x]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(core.List<core.int>) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(core.List<core.int>) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(core.List<core.int>) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, [int]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [int]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [int]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, {List<Function> x}) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {List<Function> x}) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int x) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int x) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, [List<Function> x]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [List<Function> x]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(int y, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int, [List<T>]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<T>]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int, [List<T>]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function({Function x}) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({Function x}) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function({Function x}) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(List<T> x) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<T> x) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(List<T> x) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [Function x]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [Function x]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [Function x]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([core.List<core.int>]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([core.List<core.int>]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function([core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int x, [int]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [int]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int x, [int]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, {List<Function> x}) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {List<Function> x}) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([int x]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([int x]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function([int x]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(List<Function>) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(List<Function>) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(List<Function>) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int x, [List<T>]) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [List<T>]) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int x, [List<T>]) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<T> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<T> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(List<T> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// Function<A>() Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>() Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>() Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(A x) Function()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(A x) Function() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>(A x) Function());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U12().runTests();
+  new U12<int>(tIsInt: true).runTests();
+  new U12<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type13_test.dart b/tests/language/function_type/function_type13_test.dart
new file mode 100644
index 0000000..bdf2ac2
--- /dev/null
+++ b/tests/language/function_type/function_type13_test.dart
@@ -0,0 +1,924 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, [Function x]);
+typedef F1<T> = List<Function> Function([int x]);
+typedef F2<T> = core.List<core.int> Function([List<T> x]);
+typedef F3<T> = Function(core.List<core.int> x);
+typedef F4<T> = List<Function> Function<A>();
+typedef F5<T> = int Function([Function x]) Function(int x);
+typedef F6<T> = int Function(core.List<core.int>) Function(int x);
+typedef F7<T> = Function Function(int, [int]) Function(int x);
+typedef F8<T> = Function Function(int, {List<Function> x}) Function(int x);
+typedef F9<T> = List<Function> Function(int x) Function(int x);
+typedef F10<T> = List<Function> Function(int y, [List<Function> x]) Function(
+    int x);
+typedef F11<T> = List<Function> Function(int, [List<T>]) Function(int x);
+typedef F12<T> = core.List<core.int> Function({Function x}) Function(int x);
+typedef F13<T> = core.List<core.int> Function(List<T> x) Function(int x);
+typedef F14<T> = List<T> Function(int, [Function x]) Function(int x);
+typedef F15<T> = List<T> Function([core.List<core.int>]) Function(int x);
+typedef F16<T> = Function(int x, [int]) Function(int x);
+typedef F17<T> = Function(int y, {List<Function> x}) Function(int x);
+typedef F18<T> = void Function([int x]) Function(int x);
+typedef F19<T> = void Function(List<Function>) Function(int x);
+typedef F20<T> = void Function(int x, [List<T>]) Function(int x);
+typedef F21<T> = List<Function> Function<A>(List<T> x) Function(int x);
+typedef F22<T> = Function<A>() Function(int x);
+typedef F23<T> = void Function<A>(A x) Function(int x);
+
+int f0(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+List<Function> f1([int x = -1]) => throw 'uncalled';
+core.List<core.int> f2([List<int> x = const []]) => throw 'uncalled';
+f3(core.List<core.int> x) => throw 'uncalled';
+List<Function> f4<A>() => throw 'uncalled';
+int Function([Function x]) f5(int x) => throw 'uncalled';
+int Function(core.List<core.int>) f6(int x) => throw 'uncalled';
+Function Function(int, [int]) f7(int x) => throw 'uncalled';
+Function Function(int, {List<Function> x}) f8(int x) => throw 'uncalled';
+List<Function> Function(int x) f9(int x) => throw 'uncalled';
+List<Function> Function(int y, [List<Function> x]) f10(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, [List<int>]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function({Function x}) f12(int x) => throw 'uncalled';
+core.List<core.int> Function(List<int> x) f13(int x) => throw 'uncalled';
+List<int> Function(int, [Function x]) f14(int x) => throw 'uncalled';
+List<int> Function([core.List<core.int>]) f15(int x) => throw 'uncalled';
+Function(int x, [int]) f16(int x) => throw 'uncalled';
+Function(int y, {List<Function> x}) f17(int x) => throw 'uncalled';
+void Function([int x]) f18(int x) => throw 'uncalled';
+void Function(List<Function>) f19(int x) => throw 'uncalled';
+void Function(int x, [List<int>]) f20(int x) => throw 'uncalled';
+List<Function> Function<A>(List<int> x) f21(int x) => throw 'uncalled';
+Function<A>() f22(int x) => throw 'uncalled';
+void Function<A>(A x) f23(int x) => throw 'uncalled';
+
+class U13<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, [Function x]) x0;
+  late List<Function> Function([int x]) x1;
+  late core.List<core.int> Function([List<T> x]) x2;
+  late Function(core.List<core.int> x) x3;
+  late List<Function> Function<A>() x4;
+  late int Function([Function x]) Function(int x) x5;
+  late int Function(core.List<core.int>) Function(int x) x6;
+  late Function Function(int, [int]) Function(int x) x7;
+  late Function Function(int, {List<Function> x}) Function(int x) x8;
+  late List<Function> Function(int x) Function(int x) x9;
+  late List<Function> Function(int y, [List<Function> x]) Function(int x) x10;
+  late List<Function> Function(int, [List<T>]) Function(int x) x11;
+  late core.List<core.int> Function({Function x}) Function(int x) x12;
+  late core.List<core.int> Function(List<T> x) Function(int x) x13;
+  late List<T> Function(int, [Function x]) Function(int x) x14;
+  late List<T> Function([core.List<core.int>]) Function(int x) x15;
+  late Function(int x, [int]) Function(int x) x16;
+  late Function(int y, {List<Function> x}) Function(int x) x17;
+  late void Function([int x]) Function(int x) x18;
+  late void Function(List<Function>) Function(int x) x19;
+  late void Function(int x, [List<T>]) Function(int x) x20;
+  late List<Function> Function<A>(List<T> x) Function(int x) x21;
+  late Function<A>() Function(int x) x22;
+  late void Function<A>(A x) Function(int x) x23;
+
+  U13({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+  List<Function> m1([int x = -1]) => throw 'uncalled';
+  core.List<core.int> m2([List<T> x = const []]) => throw 'uncalled';
+  m3(core.List<core.int> x) => throw 'uncalled';
+  List<Function> m4<A>() => throw 'uncalled';
+  int Function([Function x]) m5(int x) => throw 'uncalled';
+  int Function(core.List<core.int>) m6(int x) => throw 'uncalled';
+  Function Function(int, [int]) m7(int x) => throw 'uncalled';
+  Function Function(int, {List<Function> x}) m8(int x) => throw 'uncalled';
+  List<Function> Function(int x) m9(int x) => throw 'uncalled';
+  List<Function> Function(int y, [List<Function> x]) m10(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, [List<T>]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function({Function x}) m12(int x) => throw 'uncalled';
+  core.List<core.int> Function(List<T> x) m13(int x) => throw 'uncalled';
+  List<T> Function(int, [Function x]) m14(int x) => throw 'uncalled';
+  List<T> Function([core.List<core.int>]) m15(int x) => throw 'uncalled';
+  Function(int x, [int]) m16(int x) => throw 'uncalled';
+  Function(int y, {List<Function> x}) m17(int x) => throw 'uncalled';
+  void Function([int x]) m18(int x) => throw 'uncalled';
+  void Function(List<Function>) m19(int x) => throw 'uncalled';
+  void Function(int x, [List<T>]) m20(int x) => throw 'uncalled';
+  List<Function> Function<A>(List<T> x) m21(int x) => throw 'uncalled';
+  Function<A>() m22(int x) => throw 'uncalled';
+  void Function<A>(A x) m23(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, [Function x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [Function x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, [Function x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function([int x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([int x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function([int x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function([List<T> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<T> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function([List<T> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(core.List<core.int> x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(core.List<core.int> x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(core.List<core.int> x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<Function> Function<A>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<Function> Function<A>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([Function x]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([Function x]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function([Function x]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(core.List<core.int>) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(core.List<core.int>) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(core.List<core.int>) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, [int]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [int]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [int]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, {List<Function> x}) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {List<Function> x}) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int, {List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int x) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int x) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, [List<Function> x]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [List<Function> x]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, [List<Function> x])
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int, [List<T>]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<T>]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is List<Function> Function(int, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function({Function x}) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({Function x}) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function({Function x}) Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(List<T> x) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<T> x) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [Function x]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [Function x]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([core.List<core.int>]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([core.List<core.int>]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function([core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int x, [int]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [int]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int x, [int]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, {List<Function> x}) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {List<Function> x}) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, {List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([int x]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([int x]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function([int x]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(List<Function>) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(List<Function>) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(List<Function>) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int x, [List<T>]) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [List<T>]) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int x, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<T> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<T> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// Function<A>() Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>() Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>() Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(A x) Function(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(A x) Function(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>(A x) Function(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U13().runTests();
+  new U13<int>(tIsInt: true).runTests();
+  new U13<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type14_test.dart b/tests/language/function_type/function_type14_test.dart
new file mode 100644
index 0000000..9b9f58c0
--- /dev/null
+++ b/tests/language/function_type/function_type14_test.dart
@@ -0,0 +1,968 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int y, [Function x]);
+typedef F1<T> = List<Function> Function(int, [int x]);
+typedef F2<T> = core.List<core.int> Function(int, [List<T> x]);
+typedef F3<T> = Function([core.List<core.int> x]);
+typedef F4<T> = List<Function> Function<A>(A x);
+typedef F5<T> = int Function([Function x]) Function<B extends core.int>();
+typedef F6<T> = int Function(core.List<core.int>)
+    Function<B extends core.int>();
+typedef F7<T> = Function Function(int, [int]) Function<B extends core.int>();
+typedef F8<T> = Function Function(int, {List<Function> x})
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int x) Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int y, [List<Function> x])
+    Function<B extends core.int>();
+typedef F11<T> = List<Function> Function(int, [List<T>])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function({Function x})
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function(List<T> x)
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int, [Function x])
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function([core.List<core.int>])
+    Function<B extends core.int>();
+typedef F16<T> = Function(int x, [int]) Function<B extends core.int>();
+typedef F17<T> = Function(int y, {List<Function> x})
+    Function<B extends core.int>();
+typedef F18<T> = void Function([int x]) Function<B extends core.int>();
+typedef F19<T> = void Function(List<Function>) Function<B extends core.int>();
+typedef F20<T> = void Function(int x, [List<T>]) Function<B extends core.int>();
+typedef F21<T> = List<Function> Function<A>(List<T> x)
+    Function<B extends core.int>();
+typedef F22<T> = Function<A>() Function<B extends core.int>();
+typedef F23<T> = void Function<A>(A x) Function<B extends core.int>();
+
+int f0(int y, [Function x = _voidFunction]) => throw 'uncalled';
+List<Function> f1(int x0, [int x = -1]) => throw 'uncalled';
+core.List<core.int> f2(int x0, [List<int> x = const []]) => throw 'uncalled';
+f3([core.List<core.int> x = const []]) => throw 'uncalled';
+List<Function> f4<A>(A x) => throw 'uncalled';
+int Function([Function x]) f5<B extends core.int>() => throw 'uncalled';
+int Function(core.List<core.int>) f6<B extends core.int>() => throw 'uncalled';
+Function Function(int, [int]) f7<B extends core.int>() => throw 'uncalled';
+Function Function(int, {List<Function> x}) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int x) f9<B extends core.int>() => throw 'uncalled';
+List<Function> Function(int y, [List<Function> x]) f10<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, [List<int>]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function({Function x}) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(List<int> x) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, [Function x]) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function([core.List<core.int>]) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function(int x, [int]) f16<B extends core.int>() => throw 'uncalled';
+Function(int y, {List<Function> x}) f17<B extends core.int>() =>
+    throw 'uncalled';
+void Function([int x]) f18<B extends core.int>() => throw 'uncalled';
+void Function(List<Function>) f19<B extends core.int>() => throw 'uncalled';
+void Function(int x, [List<int>]) f20<B extends core.int>() => throw 'uncalled';
+List<Function> Function<A>(List<int> x) f21<B extends core.int>() =>
+    throw 'uncalled';
+Function<A>() f22<B extends core.int>() => throw 'uncalled';
+void Function<A>(A x) f23<B extends core.int>() => throw 'uncalled';
+
+class U14<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int y, [Function x]) x0;
+  late List<Function> Function(int, [int x]) x1;
+  late core.List<core.int> Function(int, [List<T> x]) x2;
+  late Function([core.List<core.int> x]) x3;
+  late List<Function> Function<A>(A x) x4;
+  late int Function([Function x]) Function<B extends core.int>() x5;
+  late int Function(core.List<core.int>) Function<B extends core.int>() x6;
+  late Function Function(int, [int]) Function<B extends core.int>() x7;
+  late Function Function(int, {List<Function> x}) Function<B extends core.int>()
+      x8;
+  late List<Function> Function(int x) Function<B extends core.int>() x9;
+  late List<Function> Function(int y, [List<Function> x])
+      Function<B extends core.int>() x10;
+  late List<Function> Function(int, [List<T>]) Function<B extends core.int>()
+      x11;
+  late core.List<core.int> Function({Function x}) Function<B extends core.int>()
+      x12;
+  late core.List<core.int> Function(List<T> x) Function<B extends core.int>()
+      x13;
+  late List<T> Function(int, [Function x]) Function<B extends core.int>() x14;
+  late List<T> Function([core.List<core.int>]) Function<B extends core.int>()
+      x15;
+  late Function(int x, [int]) Function<B extends core.int>() x16;
+  late Function(int y, {List<Function> x}) Function<B extends core.int>() x17;
+  late void Function([int x]) Function<B extends core.int>() x18;
+  late void Function(List<Function>) Function<B extends core.int>() x19;
+  late void Function(int x, [List<T>]) Function<B extends core.int>() x20;
+  late List<Function> Function<A>(List<T> x) Function<B extends core.int>() x21;
+  late Function<A>() Function<B extends core.int>() x22;
+  late void Function<A>(A x) Function<B extends core.int>() x23;
+
+  U14({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int y, [Function x = _voidFunction]) => throw 'uncalled';
+  List<Function> m1(int x0, [int x = -1]) => throw 'uncalled';
+  core.List<core.int> m2(int x0, [List<T> x = const []]) => throw 'uncalled';
+  m3([core.List<core.int> x = const []]) => throw 'uncalled';
+  List<Function> m4<A>(A x) => throw 'uncalled';
+  int Function([Function x]) m5<B extends core.int>() => throw 'uncalled';
+  int Function(core.List<core.int>) m6<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int, [int]) m7<B extends core.int>() => throw 'uncalled';
+  Function Function(int, {List<Function> x}) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int x) m9<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(int y, [List<Function> x])
+      m10<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(int, [List<T>]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function({Function x}) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(List<T> x) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, [Function x]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function([core.List<core.int>]) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int x, [int]) m16<B extends core.int>() => throw 'uncalled';
+  Function(int y, {List<Function> x}) m17<B extends core.int>() =>
+      throw 'uncalled';
+  void Function([int x]) m18<B extends core.int>() => throw 'uncalled';
+  void Function(List<Function>) m19<B extends core.int>() => throw 'uncalled';
+  void Function(int x, [List<T>]) m20<B extends core.int>() => throw 'uncalled';
+  List<Function> Function<A>(List<T> x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  Function<A>() m22<B extends core.int>() => throw 'uncalled';
+  void Function<A>(A x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int y, [Function x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [Function x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int y, [Function x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, [int x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [int x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, [int x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function(int, [List<T> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<T> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function(int, [List<T> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function([core.List<core.int> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function([core.List<core.int> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function([core.List<core.int> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<Function> Function<A>(A x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(A x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<Function> Function<A>(A x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([Function x]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([Function x]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function([Function x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(core.List<core.int>) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(core.List<core.int>) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(core.List<core.int>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, [int]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [int]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(int, [int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, {List<Function> x}) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {List<Function> x}) Function<B extends core.int>()
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int x) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, [List<Function> x]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [List<Function> x])
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int, [List<T>]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<T>]) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int, [List<T>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function({Function x}) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({Function x}) Function<B extends core.int>()
+        l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function({Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(List<T> x) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<T> x) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(List<T> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [Function x]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [Function x]) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([core.List<core.int>]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([core.List<core.int>]) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function([core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int x, [int]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [int]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int x, [int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, {List<Function> x}) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {List<Function> x}) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([int x]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([int x]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function([int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(List<Function>) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(List<Function>) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(List<Function>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int x, [List<T>]) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [List<T>]) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is void Function(int x, [List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<T> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<T> x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(List<T> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// Function<A>() Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>() Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>() Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(A x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(A x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>(A x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U14().runTests();
+  new U14<int>(tIsInt: true).runTests();
+  new U14<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type15_test.dart b/tests/language/function_type/function_type15_test.dart
new file mode 100644
index 0000000..0083d12
--- /dev/null
+++ b/tests/language/function_type/function_type15_test.dart
@@ -0,0 +1,992 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(Function);
+typedef F1<T> = List<Function> Function(int y, [int x]);
+typedef F2<T> = core.List<core.int> Function(int y, [List<T> x]);
+typedef F3<T> = Function(int, [core.List<core.int> x]);
+typedef F4<T> = List<Function> Function<A>(List<A> x);
+typedef F5<T> = int Function([Function x]) Function<B extends core.int>(int x);
+typedef F6<T> = int Function(core.List<core.int>) Function<B extends core.int>(
+    int x);
+typedef F7<T> = Function Function(int, [int]) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function(int, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(int x) Function<B extends core.int>(
+    int x);
+typedef F10<T> = List<Function> Function(int y, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F11<T> = List<Function> Function(int, [List<T>])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function({Function x})
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function(List<T> x)
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(int, [Function x])
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function([core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function(int x, [int]) Function<B extends core.int>(int x);
+typedef F17<T> = Function(int y, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F18<T> = void Function([int x]) Function<B extends core.int>(int x);
+typedef F19<T> = void Function(List<Function>) Function<B extends core.int>(
+    int x);
+typedef F20<T> = void Function(int x, [List<T>]) Function<B extends core.int>(
+    int x);
+typedef F21<T> = List<Function> Function<A>(List<T> x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = Function<A>() Function<B extends core.int>(int x);
+typedef F23<T> = void Function<A>(A x) Function<B extends core.int>(int x);
+
+int f0(Function x0) => throw 'uncalled';
+List<Function> f1(int y, [int x = -1]) => throw 'uncalled';
+core.List<core.int> f2(int y, [List<int> x = const []]) => throw 'uncalled';
+f3(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
+List<Function> f4<A>(List<A> x) => throw 'uncalled';
+int Function([Function x]) f5<B extends core.int>(int x) => throw 'uncalled';
+int Function(core.List<core.int>) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, [int]) f7<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int, {List<Function> x}) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int x) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int y, [List<Function> x]) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<Function> Function(int, [List<int>]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function({Function x}) f12<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(List<int> x) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, [Function x]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function([core.List<core.int>]) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int x, [int]) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(int y, {List<Function> x}) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function([int x]) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(List<Function>) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int x, [List<int>]) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function<A>(List<int> x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function<A>() f22<B extends core.int>(int x) => throw 'uncalled';
+void Function<A>(A x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U15<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(Function) x0;
+  late List<Function> Function(int y, [int x]) x1;
+  late core.List<core.int> Function(int y, [List<T> x]) x2;
+  late Function(int, [core.List<core.int> x]) x3;
+  late List<Function> Function<A>(List<A> x) x4;
+  late int Function([Function x]) Function<B extends core.int>(int x) x5;
+  late int Function(core.List<core.int>) Function<B extends core.int>(int x) x6;
+  late Function Function(int, [int]) Function<B extends core.int>(int x) x7;
+  late Function Function(int, {List<Function> x}) Function<B extends core.int>(
+      int x) x8;
+  late List<Function> Function(int x) Function<B extends core.int>(int x) x9;
+  late List<Function> Function(int y, [List<Function> x])
+      Function<B extends core.int>(int x) x10;
+  late List<Function> Function(int, [List<T>]) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function({Function x}) Function<B extends core.int>(
+      int x) x12;
+  late core.List<core.int> Function(List<T> x) Function<B extends core.int>(
+      int x) x13;
+  late List<T> Function(int, [Function x]) Function<B extends core.int>(int x)
+      x14;
+  late List<T> Function([core.List<core.int>]) Function<B extends core.int>(
+      int x) x15;
+  late Function(int x, [int]) Function<B extends core.int>(int x) x16;
+  late Function(int y, {List<Function> x}) Function<B extends core.int>(int x)
+      x17;
+  late void Function([int x]) Function<B extends core.int>(int x) x18;
+  late void Function(List<Function>) Function<B extends core.int>(int x) x19;
+  late void Function(int x, [List<T>]) Function<B extends core.int>(int x) x20;
+  late List<Function> Function<A>(List<T> x) Function<B extends core.int>(int x)
+      x21;
+  late Function<A>() Function<B extends core.int>(int x) x22;
+  late void Function<A>(A x) Function<B extends core.int>(int x) x23;
+
+  U15({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(Function x0) => throw 'uncalled';
+  List<Function> m1(int y, [int x = -1]) => throw 'uncalled';
+  core.List<core.int> m2(int y, [List<T> x = const []]) => throw 'uncalled';
+  m3(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
+  List<Function> m4<A>(List<A> x) => throw 'uncalled';
+  int Function([Function x]) m5<B extends core.int>(int x) => throw 'uncalled';
+  int Function(core.List<core.int>) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, [int]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, {List<Function> x}) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int x) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, [List<Function> x]) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, [List<T>]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function({Function x}) m12<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(List<T> x) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [Function x]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function([core.List<core.int>]) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int x, [int]) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(int y, {List<Function> x}) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function([int x]) m18<B extends core.int>(int x) => throw 'uncalled';
+  void Function(List<Function>) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int x, [List<T>]) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function<A>(List<T> x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function<A>() m22<B extends core.int>(int x) => throw 'uncalled';
+  void Function<A>(A x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(Function)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(Function) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(Function));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int y, [int x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [int x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int y, [int x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function(int y, [List<T> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [List<T> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function(int y, [List<T> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int, [core.List<core.int> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int, [core.List<core.int> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<Function> Function<A>(List<A> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<A> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<Function> Function<A>(List<A> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([Function x]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([Function x]) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function([Function x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(core.List<core.int>) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(core.List<core.int>) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(core.List<core.int>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, [int]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [int]) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [int])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {List<Function> x}) Function<B extends core.int>(
+        int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int x) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x) Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [List<Function> x])
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int, [List<T>]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<T>]) Function<B extends core.int>(int x)
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function({Function x}) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({Function x}) Function<B extends core.int>(
+        int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function({Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(List<T> x) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<T> x) Function<B extends core.int>(int x)
+        l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(List<T> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [Function x]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [Function x]) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([core.List<core.int>]) Function<B extends core.int>(int x)
+        l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function([core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int x, [int]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [int]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int x, [int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {List<Function> x}) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([int x]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([int x]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function([int x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(List<Function>) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(List<Function>) Function<B extends core.int>(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(List<Function>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int x, [List<T>]) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [List<T>]) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int x, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<T> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<T> x) Function<B extends core.int>(int x)
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(List<T> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// Function<A>() Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>() Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(A x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(A x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is void Function<A>(A x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U15().runTests();
+  new U15<int>(tIsInt: true).runTests();
+  new U15<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type16_test.dart b/tests/language/function_type/function_type16_test.dart
new file mode 100644
index 0000000..63edfae
--- /dev/null
+++ b/tests/language/function_type/function_type16_test.dart
@@ -0,0 +1,893 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function([Function]);
+typedef F1<T> = List<Function> Function(int);
+typedef F2<T> = core.List<core.int> Function(List<T>);
+typedef F3<T> = Function(int y, [core.List<core.int> x]);
+typedef F4<T> = core.List<core.int> Function<A>(int x);
+typedef F5<T> = int Function(int, [Function x]) Function();
+typedef F6<T> = int Function([core.List<core.int>]) Function();
+typedef F7<T> = Function Function(int x, [int]) Function();
+typedef F8<T> = Function Function(int y, {List<Function> x}) Function();
+typedef F9<T> = List<Function> Function([int x]) Function();
+typedef F10<T> = List<Function> Function(List<Function>) Function();
+typedef F11<T> = List<Function> Function(int x, [List<T>]) Function();
+typedef F12<T> = core.List<core.int> Function(int, {Function x}) Function();
+typedef F13<T> = core.List<core.int> Function([List<T> x]) Function();
+typedef F14<T> = List<T> Function(int y, [Function x]) Function();
+typedef F15<T> = List<T> Function(int, [core.List<core.int>]) Function();
+typedef F16<T> = Function({int x}) Function();
+typedef F17<T> = Function(core.List<core.int> x) Function();
+typedef F18<T> = void Function(int, [int x]) Function();
+typedef F19<T> = void Function([List<Function>]) Function();
+typedef F20<T> = void Function({List<T> x}) Function();
+typedef F21<T> = List<Function> Function<A>() Function();
+typedef F22<T> = Function<A>(A x) Function();
+typedef F23<T> = void Function<A>(List<A> x) Function();
+
+int f0([Function x0 = _voidFunction]) => throw 'uncalled';
+List<Function> f1(int x0) => throw 'uncalled';
+core.List<core.int> f2(List<int> x0) => throw 'uncalled';
+f3(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
+core.List<core.int> f4<A>(int x) => throw 'uncalled';
+int Function(int, [Function x]) f5() => throw 'uncalled';
+int Function([core.List<core.int>]) f6() => throw 'uncalled';
+Function Function(int x, [int]) f7() => throw 'uncalled';
+Function Function(int y, {List<Function> x}) f8() => throw 'uncalled';
+List<Function> Function([int x]) f9() => throw 'uncalled';
+List<Function> Function(List<Function>) f10() => throw 'uncalled';
+List<Function> Function(int x, [List<int>]) f11() => throw 'uncalled';
+core.List<core.int> Function(int, {Function x}) f12() => throw 'uncalled';
+core.List<core.int> Function([List<int> x]) f13() => throw 'uncalled';
+List<int> Function(int y, [Function x]) f14() => throw 'uncalled';
+List<int> Function(int, [core.List<core.int>]) f15() => throw 'uncalled';
+Function({int x}) f16() => throw 'uncalled';
+Function(core.List<core.int> x) f17() => throw 'uncalled';
+void Function(int, [int x]) f18() => throw 'uncalled';
+void Function([List<Function>]) f19() => throw 'uncalled';
+void Function({List<int> x}) f20() => throw 'uncalled';
+List<Function> Function<A>() f21() => throw 'uncalled';
+Function<A>(A x) f22() => throw 'uncalled';
+void Function<A>(List<A> x) f23() => throw 'uncalled';
+
+class U16<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function([Function]) x0;
+  late List<Function> Function(int) x1;
+  late core.List<core.int> Function(List<T>) x2;
+  late Function(int y, [core.List<core.int> x]) x3;
+  late core.List<core.int> Function<A>(int x) x4;
+  late int Function(int, [Function x]) Function() x5;
+  late int Function([core.List<core.int>]) Function() x6;
+  late Function Function(int x, [int]) Function() x7;
+  late Function Function(int y, {List<Function> x}) Function() x8;
+  late List<Function> Function([int x]) Function() x9;
+  late List<Function> Function(List<Function>) Function() x10;
+  late List<Function> Function(int x, [List<T>]) Function() x11;
+  late core.List<core.int> Function(int, {Function x}) Function() x12;
+  late core.List<core.int> Function([List<T> x]) Function() x13;
+  late List<T> Function(int y, [Function x]) Function() x14;
+  late List<T> Function(int, [core.List<core.int>]) Function() x15;
+  late Function({int x}) Function() x16;
+  late Function(core.List<core.int> x) Function() x17;
+  late void Function(int, [int x]) Function() x18;
+  late void Function([List<Function>]) Function() x19;
+  late void Function({List<T> x}) Function() x20;
+  late List<Function> Function<A>() Function() x21;
+  late Function<A>(A x) Function() x22;
+  late void Function<A>(List<A> x) Function() x23;
+
+  U16({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0([Function x0 = _voidFunction]) => throw 'uncalled';
+  List<Function> m1(int x0) => throw 'uncalled';
+  core.List<core.int> m2(List<T> x0) => throw 'uncalled';
+  m3(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
+  core.List<core.int> m4<A>(int x) => throw 'uncalled';
+  int Function(int, [Function x]) m5() => throw 'uncalled';
+  int Function([core.List<core.int>]) m6() => throw 'uncalled';
+  Function Function(int x, [int]) m7() => throw 'uncalled';
+  Function Function(int y, {List<Function> x}) m8() => throw 'uncalled';
+  List<Function> Function([int x]) m9() => throw 'uncalled';
+  List<Function> Function(List<Function>) m10() => throw 'uncalled';
+  List<Function> Function(int x, [List<T>]) m11() => throw 'uncalled';
+  core.List<core.int> Function(int, {Function x}) m12() => throw 'uncalled';
+  core.List<core.int> Function([List<T> x]) m13() => throw 'uncalled';
+  List<T> Function(int y, [Function x]) m14() => throw 'uncalled';
+  List<T> Function(int, [core.List<core.int>]) m15() => throw 'uncalled';
+  Function({int x}) m16() => throw 'uncalled';
+  Function(core.List<core.int> x) m17() => throw 'uncalled';
+  void Function(int, [int x]) m18() => throw 'uncalled';
+  void Function([List<Function>]) m19() => throw 'uncalled';
+  void Function({List<T> x}) m20() => throw 'uncalled';
+  List<Function> Function<A>() m21() => throw 'uncalled';
+  Function<A>(A x) m22() => throw 'uncalled';
+  void Function<A>(List<A> x) m23() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function([Function])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function([Function]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function([Function]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function(List<T>)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<T>) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function(List<T>));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int y, [core.List<core.int> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [core.List<core.int> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int y, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// core.List<core.int> Function<A>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is core.List<core.int> Function<A>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [Function x]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [Function x]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [Function x]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([core.List<core.int>]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([core.List<core.int>]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int x, [int]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [int]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int x, [int]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, {List<Function> x}) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {List<Function> x}) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int y, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([int x]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([int x]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([int x]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(List<Function>) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<Function>) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(List<Function>) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int x, [List<T>]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [List<T>]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int x, [List<T>]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, {Function x}) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {Function x}) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(int, {Function x}) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function([List<T> x]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<T> x]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function([List<T> x]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [Function x]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [Function x]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, [Function x]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [core.List<core.int>]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [core.List<core.int>]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function({int x}) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function({int x}) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function({int x}) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(core.List<core.int> x) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(core.List<core.int> x) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, [int x]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [int x]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, [int x]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([List<Function>]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<Function>]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([List<Function>]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function({List<T> x}) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function({List<T> x}) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function({List<T> x}) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>() Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>() Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>() Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(A x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(A x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(A x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(List<A> x) Function()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<A> x) Function() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>(List<A> x) Function());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U16().runTests();
+  new U16<int>(tIsInt: true).runTests();
+  new U16<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type17_test.dart b/tests/language/function_type/function_type17_test.dart
new file mode 100644
index 0000000..50b4291d
--- /dev/null
+++ b/tests/language/function_type/function_type17_test.dart
@@ -0,0 +1,898 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, [Function]);
+typedef F1<T> = List<Function> Function([int]);
+typedef F2<T> = core.List<core.int> Function([List<T>]);
+typedef F3<T> = Function(core.List<core.int>);
+typedef F4<T> = core.List<core.int> Function<A>(Function x);
+typedef F5<T> = int Function(int, [Function x]) Function(int x);
+typedef F6<T> = int Function([core.List<core.int>]) Function(int x);
+typedef F7<T> = Function Function(int x, [int]) Function(int x);
+typedef F8<T> = Function Function(int y, {List<Function> x}) Function(int x);
+typedef F9<T> = List<Function> Function([int x]) Function(int x);
+typedef F10<T> = List<Function> Function(List<Function>) Function(int x);
+typedef F11<T> = List<Function> Function(int x, [List<T>]) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int, {Function x}) Function(
+    int x);
+typedef F13<T> = core.List<core.int> Function([List<T> x]) Function(int x);
+typedef F14<T> = List<T> Function(int y, [Function x]) Function(int x);
+typedef F15<T> = List<T> Function(int, [core.List<core.int>]) Function(int x);
+typedef F16<T> = Function({int x}) Function(int x);
+typedef F17<T> = Function(core.List<core.int> x) Function(int x);
+typedef F18<T> = void Function(int, [int x]) Function(int x);
+typedef F19<T> = void Function([List<Function>]) Function(int x);
+typedef F20<T> = void Function({List<T> x}) Function(int x);
+typedef F21<T> = List<Function> Function<A>() Function(int x);
+typedef F22<T> = Function<A>(A x) Function(int x);
+typedef F23<T> = void Function<A>(List<A> x) Function(int x);
+
+int f0(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+List<Function> f1([int x0 = -1]) => throw 'uncalled';
+core.List<core.int> f2([List<int> x0 = const []]) => throw 'uncalled';
+f3(core.List<core.int> x0) => throw 'uncalled';
+core.List<core.int> f4<A>(Function x) => throw 'uncalled';
+int Function(int, [Function x]) f5(int x) => throw 'uncalled';
+int Function([core.List<core.int>]) f6(int x) => throw 'uncalled';
+Function Function(int x, [int]) f7(int x) => throw 'uncalled';
+Function Function(int y, {List<Function> x}) f8(int x) => throw 'uncalled';
+List<Function> Function([int x]) f9(int x) => throw 'uncalled';
+List<Function> Function(List<Function>) f10(int x) => throw 'uncalled';
+List<Function> Function(int x, [List<int>]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int, {Function x}) f12(int x) => throw 'uncalled';
+core.List<core.int> Function([List<int> x]) f13(int x) => throw 'uncalled';
+List<int> Function(int y, [Function x]) f14(int x) => throw 'uncalled';
+List<int> Function(int, [core.List<core.int>]) f15(int x) => throw 'uncalled';
+Function({int x}) f16(int x) => throw 'uncalled';
+Function(core.List<core.int> x) f17(int x) => throw 'uncalled';
+void Function(int, [int x]) f18(int x) => throw 'uncalled';
+void Function([List<Function>]) f19(int x) => throw 'uncalled';
+void Function({List<int> x}) f20(int x) => throw 'uncalled';
+List<Function> Function<A>() f21(int x) => throw 'uncalled';
+Function<A>(A x) f22(int x) => throw 'uncalled';
+void Function<A>(List<A> x) f23(int x) => throw 'uncalled';
+
+class U17<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, [Function]) x0;
+  late List<Function> Function([int]) x1;
+  late core.List<core.int> Function([List<T>]) x2;
+  late Function(core.List<core.int>) x3;
+  late core.List<core.int> Function<A>(Function x) x4;
+  late int Function(int, [Function x]) Function(int x) x5;
+  late int Function([core.List<core.int>]) Function(int x) x6;
+  late Function Function(int x, [int]) Function(int x) x7;
+  late Function Function(int y, {List<Function> x}) Function(int x) x8;
+  late List<Function> Function([int x]) Function(int x) x9;
+  late List<Function> Function(List<Function>) Function(int x) x10;
+  late List<Function> Function(int x, [List<T>]) Function(int x) x11;
+  late core.List<core.int> Function(int, {Function x}) Function(int x) x12;
+  late core.List<core.int> Function([List<T> x]) Function(int x) x13;
+  late List<T> Function(int y, [Function x]) Function(int x) x14;
+  late List<T> Function(int, [core.List<core.int>]) Function(int x) x15;
+  late Function({int x}) Function(int x) x16;
+  late Function(core.List<core.int> x) Function(int x) x17;
+  late void Function(int, [int x]) Function(int x) x18;
+  late void Function([List<Function>]) Function(int x) x19;
+  late void Function({List<T> x}) Function(int x) x20;
+  late List<Function> Function<A>() Function(int x) x21;
+  late Function<A>(A x) Function(int x) x22;
+  late void Function<A>(List<A> x) Function(int x) x23;
+
+  U17({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+  List<Function> m1([int x0 = -1]) => throw 'uncalled';
+  core.List<core.int> m2([List<T> x0 = const []]) => throw 'uncalled';
+  m3(core.List<core.int> x0) => throw 'uncalled';
+  core.List<core.int> m4<A>(Function x) => throw 'uncalled';
+  int Function(int, [Function x]) m5(int x) => throw 'uncalled';
+  int Function([core.List<core.int>]) m6(int x) => throw 'uncalled';
+  Function Function(int x, [int]) m7(int x) => throw 'uncalled';
+  Function Function(int y, {List<Function> x}) m8(int x) => throw 'uncalled';
+  List<Function> Function([int x]) m9(int x) => throw 'uncalled';
+  List<Function> Function(List<Function>) m10(int x) => throw 'uncalled';
+  List<Function> Function(int x, [List<T>]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, {Function x}) m12(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([List<T> x]) m13(int x) => throw 'uncalled';
+  List<T> Function(int y, [Function x]) m14(int x) => throw 'uncalled';
+  List<T> Function(int, [core.List<core.int>]) m15(int x) => throw 'uncalled';
+  Function({int x}) m16(int x) => throw 'uncalled';
+  Function(core.List<core.int> x) m17(int x) => throw 'uncalled';
+  void Function(int, [int x]) m18(int x) => throw 'uncalled';
+  void Function([List<Function>]) m19(int x) => throw 'uncalled';
+  void Function({List<T> x}) m20(int x) => throw 'uncalled';
+  List<Function> Function<A>() m21(int x) => throw 'uncalled';
+  Function<A>(A x) m22(int x) => throw 'uncalled';
+  void Function<A>(List<A> x) m23(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, [Function])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [Function]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, [Function]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function([int])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([int]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function([int]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function([List<T>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<T>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function([List<T>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(core.List<core.int>)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(core.List<core.int>) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(core.List<core.int>));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// core.List<core.int> Function<A>(Function x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(Function x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is core.List<core.int> Function<A>(Function x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [Function x]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [Function x]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([core.List<core.int>]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([core.List<core.int>]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int x, [int]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [int]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int x, [int]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, {List<Function> x}) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {List<Function> x}) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int y, {List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([int x]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([int x]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([int x]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(List<Function>) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<Function>) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(List<Function>) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int x, [List<T>]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [List<T>]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is List<Function> Function(int x, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, {Function x}) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {Function x}) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(int, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function([List<T> x]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<T> x]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function([List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [Function x]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [Function x]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [core.List<core.int>]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [core.List<core.int>]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int, [core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function({int x}) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function({int x}) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function({int x}) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(core.List<core.int> x) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(core.List<core.int> x) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, [int x]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [int x]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, [int x]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([List<Function>]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<Function>]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function({List<T> x}) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function({List<T> x}) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function({List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>() Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>() Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>() Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(A x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(A x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(A x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(List<A> x) Function(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<A> x) Function(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>(List<A> x) Function(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U17().runTests();
+  new U17<int>(tIsInt: true).runTests();
+  new U17<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type18_test.dart b/tests/language/function_type/function_type18_test.dart
new file mode 100644
index 0000000..6df5530
--- /dev/null
+++ b/tests/language/function_type/function_type18_test.dart
@@ -0,0 +1,942 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int x, [Function]);
+typedef F1<T> = List<Function> Function(int, [int]);
+typedef F2<T> = core.List<core.int> Function(int, [List<T>]);
+typedef F3<T> = Function([core.List<core.int>]);
+typedef F4<T> = core.List<core.int> Function<A>(List<Function> x);
+typedef F5<T> = int Function(int, [Function x]) Function<B extends core.int>();
+typedef F6<T> = int Function([core.List<core.int>])
+    Function<B extends core.int>();
+typedef F7<T> = Function Function(int x, [int]) Function<B extends core.int>();
+typedef F8<T> = Function Function(int y, {List<Function> x})
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function([int x]) Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(List<Function>)
+    Function<B extends core.int>();
+typedef F11<T> = List<Function> Function(int x, [List<T>])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int, {Function x})
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function([List<T> x])
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int y, [Function x])
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F16<T> = Function({int x}) Function<B extends core.int>();
+typedef F17<T> = Function(core.List<core.int> x) Function<B extends core.int>();
+typedef F18<T> = void Function(int, [int x]) Function<B extends core.int>();
+typedef F19<T> = void Function([List<Function>]) Function<B extends core.int>();
+typedef F20<T> = void Function({List<T> x}) Function<B extends core.int>();
+typedef F21<T> = List<Function> Function<A>() Function<B extends core.int>();
+typedef F22<T> = Function<A>(A x) Function<B extends core.int>();
+typedef F23<T> = void Function<A>(List<A> x) Function<B extends core.int>();
+
+int f0(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+List<Function> f1(int x0, [int x1 = -1]) => throw 'uncalled';
+core.List<core.int> f2(int x0, [List<int> x1 = const []]) => throw 'uncalled';
+f3([core.List<core.int> x0 = const []]) => throw 'uncalled';
+core.List<core.int> f4<A>(List<Function> x) => throw 'uncalled';
+int Function(int, [Function x]) f5<B extends core.int>() => throw 'uncalled';
+int Function([core.List<core.int>]) f6<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int x, [int]) f7<B extends core.int>() => throw 'uncalled';
+Function Function(int y, {List<Function> x}) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function([int x]) f9<B extends core.int>() => throw 'uncalled';
+List<Function> Function(List<Function>) f10<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int x, [List<int>]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {Function x}) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function([List<int> x]) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int y, [Function x]) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, [core.List<core.int>]) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function({int x}) f16<B extends core.int>() => throw 'uncalled';
+Function(core.List<core.int> x) f17<B extends core.int>() => throw 'uncalled';
+void Function(int, [int x]) f18<B extends core.int>() => throw 'uncalled';
+void Function([List<Function>]) f19<B extends core.int>() => throw 'uncalled';
+void Function({List<int> x}) f20<B extends core.int>() => throw 'uncalled';
+List<Function> Function<A>() f21<B extends core.int>() => throw 'uncalled';
+Function<A>(A x) f22<B extends core.int>() => throw 'uncalled';
+void Function<A>(List<A> x) f23<B extends core.int>() => throw 'uncalled';
+
+class U18<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int x, [Function]) x0;
+  late List<Function> Function(int, [int]) x1;
+  late core.List<core.int> Function(int, [List<T>]) x2;
+  late Function([core.List<core.int>]) x3;
+  late core.List<core.int> Function<A>(List<Function> x) x4;
+  late int Function(int, [Function x]) Function<B extends core.int>() x5;
+  late int Function([core.List<core.int>]) Function<B extends core.int>() x6;
+  late Function Function(int x, [int]) Function<B extends core.int>() x7;
+  late Function Function(int y, {List<Function> x})
+      Function<B extends core.int>() x8;
+  late List<Function> Function([int x]) Function<B extends core.int>() x9;
+  late List<Function> Function(List<Function>) Function<B extends core.int>()
+      x10;
+  late List<Function> Function(int x, [List<T>]) Function<B extends core.int>()
+      x11;
+  late core.List<core.int> Function(int, {Function x})
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function([List<T> x]) Function<B extends core.int>()
+      x13;
+  late List<T> Function(int y, [Function x]) Function<B extends core.int>() x14;
+  late List<T> Function(int, [core.List<core.int>])
+      Function<B extends core.int>() x15;
+  late Function({int x}) Function<B extends core.int>() x16;
+  late Function(core.List<core.int> x) Function<B extends core.int>() x17;
+  late void Function(int, [int x]) Function<B extends core.int>() x18;
+  late void Function([List<Function>]) Function<B extends core.int>() x19;
+  late void Function({List<T> x}) Function<B extends core.int>() x20;
+  late List<Function> Function<A>() Function<B extends core.int>() x21;
+  late Function<A>(A x) Function<B extends core.int>() x22;
+  late void Function<A>(List<A> x) Function<B extends core.int>() x23;
+
+  U18({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+  List<Function> m1(int x0, [int x1 = -1]) => throw 'uncalled';
+  core.List<core.int> m2(int x0, [List<T> x1 = const []]) => throw 'uncalled';
+  m3([core.List<core.int> x0 = const []]) => throw 'uncalled';
+  core.List<core.int> m4<A>(List<Function> x) => throw 'uncalled';
+  int Function(int, [Function x]) m5<B extends core.int>() => throw 'uncalled';
+  int Function([core.List<core.int>]) m6<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int x, [int]) m7<B extends core.int>() => throw 'uncalled';
+  Function Function(int y, {List<Function> x}) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function([int x]) m9<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(List<Function>) m10<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int x, [List<T>]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {Function x}) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function([List<T> x]) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int y, [Function x]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, [core.List<core.int>]) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function({int x}) m16<B extends core.int>() => throw 'uncalled';
+  Function(core.List<core.int> x) m17<B extends core.int>() => throw 'uncalled';
+  void Function(int, [int x]) m18<B extends core.int>() => throw 'uncalled';
+  void Function([List<Function>]) m19<B extends core.int>() => throw 'uncalled';
+  void Function({List<T> x}) m20<B extends core.int>() => throw 'uncalled';
+  List<Function> Function<A>() m21<B extends core.int>() => throw 'uncalled';
+  Function<A>(A x) m22<B extends core.int>() => throw 'uncalled';
+  void Function<A>(List<A> x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int x, [Function])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [Function]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int x, [Function]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, [int])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [int]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, [int]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function(int, [List<T>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<T>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function(int, [List<T>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function([core.List<core.int>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function([core.List<core.int>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function([core.List<core.int>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// core.List<core.int> Function<A>(List<Function> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<Function> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is core.List<core.int> Function<A>(List<Function> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [Function x]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [Function x]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int, [Function x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([core.List<core.int>]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([core.List<core.int>]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int x, [int]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [int]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(int x, [int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, {List<Function> x}) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {List<Function> x}) Function<B extends core.int>()
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([int x]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([int x]) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function([int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(List<Function>) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<Function>) Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(List<Function>)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int x, [List<T>]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [List<T>]) Function<B extends core.int>()
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int x, [List<T>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, {Function x}) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {Function x})
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, {Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function([List<T> x]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<T> x]) Function<B extends core.int>()
+        l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function([List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [Function x]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [Function x]) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, [Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [core.List<core.int>]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [core.List<core.int>]) Function<B extends core.int>()
+        l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function({int x}) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function({int x}) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function({int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(core.List<core.int> x) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(core.List<core.int> x) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(core.List<core.int> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, [int x]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [int x]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int, [int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([List<Function>]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<Function>]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function([List<Function>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function({List<T> x}) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function({List<T> x}) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is void Function({List<T> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>() Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>() Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<Function> Function<A>() Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(A x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(A x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(A x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(List<A> x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<A> x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is void Function<A>(List<A> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U18().runTests();
+  new U18<int>(tIsInt: true).runTests();
+  new U18<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type19_test.dart b/tests/language/function_type/function_type19_test.dart
new file mode 100644
index 0000000..7a276f1
--- /dev/null
+++ b/tests/language/function_type/function_type19_test.dart
@@ -0,0 +1,969 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function({Function x});
+typedef F1<T> = List<Function> Function(int x, [int]);
+typedef F2<T> = core.List<core.int> Function(int x, [List<T>]);
+typedef F3<T> = Function(int, [core.List<core.int>]);
+typedef F4<T> = core.List<core.int> Function<A>(core.List<core.int> x);
+typedef F5<T> = int Function(int, [Function x]) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function([core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int x, [int]) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function(int y, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function([int x]) Function<B extends core.int>(
+    int x);
+typedef F10<T> = List<Function> Function(List<Function>)
+    Function<B extends core.int>(int x);
+typedef F11<T> = List<Function> Function(int x, [List<T>])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int, {Function x})
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function([List<T> x])
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(int y, [Function x])
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function(int, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function({int x}) Function<B extends core.int>(int x);
+typedef F17<T> = Function(core.List<core.int> x) Function<B extends core.int>(
+    int x);
+typedef F18<T> = void Function(int, [int x]) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function([List<Function>]) Function<B extends core.int>(
+    int x);
+typedef F20<T> = void Function({List<T> x}) Function<B extends core.int>(int x);
+typedef F21<T> = List<Function> Function<A>() Function<B extends core.int>(
+    int x);
+typedef F22<T> = Function<A>(A x) Function<B extends core.int>(int x);
+typedef F23<T> = void Function<A>(List<A> x) Function<B extends core.int>(
+    int x);
+
+int f0({Function x = _voidFunction}) => throw 'uncalled';
+List<Function> f1(int x, [int x0 = -1]) => throw 'uncalled';
+core.List<core.int> f2(int x, [List<int> x0 = const []]) => throw 'uncalled';
+f3(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
+core.List<core.int> f4<A>(core.List<core.int> x) => throw 'uncalled';
+int Function(int, [Function x]) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function([core.List<core.int>]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int x, [int]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int y, {List<Function> x}) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function([int x]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(List<Function>) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int x, [List<int>]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {Function x}) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([List<int> x]) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int y, [Function x]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, [core.List<core.int>]) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function({int x}) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(core.List<core.int> x) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int, [int x]) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function([List<Function>]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function({List<int> x}) f20<B extends core.int>(int x) => throw 'uncalled';
+List<Function> Function<A>() f21<B extends core.int>(int x) => throw 'uncalled';
+Function<A>(A x) f22<B extends core.int>(int x) => throw 'uncalled';
+void Function<A>(List<A> x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U19<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function({Function x}) x0;
+  late List<Function> Function(int x, [int]) x1;
+  late core.List<core.int> Function(int x, [List<T>]) x2;
+  late Function(int, [core.List<core.int>]) x3;
+  late core.List<core.int> Function<A>(core.List<core.int> x) x4;
+  late int Function(int, [Function x]) Function<B extends core.int>(int x) x5;
+  late int Function([core.List<core.int>]) Function<B extends core.int>(int x)
+      x6;
+  late Function Function(int x, [int]) Function<B extends core.int>(int x) x7;
+  late Function Function(int y, {List<Function> x})
+      Function<B extends core.int>(int x) x8;
+  late List<Function> Function([int x]) Function<B extends core.int>(int x) x9;
+  late List<Function> Function(List<Function>) Function<B extends core.int>(
+      int x) x10;
+  late List<Function> Function(int x, [List<T>]) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function(int, {Function x})
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function([List<T> x]) Function<B extends core.int>(
+      int x) x13;
+  late List<T> Function(int y, [Function x]) Function<B extends core.int>(int x)
+      x14;
+  late List<T> Function(int, [core.List<core.int>])
+      Function<B extends core.int>(int x) x15;
+  late Function({int x}) Function<B extends core.int>(int x) x16;
+  late Function(core.List<core.int> x) Function<B extends core.int>(int x) x17;
+  late void Function(int, [int x]) Function<B extends core.int>(int x) x18;
+  late void Function([List<Function>]) Function<B extends core.int>(int x) x19;
+  late void Function({List<T> x}) Function<B extends core.int>(int x) x20;
+  late List<Function> Function<A>() Function<B extends core.int>(int x) x21;
+  late Function<A>(A x) Function<B extends core.int>(int x) x22;
+  late void Function<A>(List<A> x) Function<B extends core.int>(int x) x23;
+
+  U19({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0({Function x = _voidFunction}) => throw 'uncalled';
+  List<Function> m1(int x, [int x0 = -1]) => throw 'uncalled';
+  core.List<core.int> m2(int x, [List<T> x0 = const []]) => throw 'uncalled';
+  m3(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
+  core.List<core.int> m4<A>(core.List<core.int> x) => throw 'uncalled';
+  int Function(int, [Function x]) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function([core.List<core.int>]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int x, [int]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int y, {List<Function> x}) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function([int x]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(List<Function>) m10<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int x, [List<T>]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {Function x}) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([List<T> x]) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, [Function x]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [core.List<core.int>]) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function({int x}) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(core.List<core.int> x) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int, [int x]) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function([List<Function>]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function({List<T> x}) m20<B extends core.int>(int x) => throw 'uncalled';
+  List<Function> Function<A>() m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function<A>(A x) m22<B extends core.int>(int x) => throw 'uncalled';
+  void Function<A>(List<A> x) m23<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function({Function x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function({Function x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function({Function x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int x, [int])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [int]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int x, [int]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function(int x, [List<T>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [List<T>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function(int x, [List<T>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int, [core.List<core.int>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int, [core.List<core.int>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int, [core.List<core.int>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// core.List<core.int> Function<A>(core.List<core.int> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(core.List<core.int> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is core.List<core.int> Function<A>(core.List<core.int> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [Function x]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [Function x]) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([core.List<core.int>]) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int x, [int]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [int]) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int x, [int])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {List<Function> x}) Function<B extends core.int>(
+        int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([int x]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([int x]) Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(List<Function>) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<Function>) Function<B extends core.int>(int x)
+        l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(List<Function>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int x, [List<T>]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [List<T>]) Function<B extends core.int>(
+        int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int x, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, {Function x}) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {Function x})
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function([List<T> x]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<T> x]) Function<B extends core.int>(
+        int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function([List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [Function x]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [Function x]) Function<B extends core.int>(int x)
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [core.List<core.int>]) Function<B extends core.int>(
+        int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function({int x}) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function({int x}) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function({int x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(core.List<core.int> x) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, [int x]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [int x]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int, [int x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([List<Function>]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<Function>]) Function<B extends core.int>(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function({List<T> x}) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function({List<T> x}) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is void Function({List<T> x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>() Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>() Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>()
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(A x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(A x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(A x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(List<A> x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<A> x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is void Function<A>(List<A> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U19().runTests();
+  new U19<int>(tIsInt: true).runTests();
+  new U19<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type1_test.dart b/tests/language/function_type/function_type1_test.dart
new file mode 100644
index 0000000..4358f50
--- /dev/null
+++ b/tests/language/function_type/function_type1_test.dart
@@ -0,0 +1,927 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function([int x]);
+typedef F1<T> = Function Function([List<T> x]);
+typedef F2<T> = core.List<core.int> Function(core.List<core.int> x);
+typedef F3<T> = Function(int y, {Function x});
+typedef F4<T> = Function Function<A>(Function x);
+typedef F5<T> = int Function(int, {int x}) Function(int x);
+typedef F6<T> = int Function([core.List<core.int> x]) Function(int x);
+typedef F7<T> = Function Function(int y, [int x]) Function(int x);
+typedef F8<T> = Function Function(int, [List<Function>]) Function(int x);
+typedef F9<T> = Function Function(int, {List<T> x}) Function(int x);
+typedef F10<T> = List<Function> Function(List<Function> x) Function(int x);
+typedef F11<T> = List<Function> Function(int y, [List<T> x]) Function(int x);
+typedef F12<T> = core.List<core.int> Function([Function]) Function(int x);
+typedef F13<T> = core.List<core.int> Function({core.List<core.int> x}) Function(
+    int x);
+typedef F14<T> = List<T> Function(int y, {int x}) Function(int x);
+typedef F15<T> = List<T> Function(int, [core.List<core.int> x]) Function(int x);
+typedef F16<T> = Function(int) Function(int x);
+typedef F17<T> = Function(int x, [List<Function>]) Function(int x);
+typedef F18<T> = Function(int y, {List<T> x}) Function(int x);
+typedef F19<T> = void Function([List<Function> x]) Function(int x);
+typedef F20<T> = void Function(List<T>) Function(int x);
+typedef F21<T> = List<Function> Function<A>(Function x) Function(int x);
+typedef F22<T> = Function<A>(List<Function> x) Function(int x);
+typedef F23<T> = void Function<A>(core.List<core.int> x) Function(int x);
+
+int f0([int x = -1]) => throw 'uncalled';
+Function f1([List<int> x = const []]) => throw 'uncalled';
+core.List<core.int> f2(core.List<core.int> x) => throw 'uncalled';
+f3(int y, {Function x = _voidFunction}) => throw 'uncalled';
+Function f4<A>(Function x) => throw 'uncalled';
+int Function(int, {int x}) f5(int x) => throw 'uncalled';
+int Function([core.List<core.int> x]) f6(int x) => throw 'uncalled';
+Function Function(int y, [int x]) f7(int x) => throw 'uncalled';
+Function Function(int, [List<Function>]) f8(int x) => throw 'uncalled';
+Function Function(int, {List<int> x}) f9(int x) => throw 'uncalled';
+List<Function> Function(List<Function> x) f10(int x) => throw 'uncalled';
+List<Function> Function(int y, [List<int> x]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function([Function]) f12(int x) => throw 'uncalled';
+core.List<core.int> Function({core.List<core.int> x}) f13(int x) =>
+    throw 'uncalled';
+List<int> Function(int y, {int x}) f14(int x) => throw 'uncalled';
+List<int> Function(int, [core.List<core.int> x]) f15(int x) => throw 'uncalled';
+Function(int) f16(int x) => throw 'uncalled';
+Function(int x, [List<Function>]) f17(int x) => throw 'uncalled';
+Function(int y, {List<int> x}) f18(int x) => throw 'uncalled';
+void Function([List<Function> x]) f19(int x) => throw 'uncalled';
+void Function(List<int>) f20(int x) => throw 'uncalled';
+List<Function> Function<A>(Function x) f21(int x) => throw 'uncalled';
+Function<A>(List<Function> x) f22(int x) => throw 'uncalled';
+void Function<A>(core.List<core.int> x) f23(int x) => throw 'uncalled';
+
+class U1<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function([int x]) x0;
+  late Function Function([List<T> x]) x1;
+  late core.List<core.int> Function(core.List<core.int> x) x2;
+  late Function(int y, {Function x}) x3;
+  late Function Function<A>(Function x) x4;
+  late int Function(int, {int x}) Function(int x) x5;
+  late int Function([core.List<core.int> x]) Function(int x) x6;
+  late Function Function(int y, [int x]) Function(int x) x7;
+  late Function Function(int, [List<Function>]) Function(int x) x8;
+  late Function Function(int, {List<T> x}) Function(int x) x9;
+  late List<Function> Function(List<Function> x) Function(int x) x10;
+  late List<Function> Function(int y, [List<T> x]) Function(int x) x11;
+  late core.List<core.int> Function([Function]) Function(int x) x12;
+  late core.List<core.int> Function({core.List<core.int> x}) Function(int x)
+      x13;
+  late List<T> Function(int y, {int x}) Function(int x) x14;
+  late List<T> Function(int, [core.List<core.int> x]) Function(int x) x15;
+  late Function(int) Function(int x) x16;
+  late Function(int x, [List<Function>]) Function(int x) x17;
+  late Function(int y, {List<T> x}) Function(int x) x18;
+  late void Function([List<Function> x]) Function(int x) x19;
+  late void Function(List<T>) Function(int x) x20;
+  late List<Function> Function<A>(Function x) Function(int x) x21;
+  late Function<A>(List<Function> x) Function(int x) x22;
+  late void Function<A>(core.List<core.int> x) Function(int x) x23;
+
+  U1({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0([int x = -1]) => throw 'uncalled';
+  Function m1([List<T> x = const []]) => throw 'uncalled';
+  core.List<core.int> m2(core.List<core.int> x) => throw 'uncalled';
+  m3(int y, {Function x = _voidFunction}) => throw 'uncalled';
+  Function m4<A>(Function x) => throw 'uncalled';
+  int Function(int, {int x}) m5(int x) => throw 'uncalled';
+  int Function([core.List<core.int> x]) m6(int x) => throw 'uncalled';
+  Function Function(int y, [int x]) m7(int x) => throw 'uncalled';
+  Function Function(int, [List<Function>]) m8(int x) => throw 'uncalled';
+  Function Function(int, {List<T> x}) m9(int x) => throw 'uncalled';
+  List<Function> Function(List<Function> x) m10(int x) => throw 'uncalled';
+  List<Function> Function(int y, [List<T> x]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function([Function]) m12(int x) => throw 'uncalled';
+  core.List<core.int> Function({core.List<core.int> x}) m13(int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, {int x}) m14(int x) => throw 'uncalled';
+  List<T> Function(int, [core.List<core.int> x]) m15(int x) => throw 'uncalled';
+  Function(int) m16(int x) => throw 'uncalled';
+  Function(int x, [List<Function>]) m17(int x) => throw 'uncalled';
+  Function(int y, {List<T> x}) m18(int x) => throw 'uncalled';
+  void Function([List<Function> x]) m19(int x) => throw 'uncalled';
+  void Function(List<T>) m20(int x) => throw 'uncalled';
+  List<Function> Function<A>(Function x) m21(int x) => throw 'uncalled';
+  Function<A>(List<Function> x) m22(int x) => throw 'uncalled';
+  void Function<A>(core.List<core.int> x) m23(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function([int x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function([int x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function([int x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function([List<T> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<T> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function([List<T> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(core.List<core.int> x)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(core.List<core.int> x) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function(core.List<core.int> x));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function(int y, {Function x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {Function x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int y, {Function x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function Function<A>(Function x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(Function x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function Function<A>(Function x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {int x}) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {int x}) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, {int x}) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([core.List<core.int> x]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([core.List<core.int> x]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, [int x]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [int x]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, [int x]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<Function>]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<Function>]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function(int, {List<T> x}) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {List<T> x}) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function(int, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+    // The static function has its T always set to int.
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isFalse(f9 is F9<bool>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    Expect.isFalse(confuse(f9) is F9<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        x9 = confuse(f9);
+      });
+      Expect.throws(() {
+        l9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        l9 = confuse(f9);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m9 is F9<int>);
+      Expect.equals(tIsBool, m9 is F9<bool>);
+      Expect.equals(tIsInt, confuse(m9) is F9<int>);
+      Expect.equals(tIsBool, confuse(m9) is F9<bool>);
+    }
+  }
+
+  /// List<Function> Function(List<Function> x) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<Function> x) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int y, [List<T> x]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [List<T> x]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is List<Function> Function(int y, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function([Function]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([Function]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function([Function]) Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function({core.List<core.int> x}) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({core.List<core.int> x}) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function({core.List<core.int> x})
+        Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(int y, {int x}) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {int x}) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, {int x}) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [core.List<core.int> x]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [core.List<core.int> x]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int, [core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [List<Function>]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [List<Function>]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int x, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// Function(int y, {List<T> x}) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {List<T> x}) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is Function(int y, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+    // The static function has its T always set to int.
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isFalse(f18 is F18<bool>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    Expect.isFalse(confuse(f18) is F18<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x18 = (f18 as dynamic);
+      });
+      Expect.throws(() {
+        x18 = confuse(f18);
+      });
+      Expect.throws(() {
+        l18 = (f18 as dynamic);
+      });
+      Expect.throws(() {
+        l18 = confuse(f18);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m18 is F18<int>);
+      Expect.equals(tIsBool, m18 is F18<bool>);
+      Expect.equals(tIsInt, confuse(m18) is F18<int>);
+      Expect.equals(tIsBool, confuse(m18) is F18<bool>);
+    }
+  }
+
+  /// void Function([List<Function> x]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<Function> x]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(List<T>) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(List<T>) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(List<T>) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(Function x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(Function x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<Function> Function<A>(Function x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<Function> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<Function> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(core.List<core.int> x) Function(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(core.List<core.int> x) Function(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is void Function<A>(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U1().runTests();
+  new U1<int>(tIsInt: true).runTests();
+  new U1<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type20_test.dart b/tests/language/function_type/function_type20_test.dart
new file mode 100644
index 0000000..a8df364
--- /dev/null
+++ b/tests/language/function_type/function_type20_test.dart
@@ -0,0 +1,918 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, {Function x});
+typedef F1<T> = List<Function> Function({int x});
+typedef F2<T> = core.List<core.int> Function({List<T> x});
+typedef F3<T> = Function(int x, [core.List<core.int>]);
+typedef F4<T> = core.List<core.int> Function<A>(List<T> x);
+typedef F5<T> = int Function(int y, [Function x]) Function();
+typedef F6<T> = int Function(int, [core.List<core.int>]) Function();
+typedef F7<T> = Function Function({int x}) Function();
+typedef F8<T> = Function Function(core.List<core.int> x) Function();
+typedef F9<T> = List<Function> Function(int, [int x]) Function();
+typedef F10<T> = List<Function> Function([List<Function>]) Function();
+typedef F11<T> = List<Function> Function({List<T> x}) Function();
+typedef F12<T> = core.List<core.int> Function(int y, {Function x}) Function();
+typedef F13<T> = core.List<core.int> Function(int, [List<T> x]) Function();
+typedef F14<T> = List<T> Function(Function) Function();
+typedef F15<T> = List<T> Function(int x, [core.List<core.int>]) Function();
+typedef F16<T> = Function(int, {int x}) Function();
+typedef F17<T> = Function([core.List<core.int> x]) Function();
+typedef F18<T> = void Function(int y, [int x]) Function();
+typedef F19<T> = void Function(int, [List<Function>]) Function();
+typedef F20<T> = void Function(int, {List<T> x}) Function();
+typedef F21<T> = List<Function> Function<A>(A x) Function();
+typedef F22<T> = Function<A>(List<A> x) Function();
+typedef F23<T> = int Function(B x) Function<B extends core.int>();
+
+int f0(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+List<Function> f1({int x = -1}) => throw 'uncalled';
+core.List<core.int> f2({List<int> x = const []}) => throw 'uncalled';
+f3(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
+core.List<core.int> f4<A>(List<int> x) => throw 'uncalled';
+int Function(int y, [Function x]) f5() => throw 'uncalled';
+int Function(int, [core.List<core.int>]) f6() => throw 'uncalled';
+Function Function({int x}) f7() => throw 'uncalled';
+Function Function(core.List<core.int> x) f8() => throw 'uncalled';
+List<Function> Function(int, [int x]) f9() => throw 'uncalled';
+List<Function> Function([List<Function>]) f10() => throw 'uncalled';
+List<Function> Function({List<int> x}) f11() => throw 'uncalled';
+core.List<core.int> Function(int y, {Function x}) f12() => throw 'uncalled';
+core.List<core.int> Function(int, [List<int> x]) f13() => throw 'uncalled';
+List<int> Function(Function) f14() => throw 'uncalled';
+List<int> Function(int x, [core.List<core.int>]) f15() => throw 'uncalled';
+Function(int, {int x}) f16() => throw 'uncalled';
+Function([core.List<core.int> x]) f17() => throw 'uncalled';
+void Function(int y, [int x]) f18() => throw 'uncalled';
+void Function(int, [List<Function>]) f19() => throw 'uncalled';
+void Function(int, {List<int> x}) f20() => throw 'uncalled';
+List<Function> Function<A>(A x) f21() => throw 'uncalled';
+Function<A>(List<A> x) f22() => throw 'uncalled';
+int Function(B x) f23<B extends core.int>() => throw 'uncalled';
+
+class U20<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, {Function x}) x0;
+  late List<Function> Function({int x}) x1;
+  late core.List<core.int> Function({List<T> x}) x2;
+  late Function(int x, [core.List<core.int>]) x3;
+  late core.List<core.int> Function<A>(List<T> x) x4;
+  late int Function(int y, [Function x]) Function() x5;
+  late int Function(int, [core.List<core.int>]) Function() x6;
+  late Function Function({int x}) Function() x7;
+  late Function Function(core.List<core.int> x) Function() x8;
+  late List<Function> Function(int, [int x]) Function() x9;
+  late List<Function> Function([List<Function>]) Function() x10;
+  late List<Function> Function({List<T> x}) Function() x11;
+  late core.List<core.int> Function(int y, {Function x}) Function() x12;
+  late core.List<core.int> Function(int, [List<T> x]) Function() x13;
+  late List<T> Function(Function) Function() x14;
+  late List<T> Function(int x, [core.List<core.int>]) Function() x15;
+  late Function(int, {int x}) Function() x16;
+  late Function([core.List<core.int> x]) Function() x17;
+  late void Function(int y, [int x]) Function() x18;
+  late void Function(int, [List<Function>]) Function() x19;
+  late void Function(int, {List<T> x}) Function() x20;
+  late List<Function> Function<A>(A x) Function() x21;
+  late Function<A>(List<A> x) Function() x22;
+  late int Function(B x) Function<B extends core.int>() x23;
+
+  U20({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+  List<Function> m1({int x = -1}) => throw 'uncalled';
+  core.List<core.int> m2({List<T> x = const []}) => throw 'uncalled';
+  m3(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
+  core.List<core.int> m4<A>(List<T> x) => throw 'uncalled';
+  int Function(int y, [Function x]) m5() => throw 'uncalled';
+  int Function(int, [core.List<core.int>]) m6() => throw 'uncalled';
+  Function Function({int x}) m7() => throw 'uncalled';
+  Function Function(core.List<core.int> x) m8() => throw 'uncalled';
+  List<Function> Function(int, [int x]) m9() => throw 'uncalled';
+  List<Function> Function([List<Function>]) m10() => throw 'uncalled';
+  List<Function> Function({List<T> x}) m11() => throw 'uncalled';
+  core.List<core.int> Function(int y, {Function x}) m12() => throw 'uncalled';
+  core.List<core.int> Function(int, [List<T> x]) m13() => throw 'uncalled';
+  List<T> Function(Function) m14() => throw 'uncalled';
+  List<T> Function(int x, [core.List<core.int>]) m15() => throw 'uncalled';
+  Function(int, {int x}) m16() => throw 'uncalled';
+  Function([core.List<core.int> x]) m17() => throw 'uncalled';
+  void Function(int y, [int x]) m18() => throw 'uncalled';
+  void Function(int, [List<Function>]) m19() => throw 'uncalled';
+  void Function(int, {List<T> x}) m20() => throw 'uncalled';
+  List<Function> Function<A>(A x) m21() => throw 'uncalled';
+  Function<A>(List<A> x) m22() => throw 'uncalled';
+  int Function(B x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, {Function x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {Function x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, {Function x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function({int x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({int x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function({int x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function({List<T> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({List<T> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function({List<T> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int x, [core.List<core.int>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [core.List<core.int>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int x, [core.List<core.int>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// core.List<core.int> Function<A>(List<T> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<T> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is core.List<core.int> Function<A>(List<T> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m4 is F4<int>);
+      Expect.equals(true, m4 is F4<bool>);
+      Expect.equals(true, confuse(m4) is F4<int>);
+      Expect.equals(true, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function(int y, [Function x]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [Function x]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, [Function x]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [core.List<core.int>]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [core.List<core.int>]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function({int x}) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function({int x}) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function({int x}) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(core.List<core.int> x) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(core.List<core.int> x) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, [int x]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [int x]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [int x]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([List<Function>]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<Function>]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([List<Function>]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function({List<T> x}) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({List<T> x}) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function({List<T> x}) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int y, {Function x}) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {Function x}) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(int y, {Function x}) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, [List<T> x]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<T> x]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(int, [List<T> x]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(Function) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(Function) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(Function) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [core.List<core.int>]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [core.List<core.int>]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int x, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, {int x}) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, {int x}) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, {int x}) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([core.List<core.int> x]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([core.List<core.int> x]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int y, [int x]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [int x]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, [int x]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<Function>]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<Function>]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [List<Function>]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int, {List<T> x}) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {List<T> x}) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int, {List<T> x}) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(A x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(A x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(A x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<A> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<A> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(List<A> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// int Function(B x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    int Function(B x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is int Function(B x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U20().runTests();
+  new U20<int>(tIsInt: true).runTests();
+  new U20<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type21_test.dart b/tests/language/function_type/function_type21_test.dart
new file mode 100644
index 0000000..ae5fdb6
--- /dev/null
+++ b/tests/language/function_type/function_type21_test.dart
@@ -0,0 +1,899 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int y, {Function x});
+typedef F1<T> = List<Function> Function(int, {int x});
+typedef F2<T> = core.List<core.int> Function(int, {List<T> x});
+typedef F3<T> = Function({core.List<core.int> x});
+typedef F4<T> = core.List<core.int> Function<A>();
+typedef F5<T> = int Function(int y, [Function x]) Function(int x);
+typedef F6<T> = int Function(int, [core.List<core.int>]) Function(int x);
+typedef F7<T> = Function Function({int x}) Function(int x);
+typedef F8<T> = Function Function(core.List<core.int> x) Function(int x);
+typedef F9<T> = List<Function> Function(int, [int x]) Function(int x);
+typedef F10<T> = List<Function> Function([List<Function>]) Function(int x);
+typedef F11<T> = List<Function> Function({List<T> x}) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int y, {Function x}) Function(
+    int x);
+typedef F13<T> = core.List<core.int> Function(int, [List<T> x]) Function(int x);
+typedef F14<T> = List<T> Function(Function) Function(int x);
+typedef F15<T> = List<T> Function(int x, [core.List<core.int>]) Function(int x);
+typedef F16<T> = Function(int, {int x}) Function(int x);
+typedef F17<T> = Function([core.List<core.int> x]) Function(int x);
+typedef F18<T> = void Function(int y, [int x]) Function(int x);
+typedef F19<T> = void Function(int, [List<Function>]) Function(int x);
+typedef F20<T> = void Function(int, {List<T> x}) Function(int x);
+typedef F21<T> = List<Function> Function<A>(A x) Function(int x);
+typedef F22<T> = Function<A>(List<A> x) Function(int x);
+typedef F23<T> = int Function(B x) Function<B extends core.int>(int x);
+
+int f0(int y, {Function x = _voidFunction}) => throw 'uncalled';
+List<Function> f1(int x0, {int x = -1}) => throw 'uncalled';
+core.List<core.int> f2(int x0, {List<int> x = const []}) => throw 'uncalled';
+f3({core.List<core.int> x = const []}) => throw 'uncalled';
+core.List<core.int> f4<A>() => throw 'uncalled';
+int Function(int y, [Function x]) f5(int x) => throw 'uncalled';
+int Function(int, [core.List<core.int>]) f6(int x) => throw 'uncalled';
+Function Function({int x}) f7(int x) => throw 'uncalled';
+Function Function(core.List<core.int> x) f8(int x) => throw 'uncalled';
+List<Function> Function(int, [int x]) f9(int x) => throw 'uncalled';
+List<Function> Function([List<Function>]) f10(int x) => throw 'uncalled';
+List<Function> Function({List<int> x}) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int y, {Function x}) f12(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [List<int> x]) f13(int x) => throw 'uncalled';
+List<int> Function(Function) f14(int x) => throw 'uncalled';
+List<int> Function(int x, [core.List<core.int>]) f15(int x) => throw 'uncalled';
+Function(int, {int x}) f16(int x) => throw 'uncalled';
+Function([core.List<core.int> x]) f17(int x) => throw 'uncalled';
+void Function(int y, [int x]) f18(int x) => throw 'uncalled';
+void Function(int, [List<Function>]) f19(int x) => throw 'uncalled';
+void Function(int, {List<int> x}) f20(int x) => throw 'uncalled';
+List<Function> Function<A>(A x) f21(int x) => throw 'uncalled';
+Function<A>(List<A> x) f22(int x) => throw 'uncalled';
+int Function(B x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U21<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int y, {Function x}) x0;
+  late List<Function> Function(int, {int x}) x1;
+  late core.List<core.int> Function(int, {List<T> x}) x2;
+  late Function({core.List<core.int> x}) x3;
+  late core.List<core.int> Function<A>() x4;
+  late int Function(int y, [Function x]) Function(int x) x5;
+  late int Function(int, [core.List<core.int>]) Function(int x) x6;
+  late Function Function({int x}) Function(int x) x7;
+  late Function Function(core.List<core.int> x) Function(int x) x8;
+  late List<Function> Function(int, [int x]) Function(int x) x9;
+  late List<Function> Function([List<Function>]) Function(int x) x10;
+  late List<Function> Function({List<T> x}) Function(int x) x11;
+  late core.List<core.int> Function(int y, {Function x}) Function(int x) x12;
+  late core.List<core.int> Function(int, [List<T> x]) Function(int x) x13;
+  late List<T> Function(Function) Function(int x) x14;
+  late List<T> Function(int x, [core.List<core.int>]) Function(int x) x15;
+  late Function(int, {int x}) Function(int x) x16;
+  late Function([core.List<core.int> x]) Function(int x) x17;
+  late void Function(int y, [int x]) Function(int x) x18;
+  late void Function(int, [List<Function>]) Function(int x) x19;
+  late void Function(int, {List<T> x}) Function(int x) x20;
+  late List<Function> Function<A>(A x) Function(int x) x21;
+  late Function<A>(List<A> x) Function(int x) x22;
+  late int Function(B x) Function<B extends core.int>(int x) x23;
+
+  U21({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int y, {Function x = _voidFunction}) => throw 'uncalled';
+  List<Function> m1(int x0, {int x = -1}) => throw 'uncalled';
+  core.List<core.int> m2(int x0, {List<T> x = const []}) => throw 'uncalled';
+  m3({core.List<core.int> x = const []}) => throw 'uncalled';
+  core.List<core.int> m4<A>() => throw 'uncalled';
+  int Function(int y, [Function x]) m5(int x) => throw 'uncalled';
+  int Function(int, [core.List<core.int>]) m6(int x) => throw 'uncalled';
+  Function Function({int x}) m7(int x) => throw 'uncalled';
+  Function Function(core.List<core.int> x) m8(int x) => throw 'uncalled';
+  List<Function> Function(int, [int x]) m9(int x) => throw 'uncalled';
+  List<Function> Function([List<Function>]) m10(int x) => throw 'uncalled';
+  List<Function> Function({List<T> x}) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int y, {Function x}) m12(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [List<T> x]) m13(int x) => throw 'uncalled';
+  List<T> Function(Function) m14(int x) => throw 'uncalled';
+  List<T> Function(int x, [core.List<core.int>]) m15(int x) => throw 'uncalled';
+  Function(int, {int x}) m16(int x) => throw 'uncalled';
+  Function([core.List<core.int> x]) m17(int x) => throw 'uncalled';
+  void Function(int y, [int x]) m18(int x) => throw 'uncalled';
+  void Function(int, [List<Function>]) m19(int x) => throw 'uncalled';
+  void Function(int, {List<T> x}) m20(int x) => throw 'uncalled';
+  List<Function> Function<A>(A x) m21(int x) => throw 'uncalled';
+  Function<A>(List<A> x) m22(int x) => throw 'uncalled';
+  int Function(B x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int y, {Function x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {Function x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int y, {Function x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, {int x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {int x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, {int x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function(int, {List<T> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {List<T> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function(int, {List<T> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function({core.List<core.int> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function({core.List<core.int> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function({core.List<core.int> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// core.List<core.int> Function<A>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is core.List<core.int> Function<A>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, [Function x]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [Function x]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [core.List<core.int>]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [core.List<core.int>]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int, [core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function({int x}) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function({int x}) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function({int x}) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(core.List<core.int> x) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(core.List<core.int> x) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, [int x]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [int x]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [int x]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([List<Function>]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<Function>]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function([List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function({List<T> x}) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({List<T> x}) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function({List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int y, {Function x}) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {Function x}) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, {Function x})
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, [List<T> x]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<T> x]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(int, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(Function) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(Function) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(Function) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [core.List<core.int>]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [core.List<core.int>]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int x, [core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, {int x}) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, {int x}) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, {int x}) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([core.List<core.int> x]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([core.List<core.int> x]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int y, [int x]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [int x]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, [int x]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<Function>]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<Function>]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int, {List<T> x}) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {List<T> x}) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(A x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(A x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(A x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<A> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<A> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(List<A> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// int Function(B x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    int Function(B x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is int Function(B x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U21().runTests();
+  new U21<int>(tIsInt: true).runTests();
+  new U21<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type22_test.dart b/tests/language/function_type/function_type22_test.dart
new file mode 100644
index 0000000..371ad94
--- /dev/null
+++ b/tests/language/function_type/function_type22_test.dart
@@ -0,0 +1,947 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(List<Function> x);
+typedef F1<T> = List<Function> Function(int y, {int x});
+typedef F2<T> = core.List<core.int> Function(int y, {List<T> x});
+typedef F3<T> = Function(int, {core.List<core.int> x});
+typedef F4<T> = core.List<core.int> Function<A>(A x);
+typedef F5<T> = int Function(int y, [Function x])
+    Function<B extends core.int>();
+typedef F6<T> = int Function(int, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F7<T> = Function Function({int x}) Function<B extends core.int>();
+typedef F8<T> = Function Function(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int, [int x])
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function([List<Function>])
+    Function<B extends core.int>();
+typedef F11<T> = List<Function> Function({List<T> x})
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int y, {Function x})
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function(int, [List<T> x])
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(Function) Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int x, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F16<T> = Function(int, {int x}) Function<B extends core.int>();
+typedef F17<T> = Function([core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F18<T> = void Function(int y, [int x]) Function<B extends core.int>();
+typedef F19<T> = void Function(int, [List<Function>])
+    Function<B extends core.int>();
+typedef F20<T> = void Function(int, {List<T> x}) Function<B extends core.int>();
+typedef F21<T> = List<Function> Function<A>(A x) Function<B extends core.int>();
+typedef F22<T> = Function<A>(List<A> x) Function<B extends core.int>();
+typedef F23<T> = Function Function(B x) Function<B extends core.int>();
+
+int f0(List<Function> x) => throw 'uncalled';
+List<Function> f1(int y, {int x = -1}) => throw 'uncalled';
+core.List<core.int> f2(int y, {List<int> x = const []}) => throw 'uncalled';
+f3(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
+core.List<core.int> f4<A>(A x) => throw 'uncalled';
+int Function(int y, [Function x]) f5<B extends core.int>() => throw 'uncalled';
+int Function(int, [core.List<core.int>]) f6<B extends core.int>() =>
+    throw 'uncalled';
+Function Function({int x}) f7<B extends core.int>() => throw 'uncalled';
+Function Function(core.List<core.int> x) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, [int x]) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function([List<Function>]) f10<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function({List<int> x}) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, {Function x}) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [List<int> x]) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(Function) f14<B extends core.int>() => throw 'uncalled';
+List<int> Function(int x, [core.List<core.int>]) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function(int, {int x}) f16<B extends core.int>() => throw 'uncalled';
+Function([core.List<core.int> x]) f17<B extends core.int>() => throw 'uncalled';
+void Function(int y, [int x]) f18<B extends core.int>() => throw 'uncalled';
+void Function(int, [List<Function>]) f19<B extends core.int>() =>
+    throw 'uncalled';
+void Function(int, {List<int> x}) f20<B extends core.int>() => throw 'uncalled';
+List<Function> Function<A>(A x) f21<B extends core.int>() => throw 'uncalled';
+Function<A>(List<A> x) f22<B extends core.int>() => throw 'uncalled';
+Function Function(B x) f23<B extends core.int>() => throw 'uncalled';
+
+class U22<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(List<Function> x) x0;
+  late List<Function> Function(int y, {int x}) x1;
+  late core.List<core.int> Function(int y, {List<T> x}) x2;
+  late Function(int, {core.List<core.int> x}) x3;
+  late core.List<core.int> Function<A>(A x) x4;
+  late int Function(int y, [Function x]) Function<B extends core.int>() x5;
+  late int Function(int, [core.List<core.int>]) Function<B extends core.int>()
+      x6;
+  late Function Function({int x}) Function<B extends core.int>() x7;
+  late Function Function(core.List<core.int> x) Function<B extends core.int>()
+      x8;
+  late List<Function> Function(int, [int x]) Function<B extends core.int>() x9;
+  late List<Function> Function([List<Function>]) Function<B extends core.int>()
+      x10;
+  late List<Function> Function({List<T> x}) Function<B extends core.int>() x11;
+  late core.List<core.int> Function(int y, {Function x})
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function(int, [List<T> x])
+      Function<B extends core.int>() x13;
+  late List<T> Function(Function) Function<B extends core.int>() x14;
+  late List<T> Function(int x, [core.List<core.int>])
+      Function<B extends core.int>() x15;
+  late Function(int, {int x}) Function<B extends core.int>() x16;
+  late Function([core.List<core.int> x]) Function<B extends core.int>() x17;
+  late void Function(int y, [int x]) Function<B extends core.int>() x18;
+  late void Function(int, [List<Function>]) Function<B extends core.int>() x19;
+  late void Function(int, {List<T> x}) Function<B extends core.int>() x20;
+  late List<Function> Function<A>(A x) Function<B extends core.int>() x21;
+  late Function<A>(List<A> x) Function<B extends core.int>() x22;
+  late Function Function(B x) Function<B extends core.int>() x23;
+
+  U22({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(List<Function> x) => throw 'uncalled';
+  List<Function> m1(int y, {int x = -1}) => throw 'uncalled';
+  core.List<core.int> m2(int y, {List<T> x = const []}) => throw 'uncalled';
+  m3(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
+  core.List<core.int> m4<A>(A x) => throw 'uncalled';
+  int Function(int y, [Function x]) m5<B extends core.int>() =>
+      throw 'uncalled';
+  int Function(int, [core.List<core.int>]) m6<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function({int x}) m7<B extends core.int>() => throw 'uncalled';
+  Function Function(core.List<core.int> x) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, [int x]) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function([List<Function>]) m10<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function({List<T> x}) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {Function x}) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [List<T> x]) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(Function) m14<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int x, [core.List<core.int>]) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int, {int x}) m16<B extends core.int>() => throw 'uncalled';
+  Function([core.List<core.int> x]) m17<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int y, [int x]) m18<B extends core.int>() => throw 'uncalled';
+  void Function(int, [List<Function>]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int, {List<T> x}) m20<B extends core.int>() => throw 'uncalled';
+  List<Function> Function<A>(A x) m21<B extends core.int>() => throw 'uncalled';
+  Function<A>(List<A> x) m22<B extends core.int>() => throw 'uncalled';
+  Function Function(B x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(List<Function> x)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(List<Function> x) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(List<Function> x));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int y, {int x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {int x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int y, {int x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function(int y, {List<T> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {List<T> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function(int y, {List<T> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m2 is F2<int>);
+      Expect.equals(true, m2 is F2<bool>);
+      Expect.equals(true, confuse(m2) is F2<int>);
+      Expect.equals(true, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int, {core.List<core.int> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int, {core.List<core.int> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// core.List<core.int> Function<A>(A x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(A x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is core.List<core.int> Function<A>(A x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, [Function x]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [Function x]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int y, [Function x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [core.List<core.int>]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [core.List<core.int>]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function({int x}) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function({int x}) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function({int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(core.List<core.int> x) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(core.List<core.int> x) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, [int x]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [int x]) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [int x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([List<Function>]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<Function>]) Function<B extends core.int>()
+        l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function({List<T> x}) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({List<T> x}) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function({List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int y, {Function x}) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {Function x})
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, {Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, [List<T> x]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<T> x])
+        Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int, [List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(Function) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(Function) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(Function) Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [core.List<core.int>])
+        Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int x, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, {int x}) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, {int x}) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, {int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([core.List<core.int> x]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([core.List<core.int> x]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int y, [int x]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [int x]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int y, [int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<Function>]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<Function>]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int, {List<T> x}) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {List<T> x}) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is void Function(int, {List<T> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(A x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(A x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<Function> Function<A>(A x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<A> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<A> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(List<A> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// Function Function(B x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    Function Function(B x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is Function Function(B x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U22().runTests();
+  new U22<int>(tIsInt: true).runTests();
+  new U22<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type23_test.dart b/tests/language/function_type/function_type23_test.dart
new file mode 100644
index 0000000..eb2db97
--- /dev/null
+++ b/tests/language/function_type/function_type23_test.dart
@@ -0,0 +1,951 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function([List<Function> x]);
+typedef F1<T> = List<Function> Function(Function x);
+typedef F2<T> = core.List<core.int> Function();
+typedef F3<T> = Function(int y, {core.List<core.int> x});
+typedef F4<T> = core.List<core.int> Function<A>(List<A> x);
+typedef F5<T> = int Function(int y, [Function x]) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function(int, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F7<T> = Function Function({int x}) Function<B extends core.int>(int x);
+typedef F8<T> = Function Function(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(int, [int x])
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function([List<Function>])
+    Function<B extends core.int>(int x);
+typedef F11<T> = List<Function> Function({List<T> x})
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int y, {Function x})
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function(int, [List<T> x])
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(Function) Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function(int x, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function(int, {int x}) Function<B extends core.int>(int x);
+typedef F17<T> = Function([core.List<core.int> x]) Function<B extends core.int>(
+    int x);
+typedef F18<T> = void Function(int y, [int x]) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function(int, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F20<T> = void Function(int, {List<T> x}) Function<B extends core.int>(
+    int x);
+typedef F21<T> = List<Function> Function<A>(A x) Function<B extends core.int>(
+    int x);
+typedef F22<T> = Function<A>(List<A> x) Function<B extends core.int>(int x);
+typedef F23<T> = Function Function(B x) Function<B extends core.int>(int x);
+
+int f0([List<Function> x = const []]) => throw 'uncalled';
+List<Function> f1(Function x) => throw 'uncalled';
+core.List<core.int> f2() => throw 'uncalled';
+f3(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
+core.List<core.int> f4<A>(List<A> x) => throw 'uncalled';
+int Function(int y, [Function x]) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function(int, [core.List<core.int>]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function({int x}) f7<B extends core.int>(int x) => throw 'uncalled';
+Function Function(core.List<core.int> x) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, [int x]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function([List<Function>]) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function({List<int> x}) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, {Function x}) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [List<int> x]) f13<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function(Function) f14<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function(int x, [core.List<core.int>]) f15<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+Function(int, {int x}) f16<B extends core.int>(int x) => throw 'uncalled';
+Function([core.List<core.int> x]) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int y, [int x]) f18<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int, [List<Function>]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int, {List<int> x}) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function<A>(A x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function<A>(List<A> x) f22<B extends core.int>(int x) => throw 'uncalled';
+Function Function(B x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U23<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function([List<Function> x]) x0;
+  late List<Function> Function(Function x) x1;
+  late core.List<core.int> Function() x2;
+  late Function(int y, {core.List<core.int> x}) x3;
+  late core.List<core.int> Function<A>(List<A> x) x4;
+  late int Function(int y, [Function x]) Function<B extends core.int>(int x) x5;
+  late int Function(int, [core.List<core.int>]) Function<B extends core.int>(
+      int x) x6;
+  late Function Function({int x}) Function<B extends core.int>(int x) x7;
+  late Function Function(core.List<core.int> x) Function<B extends core.int>(
+      int x) x8;
+  late List<Function> Function(int, [int x]) Function<B extends core.int>(int x)
+      x9;
+  late List<Function> Function([List<Function>]) Function<B extends core.int>(
+      int x) x10;
+  late List<Function> Function({List<T> x}) Function<B extends core.int>(int x)
+      x11;
+  late core.List<core.int> Function(int y, {Function x})
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function(int, [List<T> x])
+      Function<B extends core.int>(int x) x13;
+  late List<T> Function(Function) Function<B extends core.int>(int x) x14;
+  late List<T> Function(int x, [core.List<core.int>])
+      Function<B extends core.int>(int x) x15;
+  late Function(int, {int x}) Function<B extends core.int>(int x) x16;
+  late Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+      x17;
+  late void Function(int y, [int x]) Function<B extends core.int>(int x) x18;
+  late void Function(int, [List<Function>]) Function<B extends core.int>(int x)
+      x19;
+  late void Function(int, {List<T> x}) Function<B extends core.int>(int x) x20;
+  late List<Function> Function<A>(A x) Function<B extends core.int>(int x) x21;
+  late Function<A>(List<A> x) Function<B extends core.int>(int x) x22;
+  late Function Function(B x) Function<B extends core.int>(int x) x23;
+
+  U23({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0([List<Function> x = const []]) => throw 'uncalled';
+  List<Function> m1(Function x) => throw 'uncalled';
+  core.List<core.int> m2() => throw 'uncalled';
+  m3(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
+  core.List<core.int> m4<A>(List<A> x) => throw 'uncalled';
+  int Function(int y, [Function x]) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int, [core.List<core.int>]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function({int x}) m7<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(core.List<core.int> x) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, [int x]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function([List<Function>]) m10<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function({List<T> x}) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {Function x}) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [List<T> x]) m13<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function(Function) m14<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function(int x, [core.List<core.int>]) m15<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  Function(int, {int x}) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function([core.List<core.int> x]) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int y, [int x]) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int, [List<Function>]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int, {List<T> x}) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function<A>(A x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function<A>(List<A> x) m22<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(B x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function([List<Function> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function([List<Function> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function([List<Function> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(Function x)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(Function x) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(Function x));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// core.List<core.int> Function()
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function() l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function());
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function(int y, {core.List<core.int> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {core.List<core.int> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int y, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// core.List<core.int> Function<A>(List<A> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<A> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is core.List<core.int> Function<A>(List<A> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, [Function x]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [Function x]) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [core.List<core.int>]) Function<B extends core.int>(int x)
+        l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function({int x}) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function({int x}) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function({int x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(core.List<core.int> x) Function<B extends core.int>(int x)
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, [int x]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [int x]) Function<B extends core.int>(int x)
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([List<Function>]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<Function>]) Function<B extends core.int>(
+        int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function({List<T> x}) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({List<T> x}) Function<B extends core.int>(int x)
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function({List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int y, {Function x}) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {Function x})
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, [List<T> x]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<T> x]) Function<B extends core.int>(
+        int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(Function) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(Function) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(Function) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [core.List<core.int>]) Function<B extends core.int>(
+        int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int x, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, {int x}) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, {int x}) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int, {int x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([core.List<core.int> x]) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int y, [int x]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [int x]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, [int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<Function>]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<Function>]) Function<B extends core.int>(int x)
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int, {List<T> x}) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {List<T> x}) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(A x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(A x) Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(A x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<A> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<A> x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is Function<A>(List<A> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// Function Function(B x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    Function Function(B x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is Function Function(B x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U23().runTests();
+  new U23<int>(tIsInt: true).runTests();
+  new U23<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type24_test.dart b/tests/language/function_type/function_type24_test.dart
new file mode 100644
index 0000000..71b8e09
--- /dev/null
+++ b/tests/language/function_type/function_type24_test.dart
@@ -0,0 +1,944 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, [List<Function> x]);
+typedef F1<T> = List<Function> Function([Function x]);
+typedef F2<T> = List<T> Function(int x);
+typedef F3<T> = Function(List<T> x);
+typedef F4<T> = List<T> Function<A>(int x);
+typedef F5<T> = int Function(Function) Function();
+typedef F6<T> = int Function(int x, [core.List<core.int>]) Function();
+typedef F7<T> = Function Function(int, {int x}) Function();
+typedef F8<T> = Function Function([core.List<core.int> x]) Function();
+typedef F9<T> = List<Function> Function(int y, [int x]) Function();
+typedef F10<T> = List<Function> Function(int, [List<Function>]) Function();
+typedef F11<T> = List<Function> Function(int, {List<T> x}) Function();
+typedef F12<T> = core.List<core.int> Function(List<Function> x) Function();
+typedef F13<T> = core.List<core.int> Function(int y, [List<T> x]) Function();
+typedef F14<T> = List<T> Function([Function]) Function();
+typedef F15<T> = List<T> Function({core.List<core.int> x}) Function();
+typedef F16<T> = Function(int y, {int x}) Function();
+typedef F17<T> = Function(int, [core.List<core.int> x]) Function();
+typedef F18<T> = void Function(int) Function();
+typedef F19<T> = void Function(int x, [List<Function>]) Function();
+typedef F20<T> = void Function(int y, {List<T> x}) Function();
+typedef F21<T> = List<Function> Function<A>(List<A> x) Function();
+typedef F22<T> = A Function<A>(int x) Function();
+typedef F23<T> = List<Function> Function(B x) Function<B extends core.int>();
+
+int f0(int x0, [List<Function> x = const []]) => throw 'uncalled';
+List<Function> f1([Function x = _voidFunction]) => throw 'uncalled';
+List<int> f2(int x) => throw 'uncalled';
+f3(List<int> x) => throw 'uncalled';
+List<int> f4<A>(int x) => throw 'uncalled';
+int Function(Function) f5() => throw 'uncalled';
+int Function(int x, [core.List<core.int>]) f6() => throw 'uncalled';
+Function Function(int, {int x}) f7() => throw 'uncalled';
+Function Function([core.List<core.int> x]) f8() => throw 'uncalled';
+List<Function> Function(int y, [int x]) f9() => throw 'uncalled';
+List<Function> Function(int, [List<Function>]) f10() => throw 'uncalled';
+List<Function> Function(int, {List<int> x}) f11() => throw 'uncalled';
+core.List<core.int> Function(List<Function> x) f12() => throw 'uncalled';
+core.List<core.int> Function(int y, [List<int> x]) f13() => throw 'uncalled';
+List<int> Function([Function]) f14() => throw 'uncalled';
+List<int> Function({core.List<core.int> x}) f15() => throw 'uncalled';
+Function(int y, {int x}) f16() => throw 'uncalled';
+Function(int, [core.List<core.int> x]) f17() => throw 'uncalled';
+void Function(int) f18() => throw 'uncalled';
+void Function(int x, [List<Function>]) f19() => throw 'uncalled';
+void Function(int y, {List<int> x}) f20() => throw 'uncalled';
+List<Function> Function<A>(List<A> x) f21() => throw 'uncalled';
+A Function<A>(int x) f22() => throw 'uncalled';
+List<Function> Function(B x) f23<B extends core.int>() => throw 'uncalled';
+
+class U24<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, [List<Function> x]) x0;
+  late List<Function> Function([Function x]) x1;
+  late List<T> Function(int x) x2;
+  late Function(List<T> x) x3;
+  late List<T> Function<A>(int x) x4;
+  late int Function(Function) Function() x5;
+  late int Function(int x, [core.List<core.int>]) Function() x6;
+  late Function Function(int, {int x}) Function() x7;
+  late Function Function([core.List<core.int> x]) Function() x8;
+  late List<Function> Function(int y, [int x]) Function() x9;
+  late List<Function> Function(int, [List<Function>]) Function() x10;
+  late List<Function> Function(int, {List<T> x}) Function() x11;
+  late core.List<core.int> Function(List<Function> x) Function() x12;
+  late core.List<core.int> Function(int y, [List<T> x]) Function() x13;
+  late List<T> Function([Function]) Function() x14;
+  late List<T> Function({core.List<core.int> x}) Function() x15;
+  late Function(int y, {int x}) Function() x16;
+  late Function(int, [core.List<core.int> x]) Function() x17;
+  late void Function(int) Function() x18;
+  late void Function(int x, [List<Function>]) Function() x19;
+  late void Function(int y, {List<T> x}) Function() x20;
+  late List<Function> Function<A>(List<A> x) Function() x21;
+  late A Function<A>(int x) Function() x22;
+  late List<Function> Function(B x) Function<B extends core.int>() x23;
+
+  U24({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, [List<Function> x = const []]) => throw 'uncalled';
+  List<Function> m1([Function x = _voidFunction]) => throw 'uncalled';
+  List<T> m2(int x) => throw 'uncalled';
+  m3(List<T> x) => throw 'uncalled';
+  List<T> m4<A>(int x) => throw 'uncalled';
+  int Function(Function) m5() => throw 'uncalled';
+  int Function(int x, [core.List<core.int>]) m6() => throw 'uncalled';
+  Function Function(int, {int x}) m7() => throw 'uncalled';
+  Function Function([core.List<core.int> x]) m8() => throw 'uncalled';
+  List<Function> Function(int y, [int x]) m9() => throw 'uncalled';
+  List<Function> Function(int, [List<Function>]) m10() => throw 'uncalled';
+  List<Function> Function(int, {List<T> x}) m11() => throw 'uncalled';
+  core.List<core.int> Function(List<Function> x) m12() => throw 'uncalled';
+  core.List<core.int> Function(int y, [List<T> x]) m13() => throw 'uncalled';
+  List<T> Function([Function]) m14() => throw 'uncalled';
+  List<T> Function({core.List<core.int> x}) m15() => throw 'uncalled';
+  Function(int y, {int x}) m16() => throw 'uncalled';
+  Function(int, [core.List<core.int> x]) m17() => throw 'uncalled';
+  void Function(int) m18() => throw 'uncalled';
+  void Function(int x, [List<Function>]) m19() => throw 'uncalled';
+  void Function(int y, {List<T> x}) m20() => throw 'uncalled';
+  List<Function> Function<A>(List<A> x) m21() => throw 'uncalled';
+  A Function<A>(int x) m22() => throw 'uncalled';
+  List<Function> Function(B x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, [List<Function> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<Function> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, [List<Function> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function([Function x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([Function x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function([Function x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int x)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int x));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(List<T> x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(List<T> x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(List<T> x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// List<T> Function<A>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<T> Function<A>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m4 is F4<int>);
+      Expect.equals(tIsBool, m4 is F4<bool>);
+      Expect.equals(tIsInt, confuse(m4) is F4<int>);
+      Expect.equals(tIsBool, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function(Function) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(Function) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(Function) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int x, [core.List<core.int>]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [core.List<core.int>]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int x, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, {int x}) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {int x}) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, {int x}) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([core.List<core.int> x]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([core.List<core.int> x]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int y, [int x]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [int x]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int y, [int x]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<Function>]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<Function>]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(int, [List<Function>]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int, {List<T> x}) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {List<T> x}) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int, {List<T> x}) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(List<Function> x) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<Function> x) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(List<Function> x) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, [List<T> x]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [List<T> x]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(int y, [List<T> x]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([Function]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([Function]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([Function]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function({core.List<core.int> x}) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({core.List<core.int> x}) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function({core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, {int x}) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {int x}) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, {int x}) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [core.List<core.int> x]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [core.List<core.int> x]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int x, [List<Function>]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [List<Function>]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int x, [List<Function>]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int y, {List<T> x}) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {List<T> x}) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int y, {List<T> x}) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<A> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<A> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(List<A> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(int x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(int x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(int x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// List<Function> Function(B x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(B x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is List<Function> Function(B x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U24().runTests();
+  new U24<int>(tIsInt: true).runTests();
+  new U24<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type25_test.dart b/tests/language/function_type/function_type25_test.dart
new file mode 100644
index 0000000..e50f32c
--- /dev/null
+++ b/tests/language/function_type/function_type25_test.dart
@@ -0,0 +1,956 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int y, [List<Function> x]);
+typedef F1<T> = List<Function> Function(int, [Function x]);
+typedef F2<T> = List<T> Function([int x]);
+typedef F3<T> = Function([List<T> x]);
+typedef F4<T> = List<T> Function<A>(Function x);
+typedef F5<T> = int Function(Function) Function(int x);
+typedef F6<T> = int Function(int x, [core.List<core.int>]) Function(int x);
+typedef F7<T> = Function Function(int, {int x}) Function(int x);
+typedef F8<T> = Function Function([core.List<core.int> x]) Function(int x);
+typedef F9<T> = List<Function> Function(int y, [int x]) Function(int x);
+typedef F10<T> = List<Function> Function(int, [List<Function>]) Function(int x);
+typedef F11<T> = List<Function> Function(int, {List<T> x}) Function(int x);
+typedef F12<T> = core.List<core.int> Function(List<Function> x) Function(int x);
+typedef F13<T> = core.List<core.int> Function(int y, [List<T> x]) Function(
+    int x);
+typedef F14<T> = List<T> Function([Function]) Function(int x);
+typedef F15<T> = List<T> Function({core.List<core.int> x}) Function(int x);
+typedef F16<T> = Function(int y, {int x}) Function(int x);
+typedef F17<T> = Function(int, [core.List<core.int> x]) Function(int x);
+typedef F18<T> = void Function(int) Function(int x);
+typedef F19<T> = void Function(int x, [List<Function>]) Function(int x);
+typedef F20<T> = void Function(int y, {List<T> x}) Function(int x);
+typedef F21<T> = List<Function> Function<A>(List<A> x) Function(int x);
+typedef F22<T> = A Function<A>(int x) Function(int x);
+typedef F23<T> = List<Function> Function(B x) Function<B extends core.int>(
+    int x);
+
+int f0(int y, [List<Function> x = const []]) => throw 'uncalled';
+List<Function> f1(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+List<int> f2([int x = -1]) => throw 'uncalled';
+f3([List<int> x = const []]) => throw 'uncalled';
+List<int> f4<A>(Function x) => throw 'uncalled';
+int Function(Function) f5(int x) => throw 'uncalled';
+int Function(int x, [core.List<core.int>]) f6(int x) => throw 'uncalled';
+Function Function(int, {int x}) f7(int x) => throw 'uncalled';
+Function Function([core.List<core.int> x]) f8(int x) => throw 'uncalled';
+List<Function> Function(int y, [int x]) f9(int x) => throw 'uncalled';
+List<Function> Function(int, [List<Function>]) f10(int x) => throw 'uncalled';
+List<Function> Function(int, {List<int> x}) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(List<Function> x) f12(int x) => throw 'uncalled';
+core.List<core.int> Function(int y, [List<int> x]) f13(int x) =>
+    throw 'uncalled';
+List<int> Function([Function]) f14(int x) => throw 'uncalled';
+List<int> Function({core.List<core.int> x}) f15(int x) => throw 'uncalled';
+Function(int y, {int x}) f16(int x) => throw 'uncalled';
+Function(int, [core.List<core.int> x]) f17(int x) => throw 'uncalled';
+void Function(int) f18(int x) => throw 'uncalled';
+void Function(int x, [List<Function>]) f19(int x) => throw 'uncalled';
+void Function(int y, {List<int> x}) f20(int x) => throw 'uncalled';
+List<Function> Function<A>(List<A> x) f21(int x) => throw 'uncalled';
+A Function<A>(int x) f22(int x) => throw 'uncalled';
+List<Function> Function(B x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U25<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int y, [List<Function> x]) x0;
+  late List<Function> Function(int, [Function x]) x1;
+  late List<T> Function([int x]) x2;
+  late Function([List<T> x]) x3;
+  late List<T> Function<A>(Function x) x4;
+  late int Function(Function) Function(int x) x5;
+  late int Function(int x, [core.List<core.int>]) Function(int x) x6;
+  late Function Function(int, {int x}) Function(int x) x7;
+  late Function Function([core.List<core.int> x]) Function(int x) x8;
+  late List<Function> Function(int y, [int x]) Function(int x) x9;
+  late List<Function> Function(int, [List<Function>]) Function(int x) x10;
+  late List<Function> Function(int, {List<T> x}) Function(int x) x11;
+  late core.List<core.int> Function(List<Function> x) Function(int x) x12;
+  late core.List<core.int> Function(int y, [List<T> x]) Function(int x) x13;
+  late List<T> Function([Function]) Function(int x) x14;
+  late List<T> Function({core.List<core.int> x}) Function(int x) x15;
+  late Function(int y, {int x}) Function(int x) x16;
+  late Function(int, [core.List<core.int> x]) Function(int x) x17;
+  late void Function(int) Function(int x) x18;
+  late void Function(int x, [List<Function>]) Function(int x) x19;
+  late void Function(int y, {List<T> x}) Function(int x) x20;
+  late List<Function> Function<A>(List<A> x) Function(int x) x21;
+  late A Function<A>(int x) Function(int x) x22;
+  late List<Function> Function(B x) Function<B extends core.int>(int x) x23;
+
+  U25({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int y, [List<Function> x = const []]) => throw 'uncalled';
+  List<Function> m1(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+  List<T> m2([int x = -1]) => throw 'uncalled';
+  m3([List<T> x = const []]) => throw 'uncalled';
+  List<T> m4<A>(Function x) => throw 'uncalled';
+  int Function(Function) m5(int x) => throw 'uncalled';
+  int Function(int x, [core.List<core.int>]) m6(int x) => throw 'uncalled';
+  Function Function(int, {int x}) m7(int x) => throw 'uncalled';
+  Function Function([core.List<core.int> x]) m8(int x) => throw 'uncalled';
+  List<Function> Function(int y, [int x]) m9(int x) => throw 'uncalled';
+  List<Function> Function(int, [List<Function>]) m10(int x) => throw 'uncalled';
+  List<Function> Function(int, {List<T> x}) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(List<Function> x) m12(int x) => throw 'uncalled';
+  core.List<core.int> Function(int y, [List<T> x]) m13(int x) =>
+      throw 'uncalled';
+  List<T> Function([Function]) m14(int x) => throw 'uncalled';
+  List<T> Function({core.List<core.int> x}) m15(int x) => throw 'uncalled';
+  Function(int y, {int x}) m16(int x) => throw 'uncalled';
+  Function(int, [core.List<core.int> x]) m17(int x) => throw 'uncalled';
+  void Function(int) m18(int x) => throw 'uncalled';
+  void Function(int x, [List<Function>]) m19(int x) => throw 'uncalled';
+  void Function(int y, {List<T> x}) m20(int x) => throw 'uncalled';
+  List<Function> Function<A>(List<A> x) m21(int x) => throw 'uncalled';
+  A Function<A>(int x) m22(int x) => throw 'uncalled';
+  List<Function> Function(B x) m23<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int y, [List<Function> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [List<Function> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int y, [List<Function> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, [Function x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [Function x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, [Function x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function([int x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([int x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function([int x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function([List<T> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function([List<T> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function([List<T> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// List<T> Function<A>(Function x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(Function x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<T> Function<A>(Function x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m4 is F4<int>);
+      Expect.equals(tIsBool, m4 is F4<bool>);
+      Expect.equals(tIsInt, confuse(m4) is F4<int>);
+      Expect.equals(tIsBool, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function(Function) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(Function) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(Function) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int x, [core.List<core.int>]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [core.List<core.int>]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int x, [core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, {int x}) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {int x}) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, {int x}) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([core.List<core.int> x]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([core.List<core.int> x]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function([core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int y, [int x]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [int x]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int y, [int x]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<Function>]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<Function>]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(int, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int, {List<T> x}) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {List<T> x}) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is List<Function> Function(int, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(List<Function> x) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<Function> x) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, [List<T> x]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [List<T> x]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int y, [List<T> x])
+        Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([Function]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([Function]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([Function]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function({core.List<core.int> x}) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({core.List<core.int> x}) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function({core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, {int x}) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {int x}) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, {int x}) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [core.List<core.int> x]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [core.List<core.int> x]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int, [core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int x, [List<Function>]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [List<Function>]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int x, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int y, {List<T> x}) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {List<T> x}) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int y, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<A> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<A> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(List<A> x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(int x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(int x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(int x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// List<Function> Function(B x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(B x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is List<Function> Function(B x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U25().runTests();
+  new U25<int>(tIsInt: true).runTests();
+  new U25<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type26_test.dart b/tests/language/function_type/function_type26_test.dart
new file mode 100644
index 0000000..bb5510c
--- /dev/null
+++ b/tests/language/function_type/function_type26_test.dart
@@ -0,0 +1,1011 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(List<Function>);
+typedef F1<T> = List<Function> Function(int y, [Function x]);
+typedef F2<T> = List<T> Function(int, [int x]);
+typedef F3<T> = Function(int, [List<T> x]);
+typedef F4<T> = List<T> Function<A>(List<Function> x);
+typedef F5<T> = int Function(Function) Function<B extends core.int>();
+typedef F6<T> = int Function(int x, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F7<T> = Function Function(int, {int x}) Function<B extends core.int>();
+typedef F8<T> = Function Function([core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int y, [int x])
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int, [List<Function>])
+    Function<B extends core.int>();
+typedef F11<T> = List<Function> Function(int, {List<T> x})
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(List<Function> x)
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function(int y, [List<T> x])
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function([Function]) Function<B extends core.int>();
+typedef F15<T> = List<T> Function({core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F16<T> = Function(int y, {int x}) Function<B extends core.int>();
+typedef F17<T> = Function(int, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F18<T> = void Function(int) Function<B extends core.int>();
+typedef F19<T> = void Function(int x, [List<Function>])
+    Function<B extends core.int>();
+typedef F20<T> = void Function(int y, {List<T> x})
+    Function<B extends core.int>();
+typedef F21<T> = List<Function> Function<A>(List<A> x)
+    Function<B extends core.int>();
+typedef F22<T> = A Function<A>(int x) Function<B extends core.int>();
+typedef F23<T> = core.List<core.int> Function(B x)
+    Function<B extends core.int>();
+
+int f0(List<Function> x0) => throw 'uncalled';
+List<Function> f1(int y, [Function x = _voidFunction]) => throw 'uncalled';
+List<int> f2(int x0, [int x = -1]) => throw 'uncalled';
+f3(int x0, [List<int> x = const []]) => throw 'uncalled';
+List<int> f4<A>(List<Function> x) => throw 'uncalled';
+int Function(Function) f5<B extends core.int>() => throw 'uncalled';
+int Function(int x, [core.List<core.int>]) f6<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int, {int x}) f7<B extends core.int>() => throw 'uncalled';
+Function Function([core.List<core.int> x]) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int y, [int x]) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, [List<Function>]) f10<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, {List<int> x}) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(List<Function> x) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, [List<int> x]) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function([Function]) f14<B extends core.int>() => throw 'uncalled';
+List<int> Function({core.List<core.int> x}) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function(int y, {int x}) f16<B extends core.int>() => throw 'uncalled';
+Function(int, [core.List<core.int> x]) f17<B extends core.int>() =>
+    throw 'uncalled';
+void Function(int) f18<B extends core.int>() => throw 'uncalled';
+void Function(int x, [List<Function>]) f19<B extends core.int>() =>
+    throw 'uncalled';
+void Function(int y, {List<int> x}) f20<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function<A>(List<A> x) f21<B extends core.int>() =>
+    throw 'uncalled';
+A Function<A>(int x) f22<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function(B x) f23<B extends core.int>() => throw 'uncalled';
+
+class U26<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(List<Function>) x0;
+  late List<Function> Function(int y, [Function x]) x1;
+  late List<T> Function(int, [int x]) x2;
+  late Function(int, [List<T> x]) x3;
+  late List<T> Function<A>(List<Function> x) x4;
+  late int Function(Function) Function<B extends core.int>() x5;
+  late int Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+      x6;
+  late Function Function(int, {int x}) Function<B extends core.int>() x7;
+  late Function Function([core.List<core.int> x]) Function<B extends core.int>()
+      x8;
+  late List<Function> Function(int y, [int x]) Function<B extends core.int>()
+      x9;
+  late List<Function> Function(int, [List<Function>])
+      Function<B extends core.int>() x10;
+  late List<Function> Function(int, {List<T> x}) Function<B extends core.int>()
+      x11;
+  late core.List<core.int> Function(List<Function> x)
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function(int y, [List<T> x])
+      Function<B extends core.int>() x13;
+  late List<T> Function([Function]) Function<B extends core.int>() x14;
+  late List<T> Function({core.List<core.int> x}) Function<B extends core.int>()
+      x15;
+  late Function(int y, {int x}) Function<B extends core.int>() x16;
+  late Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+      x17;
+  late void Function(int) Function<B extends core.int>() x18;
+  late void Function(int x, [List<Function>]) Function<B extends core.int>()
+      x19;
+  late void Function(int y, {List<T> x}) Function<B extends core.int>() x20;
+  late List<Function> Function<A>(List<A> x) Function<B extends core.int>() x21;
+  late A Function<A>(int x) Function<B extends core.int>() x22;
+  late core.List<core.int> Function(B x) Function<B extends core.int>() x23;
+
+  U26({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(List<Function> x0) => throw 'uncalled';
+  List<Function> m1(int y, [Function x = _voidFunction]) => throw 'uncalled';
+  List<T> m2(int x0, [int x = -1]) => throw 'uncalled';
+  m3(int x0, [List<T> x = const []]) => throw 'uncalled';
+  List<T> m4<A>(List<Function> x) => throw 'uncalled';
+  int Function(Function) m5<B extends core.int>() => throw 'uncalled';
+  int Function(int x, [core.List<core.int>]) m6<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int, {int x}) m7<B extends core.int>() => throw 'uncalled';
+  Function Function([core.List<core.int> x]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int y, [int x]) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, [List<Function>]) m10<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, {List<T> x}) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(List<Function> x) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [List<T> x]) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function([Function]) m14<B extends core.int>() => throw 'uncalled';
+  List<T> Function({core.List<core.int> x}) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int y, {int x}) m16<B extends core.int>() => throw 'uncalled';
+  Function(int, [core.List<core.int> x]) m17<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int) m18<B extends core.int>() => throw 'uncalled';
+  void Function(int x, [List<Function>]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int y, {List<T> x}) m20<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function<A>(List<A> x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  A Function<A>(int x) m22<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function(B x) m23<B extends core.int>() =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(List<Function>)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(List<Function>) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(List<Function>));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int y, [Function x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [Function x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int y, [Function x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, [int x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [int x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, [int x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int, [List<T> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<T> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int, [List<T> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// List<T> Function<A>(List<Function> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<Function> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<T> Function<A>(List<Function> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m4 is F4<int>);
+      Expect.equals(tIsBool, m4 is F4<bool>);
+      Expect.equals(tIsInt, confuse(m4) is F4<int>);
+      Expect.equals(tIsBool, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function(Function) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(Function) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(Function) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+        l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int x, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, {int x}) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {int x}) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(int, {int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([core.List<core.int> x]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([core.List<core.int> x]) Function<B extends core.int>()
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int y, [int x]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [int x]) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int y, [int x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<Function>]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<Function>])
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int, {List<T> x}) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {List<T> x}) Function<B extends core.int>()
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int, {List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(List<Function> x) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<Function> x)
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, [List<T> x]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [List<T> x])
+        Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int y, [List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([Function]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([Function]) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function([Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function({core.List<core.int> x}) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({core.List<core.int> x}) Function<B extends core.int>()
+        l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function({core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, {int x}) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {int x}) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int y, {int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [core.List<core.int> x]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int x, [List<Function>]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [List<Function>]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int x, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int y, {List<T> x}) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {List<T> x}) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int y, {List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<A> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<A> x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(List<A> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(int x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(int x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// core.List<core.int> Function(B x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(B x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is core.List<core.int> Function(B x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U26().runTests();
+  new U26<int>(tIsInt: true).runTests();
+  new U26<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type27_test.dart b/tests/language/function_type/function_type27_test.dart
new file mode 100644
index 0000000..d96f60e
--- /dev/null
+++ b/tests/language/function_type/function_type27_test.dart
@@ -0,0 +1,1032 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function([List<Function>]);
+typedef F1<T> = List<Function> Function(Function);
+typedef F2<T> = List<T> Function(int y, [int x]);
+typedef F3<T> = Function(int y, [List<T> x]);
+typedef F4<T> = List<T> Function<A>(core.List<core.int> x);
+typedef F5<T> = int Function(Function) Function<B extends core.int>(int x);
+typedef F6<T> = int Function(int x, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int, {int x}) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function([core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(int y, [int x])
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(int, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F11<T> = List<Function> Function(int, {List<T> x})
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(List<Function> x)
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function(int y, [List<T> x])
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function([Function]) Function<B extends core.int>(
+    int x);
+typedef F15<T> = List<T> Function({core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function(int y, {int x}) Function<B extends core.int>(int x);
+typedef F17<T> = Function(int, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F18<T> = void Function(int) Function<B extends core.int>(int x);
+typedef F19<T> = void Function(int x, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F20<T> = void Function(int y, {List<T> x}) Function<B extends core.int>(
+    int x);
+typedef F21<T> = List<Function> Function<A>(List<A> x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = A Function<A>(int x) Function<B extends core.int>(int x);
+typedef F23<T> = core.List<core.int> Function(B x) Function<B extends core.int>(
+    int x);
+
+int f0([List<Function> x0 = const []]) => throw 'uncalled';
+List<Function> f1(Function x0) => throw 'uncalled';
+List<int> f2(int y, [int x = -1]) => throw 'uncalled';
+f3(int y, [List<int> x = const []]) => throw 'uncalled';
+List<int> f4<A>(core.List<core.int> x) => throw 'uncalled';
+int Function(Function) f5<B extends core.int>(int x) => throw 'uncalled';
+int Function(int x, [core.List<core.int>]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, {int x}) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function([core.List<core.int> x]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int y, [int x]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, [List<Function>]) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, {List<int> x}) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(List<Function> x) f12<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, [List<int> x]) f13<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function([Function]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function({core.List<core.int> x}) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int y, {int x}) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(int, [core.List<core.int> x]) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(int x, [List<Function>]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int y, {List<int> x}) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function<A>(List<A> x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+A Function<A>(int x) f22<B extends core.int>(int x) => throw 'uncalled';
+core.List<core.int> Function(B x) f23<B extends core.int>(int x) =>
+    throw 'uncalled';
+
+class U27<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function([List<Function>]) x0;
+  late List<Function> Function(Function) x1;
+  late List<T> Function(int y, [int x]) x2;
+  late Function(int y, [List<T> x]) x3;
+  late List<T> Function<A>(core.List<core.int> x) x4;
+  late int Function(Function) Function<B extends core.int>(int x) x5;
+  late int Function(int x, [core.List<core.int>]) Function<B extends core.int>(
+      int x) x6;
+  late Function Function(int, {int x}) Function<B extends core.int>(int x) x7;
+  late Function Function([core.List<core.int> x]) Function<B extends core.int>(
+      int x) x8;
+  late List<Function> Function(int y, [int x]) Function<B extends core.int>(
+      int x) x9;
+  late List<Function> Function(int, [List<Function>])
+      Function<B extends core.int>(int x) x10;
+  late List<Function> Function(int, {List<T> x}) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function(List<Function> x)
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function(int y, [List<T> x])
+      Function<B extends core.int>(int x) x13;
+  late List<T> Function([Function]) Function<B extends core.int>(int x) x14;
+  late List<T> Function({core.List<core.int> x}) Function<B extends core.int>(
+      int x) x15;
+  late Function(int y, {int x}) Function<B extends core.int>(int x) x16;
+  late Function(int, [core.List<core.int> x]) Function<B extends core.int>(
+      int x) x17;
+  late void Function(int) Function<B extends core.int>(int x) x18;
+  late void Function(int x, [List<Function>]) Function<B extends core.int>(
+      int x) x19;
+  late void Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+      x20;
+  late List<Function> Function<A>(List<A> x) Function<B extends core.int>(int x)
+      x21;
+  late A Function<A>(int x) Function<B extends core.int>(int x) x22;
+  late core.List<core.int> Function(B x) Function<B extends core.int>(int x)
+      x23;
+
+  U27({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0([List<Function> x0 = const []]) => throw 'uncalled';
+  List<Function> m1(Function x0) => throw 'uncalled';
+  List<T> m2(int y, [int x = -1]) => throw 'uncalled';
+  m3(int y, [List<T> x = const []]) => throw 'uncalled';
+  List<T> m4<A>(core.List<core.int> x) => throw 'uncalled';
+  int Function(Function) m5<B extends core.int>(int x) => throw 'uncalled';
+  int Function(int x, [core.List<core.int>]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, {int x}) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function([core.List<core.int> x]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, [int x]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, [List<Function>]) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, {List<T> x}) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(List<Function> x) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [List<T> x]) m13<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function([Function]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function({core.List<core.int> x}) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int y, {int x}) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(int, [core.List<core.int> x]) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int) m18<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int x, [List<Function>]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int y, {List<T> x}) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function<A>(List<A> x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  A Function<A>(int x) m22<B extends core.int>(int x) => throw 'uncalled';
+  core.List<core.int> Function(B x) m23<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function([List<Function>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function([List<Function>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function([List<Function>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(Function)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(Function) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(Function));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int y, [int x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [int x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int y, [int x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int y, [List<T> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [List<T> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int y, [List<T> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// List<T> Function<A>(core.List<core.int> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(core.List<core.int> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<T> Function<A>(core.List<core.int> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m4 is F4<int>);
+      Expect.equals(tIsBool, m4 is F4<bool>);
+      Expect.equals(tIsInt, confuse(m4) is F4<int>);
+      Expect.equals(tIsBool, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function(Function) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(Function) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(Function) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int x, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [core.List<core.int>]) Function<B extends core.int>(
+        int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int x, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, {int x}) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {int x}) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, {int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([core.List<core.int> x]) Function<B extends core.int>(
+        int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int y, [int x]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [int x]) Function<B extends core.int>(int x)
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int y, [int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<Function>]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<Function>]) Function<B extends core.int>(
+        int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int, {List<T> x}) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {List<T> x}) Function<B extends core.int>(
+        int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(List<Function> x) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<Function> x) Function<B extends core.int>(
+        int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [List<T> x])
+        Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int y, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([Function]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([Function]) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({core.List<core.int> x}) Function<B extends core.int>(
+        int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function({core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, {int x}) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {int x}) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int y, {int x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [core.List<core.int> x]) Function<B extends core.int>(int x)
+        l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int x, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {List<T> x}) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int y, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<A> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<A> x) Function<B extends core.int>(int x)
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(List<A> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(int x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(int x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is A Function<A>(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// core.List<core.int> Function(B x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(B x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is core.List<core.int> Function(B x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U27().runTests();
+  new U27<int>(tIsInt: true).runTests();
+  new U27<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type28_test.dart b/tests/language/function_type/function_type28_test.dart
new file mode 100644
index 0000000..43d24f0
--- /dev/null
+++ b/tests/language/function_type/function_type28_test.dart
@@ -0,0 +1,945 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, [List<Function>]);
+typedef F1<T> = List<Function> Function([Function]);
+typedef F2<T> = List<T> Function(int);
+typedef F3<T> = Function(List<T>);
+typedef F4<T> = List<T> Function<A>(List<T> x);
+typedef F5<T> = int Function([Function]) Function();
+typedef F6<T> = int Function({core.List<core.int> x}) Function();
+typedef F7<T> = Function Function(int y, {int x}) Function();
+typedef F8<T> = Function Function(int, [core.List<core.int> x]) Function();
+typedef F9<T> = List<Function> Function(int) Function();
+typedef F10<T> = List<Function> Function(int x, [List<Function>]) Function();
+typedef F11<T> = List<Function> Function(int y, {List<T> x}) Function();
+typedef F12<T> = core.List<core.int> Function([List<Function> x]) Function();
+typedef F13<T> = core.List<core.int> Function(List<T>) Function();
+typedef F14<T> = List<T> Function(int, [Function]) Function();
+typedef F15<T> = List<T> Function(int, {core.List<core.int> x}) Function();
+typedef F16<T> = Function(Function x) Function();
+typedef F17<T> = Function(int y, [core.List<core.int> x]) Function();
+typedef F18<T> = void Function([int]) Function();
+typedef F19<T> = void Function({List<Function> x}) Function();
+typedef F20<T> = void Function() Function();
+typedef F21<T> = core.List<core.int> Function<A>(int x) Function();
+typedef F22<T> = A Function<A>(Function x) Function();
+typedef F23<T> = List<T> Function(B x) Function<B extends core.int>();
+
+int f0(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+List<Function> f1([Function x0 = _voidFunction]) => throw 'uncalled';
+List<int> f2(int x0) => throw 'uncalled';
+f3(List<int> x0) => throw 'uncalled';
+List<int> f4<A>(List<int> x) => throw 'uncalled';
+int Function([Function]) f5() => throw 'uncalled';
+int Function({core.List<core.int> x}) f6() => throw 'uncalled';
+Function Function(int y, {int x}) f7() => throw 'uncalled';
+Function Function(int, [core.List<core.int> x]) f8() => throw 'uncalled';
+List<Function> Function(int) f9() => throw 'uncalled';
+List<Function> Function(int x, [List<Function>]) f10() => throw 'uncalled';
+List<Function> Function(int y, {List<int> x}) f11() => throw 'uncalled';
+core.List<core.int> Function([List<Function> x]) f12() => throw 'uncalled';
+core.List<core.int> Function(List<int>) f13() => throw 'uncalled';
+List<int> Function(int, [Function]) f14() => throw 'uncalled';
+List<int> Function(int, {core.List<core.int> x}) f15() => throw 'uncalled';
+Function(Function x) f16() => throw 'uncalled';
+Function(int y, [core.List<core.int> x]) f17() => throw 'uncalled';
+void Function([int]) f18() => throw 'uncalled';
+void Function({List<Function> x}) f19() => throw 'uncalled';
+void Function() f20() => throw 'uncalled';
+core.List<core.int> Function<A>(int x) f21() => throw 'uncalled';
+A Function<A>(Function x) f22() => throw 'uncalled';
+List<int> Function(B x) f23<B extends core.int>() => throw 'uncalled';
+
+class U28<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, [List<Function>]) x0;
+  late List<Function> Function([Function]) x1;
+  late List<T> Function(int) x2;
+  late Function(List<T>) x3;
+  late List<T> Function<A>(List<T> x) x4;
+  late int Function([Function]) Function() x5;
+  late int Function({core.List<core.int> x}) Function() x6;
+  late Function Function(int y, {int x}) Function() x7;
+  late Function Function(int, [core.List<core.int> x]) Function() x8;
+  late List<Function> Function(int) Function() x9;
+  late List<Function> Function(int x, [List<Function>]) Function() x10;
+  late List<Function> Function(int y, {List<T> x}) Function() x11;
+  late core.List<core.int> Function([List<Function> x]) Function() x12;
+  late core.List<core.int> Function(List<T>) Function() x13;
+  late List<T> Function(int, [Function]) Function() x14;
+  late List<T> Function(int, {core.List<core.int> x}) Function() x15;
+  late Function(Function x) Function() x16;
+  late Function(int y, [core.List<core.int> x]) Function() x17;
+  late void Function([int]) Function() x18;
+  late void Function({List<Function> x}) Function() x19;
+  late void Function() Function() x20;
+  late core.List<core.int> Function<A>(int x) Function() x21;
+  late A Function<A>(Function x) Function() x22;
+  late List<T> Function(B x) Function<B extends core.int>() x23;
+
+  U28({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+  List<Function> m1([Function x0 = _voidFunction]) => throw 'uncalled';
+  List<T> m2(int x0) => throw 'uncalled';
+  m3(List<T> x0) => throw 'uncalled';
+  List<T> m4<A>(List<T> x) => throw 'uncalled';
+  int Function([Function]) m5() => throw 'uncalled';
+  int Function({core.List<core.int> x}) m6() => throw 'uncalled';
+  Function Function(int y, {int x}) m7() => throw 'uncalled';
+  Function Function(int, [core.List<core.int> x]) m8() => throw 'uncalled';
+  List<Function> Function(int) m9() => throw 'uncalled';
+  List<Function> Function(int x, [List<Function>]) m10() => throw 'uncalled';
+  List<Function> Function(int y, {List<T> x}) m11() => throw 'uncalled';
+  core.List<core.int> Function([List<Function> x]) m12() => throw 'uncalled';
+  core.List<core.int> Function(List<T>) m13() => throw 'uncalled';
+  List<T> Function(int, [Function]) m14() => throw 'uncalled';
+  List<T> Function(int, {core.List<core.int> x}) m15() => throw 'uncalled';
+  Function(Function x) m16() => throw 'uncalled';
+  Function(int y, [core.List<core.int> x]) m17() => throw 'uncalled';
+  void Function([int]) m18() => throw 'uncalled';
+  void Function({List<Function> x}) m19() => throw 'uncalled';
+  void Function() m20() => throw 'uncalled';
+  core.List<core.int> Function<A>(int x) m21() => throw 'uncalled';
+  A Function<A>(Function x) m22() => throw 'uncalled';
+  List<T> Function(B x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, [List<Function>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<Function>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, [List<Function>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function([Function])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([Function]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function([Function]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(List<T>)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(List<T>) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(List<T>));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// List<T> Function<A>(List<T> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<T> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<T> Function<A>(List<T> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m4 is F4<int>);
+      Expect.equals(tIsBool, m4 is F4<bool>);
+      Expect.equals(tIsInt, confuse(m4) is F4<int>);
+      Expect.equals(tIsBool, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function([Function]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([Function]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function([Function]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function({core.List<core.int> x}) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function({core.List<core.int> x}) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function({core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, {int x}) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {int x}) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, {int x}) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [core.List<core.int> x]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [core.List<core.int> x]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int, [core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int x, [List<Function>]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [List<Function>]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(int x, [List<Function>]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int y, {List<T> x}) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {List<T> x}) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is List<Function> Function(int y, {List<T> x}) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function([List<Function> x]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<Function> x]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function([List<Function> x]) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(List<T>) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<T>) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(List<T>) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [Function]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [Function]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [Function]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {core.List<core.int> x}) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {core.List<core.int> x}) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int, {core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(Function x) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(Function x) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(Function x) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, [core.List<core.int> x]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [core.List<core.int> x]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, [core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([int]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([int]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function([int]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function({List<Function> x}) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function({List<Function> x}) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function({List<Function> x}) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function() Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function() Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function() Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(int x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(int x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(int x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(Function x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(Function x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(Function x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// List<T> Function(B x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(B x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is List<T> Function(B x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+    // The static function has its T always set to int.
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isFalse(f23 is F23<bool>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    Expect.isFalse(confuse(f23) is F23<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        x23 = confuse(f23);
+      });
+      Expect.throws(() {
+        l23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        l23 = confuse(f23);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m23 is F23<int>);
+      Expect.equals(tIsBool, m23 is F23<bool>);
+      Expect.equals(tIsInt, confuse(m23) is F23<int>);
+      Expect.equals(tIsBool, confuse(m23) is F23<bool>);
+    }
+  }
+}
+
+void main() {
+  new U28().runTests();
+  new U28<int>(tIsInt: true).runTests();
+  new U28<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type29_test.dart b/tests/language/function_type/function_type29_test.dart
new file mode 100644
index 0000000..698cd38
--- /dev/null
+++ b/tests/language/function_type/function_type29_test.dart
@@ -0,0 +1,952 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int x, [List<Function>]);
+typedef F1<T> = List<Function> Function(int, [Function]);
+typedef F2<T> = List<T> Function([int]);
+typedef F3<T> = Function([List<T>]);
+typedef F4<T> = List<T> Function<A>();
+typedef F5<T> = int Function([Function]) Function(int x);
+typedef F6<T> = int Function({core.List<core.int> x}) Function(int x);
+typedef F7<T> = Function Function(int y, {int x}) Function(int x);
+typedef F8<T> = Function Function(int, [core.List<core.int> x]) Function(int x);
+typedef F9<T> = List<Function> Function(int) Function(int x);
+typedef F10<T> = List<Function> Function(int x, [List<Function>]) Function(
+    int x);
+typedef F11<T> = List<Function> Function(int y, {List<T> x}) Function(int x);
+typedef F12<T> = core.List<core.int> Function([List<Function> x]) Function(
+    int x);
+typedef F13<T> = core.List<core.int> Function(List<T>) Function(int x);
+typedef F14<T> = List<T> Function(int, [Function]) Function(int x);
+typedef F15<T> = List<T> Function(int, {core.List<core.int> x}) Function(int x);
+typedef F16<T> = Function(Function x) Function(int x);
+typedef F17<T> = Function(int y, [core.List<core.int> x]) Function(int x);
+typedef F18<T> = void Function([int]) Function(int x);
+typedef F19<T> = void Function({List<Function> x}) Function(int x);
+typedef F20<T> = void Function() Function(int x);
+typedef F21<T> = core.List<core.int> Function<A>(int x) Function(int x);
+typedef F22<T> = A Function<A>(Function x) Function(int x);
+typedef F23<T> = List<T> Function(B x) Function<B extends core.int>(int x);
+
+int f0(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+List<Function> f1(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+List<int> f2([int x0 = -1]) => throw 'uncalled';
+f3([List<int> x0 = const []]) => throw 'uncalled';
+List<int> f4<A>() => throw 'uncalled';
+int Function([Function]) f5(int x) => throw 'uncalled';
+int Function({core.List<core.int> x}) f6(int x) => throw 'uncalled';
+Function Function(int y, {int x}) f7(int x) => throw 'uncalled';
+Function Function(int, [core.List<core.int> x]) f8(int x) => throw 'uncalled';
+List<Function> Function(int) f9(int x) => throw 'uncalled';
+List<Function> Function(int x, [List<Function>]) f10(int x) => throw 'uncalled';
+List<Function> Function(int y, {List<int> x}) f11(int x) => throw 'uncalled';
+core.List<core.int> Function([List<Function> x]) f12(int x) => throw 'uncalled';
+core.List<core.int> Function(List<int>) f13(int x) => throw 'uncalled';
+List<int> Function(int, [Function]) f14(int x) => throw 'uncalled';
+List<int> Function(int, {core.List<core.int> x}) f15(int x) => throw 'uncalled';
+Function(Function x) f16(int x) => throw 'uncalled';
+Function(int y, [core.List<core.int> x]) f17(int x) => throw 'uncalled';
+void Function([int]) f18(int x) => throw 'uncalled';
+void Function({List<Function> x}) f19(int x) => throw 'uncalled';
+void Function() f20(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(int x) f21(int x) => throw 'uncalled';
+A Function<A>(Function x) f22(int x) => throw 'uncalled';
+List<int> Function(B x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U29<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int x, [List<Function>]) x0;
+  late List<Function> Function(int, [Function]) x1;
+  late List<T> Function([int]) x2;
+  late Function([List<T>]) x3;
+  late List<T> Function<A>() x4;
+  late int Function([Function]) Function(int x) x5;
+  late int Function({core.List<core.int> x}) Function(int x) x6;
+  late Function Function(int y, {int x}) Function(int x) x7;
+  late Function Function(int, [core.List<core.int> x]) Function(int x) x8;
+  late List<Function> Function(int) Function(int x) x9;
+  late List<Function> Function(int x, [List<Function>]) Function(int x) x10;
+  late List<Function> Function(int y, {List<T> x}) Function(int x) x11;
+  late core.List<core.int> Function([List<Function> x]) Function(int x) x12;
+  late core.List<core.int> Function(List<T>) Function(int x) x13;
+  late List<T> Function(int, [Function]) Function(int x) x14;
+  late List<T> Function(int, {core.List<core.int> x}) Function(int x) x15;
+  late Function(Function x) Function(int x) x16;
+  late Function(int y, [core.List<core.int> x]) Function(int x) x17;
+  late void Function([int]) Function(int x) x18;
+  late void Function({List<Function> x}) Function(int x) x19;
+  late void Function() Function(int x) x20;
+  late core.List<core.int> Function<A>(int x) Function(int x) x21;
+  late A Function<A>(Function x) Function(int x) x22;
+  late List<T> Function(B x) Function<B extends core.int>(int x) x23;
+
+  U29({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+  List<Function> m1(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+  List<T> m2([int x0 = -1]) => throw 'uncalled';
+  m3([List<T> x0 = const []]) => throw 'uncalled';
+  List<T> m4<A>() => throw 'uncalled';
+  int Function([Function]) m5(int x) => throw 'uncalled';
+  int Function({core.List<core.int> x}) m6(int x) => throw 'uncalled';
+  Function Function(int y, {int x}) m7(int x) => throw 'uncalled';
+  Function Function(int, [core.List<core.int> x]) m8(int x) => throw 'uncalled';
+  List<Function> Function(int) m9(int x) => throw 'uncalled';
+  List<Function> Function(int x, [List<Function>]) m10(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, {List<T> x}) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function([List<Function> x]) m12(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(List<T>) m13(int x) => throw 'uncalled';
+  List<T> Function(int, [Function]) m14(int x) => throw 'uncalled';
+  List<T> Function(int, {core.List<core.int> x}) m15(int x) => throw 'uncalled';
+  Function(Function x) m16(int x) => throw 'uncalled';
+  Function(int y, [core.List<core.int> x]) m17(int x) => throw 'uncalled';
+  void Function([int]) m18(int x) => throw 'uncalled';
+  void Function({List<Function> x}) m19(int x) => throw 'uncalled';
+  void Function() m20(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(int x) m21(int x) => throw 'uncalled';
+  A Function<A>(Function x) m22(int x) => throw 'uncalled';
+  List<T> Function(B x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int x, [List<Function>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [List<Function>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int x, [List<Function>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, [Function])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [Function]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, [Function]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function([int])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([int]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function([int]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function([List<T>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function([List<T>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function([List<T>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// List<T> Function<A>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<T> Function<A>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m4 is F4<int>);
+      Expect.equals(tIsBool, m4 is F4<bool>);
+      Expect.equals(tIsInt, confuse(m4) is F4<int>);
+      Expect.equals(tIsBool, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function([Function]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([Function]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function([Function]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function({core.List<core.int> x}) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function({core.List<core.int> x}) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function({core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, {int x}) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {int x}) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, {int x}) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [core.List<core.int> x]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [core.List<core.int> x]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int, [core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int x, [List<Function>]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [List<Function>]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int x, [List<Function>])
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int y, {List<T> x}) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {List<T> x}) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is List<Function> Function(int y, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function([List<Function> x]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<Function> x]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([List<Function> x])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(List<T>) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<T>) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(List<T>) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [Function]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [Function]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [Function]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {core.List<core.int> x}) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {core.List<core.int> x}) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int, {core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(Function x) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(Function x) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(Function x) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, [core.List<core.int> x]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [core.List<core.int> x]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int y, [core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([int]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([int]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function([int]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function({List<Function> x}) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function({List<Function> x}) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function({List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function() Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function() Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function() Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(int x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(int x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is core.List<core.int> Function<A>(int x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(Function x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(Function x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(Function x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// List<T> Function(B x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(B x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is List<T> Function(B x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+    // The static function has its T always set to int.
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isFalse(f23 is F23<bool>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    Expect.isFalse(confuse(f23) is F23<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        x23 = confuse(f23);
+      });
+      Expect.throws(() {
+        l23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        l23 = confuse(f23);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m23 is F23<int>);
+      Expect.equals(tIsBool, m23 is F23<bool>);
+      Expect.equals(tIsInt, confuse(m23) is F23<int>);
+      Expect.equals(tIsBool, confuse(m23) is F23<bool>);
+    }
+  }
+}
+
+void main() {
+  new U29().runTests();
+  new U29<int>(tIsInt: true).runTests();
+  new U29<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type2_test.dart b/tests/language/function_type/function_type2_test.dart
new file mode 100644
index 0000000..91eb040
--- /dev/null
+++ b/tests/language/function_type/function_type2_test.dart
@@ -0,0 +1,984 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, [int x]);
+typedef F1<T> = Function Function(int, [List<T> x]);
+typedef F2<T> = core.List<core.int> Function([core.List<core.int> x]);
+typedef F3<T> = Function(List<Function> x);
+typedef F4<T> = Function Function<A>(List<Function> x);
+typedef F5<T> = int Function(int, {int x}) Function<B extends core.int>();
+typedef F6<T> = int Function([core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F7<T> = Function Function(int y, [int x])
+    Function<B extends core.int>();
+typedef F8<T> = Function Function(int, [List<Function>])
+    Function<B extends core.int>();
+typedef F9<T> = Function Function(int, {List<T> x})
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(List<Function> x)
+    Function<B extends core.int>();
+typedef F11<T> = List<Function> Function(int y, [List<T> x])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function([Function])
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function({core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int y, {int x})
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F16<T> = Function(int) Function<B extends core.int>();
+typedef F17<T> = Function(int x, [List<Function>])
+    Function<B extends core.int>();
+typedef F18<T> = Function(int y, {List<T> x}) Function<B extends core.int>();
+typedef F19<T> = void Function([List<Function> x])
+    Function<B extends core.int>();
+typedef F20<T> = void Function(List<T>) Function<B extends core.int>();
+typedef F21<T> = List<Function> Function<A>(Function x)
+    Function<B extends core.int>();
+typedef F22<T> = Function<A>(List<Function> x) Function<B extends core.int>();
+typedef F23<T> = void Function<A>(core.List<core.int> x)
+    Function<B extends core.int>();
+
+int f0(int x0, [int x = -1]) => throw 'uncalled';
+Function f1(int x0, [List<int> x = const []]) => throw 'uncalled';
+core.List<core.int> f2([core.List<core.int> x = const []]) => throw 'uncalled';
+f3(List<Function> x) => throw 'uncalled';
+Function f4<A>(List<Function> x) => throw 'uncalled';
+int Function(int, {int x}) f5<B extends core.int>() => throw 'uncalled';
+int Function([core.List<core.int> x]) f6<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int y, [int x]) f7<B extends core.int>() => throw 'uncalled';
+Function Function(int, [List<Function>]) f8<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int, {List<int> x}) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(List<Function> x) f10<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int y, [List<int> x]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function([Function]) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function({core.List<core.int> x})
+    f13<B extends core.int>() => throw 'uncalled';
+List<int> Function(int y, {int x}) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, [core.List<core.int> x]) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function(int) f16<B extends core.int>() => throw 'uncalled';
+Function(int x, [List<Function>]) f17<B extends core.int>() => throw 'uncalled';
+Function(int y, {List<int> x}) f18<B extends core.int>() => throw 'uncalled';
+void Function([List<Function> x]) f19<B extends core.int>() => throw 'uncalled';
+void Function(List<int>) f20<B extends core.int>() => throw 'uncalled';
+List<Function> Function<A>(Function x) f21<B extends core.int>() =>
+    throw 'uncalled';
+Function<A>(List<Function> x) f22<B extends core.int>() => throw 'uncalled';
+void Function<A>(core.List<core.int> x) f23<B extends core.int>() =>
+    throw 'uncalled';
+
+class U2<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, [int x]) x0;
+  late Function Function(int, [List<T> x]) x1;
+  late core.List<core.int> Function([core.List<core.int> x]) x2;
+  late Function(List<Function> x) x3;
+  late Function Function<A>(List<Function> x) x4;
+  late int Function(int, {int x}) Function<B extends core.int>() x5;
+  late int Function([core.List<core.int> x]) Function<B extends core.int>() x6;
+  late Function Function(int y, [int x]) Function<B extends core.int>() x7;
+  late Function Function(int, [List<Function>]) Function<B extends core.int>()
+      x8;
+  late Function Function(int, {List<T> x}) Function<B extends core.int>() x9;
+  late List<Function> Function(List<Function> x) Function<B extends core.int>()
+      x10;
+  late List<Function> Function(int y, [List<T> x])
+      Function<B extends core.int>() x11;
+  late core.List<core.int> Function([Function]) Function<B extends core.int>()
+      x12;
+  late core.List<core.int> Function({core.List<core.int> x})
+      Function<B extends core.int>() x13;
+  late List<T> Function(int y, {int x}) Function<B extends core.int>() x14;
+  late List<T> Function(int, [core.List<core.int> x])
+      Function<B extends core.int>() x15;
+  late Function(int) Function<B extends core.int>() x16;
+  late Function(int x, [List<Function>]) Function<B extends core.int>() x17;
+  late Function(int y, {List<T> x}) Function<B extends core.int>() x18;
+  late void Function([List<Function> x]) Function<B extends core.int>() x19;
+  late void Function(List<T>) Function<B extends core.int>() x20;
+  late List<Function> Function<A>(Function x) Function<B extends core.int>()
+      x21;
+  late Function<A>(List<Function> x) Function<B extends core.int>() x22;
+  late void Function<A>(core.List<core.int> x) Function<B extends core.int>()
+      x23;
+
+  U2({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, [int x = -1]) => throw 'uncalled';
+  Function m1(int x0, [List<T> x = const []]) => throw 'uncalled';
+  core.List<core.int> m2([core.List<core.int> x = const []]) =>
+      throw 'uncalled';
+  m3(List<Function> x) => throw 'uncalled';
+  Function m4<A>(List<Function> x) => throw 'uncalled';
+  int Function(int, {int x}) m5<B extends core.int>() => throw 'uncalled';
+  int Function([core.List<core.int> x]) m6<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int y, [int x]) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int, [List<Function>]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int, {List<T> x}) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(List<Function> x) m10<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int y, [List<T> x]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function([Function]) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function({core.List<core.int> x})
+      m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int y, {int x}) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, [core.List<core.int> x]) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int) m16<B extends core.int>() => throw 'uncalled';
+  Function(int x, [List<Function>]) m17<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int y, {List<T> x}) m18<B extends core.int>() => throw 'uncalled';
+  void Function([List<Function> x]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(List<T>) m20<B extends core.int>() => throw 'uncalled';
+  List<Function> Function<A>(Function x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  Function<A>(List<Function> x) m22<B extends core.int>() => throw 'uncalled';
+  void Function<A>(core.List<core.int> x) m23<B extends core.int>() =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, [int x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [int x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, [int x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function(int, [List<T> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<T> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function(int, [List<T> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function([core.List<core.int> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([core.List<core.int> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function([core.List<core.int> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function(List<Function> x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(List<Function> x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(List<Function> x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function Function<A>(List<Function> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<Function> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function Function<A>(List<Function> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {int x}) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {int x}) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int, {int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([core.List<core.int> x]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([core.List<core.int> x]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, [int x]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [int x]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(int y, [int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<Function>]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<Function>]) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function(int, {List<T> x}) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {List<T> x}) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function(int, {List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+    // The static function has its T always set to int.
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isFalse(f9 is F9<bool>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    Expect.isFalse(confuse(f9) is F9<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        x9 = confuse(f9);
+      });
+      Expect.throws(() {
+        l9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        l9 = confuse(f9);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m9 is F9<int>);
+      Expect.equals(tIsBool, m9 is F9<bool>);
+      Expect.equals(tIsInt, confuse(m9) is F9<int>);
+      Expect.equals(tIsBool, confuse(m9) is F9<bool>);
+    }
+  }
+
+  /// List<Function> Function(List<Function> x) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<Function> x) Function<B extends core.int>()
+        l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int y, [List<T> x]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [List<T> x]) Function<B extends core.int>()
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int y, [List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function([Function]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([Function]) Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([Function])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function({core.List<core.int> x}) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({core.List<core.int> x})
+        Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function({core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(int y, {int x}) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {int x}) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(int y, {int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [core.List<core.int> x])
+        Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [List<Function>]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [List<Function>]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int x, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// Function(int y, {List<T> x}) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {List<T> x}) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is Function(int y, {List<T> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+    // The static function has its T always set to int.
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isFalse(f18 is F18<bool>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    Expect.isFalse(confuse(f18) is F18<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x18 = (f18 as dynamic);
+      });
+      Expect.throws(() {
+        x18 = confuse(f18);
+      });
+      Expect.throws(() {
+        l18 = (f18 as dynamic);
+      });
+      Expect.throws(() {
+        l18 = confuse(f18);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m18 is F18<int>);
+      Expect.equals(tIsBool, m18 is F18<bool>);
+      Expect.equals(tIsInt, confuse(m18) is F18<int>);
+      Expect.equals(tIsBool, confuse(m18) is F18<bool>);
+    }
+  }
+
+  /// void Function([List<Function> x]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<Function> x]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(List<T>) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(List<T>) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(List<T>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(Function x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(Function x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(Function x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<Function> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<Function> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is Function<A>(List<Function> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(core.List<core.int> x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(core.List<core.int> x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U2().runTests();
+  new U2<int>(tIsInt: true).runTests();
+  new U2<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type30_test.dart b/tests/language/function_type/function_type30_test.dart
new file mode 100644
index 0000000..195eaba
--- /dev/null
+++ b/tests/language/function_type/function_type30_test.dart
@@ -0,0 +1,976 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function({List<Function> x});
+typedef F1<T> = List<Function> Function(int x, [Function]);
+typedef F2<T> = List<T> Function(int, [int]);
+typedef F3<T> = Function(int, [List<T>]);
+typedef F4<T> = List<T> Function<A>(A x);
+typedef F5<T> = int Function([Function]) Function<B extends core.int>();
+typedef F6<T> = int Function({core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F7<T> = Function Function(int y, {int x})
+    Function<B extends core.int>();
+typedef F8<T> = Function Function(int, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int) Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int x, [List<Function>])
+    Function<B extends core.int>();
+typedef F11<T> = List<Function> Function(int y, {List<T> x})
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function([List<Function> x])
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function(List<T>)
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int, [Function])
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F16<T> = Function(Function x) Function<B extends core.int>();
+typedef F17<T> = Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F18<T> = void Function([int]) Function<B extends core.int>();
+typedef F19<T> = void Function({List<Function> x})
+    Function<B extends core.int>();
+typedef F20<T> = void Function() Function<B extends core.int>();
+typedef F21<T> = core.List<core.int> Function<A>(int x)
+    Function<B extends core.int>();
+typedef F22<T> = A Function<A>(Function x) Function<B extends core.int>();
+typedef F23<T> = Function(B x) Function<B extends core.int>();
+
+int f0({List<Function> x = const []}) => throw 'uncalled';
+List<Function> f1(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+List<int> f2(int x0, [int x1 = -1]) => throw 'uncalled';
+f3(int x0, [List<int> x1 = const []]) => throw 'uncalled';
+List<int> f4<A>(A x) => throw 'uncalled';
+int Function([Function]) f5<B extends core.int>() => throw 'uncalled';
+int Function({core.List<core.int> x}) f6<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int y, {int x}) f7<B extends core.int>() => throw 'uncalled';
+Function Function(int, [core.List<core.int> x]) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int) f9<B extends core.int>() => throw 'uncalled';
+List<Function> Function(int x, [List<Function>]) f10<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int y, {List<int> x}) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function([List<Function> x]) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(List<int>) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, [Function]) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, {core.List<core.int> x}) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function(Function x) f16<B extends core.int>() => throw 'uncalled';
+Function(int y, [core.List<core.int> x]) f17<B extends core.int>() =>
+    throw 'uncalled';
+void Function([int]) f18<B extends core.int>() => throw 'uncalled';
+void Function({List<Function> x}) f19<B extends core.int>() => throw 'uncalled';
+void Function() f20<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function<A>(int x) f21<B extends core.int>() =>
+    throw 'uncalled';
+A Function<A>(Function x) f22<B extends core.int>() => throw 'uncalled';
+Function(B x) f23<B extends core.int>() => throw 'uncalled';
+
+class U30<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function({List<Function> x}) x0;
+  late List<Function> Function(int x, [Function]) x1;
+  late List<T> Function(int, [int]) x2;
+  late Function(int, [List<T>]) x3;
+  late List<T> Function<A>(A x) x4;
+  late int Function([Function]) Function<B extends core.int>() x5;
+  late int Function({core.List<core.int> x}) Function<B extends core.int>() x6;
+  late Function Function(int y, {int x}) Function<B extends core.int>() x7;
+  late Function Function(int, [core.List<core.int> x])
+      Function<B extends core.int>() x8;
+  late List<Function> Function(int) Function<B extends core.int>() x9;
+  late List<Function> Function(int x, [List<Function>])
+      Function<B extends core.int>() x10;
+  late List<Function> Function(int y, {List<T> x})
+      Function<B extends core.int>() x11;
+  late core.List<core.int> Function([List<Function> x])
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function(List<T>) Function<B extends core.int>() x13;
+  late List<T> Function(int, [Function]) Function<B extends core.int>() x14;
+  late List<T> Function(int, {core.List<core.int> x})
+      Function<B extends core.int>() x15;
+  late Function(Function x) Function<B extends core.int>() x16;
+  late Function(int y, [core.List<core.int> x]) Function<B extends core.int>()
+      x17;
+  late void Function([int]) Function<B extends core.int>() x18;
+  late void Function({List<Function> x}) Function<B extends core.int>() x19;
+  late void Function() Function<B extends core.int>() x20;
+  late core.List<core.int> Function<A>(int x) Function<B extends core.int>()
+      x21;
+  late A Function<A>(Function x) Function<B extends core.int>() x22;
+  late Function(B x) Function<B extends core.int>() x23;
+
+  U30({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0({List<Function> x = const []}) => throw 'uncalled';
+  List<Function> m1(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+  List<T> m2(int x0, [int x1 = -1]) => throw 'uncalled';
+  m3(int x0, [List<T> x1 = const []]) => throw 'uncalled';
+  List<T> m4<A>(A x) => throw 'uncalled';
+  int Function([Function]) m5<B extends core.int>() => throw 'uncalled';
+  int Function({core.List<core.int> x}) m6<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int y, {int x}) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int, [core.List<core.int> x]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int) m9<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(int x, [List<Function>]) m10<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int y, {List<T> x}) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function([List<Function> x]) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(List<T>) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, [Function]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, {core.List<core.int> x}) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function(Function x) m16<B extends core.int>() => throw 'uncalled';
+  Function(int y, [core.List<core.int> x]) m17<B extends core.int>() =>
+      throw 'uncalled';
+  void Function([int]) m18<B extends core.int>() => throw 'uncalled';
+  void Function({List<Function> x}) m19<B extends core.int>() =>
+      throw 'uncalled';
+  void Function() m20<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function<A>(int x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  A Function<A>(Function x) m22<B extends core.int>() => throw 'uncalled';
+  Function(B x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function({List<Function> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function({List<Function> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function({List<Function> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int x, [Function])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [Function]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int x, [Function]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, [int])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [int]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, [int]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int, [List<T>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<T>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int, [List<T>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// List<T> Function<A>(A x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(A x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<T> Function<A>(A x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m4 is F4<int>);
+      Expect.equals(tIsBool, m4 is F4<bool>);
+      Expect.equals(tIsInt, confuse(m4) is F4<int>);
+      Expect.equals(tIsBool, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function([Function]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([Function]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function([Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function({core.List<core.int> x}) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function({core.List<core.int> x}) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function({core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, {int x}) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {int x}) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(int y, {int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [core.List<core.int> x])
+        Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int) Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int x, [List<Function>]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [List<Function>])
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int x, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int y, {List<T> x}) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {List<T> x}) Function<B extends core.int>()
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int y, {List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function([List<Function> x]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<Function> x])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(List<T>) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<T>) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(List<T>)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [Function]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [Function]) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [Function])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {core.List<core.int> x})
+        Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(Function x) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(Function x) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [core.List<core.int> x]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([int]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([int]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function([int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function({List<Function> x}) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function({List<Function> x}) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function({List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function() Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function() Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function() Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(int x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(int x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(int x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(Function x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(Function x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is A Function<A>(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// Function(B x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    Function(B x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is Function(B x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U30().runTests();
+  new U30<int>(tIsInt: true).runTests();
+  new U30<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type31_test.dart b/tests/language/function_type/function_type31_test.dart
new file mode 100644
index 0000000..3426339
--- /dev/null
+++ b/tests/language/function_type/function_type31_test.dart
@@ -0,0 +1,997 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, {List<Function> x});
+typedef F1<T> = List<Function> Function({Function x});
+typedef F2<T> = List<T> Function(int x, [int]);
+typedef F3<T> = Function(int x, [List<T>]);
+typedef F4<T> = List<T> Function<A>(List<A> x);
+typedef F5<T> = int Function([Function]) Function<B extends core.int>(int x);
+typedef F6<T> = int Function({core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int y, {int x}) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function(int, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(int) Function<B extends core.int>(
+    int x);
+typedef F10<T> = List<Function> Function(int x, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F11<T> = List<Function> Function(int y, {List<T> x})
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function([List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function(List<T>)
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(int, [Function]) Function<B extends core.int>(
+    int x);
+typedef F15<T> = List<T> Function(int, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function(Function x) Function<B extends core.int>(int x);
+typedef F17<T> = Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F18<T> = void Function([int]) Function<B extends core.int>(int x);
+typedef F19<T> = void Function({List<Function> x}) Function<B extends core.int>(
+    int x);
+typedef F20<T> = void Function() Function<B extends core.int>(int x);
+typedef F21<T> = core.List<core.int> Function<A>(int x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = A Function<A>(Function x) Function<B extends core.int>(int x);
+typedef F23<T> = Function(B x) Function<B extends core.int>(int x);
+
+int f0(int x0, {List<Function> x = const []}) => throw 'uncalled';
+List<Function> f1({Function x = _voidFunction}) => throw 'uncalled';
+List<int> f2(int x, [int x0 = -1]) => throw 'uncalled';
+f3(int x, [List<int> x0 = const []]) => throw 'uncalled';
+List<int> f4<A>(List<A> x) => throw 'uncalled';
+int Function([Function]) f5<B extends core.int>(int x) => throw 'uncalled';
+int Function({core.List<core.int> x}) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int y, {int x}) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, [core.List<core.int> x]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int) f9<B extends core.int>(int x) => throw 'uncalled';
+List<Function> Function(int x, [List<Function>]) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<Function> Function(int y, {List<int> x}) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([List<Function> x]) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(List<int>) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, [Function]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, {core.List<core.int> x}) f15<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+Function(Function x) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(int y, [core.List<core.int> x]) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function([int]) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function({List<Function> x}) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function() f20<B extends core.int>(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(int x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+A Function<A>(Function x) f22<B extends core.int>(int x) => throw 'uncalled';
+Function(B x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U31<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, {List<Function> x}) x0;
+  late List<Function> Function({Function x}) x1;
+  late List<T> Function(int x, [int]) x2;
+  late Function(int x, [List<T>]) x3;
+  late List<T> Function<A>(List<A> x) x4;
+  late int Function([Function]) Function<B extends core.int>(int x) x5;
+  late int Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+      x6;
+  late Function Function(int y, {int x}) Function<B extends core.int>(int x) x7;
+  late Function Function(int, [core.List<core.int> x])
+      Function<B extends core.int>(int x) x8;
+  late List<Function> Function(int) Function<B extends core.int>(int x) x9;
+  late List<Function> Function(int x, [List<Function>])
+      Function<B extends core.int>(int x) x10;
+  late List<Function> Function(int y, {List<T> x}) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function([List<Function> x])
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function(List<T>) Function<B extends core.int>(int x)
+      x13;
+  late List<T> Function(int, [Function]) Function<B extends core.int>(int x)
+      x14;
+  late List<T> Function(int, {core.List<core.int> x})
+      Function<B extends core.int>(int x) x15;
+  late Function(Function x) Function<B extends core.int>(int x) x16;
+  late Function(int y, [core.List<core.int> x]) Function<B extends core.int>(
+      int x) x17;
+  late void Function([int]) Function<B extends core.int>(int x) x18;
+  late void Function({List<Function> x}) Function<B extends core.int>(int x)
+      x19;
+  late void Function() Function<B extends core.int>(int x) x20;
+  late core.List<core.int> Function<A>(int x) Function<B extends core.int>(
+      int x) x21;
+  late A Function<A>(Function x) Function<B extends core.int>(int x) x22;
+  late Function(B x) Function<B extends core.int>(int x) x23;
+
+  U31({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, {List<Function> x = const []}) => throw 'uncalled';
+  List<Function> m1({Function x = _voidFunction}) => throw 'uncalled';
+  List<T> m2(int x, [int x0 = -1]) => throw 'uncalled';
+  m3(int x, [List<T> x0 = const []]) => throw 'uncalled';
+  List<T> m4<A>(List<A> x) => throw 'uncalled';
+  int Function([Function]) m5<B extends core.int>(int x) => throw 'uncalled';
+  int Function({core.List<core.int> x}) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int y, {int x}) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, [core.List<core.int> x]) m8<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<Function> Function(int) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int x, [List<Function>]) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, {List<T> x}) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([List<Function> x]) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(List<T>) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [Function]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, {core.List<core.int> x}) m15<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  Function(Function x) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(int y, [core.List<core.int> x]) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function([int]) m18<B extends core.int>(int x) => throw 'uncalled';
+  void Function({List<Function> x}) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function() m20<B extends core.int>(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(int x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  A Function<A>(Function x) m22<B extends core.int>(int x) => throw 'uncalled';
+  Function(B x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, {List<Function> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {List<Function> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, {List<Function> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function({Function x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({Function x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function({Function x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int x, [int])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [int]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int x, [int]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int x, [List<T>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [List<T>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int x, [List<T>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// List<T> Function<A>(List<A> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<A> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<T> Function<A>(List<A> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m4 is F4<int>);
+      Expect.equals(tIsBool, m4 is F4<bool>);
+      Expect.equals(tIsInt, confuse(m4) is F4<int>);
+      Expect.equals(tIsBool, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function([Function]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([Function]) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function([Function]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+        l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function({core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, {int x}) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {int x}) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, {int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [core.List<core.int> x])
+        Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int) Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [List<Function>])
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int x, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {List<T> x}) Function<B extends core.int>(
+        int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int y, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function([List<Function> x]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<Function> x])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(List<T>) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<T>) Function<B extends core.int>(int x)
+        l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(List<T>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [Function]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [Function]) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {core.List<core.int> x}) Function<B extends core.int>(
+        int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(Function x) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(Function x) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(Function x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [core.List<core.int> x]) Function<B extends core.int>(int x)
+        l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([int]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([int]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function([int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function({List<Function> x}) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function({List<Function> x}) Function<B extends core.int>(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function({List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function() Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function() Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(int x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(int x) Function<B extends core.int>(int x)
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(int x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(Function x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(Function x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is A Function<A>(Function x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// Function(B x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    Function(B x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is Function(B x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U31().runTests();
+  new U31<int>(tIsInt: true).runTests();
+  new U31<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type32_test.dart b/tests/language/function_type/function_type32_test.dart
new file mode 100644
index 0000000..423bcd1
--- /dev/null
+++ b/tests/language/function_type/function_type32_test.dart
@@ -0,0 +1,872 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int y, {List<Function> x});
+typedef F1<T> = List<Function> Function(int, {Function x});
+typedef F2<T> = List<T> Function({int x});
+typedef F3<T> = Function({List<T> x});
+typedef F4<T> = Function<A>(int x);
+typedef F5<T> = int Function(int, [Function]) Function();
+typedef F6<T> = int Function(int, {core.List<core.int> x}) Function();
+typedef F7<T> = Function Function(Function x) Function();
+typedef F8<T> = Function Function(int y, [core.List<core.int> x]) Function();
+typedef F9<T> = List<Function> Function([int]) Function();
+typedef F10<T> = List<Function> Function({List<Function> x}) Function();
+typedef F11<T> = List<Function> Function() Function();
+typedef F12<T> = core.List<core.int> Function(int, [List<Function> x])
+    Function();
+typedef F13<T> = core.List<core.int> Function([List<T>]) Function();
+typedef F14<T> = List<T> Function(int x, [Function]) Function();
+typedef F15<T> = List<T> Function(int y, {core.List<core.int> x}) Function();
+typedef F16<T> = Function([Function x]) Function();
+typedef F17<T> = Function(core.List<core.int>) Function();
+typedef F18<T> = void Function(int, [int]) Function();
+typedef F19<T> = void Function(int, {List<Function> x}) Function();
+typedef F20<T> = int Function<A>(int x) Function();
+typedef F21<T> = core.List<core.int> Function<A>(Function x) Function();
+typedef F22<T> = A Function<A>(List<Function> x) Function();
+typedef F23<T> = B Function(B x) Function<B extends core.int>();
+
+int f0(int y, {List<Function> x = const []}) => throw 'uncalled';
+List<Function> f1(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+List<int> f2({int x = -1}) => throw 'uncalled';
+f3({List<int> x = const []}) => throw 'uncalled';
+f4<A>(int x) => throw 'uncalled';
+int Function(int, [Function]) f5() => throw 'uncalled';
+int Function(int, {core.List<core.int> x}) f6() => throw 'uncalled';
+Function Function(Function x) f7() => throw 'uncalled';
+Function Function(int y, [core.List<core.int> x]) f8() => throw 'uncalled';
+List<Function> Function([int]) f9() => throw 'uncalled';
+List<Function> Function({List<Function> x}) f10() => throw 'uncalled';
+List<Function> Function() f11() => throw 'uncalled';
+core.List<core.int> Function(int, [List<Function> x]) f12() => throw 'uncalled';
+core.List<core.int> Function([List<int>]) f13() => throw 'uncalled';
+List<int> Function(int x, [Function]) f14() => throw 'uncalled';
+List<int> Function(int y, {core.List<core.int> x}) f15() => throw 'uncalled';
+Function([Function x]) f16() => throw 'uncalled';
+Function(core.List<core.int>) f17() => throw 'uncalled';
+void Function(int, [int]) f18() => throw 'uncalled';
+void Function(int, {List<Function> x}) f19() => throw 'uncalled';
+int Function<A>(int x) f20() => throw 'uncalled';
+core.List<core.int> Function<A>(Function x) f21() => throw 'uncalled';
+A Function<A>(List<Function> x) f22() => throw 'uncalled';
+B Function(B x) f23<B extends core.int>() => throw 'uncalled';
+
+class U32<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int y, {List<Function> x}) x0;
+  late List<Function> Function(int, {Function x}) x1;
+  late List<T> Function({int x}) x2;
+  late Function({List<T> x}) x3;
+  late Function<A>(int x) x4;
+  late int Function(int, [Function]) Function() x5;
+  late int Function(int, {core.List<core.int> x}) Function() x6;
+  late Function Function(Function x) Function() x7;
+  late Function Function(int y, [core.List<core.int> x]) Function() x8;
+  late List<Function> Function([int]) Function() x9;
+  late List<Function> Function({List<Function> x}) Function() x10;
+  late List<Function> Function() Function() x11;
+  late core.List<core.int> Function(int, [List<Function> x]) Function() x12;
+  late core.List<core.int> Function([List<T>]) Function() x13;
+  late List<T> Function(int x, [Function]) Function() x14;
+  late List<T> Function(int y, {core.List<core.int> x}) Function() x15;
+  late Function([Function x]) Function() x16;
+  late Function(core.List<core.int>) Function() x17;
+  late void Function(int, [int]) Function() x18;
+  late void Function(int, {List<Function> x}) Function() x19;
+  late int Function<A>(int x) Function() x20;
+  late core.List<core.int> Function<A>(Function x) Function() x21;
+  late A Function<A>(List<Function> x) Function() x22;
+  late B Function(B x) Function<B extends core.int>() x23;
+
+  U32({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int y, {List<Function> x = const []}) => throw 'uncalled';
+  List<Function> m1(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+  List<T> m2({int x = -1}) => throw 'uncalled';
+  m3({List<T> x = const []}) => throw 'uncalled';
+  m4<A>(int x) => throw 'uncalled';
+  int Function(int, [Function]) m5() => throw 'uncalled';
+  int Function(int, {core.List<core.int> x}) m6() => throw 'uncalled';
+  Function Function(Function x) m7() => throw 'uncalled';
+  Function Function(int y, [core.List<core.int> x]) m8() => throw 'uncalled';
+  List<Function> Function([int]) m9() => throw 'uncalled';
+  List<Function> Function({List<Function> x}) m10() => throw 'uncalled';
+  List<Function> Function() m11() => throw 'uncalled';
+  core.List<core.int> Function(int, [List<Function> x]) m12() =>
+      throw 'uncalled';
+  core.List<core.int> Function([List<T>]) m13() => throw 'uncalled';
+  List<T> Function(int x, [Function]) m14() => throw 'uncalled';
+  List<T> Function(int y, {core.List<core.int> x}) m15() => throw 'uncalled';
+  Function([Function x]) m16() => throw 'uncalled';
+  Function(core.List<core.int>) m17() => throw 'uncalled';
+  void Function(int, [int]) m18() => throw 'uncalled';
+  void Function(int, {List<Function> x}) m19() => throw 'uncalled';
+  int Function<A>(int x) m20() => throw 'uncalled';
+  core.List<core.int> Function<A>(Function x) m21() => throw 'uncalled';
+  A Function<A>(List<Function> x) m22() => throw 'uncalled';
+  B Function(B x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int y, {List<Function> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {List<Function> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int y, {List<Function> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, {Function x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {Function x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, {Function x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function({int x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({int x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function({int x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function({List<T> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function({List<T> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function({List<T> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// Function<A>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function<A>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function<A>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [Function]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [Function]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [Function]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, {core.List<core.int> x}) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {core.List<core.int> x}) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, {core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(Function x) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(Function x) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(Function x) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, [core.List<core.int> x]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [core.List<core.int> x]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int y, [core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([int]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([int]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([int]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function({List<Function> x}) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({List<Function> x}) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function({List<Function> x}) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function() Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function() Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function() Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [List<Function> x]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<Function> x]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, [List<Function> x])
+        Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function([List<T>]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<T>]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function([List<T>]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [Function]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [Function]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int x, [Function]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {core.List<core.int> x}) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {core.List<core.int> x}) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int y, {core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([Function x]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([Function x]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([Function x]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(core.List<core.int>) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(core.List<core.int>) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(core.List<core.int>) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, [int]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [int]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, [int]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, {List<Function> x}) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {List<Function> x}) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(int x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(int x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(int x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(Function x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(Function x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is core.List<core.int> Function<A>(Function x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<Function> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<Function> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(List<Function> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// B Function(B x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(B x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function(B x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U32().runTests();
+  new U32<int>(tIsInt: true).runTests();
+  new U32<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type33_test.dart b/tests/language/function_type/function_type33_test.dart
new file mode 100644
index 0000000..e7c166b
--- /dev/null
+++ b/tests/language/function_type/function_type33_test.dart
@@ -0,0 +1,882 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(core.List<core.int> x);
+typedef F1<T> = List<Function> Function(int y, {Function x});
+typedef F2<T> = List<T> Function(int, {int x});
+typedef F3<T> = Function(int, {List<T> x});
+typedef F4<T> = Function<A>(Function x);
+typedef F5<T> = int Function(int, [Function]) Function(int x);
+typedef F6<T> = int Function(int, {core.List<core.int> x}) Function(int x);
+typedef F7<T> = Function Function(Function x) Function(int x);
+typedef F8<T> = Function Function(int y, [core.List<core.int> x]) Function(
+    int x);
+typedef F9<T> = List<Function> Function([int]) Function(int x);
+typedef F10<T> = List<Function> Function({List<Function> x}) Function(int x);
+typedef F11<T> = List<Function> Function() Function(int x);
+typedef F12<T> = core.List<core.int> Function(int, [List<Function> x]) Function(
+    int x);
+typedef F13<T> = core.List<core.int> Function([List<T>]) Function(int x);
+typedef F14<T> = List<T> Function(int x, [Function]) Function(int x);
+typedef F15<T> = List<T> Function(int y, {core.List<core.int> x}) Function(
+    int x);
+typedef F16<T> = Function([Function x]) Function(int x);
+typedef F17<T> = Function(core.List<core.int>) Function(int x);
+typedef F18<T> = void Function(int, [int]) Function(int x);
+typedef F19<T> = void Function(int, {List<Function> x}) Function(int x);
+typedef F20<T> = int Function<A>(int x) Function(int x);
+typedef F21<T> = core.List<core.int> Function<A>(Function x) Function(int x);
+typedef F22<T> = A Function<A>(List<Function> x) Function(int x);
+typedef F23<T> = B Function(B x) Function<B extends core.int>(int x);
+
+int f0(core.List<core.int> x) => throw 'uncalled';
+List<Function> f1(int y, {Function x = _voidFunction}) => throw 'uncalled';
+List<int> f2(int x0, {int x = -1}) => throw 'uncalled';
+f3(int x0, {List<int> x = const []}) => throw 'uncalled';
+f4<A>(Function x) => throw 'uncalled';
+int Function(int, [Function]) f5(int x) => throw 'uncalled';
+int Function(int, {core.List<core.int> x}) f6(int x) => throw 'uncalled';
+Function Function(Function x) f7(int x) => throw 'uncalled';
+Function Function(int y, [core.List<core.int> x]) f8(int x) => throw 'uncalled';
+List<Function> Function([int]) f9(int x) => throw 'uncalled';
+List<Function> Function({List<Function> x}) f10(int x) => throw 'uncalled';
+List<Function> Function() f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int, [List<Function> x]) f12(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([List<int>]) f13(int x) => throw 'uncalled';
+List<int> Function(int x, [Function]) f14(int x) => throw 'uncalled';
+List<int> Function(int y, {core.List<core.int> x}) f15(int x) =>
+    throw 'uncalled';
+Function([Function x]) f16(int x) => throw 'uncalled';
+Function(core.List<core.int>) f17(int x) => throw 'uncalled';
+void Function(int, [int]) f18(int x) => throw 'uncalled';
+void Function(int, {List<Function> x}) f19(int x) => throw 'uncalled';
+int Function<A>(int x) f20(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(Function x) f21(int x) => throw 'uncalled';
+A Function<A>(List<Function> x) f22(int x) => throw 'uncalled';
+B Function(B x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U33<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(core.List<core.int> x) x0;
+  late List<Function> Function(int y, {Function x}) x1;
+  late List<T> Function(int, {int x}) x2;
+  late Function(int, {List<T> x}) x3;
+  late Function<A>(Function x) x4;
+  late int Function(int, [Function]) Function(int x) x5;
+  late int Function(int, {core.List<core.int> x}) Function(int x) x6;
+  late Function Function(Function x) Function(int x) x7;
+  late Function Function(int y, [core.List<core.int> x]) Function(int x) x8;
+  late List<Function> Function([int]) Function(int x) x9;
+  late List<Function> Function({List<Function> x}) Function(int x) x10;
+  late List<Function> Function() Function(int x) x11;
+  late core.List<core.int> Function(int, [List<Function> x]) Function(int x)
+      x12;
+  late core.List<core.int> Function([List<T>]) Function(int x) x13;
+  late List<T> Function(int x, [Function]) Function(int x) x14;
+  late List<T> Function(int y, {core.List<core.int> x}) Function(int x) x15;
+  late Function([Function x]) Function(int x) x16;
+  late Function(core.List<core.int>) Function(int x) x17;
+  late void Function(int, [int]) Function(int x) x18;
+  late void Function(int, {List<Function> x}) Function(int x) x19;
+  late int Function<A>(int x) Function(int x) x20;
+  late core.List<core.int> Function<A>(Function x) Function(int x) x21;
+  late A Function<A>(List<Function> x) Function(int x) x22;
+  late B Function(B x) Function<B extends core.int>(int x) x23;
+
+  U33({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(core.List<core.int> x) => throw 'uncalled';
+  List<Function> m1(int y, {Function x = _voidFunction}) => throw 'uncalled';
+  List<T> m2(int x0, {int x = -1}) => throw 'uncalled';
+  m3(int x0, {List<T> x = const []}) => throw 'uncalled';
+  m4<A>(Function x) => throw 'uncalled';
+  int Function(int, [Function]) m5(int x) => throw 'uncalled';
+  int Function(int, {core.List<core.int> x}) m6(int x) => throw 'uncalled';
+  Function Function(Function x) m7(int x) => throw 'uncalled';
+  Function Function(int y, [core.List<core.int> x]) m8(int x) =>
+      throw 'uncalled';
+  List<Function> Function([int]) m9(int x) => throw 'uncalled';
+  List<Function> Function({List<Function> x}) m10(int x) => throw 'uncalled';
+  List<Function> Function() m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, [List<Function> x]) m12(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([List<T>]) m13(int x) => throw 'uncalled';
+  List<T> Function(int x, [Function]) m14(int x) => throw 'uncalled';
+  List<T> Function(int y, {core.List<core.int> x}) m15(int x) =>
+      throw 'uncalled';
+  Function([Function x]) m16(int x) => throw 'uncalled';
+  Function(core.List<core.int>) m17(int x) => throw 'uncalled';
+  void Function(int, [int]) m18(int x) => throw 'uncalled';
+  void Function(int, {List<Function> x}) m19(int x) => throw 'uncalled';
+  int Function<A>(int x) m20(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(Function x) m21(int x) => throw 'uncalled';
+  A Function<A>(List<Function> x) m22(int x) => throw 'uncalled';
+  B Function(B x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(core.List<core.int> x)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(core.List<core.int> x) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(core.List<core.int> x));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int y, {Function x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {Function x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int y, {Function x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, {int x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {int x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, {int x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int, {List<T> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int, {List<T> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int, {List<T> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// Function<A>(Function x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function<A>(Function x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function<A>(Function x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [Function]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [Function]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [Function]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, {core.List<core.int> x}) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {core.List<core.int> x}) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int, {core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(Function x) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(Function x) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(Function x) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, [core.List<core.int> x]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [core.List<core.int> x]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, [core.List<core.int> x])
+        Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([int]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([int]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([int]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function({List<Function> x}) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({List<Function> x}) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function({List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function() Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function() Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function() Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [List<Function> x]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<Function> x]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, [List<Function> x])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function([List<T>]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<T>]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function([List<T>]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [Function]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [Function]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int x, [Function]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {core.List<core.int> x}) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {core.List<core.int> x}) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, {core.List<core.int> x})
+        Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([Function x]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([Function x]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([Function x]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(core.List<core.int>) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(core.List<core.int>) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(core.List<core.int>) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, [int]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [int]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, [int]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, {List<Function> x}) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {List<Function> x}) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int, {List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(int x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(int x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(int x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(Function x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(Function x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is core.List<core.int> Function<A>(Function x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<Function> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<Function> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// B Function(B x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(B x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function(B x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U33().runTests();
+  new U33<int>(tIsInt: true).runTests();
+  new U33<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type34_test.dart b/tests/language/function_type/function_type34_test.dart
new file mode 100644
index 0000000..e3643a3
--- /dev/null
+++ b/tests/language/function_type/function_type34_test.dart
@@ -0,0 +1,922 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function([core.List<core.int> x]);
+typedef F1<T> = List<Function> Function(List<Function> x);
+typedef F2<T> = List<T> Function(int y, {int x});
+typedef F3<T> = Function(int y, {List<T> x});
+typedef F4<T> = Function<A>(List<Function> x);
+typedef F5<T> = int Function(int, [Function]) Function<B extends core.int>();
+typedef F6<T> = int Function(int, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F7<T> = Function Function(Function x) Function<B extends core.int>();
+typedef F8<T> = Function Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function([int]) Function<B extends core.int>();
+typedef F10<T> = List<Function> Function({List<Function> x})
+    Function<B extends core.int>();
+typedef F11<T> = List<Function> Function() Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int, [List<Function> x])
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function([List<T>])
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int x, [Function])
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F16<T> = Function([Function x]) Function<B extends core.int>();
+typedef F17<T> = Function(core.List<core.int>) Function<B extends core.int>();
+typedef F18<T> = void Function(int, [int]) Function<B extends core.int>();
+typedef F19<T> = void Function(int, {List<Function> x})
+    Function<B extends core.int>();
+typedef F20<T> = int Function<A>(int x) Function<B extends core.int>();
+typedef F21<T> = core.List<core.int> Function<A>(Function x)
+    Function<B extends core.int>();
+typedef F22<T> = A Function<A>(List<Function> x) Function<B extends core.int>();
+typedef F23<T> = List<B> Function(B x) Function<B extends core.int>();
+
+int f0([core.List<core.int> x = const []]) => throw 'uncalled';
+List<Function> f1(List<Function> x) => throw 'uncalled';
+List<int> f2(int y, {int x = -1}) => throw 'uncalled';
+f3(int y, {List<int> x = const []}) => throw 'uncalled';
+f4<A>(List<Function> x) => throw 'uncalled';
+int Function(int, [Function]) f5<B extends core.int>() => throw 'uncalled';
+int Function(int, {core.List<core.int> x}) f6<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(Function x) f7<B extends core.int>() => throw 'uncalled';
+Function Function(int y, [core.List<core.int> x]) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function([int]) f9<B extends core.int>() => throw 'uncalled';
+List<Function> Function({List<Function> x}) f10<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function() f11<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function(int, [List<Function> x])
+    f12<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function([List<int>]) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int x, [Function]) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int y, {core.List<core.int> x}) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function([Function x]) f16<B extends core.int>() => throw 'uncalled';
+Function(core.List<core.int>) f17<B extends core.int>() => throw 'uncalled';
+void Function(int, [int]) f18<B extends core.int>() => throw 'uncalled';
+void Function(int, {List<Function> x}) f19<B extends core.int>() =>
+    throw 'uncalled';
+int Function<A>(int x) f20<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function<A>(Function x) f21<B extends core.int>() =>
+    throw 'uncalled';
+A Function<A>(List<Function> x) f22<B extends core.int>() => throw 'uncalled';
+List<B> Function(B x) f23<B extends core.int>() => throw 'uncalled';
+
+class U34<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function([core.List<core.int> x]) x0;
+  late List<Function> Function(List<Function> x) x1;
+  late List<T> Function(int y, {int x}) x2;
+  late Function(int y, {List<T> x}) x3;
+  late Function<A>(List<Function> x) x4;
+  late int Function(int, [Function]) Function<B extends core.int>() x5;
+  late int Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+      x6;
+  late Function Function(Function x) Function<B extends core.int>() x7;
+  late Function Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>() x8;
+  late List<Function> Function([int]) Function<B extends core.int>() x9;
+  late List<Function> Function({List<Function> x})
+      Function<B extends core.int>() x10;
+  late List<Function> Function() Function<B extends core.int>() x11;
+  late core.List<core.int> Function(int, [List<Function> x])
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function([List<T>]) Function<B extends core.int>()
+      x13;
+  late List<T> Function(int x, [Function]) Function<B extends core.int>() x14;
+  late List<T> Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>() x15;
+  late Function([Function x]) Function<B extends core.int>() x16;
+  late Function(core.List<core.int>) Function<B extends core.int>() x17;
+  late void Function(int, [int]) Function<B extends core.int>() x18;
+  late void Function(int, {List<Function> x}) Function<B extends core.int>()
+      x19;
+  late int Function<A>(int x) Function<B extends core.int>() x20;
+  late core.List<core.int> Function<A>(Function x)
+      Function<B extends core.int>() x21;
+  late A Function<A>(List<Function> x) Function<B extends core.int>() x22;
+  late List<B> Function(B x) Function<B extends core.int>() x23;
+
+  U34({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0([core.List<core.int> x = const []]) => throw 'uncalled';
+  List<Function> m1(List<Function> x) => throw 'uncalled';
+  List<T> m2(int y, {int x = -1}) => throw 'uncalled';
+  m3(int y, {List<T> x = const []}) => throw 'uncalled';
+  m4<A>(List<Function> x) => throw 'uncalled';
+  int Function(int, [Function]) m5<B extends core.int>() => throw 'uncalled';
+  int Function(int, {core.List<core.int> x}) m6<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(Function x) m7<B extends core.int>() => throw 'uncalled';
+  Function Function(int y, [core.List<core.int> x]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function([int]) m9<B extends core.int>() => throw 'uncalled';
+  List<Function> Function({List<Function> x}) m10<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function() m11<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function(int, [List<Function> x])
+      m12<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function([List<T>]) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int x, [Function]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int y, {core.List<core.int> x}) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function([Function x]) m16<B extends core.int>() => throw 'uncalled';
+  Function(core.List<core.int>) m17<B extends core.int>() => throw 'uncalled';
+  void Function(int, [int]) m18<B extends core.int>() => throw 'uncalled';
+  void Function(int, {List<Function> x}) m19<B extends core.int>() =>
+      throw 'uncalled';
+  int Function<A>(int x) m20<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function<A>(Function x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  A Function<A>(List<Function> x) m22<B extends core.int>() => throw 'uncalled';
+  List<B> Function(B x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function([core.List<core.int> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function([core.List<core.int> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function([core.List<core.int> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(List<Function> x)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<Function> x) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(List<Function> x));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int y, {int x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {int x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int y, {int x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function(int y, {List<T> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {List<T> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int y, {List<T> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// Function<A>(List<Function> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<Function> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function<A>(List<Function> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [Function]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [Function]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int, [Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+        l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(Function x) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(Function x) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([int]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([int]) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function([int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function({List<Function> x}) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({List<Function> x}) Function<B extends core.int>()
+        l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function({List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function() Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function() Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is List<Function> Function() Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [List<Function> x]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<Function> x])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function([List<T>]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<T>]) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function([List<T>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [Function]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [Function]) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int x, [Function])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([Function x]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([Function x]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([Function x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(core.List<core.int>) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(core.List<core.int>) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(core.List<core.int>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, [int]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [int]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int, [int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, {List<Function> x}) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {List<Function> x}) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(int x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(int x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(Function x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(Function x) Function<B extends core.int>()
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(Function x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<Function> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<Function> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is A Function<A>(List<Function> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// List<B> Function(B x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    List<B> Function(B x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is List<B> Function(B x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U34().runTests();
+  new U34<int>(tIsInt: true).runTests();
+  new U34<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type35_test.dart b/tests/language/function_type/function_type35_test.dart
new file mode 100644
index 0000000..313cf3d
--- /dev/null
+++ b/tests/language/function_type/function_type35_test.dart
@@ -0,0 +1,922 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, [core.List<core.int> x]);
+typedef F1<T> = List<Function> Function([List<Function> x]);
+typedef F2<T> = List<T> Function(Function x);
+typedef F3<T> = Function();
+typedef F4<T> = Function<A>(core.List<core.int> x);
+typedef F5<T> = int Function(int, [Function]) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function(int, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(Function x) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function([int]) Function<B extends core.int>(
+    int x);
+typedef F10<T> = List<Function> Function({List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F11<T> = List<Function> Function() Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function([List<T>])
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(int x, [Function])
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function([Function x]) Function<B extends core.int>(int x);
+typedef F17<T> = Function(core.List<core.int>) Function<B extends core.int>(
+    int x);
+typedef F18<T> = void Function(int, [int]) Function<B extends core.int>(int x);
+typedef F19<T> = void Function(int, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F20<T> = int Function<A>(int x) Function<B extends core.int>(int x);
+typedef F21<T> = core.List<core.int> Function<A>(Function x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = A Function<A>(List<Function> x) Function<B extends core.int>(
+    int x);
+typedef F23<T> = List<B> Function(B x) Function<B extends core.int>(int x);
+
+int f0(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
+List<Function> f1([List<Function> x = const []]) => throw 'uncalled';
+List<int> f2(Function x) => throw 'uncalled';
+f3() => throw 'uncalled';
+f4<A>(core.List<core.int> x) => throw 'uncalled';
+int Function(int, [Function]) f5<B extends core.int>(int x) => throw 'uncalled';
+int Function(int, {core.List<core.int> x}) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(Function x) f7<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int y, [core.List<core.int> x]) f8<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<Function> Function([int]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function({List<Function> x}) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function() f11<B extends core.int>(int x) => throw 'uncalled';
+core.List<core.int> Function(int, [List<Function> x]) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([List<int>]) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int x, [Function]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int y, {core.List<core.int> x}) f15<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+Function([Function x]) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(core.List<core.int>) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int, [int]) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(int, {List<Function> x}) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function<A>(int x) f20<B extends core.int>(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(Function x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+A Function<A>(List<Function> x) f22<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<B> Function(B x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U35<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, [core.List<core.int> x]) x0;
+  late List<Function> Function([List<Function> x]) x1;
+  late List<T> Function(Function x) x2;
+  late Function() x3;
+  late Function<A>(core.List<core.int> x) x4;
+  late int Function(int, [Function]) Function<B extends core.int>(int x) x5;
+  late int Function(int, {core.List<core.int> x}) Function<B extends core.int>(
+      int x) x6;
+  late Function Function(Function x) Function<B extends core.int>(int x) x7;
+  late Function Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>(int x) x8;
+  late List<Function> Function([int]) Function<B extends core.int>(int x) x9;
+  late List<Function> Function({List<Function> x}) Function<B extends core.int>(
+      int x) x10;
+  late List<Function> Function() Function<B extends core.int>(int x) x11;
+  late core.List<core.int> Function(int, [List<Function> x])
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function([List<T>]) Function<B extends core.int>(
+      int x) x13;
+  late List<T> Function(int x, [Function]) Function<B extends core.int>(int x)
+      x14;
+  late List<T> Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>(int x) x15;
+  late Function([Function x]) Function<B extends core.int>(int x) x16;
+  late Function(core.List<core.int>) Function<B extends core.int>(int x) x17;
+  late void Function(int, [int]) Function<B extends core.int>(int x) x18;
+  late void Function(int, {List<Function> x}) Function<B extends core.int>(
+      int x) x19;
+  late int Function<A>(int x) Function<B extends core.int>(int x) x20;
+  late core.List<core.int> Function<A>(Function x) Function<B extends core.int>(
+      int x) x21;
+  late A Function<A>(List<Function> x) Function<B extends core.int>(int x) x22;
+  late List<B> Function(B x) Function<B extends core.int>(int x) x23;
+
+  U35({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
+  List<Function> m1([List<Function> x = const []]) => throw 'uncalled';
+  List<T> m2(Function x) => throw 'uncalled';
+  m3() => throw 'uncalled';
+  m4<A>(core.List<core.int> x) => throw 'uncalled';
+  int Function(int, [Function]) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int, {core.List<core.int> x}) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(Function x) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int y, [core.List<core.int> x]) m8<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<Function> Function([int]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function({List<Function> x}) m10<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function() m11<B extends core.int>(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, [List<Function> x]) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([List<T>]) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int x, [Function]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, {core.List<core.int> x}) m15<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  Function([Function x]) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(core.List<core.int>) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int, [int]) m18<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int, {List<Function> x}) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function<A>(int x) m20<B extends core.int>(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(Function x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  A Function<A>(List<Function> x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<B> Function(B x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, [core.List<core.int> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [core.List<core.int> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function([List<Function> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<Function> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function([List<Function> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(Function x)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(Function x) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(Function x));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// Function()
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function() l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function());
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function<A>(core.List<core.int> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function<A>(core.List<core.int> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function<A>(core.List<core.int> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [Function]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [Function]) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {core.List<core.int> x}) Function<B extends core.int>(
+        int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(Function x) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(Function x) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(Function x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([int]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([int]) Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([int])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function({List<Function> x}) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({List<Function> x}) Function<B extends core.int>(
+        int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function({List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function() Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function() Function<B extends core.int>(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is List<Function> Function() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<Function> x])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function([List<T>]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<T>]) Function<B extends core.int>(int x)
+        l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function([List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [Function]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [Function]) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int x, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([Function x]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([Function x]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function([Function x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(core.List<core.int>) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(core.List<core.int>) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(core.List<core.int>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, [int]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [int]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int, [int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(int x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(int x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is int Function<A>(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(Function x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(Function x) Function<B extends core.int>(
+        int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(Function x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<Function> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<Function> x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// List<B> Function(B x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    List<B> Function(B x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is List<B> Function(B x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U35().runTests();
+  new U35<int>(tIsInt: true).runTests();
+  new U35<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type36_test.dart b/tests/language/function_type/function_type36_test.dart
new file mode 100644
index 0000000..ff2124d
--- /dev/null
+++ b/tests/language/function_type/function_type36_test.dart
@@ -0,0 +1,873 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int y, [core.List<core.int> x]);
+typedef F1<T> = List<Function> Function(int, [List<Function> x]);
+typedef F2<T> = List<T> Function([Function x]);
+typedef F3<T> = void Function(int x);
+typedef F4<T> = Function<A>(List<T> x);
+typedef F5<T> = int Function(int x, [Function]) Function();
+typedef F6<T> = int Function(int y, {core.List<core.int> x}) Function();
+typedef F7<T> = Function Function([Function x]) Function();
+typedef F8<T> = Function Function(core.List<core.int>) Function();
+typedef F9<T> = List<Function> Function(int, [int]) Function();
+typedef F10<T> = List<Function> Function(int, {List<Function> x}) Function();
+typedef F11<T> = core.List<core.int> Function(int x) Function();
+typedef F12<T> = core.List<core.int> Function(int y, [List<Function> x])
+    Function();
+typedef F13<T> = core.List<core.int> Function(int, [List<T>]) Function();
+typedef F14<T> = List<T> Function({Function x}) Function();
+typedef F15<T> = List<T> Function(List<T> x) Function();
+typedef F16<T> = Function(int, [Function x]) Function();
+typedef F17<T> = Function([core.List<core.int>]) Function();
+typedef F18<T> = void Function(int x, [int]) Function();
+typedef F19<T> = void Function(int y, {List<Function> x}) Function();
+typedef F20<T> = int Function<A>(Function x) Function();
+typedef F21<T> = core.List<core.int> Function<A>(List<Function> x) Function();
+typedef F22<T> = A Function<A>(core.List<core.int> x) Function();
+typedef F23<T> = void Function(B x) Function<B extends core.int>();
+
+int f0(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
+List<Function> f1(int x0, [List<Function> x = const []]) => throw 'uncalled';
+List<int> f2([Function x = _voidFunction]) => throw 'uncalled';
+void f3(int x) => throw 'uncalled';
+f4<A>(List<int> x) => throw 'uncalled';
+int Function(int x, [Function]) f5() => throw 'uncalled';
+int Function(int y, {core.List<core.int> x}) f6() => throw 'uncalled';
+Function Function([Function x]) f7() => throw 'uncalled';
+Function Function(core.List<core.int>) f8() => throw 'uncalled';
+List<Function> Function(int, [int]) f9() => throw 'uncalled';
+List<Function> Function(int, {List<Function> x}) f10() => throw 'uncalled';
+core.List<core.int> Function(int x) f11() => throw 'uncalled';
+core.List<core.int> Function(int y, [List<Function> x]) f12() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [List<int>]) f13() => throw 'uncalled';
+List<int> Function({Function x}) f14() => throw 'uncalled';
+List<int> Function(List<int> x) f15() => throw 'uncalled';
+Function(int, [Function x]) f16() => throw 'uncalled';
+Function([core.List<core.int>]) f17() => throw 'uncalled';
+void Function(int x, [int]) f18() => throw 'uncalled';
+void Function(int y, {List<Function> x}) f19() => throw 'uncalled';
+int Function<A>(Function x) f20() => throw 'uncalled';
+core.List<core.int> Function<A>(List<Function> x) f21() => throw 'uncalled';
+A Function<A>(core.List<core.int> x) f22() => throw 'uncalled';
+void Function(B x) f23<B extends core.int>() => throw 'uncalled';
+
+class U36<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int y, [core.List<core.int> x]) x0;
+  late List<Function> Function(int, [List<Function> x]) x1;
+  late List<T> Function([Function x]) x2;
+  late void Function(int x) x3;
+  late Function<A>(List<T> x) x4;
+  late int Function(int x, [Function]) Function() x5;
+  late int Function(int y, {core.List<core.int> x}) Function() x6;
+  late Function Function([Function x]) Function() x7;
+  late Function Function(core.List<core.int>) Function() x8;
+  late List<Function> Function(int, [int]) Function() x9;
+  late List<Function> Function(int, {List<Function> x}) Function() x10;
+  late core.List<core.int> Function(int x) Function() x11;
+  late core.List<core.int> Function(int y, [List<Function> x]) Function() x12;
+  late core.List<core.int> Function(int, [List<T>]) Function() x13;
+  late List<T> Function({Function x}) Function() x14;
+  late List<T> Function(List<T> x) Function() x15;
+  late Function(int, [Function x]) Function() x16;
+  late Function([core.List<core.int>]) Function() x17;
+  late void Function(int x, [int]) Function() x18;
+  late void Function(int y, {List<Function> x}) Function() x19;
+  late int Function<A>(Function x) Function() x20;
+  late core.List<core.int> Function<A>(List<Function> x) Function() x21;
+  late A Function<A>(core.List<core.int> x) Function() x22;
+  late void Function(B x) Function<B extends core.int>() x23;
+
+  U36({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
+  List<Function> m1(int x0, [List<Function> x = const []]) => throw 'uncalled';
+  List<T> m2([Function x = _voidFunction]) => throw 'uncalled';
+  void m3(int x) => throw 'uncalled';
+  m4<A>(List<T> x) => throw 'uncalled';
+  int Function(int x, [Function]) m5() => throw 'uncalled';
+  int Function(int y, {core.List<core.int> x}) m6() => throw 'uncalled';
+  Function Function([Function x]) m7() => throw 'uncalled';
+  Function Function(core.List<core.int>) m8() => throw 'uncalled';
+  List<Function> Function(int, [int]) m9() => throw 'uncalled';
+  List<Function> Function(int, {List<Function> x}) m10() => throw 'uncalled';
+  core.List<core.int> Function(int x) m11() => throw 'uncalled';
+  core.List<core.int> Function(int y, [List<Function> x]) m12() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [List<T>]) m13() => throw 'uncalled';
+  List<T> Function({Function x}) m14() => throw 'uncalled';
+  List<T> Function(List<T> x) m15() => throw 'uncalled';
+  Function(int, [Function x]) m16() => throw 'uncalled';
+  Function([core.List<core.int>]) m17() => throw 'uncalled';
+  void Function(int x, [int]) m18() => throw 'uncalled';
+  void Function(int y, {List<Function> x}) m19() => throw 'uncalled';
+  int Function<A>(Function x) m20() => throw 'uncalled';
+  core.List<core.int> Function<A>(List<Function> x) m21() => throw 'uncalled';
+  A Function<A>(core.List<core.int> x) m22() => throw 'uncalled';
+  void Function(B x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int y, [core.List<core.int> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [core.List<core.int> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int y, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, [List<Function> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<Function> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, [List<Function> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function([Function x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([Function x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function([Function x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function<A>(List<T> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<T> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function<A>(List<T> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m4 is F4<int>);
+      Expect.equals(true, m4 is F4<bool>);
+      Expect.equals(true, confuse(m4) is F4<int>);
+      Expect.equals(true, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function(int x, [Function]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [Function]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int x, [Function]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, {core.List<core.int> x}) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {core.List<core.int> x}) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int y, {core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([Function x]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([Function x]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([Function x]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(core.List<core.int>) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(core.List<core.int>) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(core.List<core.int>) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, [int]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [int]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [int]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, {List<Function> x}) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {List<Function> x}) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(int, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int x) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int x) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, [List<Function> x]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [List<Function> x]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, [List<Function> x])
+        Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, [List<T>]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<T>]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(int, [List<T>]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function({Function x}) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({Function x}) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function({Function x}) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(List<T> x) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<T> x) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(List<T> x) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [Function x]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [Function x]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [Function x]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([core.List<core.int>]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([core.List<core.int>]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int x, [int]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [int]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int x, [int]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, {List<Function> x}) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {List<Function> x}) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(Function x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(Function x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(Function x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<Function> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<Function> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is core.List<core.int> Function<A>(List<Function> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(core.List<core.int> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(core.List<core.int> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function(B x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function(B x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function(B x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U36().runTests();
+  new U36<int>(tIsInt: true).runTests();
+  new U36<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type37_test.dart b/tests/language/function_type/function_type37_test.dart
new file mode 100644
index 0000000..343bdca
--- /dev/null
+++ b/tests/language/function_type/function_type37_test.dart
@@ -0,0 +1,856 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(core.List<core.int>);
+typedef F1<T> = List<Function> Function(int y, [List<Function> x]);
+typedef F2<T> = List<T> Function(int, [Function x]);
+typedef F3<T> = void Function([int x]);
+typedef F4<T> = Function<A>();
+typedef F5<T> = int Function(int x, [Function]) Function(int x);
+typedef F6<T> = int Function(int y, {core.List<core.int> x}) Function(int x);
+typedef F7<T> = Function Function([Function x]) Function(int x);
+typedef F8<T> = Function Function(core.List<core.int>) Function(int x);
+typedef F9<T> = List<Function> Function(int, [int]) Function(int x);
+typedef F10<T> = List<Function> Function(int, {List<Function> x}) Function(
+    int x);
+typedef F11<T> = core.List<core.int> Function(int x) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int y, [List<Function> x])
+    Function(int x);
+typedef F13<T> = core.List<core.int> Function(int, [List<T>]) Function(int x);
+typedef F14<T> = List<T> Function({Function x}) Function(int x);
+typedef F15<T> = List<T> Function(List<T> x) Function(int x);
+typedef F16<T> = Function(int, [Function x]) Function(int x);
+typedef F17<T> = Function([core.List<core.int>]) Function(int x);
+typedef F18<T> = void Function(int x, [int]) Function(int x);
+typedef F19<T> = void Function(int y, {List<Function> x}) Function(int x);
+typedef F20<T> = int Function<A>(Function x) Function(int x);
+typedef F21<T> = core.List<core.int> Function<A>(List<Function> x) Function(
+    int x);
+typedef F22<T> = A Function<A>(core.List<core.int> x) Function(int x);
+typedef F23<T> = void Function(B x) Function<B extends core.int>(int x);
+
+int f0(core.List<core.int> x0) => throw 'uncalled';
+List<Function> f1(int y, [List<Function> x = const []]) => throw 'uncalled';
+List<int> f2(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+void f3([int x = -1]) => throw 'uncalled';
+f4<A>() => throw 'uncalled';
+int Function(int x, [Function]) f5(int x) => throw 'uncalled';
+int Function(int y, {core.List<core.int> x}) f6(int x) => throw 'uncalled';
+Function Function([Function x]) f7(int x) => throw 'uncalled';
+Function Function(core.List<core.int>) f8(int x) => throw 'uncalled';
+List<Function> Function(int, [int]) f9(int x) => throw 'uncalled';
+List<Function> Function(int, {List<Function> x}) f10(int x) => throw 'uncalled';
+core.List<core.int> Function(int x) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int y, [List<Function> x]) f12(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [List<int>]) f13(int x) => throw 'uncalled';
+List<int> Function({Function x}) f14(int x) => throw 'uncalled';
+List<int> Function(List<int> x) f15(int x) => throw 'uncalled';
+Function(int, [Function x]) f16(int x) => throw 'uncalled';
+Function([core.List<core.int>]) f17(int x) => throw 'uncalled';
+void Function(int x, [int]) f18(int x) => throw 'uncalled';
+void Function(int y, {List<Function> x}) f19(int x) => throw 'uncalled';
+int Function<A>(Function x) f20(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(List<Function> x) f21(int x) =>
+    throw 'uncalled';
+A Function<A>(core.List<core.int> x) f22(int x) => throw 'uncalled';
+void Function(B x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U37<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(core.List<core.int>) x0;
+  late List<Function> Function(int y, [List<Function> x]) x1;
+  late List<T> Function(int, [Function x]) x2;
+  late void Function([int x]) x3;
+  late Function<A>() x4;
+  late int Function(int x, [Function]) Function(int x) x5;
+  late int Function(int y, {core.List<core.int> x}) Function(int x) x6;
+  late Function Function([Function x]) Function(int x) x7;
+  late Function Function(core.List<core.int>) Function(int x) x8;
+  late List<Function> Function(int, [int]) Function(int x) x9;
+  late List<Function> Function(int, {List<Function> x}) Function(int x) x10;
+  late core.List<core.int> Function(int x) Function(int x) x11;
+  late core.List<core.int> Function(int y, [List<Function> x]) Function(int x)
+      x12;
+  late core.List<core.int> Function(int, [List<T>]) Function(int x) x13;
+  late List<T> Function({Function x}) Function(int x) x14;
+  late List<T> Function(List<T> x) Function(int x) x15;
+  late Function(int, [Function x]) Function(int x) x16;
+  late Function([core.List<core.int>]) Function(int x) x17;
+  late void Function(int x, [int]) Function(int x) x18;
+  late void Function(int y, {List<Function> x}) Function(int x) x19;
+  late int Function<A>(Function x) Function(int x) x20;
+  late core.List<core.int> Function<A>(List<Function> x) Function(int x) x21;
+  late A Function<A>(core.List<core.int> x) Function(int x) x22;
+  late void Function(B x) Function<B extends core.int>(int x) x23;
+
+  U37({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(core.List<core.int> x0) => throw 'uncalled';
+  List<Function> m1(int y, [List<Function> x = const []]) => throw 'uncalled';
+  List<T> m2(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+  void m3([int x = -1]) => throw 'uncalled';
+  m4<A>() => throw 'uncalled';
+  int Function(int x, [Function]) m5(int x) => throw 'uncalled';
+  int Function(int y, {core.List<core.int> x}) m6(int x) => throw 'uncalled';
+  Function Function([Function x]) m7(int x) => throw 'uncalled';
+  Function Function(core.List<core.int>) m8(int x) => throw 'uncalled';
+  List<Function> Function(int, [int]) m9(int x) => throw 'uncalled';
+  List<Function> Function(int, {List<Function> x}) m10(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int y, [List<Function> x]) m12(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [List<T>]) m13(int x) => throw 'uncalled';
+  List<T> Function({Function x}) m14(int x) => throw 'uncalled';
+  List<T> Function(List<T> x) m15(int x) => throw 'uncalled';
+  Function(int, [Function x]) m16(int x) => throw 'uncalled';
+  Function([core.List<core.int>]) m17(int x) => throw 'uncalled';
+  void Function(int x, [int]) m18(int x) => throw 'uncalled';
+  void Function(int y, {List<Function> x}) m19(int x) => throw 'uncalled';
+  int Function<A>(Function x) m20(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(List<Function> x) m21(int x) =>
+      throw 'uncalled';
+  A Function<A>(core.List<core.int> x) m22(int x) => throw 'uncalled';
+  void Function(B x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(core.List<core.int>)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(core.List<core.int>) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(core.List<core.int>));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int y, [List<Function> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [List<Function> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int y, [List<Function> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, [Function x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [Function x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, [Function x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function([int x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function([int x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function([int x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function<A>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function<A>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function<A>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int x, [Function]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [Function]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int x, [Function]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, {core.List<core.int> x}) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {core.List<core.int> x}) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int y, {core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([Function x]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([Function x]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([Function x]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(core.List<core.int>) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(core.List<core.int>) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(core.List<core.int>) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, [int]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [int]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [int]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, {List<Function> x}) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {List<Function> x}) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, {List<Function> x})
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int x) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int x) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, [List<Function> x]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [List<Function> x]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, [List<Function> x])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, [List<T>]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<T>]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(int, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function({Function x}) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({Function x}) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function({Function x}) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(List<T> x) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<T> x) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [Function x]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [Function x]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([core.List<core.int>]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([core.List<core.int>]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int x, [int]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [int]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int x, [int]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, {List<Function> x}) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {List<Function> x}) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int y, {List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(Function x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(Function x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(Function x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<Function> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<Function> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(List<Function> x)
+        Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(core.List<core.int> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(core.List<core.int> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function(B x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function(B x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is void Function(B x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U37().runTests();
+  new U37<int>(tIsInt: true).runTests();
+  new U37<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type38_test.dart b/tests/language/function_type/function_type38_test.dart
new file mode 100644
index 0000000..e6a102d
--- /dev/null
+++ b/tests/language/function_type/function_type38_test.dart
@@ -0,0 +1,899 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function([core.List<core.int>]);
+typedef F1<T> = List<Function> Function(List<Function>);
+typedef F2<T> = List<T> Function(int y, [Function x]);
+typedef F3<T> = void Function(int, [int x]);
+typedef F4<T> = Function<A>(A x);
+typedef F5<T> = int Function(int x, [Function]) Function<B extends core.int>();
+typedef F6<T> = int Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F7<T> = Function Function([Function x]) Function<B extends core.int>();
+typedef F8<T> = Function Function(core.List<core.int>)
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int, [int])
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int, {List<Function> x})
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(int x)
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int y, [List<Function> x])
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function(int, [List<T>])
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function({Function x}) Function<B extends core.int>();
+typedef F15<T> = List<T> Function(List<T> x) Function<B extends core.int>();
+typedef F16<T> = Function(int, [Function x]) Function<B extends core.int>();
+typedef F17<T> = Function([core.List<core.int>]) Function<B extends core.int>();
+typedef F18<T> = void Function(int x, [int]) Function<B extends core.int>();
+typedef F19<T> = void Function(int y, {List<Function> x})
+    Function<B extends core.int>();
+typedef F20<T> = int Function<A>(Function x) Function<B extends core.int>();
+typedef F21<T> = core.List<core.int> Function<A>(List<Function> x)
+    Function<B extends core.int>();
+typedef F22<T> = A Function<A>(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F23<T> = B Function(int x) Function<B extends core.int>();
+
+int f0([core.List<core.int> x0 = const []]) => throw 'uncalled';
+List<Function> f1(List<Function> x0) => throw 'uncalled';
+List<int> f2(int y, [Function x = _voidFunction]) => throw 'uncalled';
+void f3(int x0, [int x = -1]) => throw 'uncalled';
+f4<A>(A x) => throw 'uncalled';
+int Function(int x, [Function]) f5<B extends core.int>() => throw 'uncalled';
+int Function(int y, {core.List<core.int> x}) f6<B extends core.int>() =>
+    throw 'uncalled';
+Function Function([Function x]) f7<B extends core.int>() => throw 'uncalled';
+Function Function(core.List<core.int>) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, [int]) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, {List<Function> x}) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int x) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, [List<Function> x])
+    f12<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function(int, [List<int>]) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function({Function x}) f14<B extends core.int>() => throw 'uncalled';
+List<int> Function(List<int> x) f15<B extends core.int>() => throw 'uncalled';
+Function(int, [Function x]) f16<B extends core.int>() => throw 'uncalled';
+Function([core.List<core.int>]) f17<B extends core.int>() => throw 'uncalled';
+void Function(int x, [int]) f18<B extends core.int>() => throw 'uncalled';
+void Function(int y, {List<Function> x}) f19<B extends core.int>() =>
+    throw 'uncalled';
+int Function<A>(Function x) f20<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function<A>(List<Function> x) f21<B extends core.int>() =>
+    throw 'uncalled';
+A Function<A>(core.List<core.int> x) f22<B extends core.int>() =>
+    throw 'uncalled';
+B Function(int x) f23<B extends core.int>() => throw 'uncalled';
+
+class U38<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function([core.List<core.int>]) x0;
+  late List<Function> Function(List<Function>) x1;
+  late List<T> Function(int y, [Function x]) x2;
+  late void Function(int, [int x]) x3;
+  late Function<A>(A x) x4;
+  late int Function(int x, [Function]) Function<B extends core.int>() x5;
+  late int Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>() x6;
+  late Function Function([Function x]) Function<B extends core.int>() x7;
+  late Function Function(core.List<core.int>) Function<B extends core.int>() x8;
+  late List<Function> Function(int, [int]) Function<B extends core.int>() x9;
+  late List<Function> Function(int, {List<Function> x})
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function(int x) Function<B extends core.int>() x11;
+  late core.List<core.int> Function(int y, [List<Function> x])
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function(int, [List<T>])
+      Function<B extends core.int>() x13;
+  late List<T> Function({Function x}) Function<B extends core.int>() x14;
+  late List<T> Function(List<T> x) Function<B extends core.int>() x15;
+  late Function(int, [Function x]) Function<B extends core.int>() x16;
+  late Function([core.List<core.int>]) Function<B extends core.int>() x17;
+  late void Function(int x, [int]) Function<B extends core.int>() x18;
+  late void Function(int y, {List<Function> x}) Function<B extends core.int>()
+      x19;
+  late int Function<A>(Function x) Function<B extends core.int>() x20;
+  late core.List<core.int> Function<A>(List<Function> x)
+      Function<B extends core.int>() x21;
+  late A Function<A>(core.List<core.int> x) Function<B extends core.int>() x22;
+  late B Function(int x) Function<B extends core.int>() x23;
+
+  U38({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0([core.List<core.int> x0 = const []]) => throw 'uncalled';
+  List<Function> m1(List<Function> x0) => throw 'uncalled';
+  List<T> m2(int y, [Function x = _voidFunction]) => throw 'uncalled';
+  void m3(int x0, [int x = -1]) => throw 'uncalled';
+  m4<A>(A x) => throw 'uncalled';
+  int Function(int x, [Function]) m5<B extends core.int>() => throw 'uncalled';
+  int Function(int y, {core.List<core.int> x}) m6<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function([Function x]) m7<B extends core.int>() => throw 'uncalled';
+  Function Function(core.List<core.int>) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, [int]) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, {List<Function> x}) m10<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [List<Function> x])
+      m12<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function(int, [List<T>]) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function({Function x}) m14<B extends core.int>() => throw 'uncalled';
+  List<T> Function(List<T> x) m15<B extends core.int>() => throw 'uncalled';
+  Function(int, [Function x]) m16<B extends core.int>() => throw 'uncalled';
+  Function([core.List<core.int>]) m17<B extends core.int>() => throw 'uncalled';
+  void Function(int x, [int]) m18<B extends core.int>() => throw 'uncalled';
+  void Function(int y, {List<Function> x}) m19<B extends core.int>() =>
+      throw 'uncalled';
+  int Function<A>(Function x) m20<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function<A>(List<Function> x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  A Function<A>(core.List<core.int> x) m22<B extends core.int>() =>
+      throw 'uncalled';
+  B Function(int x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function([core.List<core.int>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function([core.List<core.int>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function([core.List<core.int>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(List<Function>)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<Function>) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(List<Function>));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int y, [Function x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [Function x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int y, [Function x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, [int x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [int x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, [int x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function<A>(A x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function<A>(A x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function<A>(A x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int x, [Function]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [Function]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int x, [Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {core.List<core.int> x}) Function<B extends core.int>()
+        l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([Function x]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([Function x]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function([Function x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(core.List<core.int>) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(core.List<core.int>) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(core.List<core.int>)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, [int]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [int]) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [int])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, {List<Function> x}) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {List<Function> x})
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int x) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, [List<Function> x]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [List<Function> x])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, [List<T>]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<T>]) Function<B extends core.int>()
+        l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int, [List<T>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function({Function x}) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({Function x}) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function({Function x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(List<T> x) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<T> x) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [Function x]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [Function x]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int, [Function x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([core.List<core.int>]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([core.List<core.int>]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function([core.List<core.int>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int x, [int]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [int]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int x, [int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, {List<Function> x}) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {List<Function> x}) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(Function x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(Function x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is int Function<A>(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<Function> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<Function> x)
+        Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(core.List<core.int> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(core.List<core.int> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// B Function(int x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(int x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U38().runTests();
+  new U38<int>(tIsInt: true).runTests();
+  new U38<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type39_test.dart b/tests/language/function_type/function_type39_test.dart
new file mode 100644
index 0000000..fefb0cf
--- /dev/null
+++ b/tests/language/function_type/function_type39_test.dart
@@ -0,0 +1,932 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, [core.List<core.int>]);
+typedef F1<T> = List<Function> Function([List<Function>]);
+typedef F2<T> = List<T> Function(Function);
+typedef F3<T> = void Function(int y, [int x]);
+typedef F4<T> = Function<A>(List<A> x);
+typedef F5<T> = int Function(int x, [Function]) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F7<T> = Function Function([Function x]) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function(core.List<core.int>)
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(int, [int])
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(int, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(int x)
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int y, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function(int, [List<T>])
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function({Function x}) Function<B extends core.int>(
+    int x);
+typedef F15<T> = List<T> Function(List<T> x) Function<B extends core.int>(
+    int x);
+typedef F16<T> = Function(int, [Function x]) Function<B extends core.int>(
+    int x);
+typedef F17<T> = Function([core.List<core.int>]) Function<B extends core.int>(
+    int x);
+typedef F18<T> = void Function(int x, [int]) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function(int y, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F20<T> = int Function<A>(Function x) Function<B extends core.int>(
+    int x);
+typedef F21<T> = core.List<core.int> Function<A>(List<Function> x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = A Function<A>(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F23<T> = B Function(int x) Function<B extends core.int>(int x);
+
+int f0(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
+List<Function> f1([List<Function> x0 = const []]) => throw 'uncalled';
+List<int> f2(Function x0) => throw 'uncalled';
+void f3(int y, [int x = -1]) => throw 'uncalled';
+f4<A>(List<A> x) => throw 'uncalled';
+int Function(int x, [Function]) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function(int y, {core.List<core.int> x}) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function([Function x]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(core.List<core.int>) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, [int]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, {List<Function> x}) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int x) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, [List<Function> x]) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [List<int>]) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function({Function x}) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(List<int> x) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int, [Function x]) f16<B extends core.int>(int x) => throw 'uncalled';
+Function([core.List<core.int>]) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int x, [int]) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(int y, {List<Function> x}) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function<A>(Function x) f20<B extends core.int>(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(List<Function> x) f21<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+A Function<A>(core.List<core.int> x) f22<B extends core.int>(int x) =>
+    throw 'uncalled';
+B Function(int x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U39<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, [core.List<core.int>]) x0;
+  late List<Function> Function([List<Function>]) x1;
+  late List<T> Function(Function) x2;
+  late void Function(int y, [int x]) x3;
+  late Function<A>(List<A> x) x4;
+  late int Function(int x, [Function]) Function<B extends core.int>(int x) x5;
+  late int Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>(int x) x6;
+  late Function Function([Function x]) Function<B extends core.int>(int x) x7;
+  late Function Function(core.List<core.int>) Function<B extends core.int>(
+      int x) x8;
+  late List<Function> Function(int, [int]) Function<B extends core.int>(int x)
+      x9;
+  late List<Function> Function(int, {List<Function> x})
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function(int x) Function<B extends core.int>(int x)
+      x11;
+  late core.List<core.int> Function(int y, [List<Function> x])
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function(int, [List<T>])
+      Function<B extends core.int>(int x) x13;
+  late List<T> Function({Function x}) Function<B extends core.int>(int x) x14;
+  late List<T> Function(List<T> x) Function<B extends core.int>(int x) x15;
+  late Function(int, [Function x]) Function<B extends core.int>(int x) x16;
+  late Function([core.List<core.int>]) Function<B extends core.int>(int x) x17;
+  late void Function(int x, [int]) Function<B extends core.int>(int x) x18;
+  late void Function(int y, {List<Function> x}) Function<B extends core.int>(
+      int x) x19;
+  late int Function<A>(Function x) Function<B extends core.int>(int x) x20;
+  late core.List<core.int> Function<A>(List<Function> x)
+      Function<B extends core.int>(int x) x21;
+  late A Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+      x22;
+  late B Function(int x) Function<B extends core.int>(int x) x23;
+
+  U39({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
+  List<Function> m1([List<Function> x0 = const []]) => throw 'uncalled';
+  List<T> m2(Function x0) => throw 'uncalled';
+  void m3(int y, [int x = -1]) => throw 'uncalled';
+  m4<A>(List<A> x) => throw 'uncalled';
+  int Function(int x, [Function]) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int y, {core.List<core.int> x}) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function([Function x]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(core.List<core.int>) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, [int]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, {List<Function> x}) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [List<Function> x])
+      m12<B extends core.int>(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, [List<T>]) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function({Function x}) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(List<T> x) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int, [Function x]) m16<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function([core.List<core.int>]) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int x, [int]) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int y, {List<Function> x}) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function<A>(Function x) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function<A>(List<Function> x) m21<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  A Function<A>(core.List<core.int> x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+  B Function(int x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, [core.List<core.int>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [core.List<core.int>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, [core.List<core.int>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function([List<Function>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<Function>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function([List<Function>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(Function)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(Function) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(Function));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int y, [int x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [int x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int y, [int x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function<A>(List<A> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<A> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function<A>(List<A> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int x, [Function]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [Function]) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int x, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {core.List<core.int> x}) Function<B extends core.int>(
+        int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([Function x]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([Function x]) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(core.List<core.int>) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(core.List<core.int>) Function<B extends core.int>(int x)
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(core.List<core.int>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, [int]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [int]) Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [int])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {List<Function> x})
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int x) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x) Function<B extends core.int>(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [List<Function> x])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, [List<T>]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<T>]) Function<B extends core.int>(
+        int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function({Function x}) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({Function x}) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function({Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(List<T> x) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<T> x) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(List<T> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [Function x]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [Function x]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int, [Function x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([core.List<core.int>]) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int x, [int]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [int]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int x, [int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {List<Function> x}) Function<B extends core.int>(int x)
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(Function x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(Function x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is int Function<A>(Function x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<Function> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<Function> x)
+        Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+        l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// B Function(int x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(int x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U39().runTests();
+  new U39<int>(tIsInt: true).runTests();
+  new U39<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type3_test.dart b/tests/language/function_type/function_type3_test.dart
new file mode 100644
index 0000000..23c5873
--- /dev/null
+++ b/tests/language/function_type/function_type3_test.dart
@@ -0,0 +1,1009 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int y, [int x]);
+typedef F1<T> = Function Function(int y, [List<T> x]);
+typedef F2<T> = core.List<core.int> Function(int, [core.List<core.int> x]);
+typedef F3<T> = Function([List<Function> x]);
+typedef F4<T> = Function Function<A>(core.List<core.int> x);
+typedef F5<T> = int Function(int, {int x}) Function<B extends core.int>(int x);
+typedef F6<T> = int Function([core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int y, [int x]) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function(int, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F9<T> = Function Function(int, {List<T> x})
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(List<Function> x)
+    Function<B extends core.int>(int x);
+typedef F11<T> = List<Function> Function(int y, [List<T> x])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function([Function])
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function({core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(int y, {int x}) Function<B extends core.int>(
+    int x);
+typedef F15<T> = List<T> Function(int, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function(int) Function<B extends core.int>(int x);
+typedef F17<T> = Function(int x, [List<Function>]) Function<B extends core.int>(
+    int x);
+typedef F18<T> = Function(int y, {List<T> x}) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function([List<Function> x]) Function<B extends core.int>(
+    int x);
+typedef F20<T> = void Function(List<T>) Function<B extends core.int>(int x);
+typedef F21<T> = List<Function> Function<A>(Function x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = Function<A>(List<Function> x) Function<B extends core.int>(
+    int x);
+typedef F23<T> = void Function<A>(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+
+int f0(int y, [int x = -1]) => throw 'uncalled';
+Function f1(int y, [List<int> x = const []]) => throw 'uncalled';
+core.List<core.int> f2(int x0, [core.List<core.int> x = const []]) =>
+    throw 'uncalled';
+f3([List<Function> x = const []]) => throw 'uncalled';
+Function f4<A>(core.List<core.int> x) => throw 'uncalled';
+int Function(int, {int x}) f5<B extends core.int>(int x) => throw 'uncalled';
+int Function([core.List<core.int> x]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int y, [int x]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, [List<Function>]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, {List<int> x}) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(List<Function> x) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int y, [List<int> x]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([Function]) f12<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function({core.List<core.int> x}) f13<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function(int y, {int x}) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, [core.List<core.int> x]) f15<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+Function(int) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(int x, [List<Function>]) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int y, {List<int> x}) f18<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function([List<Function> x]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(List<int>) f20<B extends core.int>(int x) => throw 'uncalled';
+List<Function> Function<A>(Function x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function<A>(List<Function> x) f22<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function<A>(core.List<core.int> x) f23<B extends core.int>(int x) =>
+    throw 'uncalled';
+
+class U3<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int y, [int x]) x0;
+  late Function Function(int y, [List<T> x]) x1;
+  late core.List<core.int> Function(int, [core.List<core.int> x]) x2;
+  late Function([List<Function> x]) x3;
+  late Function Function<A>(core.List<core.int> x) x4;
+  late int Function(int, {int x}) Function<B extends core.int>(int x) x5;
+  late int Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+      x6;
+  late Function Function(int y, [int x]) Function<B extends core.int>(int x) x7;
+  late Function Function(int, [List<Function>]) Function<B extends core.int>(
+      int x) x8;
+  late Function Function(int, {List<T> x}) Function<B extends core.int>(int x)
+      x9;
+  late List<Function> Function(List<Function> x) Function<B extends core.int>(
+      int x) x10;
+  late List<Function> Function(int y, [List<T> x]) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function([Function]) Function<B extends core.int>(
+      int x) x12;
+  late core.List<core.int> Function({core.List<core.int> x})
+      Function<B extends core.int>(int x) x13;
+  late List<T> Function(int y, {int x}) Function<B extends core.int>(int x) x14;
+  late List<T> Function(int, [core.List<core.int> x])
+      Function<B extends core.int>(int x) x15;
+  late Function(int) Function<B extends core.int>(int x) x16;
+  late Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+      x17;
+  late Function(int y, {List<T> x}) Function<B extends core.int>(int x) x18;
+  late void Function([List<Function> x]) Function<B extends core.int>(int x)
+      x19;
+  late void Function(List<T>) Function<B extends core.int>(int x) x20;
+  late List<Function> Function<A>(Function x) Function<B extends core.int>(
+      int x) x21;
+  late Function<A>(List<Function> x) Function<B extends core.int>(int x) x22;
+  late void Function<A>(core.List<core.int> x) Function<B extends core.int>(
+      int x) x23;
+
+  U3({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int y, [int x = -1]) => throw 'uncalled';
+  Function m1(int y, [List<T> x = const []]) => throw 'uncalled';
+  core.List<core.int> m2(int x0, [core.List<core.int> x = const []]) =>
+      throw 'uncalled';
+  m3([List<Function> x = const []]) => throw 'uncalled';
+  Function m4<A>(core.List<core.int> x) => throw 'uncalled';
+  int Function(int, {int x}) m5<B extends core.int>(int x) => throw 'uncalled';
+  int Function([core.List<core.int> x]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int y, [int x]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, [List<Function>]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, {List<T> x}) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(List<Function> x) m10<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, [List<T> x]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([Function]) m12<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function({core.List<core.int> x}) m13<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, {int x}) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [core.List<core.int> x]) m15<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  Function(int) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(int x, [List<Function>]) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int y, {List<T> x}) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function([List<Function> x]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(List<T>) m20<B extends core.int>(int x) => throw 'uncalled';
+  List<Function> Function<A>(Function x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function<A>(List<Function> x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function<A>(core.List<core.int> x) m23<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int y, [int x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [int x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int y, [int x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function(int y, [List<T> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [List<T> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function(int y, [List<T> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, [core.List<core.int> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [core.List<core.int> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(
+        m2 is core.List<core.int> Function(int, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function([List<Function> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function([List<Function> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function([List<Function> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function Function<A>(core.List<core.int> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(core.List<core.int> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function Function<A>(core.List<core.int> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {int x}) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {int x}) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int, {int x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+        l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, [int x]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [int x]) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, [int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<Function>]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<Function>]) Function<B extends core.int>(int x)
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function(int, {List<T> x}) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {List<T> x}) Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function(int, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+    // The static function has its T always set to int.
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isFalse(f9 is F9<bool>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    Expect.isFalse(confuse(f9) is F9<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        x9 = confuse(f9);
+      });
+      Expect.throws(() {
+        l9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        l9 = confuse(f9);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m9 is F9<int>);
+      Expect.equals(tIsBool, m9 is F9<bool>);
+      Expect.equals(tIsInt, confuse(m9) is F9<int>);
+      Expect.equals(tIsBool, confuse(m9) is F9<bool>);
+    }
+  }
+
+  /// List<Function> Function(List<Function> x) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<Function> x) Function<B extends core.int>(
+        int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [List<T> x]) Function<B extends core.int>(
+        int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(int y, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function([Function]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([Function]) Function<B extends core.int>(int x)
+        l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({core.List<core.int> x})
+        Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function({core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(int y, {int x}) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {int x}) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, {int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [core.List<core.int> x]) Function<B extends core.int>(
+        int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [List<Function>]) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int x, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {List<T> x}) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is Function(int y, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+    // The static function has its T always set to int.
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isFalse(f18 is F18<bool>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    Expect.isFalse(confuse(f18) is F18<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x18 = (f18 as dynamic);
+      });
+      Expect.throws(() {
+        x18 = confuse(f18);
+      });
+      Expect.throws(() {
+        l18 = (f18 as dynamic);
+      });
+      Expect.throws(() {
+        l18 = confuse(f18);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m18 is F18<int>);
+      Expect.equals(tIsBool, m18 is F18<bool>);
+      Expect.equals(tIsInt, confuse(m18) is F18<int>);
+      Expect.equals(tIsBool, confuse(m18) is F18<bool>);
+    }
+  }
+
+  /// void Function([List<Function> x]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<Function> x]) Function<B extends core.int>(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(List<T>) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(List<T>) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is void Function(List<T>) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(Function x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(Function x) Function<B extends core.int>(int x)
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(Function x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<Function> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<Function> x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+        l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U3().runTests();
+  new U3<int>(tIsInt: true).runTests();
+  new U3<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type40_test.dart b/tests/language/function_type/function_type40_test.dart
new file mode 100644
index 0000000..860dbec
--- /dev/null
+++ b/tests/language/function_type/function_type40_test.dart
@@ -0,0 +1,897 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int x, [core.List<core.int>]);
+typedef F1<T> = List<Function> Function(int, [List<Function>]);
+typedef F2<T> = List<T> Function([Function]);
+typedef F3<T> = void Function(int);
+typedef F4<T> = A Function<A>(int x);
+typedef F5<T> = int Function({Function x}) Function();
+typedef F6<T> = int Function(List<T> x) Function();
+typedef F7<T> = Function Function(int, [Function x]) Function();
+typedef F8<T> = Function Function([core.List<core.int>]) Function();
+typedef F9<T> = List<Function> Function(int x, [int]) Function();
+typedef F10<T> = List<Function> Function(int y, {List<Function> x}) Function();
+typedef F11<T> = core.List<core.int> Function([int x]) Function();
+typedef F12<T> = core.List<core.int> Function(List<Function>) Function();
+typedef F13<T> = core.List<core.int> Function(int x, [List<T>]) Function();
+typedef F14<T> = List<T> Function(int, {Function x}) Function();
+typedef F15<T> = List<T> Function([List<T> x]) Function();
+typedef F16<T> = Function(int y, [Function x]) Function();
+typedef F17<T> = Function(int, [core.List<core.int>]) Function();
+typedef F18<T> = void Function({int x}) Function();
+typedef F19<T> = void Function(core.List<core.int> x) Function();
+typedef F20<T> = int Function<A>(List<Function> x) Function();
+typedef F21<T> = core.List<core.int> Function<A>(core.List<core.int> x)
+    Function();
+typedef F22<T> = A Function<A>(List<T> x) Function();
+typedef F23<T> = B Function(Function x) Function<B extends core.int>();
+
+int f0(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
+List<Function> f1(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+List<int> f2([Function x0 = _voidFunction]) => throw 'uncalled';
+void f3(int x0) => throw 'uncalled';
+A f4<A>(int x) => throw 'uncalled';
+int Function({Function x}) f5() => throw 'uncalled';
+int Function(List<int> x) f6() => throw 'uncalled';
+Function Function(int, [Function x]) f7() => throw 'uncalled';
+Function Function([core.List<core.int>]) f8() => throw 'uncalled';
+List<Function> Function(int x, [int]) f9() => throw 'uncalled';
+List<Function> Function(int y, {List<Function> x}) f10() => throw 'uncalled';
+core.List<core.int> Function([int x]) f11() => throw 'uncalled';
+core.List<core.int> Function(List<Function>) f12() => throw 'uncalled';
+core.List<core.int> Function(int x, [List<int>]) f13() => throw 'uncalled';
+List<int> Function(int, {Function x}) f14() => throw 'uncalled';
+List<int> Function([List<int> x]) f15() => throw 'uncalled';
+Function(int y, [Function x]) f16() => throw 'uncalled';
+Function(int, [core.List<core.int>]) f17() => throw 'uncalled';
+void Function({int x}) f18() => throw 'uncalled';
+void Function(core.List<core.int> x) f19() => throw 'uncalled';
+int Function<A>(List<Function> x) f20() => throw 'uncalled';
+core.List<core.int> Function<A>(core.List<core.int> x) f21() =>
+    throw 'uncalled';
+A Function<A>(List<int> x) f22() => throw 'uncalled';
+B Function(Function x) f23<B extends core.int>() => throw 'uncalled';
+
+class U40<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int x, [core.List<core.int>]) x0;
+  late List<Function> Function(int, [List<Function>]) x1;
+  late List<T> Function([Function]) x2;
+  late void Function(int) x3;
+  late A Function<A>(int x) x4;
+  late int Function({Function x}) Function() x5;
+  late int Function(List<T> x) Function() x6;
+  late Function Function(int, [Function x]) Function() x7;
+  late Function Function([core.List<core.int>]) Function() x8;
+  late List<Function> Function(int x, [int]) Function() x9;
+  late List<Function> Function(int y, {List<Function> x}) Function() x10;
+  late core.List<core.int> Function([int x]) Function() x11;
+  late core.List<core.int> Function(List<Function>) Function() x12;
+  late core.List<core.int> Function(int x, [List<T>]) Function() x13;
+  late List<T> Function(int, {Function x}) Function() x14;
+  late List<T> Function([List<T> x]) Function() x15;
+  late Function(int y, [Function x]) Function() x16;
+  late Function(int, [core.List<core.int>]) Function() x17;
+  late void Function({int x}) Function() x18;
+  late void Function(core.List<core.int> x) Function() x19;
+  late int Function<A>(List<Function> x) Function() x20;
+  late core.List<core.int> Function<A>(core.List<core.int> x) Function() x21;
+  late A Function<A>(List<T> x) Function() x22;
+  late B Function(Function x) Function<B extends core.int>() x23;
+
+  U40({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
+  List<Function> m1(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+  List<T> m2([Function x0 = _voidFunction]) => throw 'uncalled';
+  void m3(int x0) => throw 'uncalled';
+  A m4<A>(int x) => throw 'uncalled';
+  int Function({Function x}) m5() => throw 'uncalled';
+  int Function(List<T> x) m6() => throw 'uncalled';
+  Function Function(int, [Function x]) m7() => throw 'uncalled';
+  Function Function([core.List<core.int>]) m8() => throw 'uncalled';
+  List<Function> Function(int x, [int]) m9() => throw 'uncalled';
+  List<Function> Function(int y, {List<Function> x}) m10() => throw 'uncalled';
+  core.List<core.int> Function([int x]) m11() => throw 'uncalled';
+  core.List<core.int> Function(List<Function>) m12() => throw 'uncalled';
+  core.List<core.int> Function(int x, [List<T>]) m13() => throw 'uncalled';
+  List<T> Function(int, {Function x}) m14() => throw 'uncalled';
+  List<T> Function([List<T> x]) m15() => throw 'uncalled';
+  Function(int y, [Function x]) m16() => throw 'uncalled';
+  Function(int, [core.List<core.int>]) m17() => throw 'uncalled';
+  void Function({int x}) m18() => throw 'uncalled';
+  void Function(core.List<core.int> x) m19() => throw 'uncalled';
+  int Function<A>(List<Function> x) m20() => throw 'uncalled';
+  core.List<core.int> Function<A>(core.List<core.int> x) m21() =>
+      throw 'uncalled';
+  A Function<A>(List<T> x) m22() => throw 'uncalled';
+  B Function(Function x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int x, [core.List<core.int>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [core.List<core.int>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int x, [core.List<core.int>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, [List<Function>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<Function>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, [List<Function>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function([Function])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([Function]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function([Function]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// A Function<A>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is A Function<A>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function({Function x}) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function({Function x}) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function({Function x}) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(List<T> x) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(List<T> x) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(List<T> x) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, [Function x]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [Function x]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [Function x]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([core.List<core.int>]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([core.List<core.int>]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int x, [int]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [int]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int x, [int]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, {List<Function> x}) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {List<Function> x}) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(int y, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([int x]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([int x]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([int x]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(List<Function>) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<Function>) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(List<Function>) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int x, [List<T>]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [List<T>]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(int x, [List<T>]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {Function x}) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {Function x}) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, {Function x}) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([List<T> x]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<T> x]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function([List<T> x]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, [Function x]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [Function x]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, [Function x]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [core.List<core.int>]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [core.List<core.int>]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function({int x}) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function({int x}) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function({int x}) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(core.List<core.int> x) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(core.List<core.int> x) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<Function> x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<Function> x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(List<Function> x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(core.List<core.int> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(core.List<core.int> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(core.List<core.int> x)
+        Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<T> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<T> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(List<T> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+
+  /// B Function(Function x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(Function x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U40().runTests();
+  new U40<int>(tIsInt: true).runTests();
+  new U40<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type41_test.dart b/tests/language/function_type/function_type41_test.dart
new file mode 100644
index 0000000..48ae18b
--- /dev/null
+++ b/tests/language/function_type/function_type41_test.dart
@@ -0,0 +1,903 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function({core.List<core.int> x});
+typedef F1<T> = List<Function> Function(int x, [List<Function>]);
+typedef F2<T> = List<T> Function(int, [Function]);
+typedef F3<T> = void Function([int]);
+typedef F4<T> = A Function<A>(Function x);
+typedef F5<T> = int Function({Function x}) Function(int x);
+typedef F6<T> = int Function(List<T> x) Function(int x);
+typedef F7<T> = Function Function(int, [Function x]) Function(int x);
+typedef F8<T> = Function Function([core.List<core.int>]) Function(int x);
+typedef F9<T> = List<Function> Function(int x, [int]) Function(int x);
+typedef F10<T> = List<Function> Function(int y, {List<Function> x}) Function(
+    int x);
+typedef F11<T> = core.List<core.int> Function([int x]) Function(int x);
+typedef F12<T> = core.List<core.int> Function(List<Function>) Function(int x);
+typedef F13<T> = core.List<core.int> Function(int x, [List<T>]) Function(int x);
+typedef F14<T> = List<T> Function(int, {Function x}) Function(int x);
+typedef F15<T> = List<T> Function([List<T> x]) Function(int x);
+typedef F16<T> = Function(int y, [Function x]) Function(int x);
+typedef F17<T> = Function(int, [core.List<core.int>]) Function(int x);
+typedef F18<T> = void Function({int x}) Function(int x);
+typedef F19<T> = void Function(core.List<core.int> x) Function(int x);
+typedef F20<T> = int Function<A>(List<Function> x) Function(int x);
+typedef F21<T> = core.List<core.int> Function<A>(core.List<core.int> x)
+    Function(int x);
+typedef F22<T> = A Function<A>(List<T> x) Function(int x);
+typedef F23<T> = B Function(Function x) Function<B extends core.int>(int x);
+
+int f0({core.List<core.int> x = const []}) => throw 'uncalled';
+List<Function> f1(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+List<int> f2(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+void f3([int x0 = -1]) => throw 'uncalled';
+A f4<A>(Function x) => throw 'uncalled';
+int Function({Function x}) f5(int x) => throw 'uncalled';
+int Function(List<int> x) f6(int x) => throw 'uncalled';
+Function Function(int, [Function x]) f7(int x) => throw 'uncalled';
+Function Function([core.List<core.int>]) f8(int x) => throw 'uncalled';
+List<Function> Function(int x, [int]) f9(int x) => throw 'uncalled';
+List<Function> Function(int y, {List<Function> x}) f10(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([int x]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(List<Function>) f12(int x) => throw 'uncalled';
+core.List<core.int> Function(int x, [List<int>]) f13(int x) => throw 'uncalled';
+List<int> Function(int, {Function x}) f14(int x) => throw 'uncalled';
+List<int> Function([List<int> x]) f15(int x) => throw 'uncalled';
+Function(int y, [Function x]) f16(int x) => throw 'uncalled';
+Function(int, [core.List<core.int>]) f17(int x) => throw 'uncalled';
+void Function({int x}) f18(int x) => throw 'uncalled';
+void Function(core.List<core.int> x) f19(int x) => throw 'uncalled';
+int Function<A>(List<Function> x) f20(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(core.List<core.int> x) f21(int x) =>
+    throw 'uncalled';
+A Function<A>(List<int> x) f22(int x) => throw 'uncalled';
+B Function(Function x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U41<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function({core.List<core.int> x}) x0;
+  late List<Function> Function(int x, [List<Function>]) x1;
+  late List<T> Function(int, [Function]) x2;
+  late void Function([int]) x3;
+  late A Function<A>(Function x) x4;
+  late int Function({Function x}) Function(int x) x5;
+  late int Function(List<T> x) Function(int x) x6;
+  late Function Function(int, [Function x]) Function(int x) x7;
+  late Function Function([core.List<core.int>]) Function(int x) x8;
+  late List<Function> Function(int x, [int]) Function(int x) x9;
+  late List<Function> Function(int y, {List<Function> x}) Function(int x) x10;
+  late core.List<core.int> Function([int x]) Function(int x) x11;
+  late core.List<core.int> Function(List<Function>) Function(int x) x12;
+  late core.List<core.int> Function(int x, [List<T>]) Function(int x) x13;
+  late List<T> Function(int, {Function x}) Function(int x) x14;
+  late List<T> Function([List<T> x]) Function(int x) x15;
+  late Function(int y, [Function x]) Function(int x) x16;
+  late Function(int, [core.List<core.int>]) Function(int x) x17;
+  late void Function({int x}) Function(int x) x18;
+  late void Function(core.List<core.int> x) Function(int x) x19;
+  late int Function<A>(List<Function> x) Function(int x) x20;
+  late core.List<core.int> Function<A>(core.List<core.int> x) Function(int x)
+      x21;
+  late A Function<A>(List<T> x) Function(int x) x22;
+  late B Function(Function x) Function<B extends core.int>(int x) x23;
+
+  U41({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0({core.List<core.int> x = const []}) => throw 'uncalled';
+  List<Function> m1(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+  List<T> m2(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+  void m3([int x0 = -1]) => throw 'uncalled';
+  A m4<A>(Function x) => throw 'uncalled';
+  int Function({Function x}) m5(int x) => throw 'uncalled';
+  int Function(List<T> x) m6(int x) => throw 'uncalled';
+  Function Function(int, [Function x]) m7(int x) => throw 'uncalled';
+  Function Function([core.List<core.int>]) m8(int x) => throw 'uncalled';
+  List<Function> Function(int x, [int]) m9(int x) => throw 'uncalled';
+  List<Function> Function(int y, {List<Function> x}) m10(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([int x]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(List<Function>) m12(int x) => throw 'uncalled';
+  core.List<core.int> Function(int x, [List<T>]) m13(int x) => throw 'uncalled';
+  List<T> Function(int, {Function x}) m14(int x) => throw 'uncalled';
+  List<T> Function([List<T> x]) m15(int x) => throw 'uncalled';
+  Function(int y, [Function x]) m16(int x) => throw 'uncalled';
+  Function(int, [core.List<core.int>]) m17(int x) => throw 'uncalled';
+  void Function({int x}) m18(int x) => throw 'uncalled';
+  void Function(core.List<core.int> x) m19(int x) => throw 'uncalled';
+  int Function<A>(List<Function> x) m20(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(core.List<core.int> x) m21(int x) =>
+      throw 'uncalled';
+  A Function<A>(List<T> x) m22(int x) => throw 'uncalled';
+  B Function(Function x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function({core.List<core.int> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function({core.List<core.int> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function({core.List<core.int> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int x, [List<Function>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [List<Function>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int x, [List<Function>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, [Function])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [Function]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, [Function]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function([int])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function([int]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function([int]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// A Function<A>(Function x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(Function x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is A Function<A>(Function x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function({Function x}) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function({Function x}) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function({Function x}) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(List<T> x) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(List<T> x) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, [Function x]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [Function x]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([core.List<core.int>]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([core.List<core.int>]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function([core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int x, [int]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [int]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int x, [int]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, {List<Function> x}) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {List<Function> x}) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, {List<Function> x})
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([int x]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([int x]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([int x]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(List<Function>) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<Function>) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(List<Function>) Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int x, [List<T>]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [List<T>]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(int x, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {Function x}) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {Function x}) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([List<T> x]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<T> x]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function([List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, [Function x]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [Function x]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [core.List<core.int>]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [core.List<core.int>]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function({int x}) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function({int x}) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function({int x}) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(core.List<core.int> x) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(core.List<core.int> x) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<Function> x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<Function> x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(core.List<core.int> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(core.List<core.int> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(core.List<core.int> x)
+        Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<T> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<T> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+
+  /// B Function(Function x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(Function x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is B Function(Function x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U41().runTests();
+  new U41<int>(tIsInt: true).runTests();
+  new U41<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type42_test.dart b/tests/language/function_type/function_type42_test.dart
new file mode 100644
index 0000000..37251c3
--- /dev/null
+++ b/tests/language/function_type/function_type42_test.dart
@@ -0,0 +1,951 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, {core.List<core.int> x});
+typedef F1<T> = List<Function> Function({List<Function> x});
+typedef F2<T> = List<T> Function(int x, [Function]);
+typedef F3<T> = void Function(int, [int]);
+typedef F4<T> = A Function<A>(List<Function> x);
+typedef F5<T> = int Function({Function x}) Function<B extends core.int>();
+typedef F6<T> = int Function(List<T> x) Function<B extends core.int>();
+typedef F7<T> = Function Function(int, [Function x])
+    Function<B extends core.int>();
+typedef F8<T> = Function Function([core.List<core.int>])
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int x, [int])
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int y, {List<Function> x})
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function([int x])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(List<Function>)
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function(int x, [List<T>])
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int, {Function x})
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function([List<T> x]) Function<B extends core.int>();
+typedef F16<T> = Function(int y, [Function x]) Function<B extends core.int>();
+typedef F17<T> = Function(int, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F18<T> = void Function({int x}) Function<B extends core.int>();
+typedef F19<T> = void Function(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F20<T> = int Function<A>(List<Function> x)
+    Function<B extends core.int>();
+typedef F21<T> = core.List<core.int> Function<A>(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F22<T> = A Function<A>(List<T> x) Function<B extends core.int>();
+typedef F23<T> = B Function(List<Function> x) Function<B extends core.int>();
+
+int f0(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
+List<Function> f1({List<Function> x = const []}) => throw 'uncalled';
+List<int> f2(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+void f3(int x0, [int x1 = -1]) => throw 'uncalled';
+A f4<A>(List<Function> x) => throw 'uncalled';
+int Function({Function x}) f5<B extends core.int>() => throw 'uncalled';
+int Function(List<int> x) f6<B extends core.int>() => throw 'uncalled';
+Function Function(int, [Function x]) f7<B extends core.int>() =>
+    throw 'uncalled';
+Function Function([core.List<core.int>]) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int x, [int]) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int y, {List<Function> x}) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function([int x]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(List<Function>) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int x, [List<int>]) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, {Function x}) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function([List<int> x]) f15<B extends core.int>() => throw 'uncalled';
+Function(int y, [Function x]) f16<B extends core.int>() => throw 'uncalled';
+Function(int, [core.List<core.int>]) f17<B extends core.int>() =>
+    throw 'uncalled';
+void Function({int x}) f18<B extends core.int>() => throw 'uncalled';
+void Function(core.List<core.int> x) f19<B extends core.int>() =>
+    throw 'uncalled';
+int Function<A>(List<Function> x) f20<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function<A>(core.List<core.int> x)
+    f21<B extends core.int>() => throw 'uncalled';
+A Function<A>(List<int> x) f22<B extends core.int>() => throw 'uncalled';
+B Function(List<Function> x) f23<B extends core.int>() => throw 'uncalled';
+
+class U42<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, {core.List<core.int> x}) x0;
+  late List<Function> Function({List<Function> x}) x1;
+  late List<T> Function(int x, [Function]) x2;
+  late void Function(int, [int]) x3;
+  late A Function<A>(List<Function> x) x4;
+  late int Function({Function x}) Function<B extends core.int>() x5;
+  late int Function(List<T> x) Function<B extends core.int>() x6;
+  late Function Function(int, [Function x]) Function<B extends core.int>() x7;
+  late Function Function([core.List<core.int>]) Function<B extends core.int>()
+      x8;
+  late List<Function> Function(int x, [int]) Function<B extends core.int>() x9;
+  late List<Function> Function(int y, {List<Function> x})
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function([int x]) Function<B extends core.int>() x11;
+  late core.List<core.int> Function(List<Function>)
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function(int x, [List<T>])
+      Function<B extends core.int>() x13;
+  late List<T> Function(int, {Function x}) Function<B extends core.int>() x14;
+  late List<T> Function([List<T> x]) Function<B extends core.int>() x15;
+  late Function(int y, [Function x]) Function<B extends core.int>() x16;
+  late Function(int, [core.List<core.int>]) Function<B extends core.int>() x17;
+  late void Function({int x}) Function<B extends core.int>() x18;
+  late void Function(core.List<core.int> x) Function<B extends core.int>() x19;
+  late int Function<A>(List<Function> x) Function<B extends core.int>() x20;
+  late core.List<core.int> Function<A>(core.List<core.int> x)
+      Function<B extends core.int>() x21;
+  late A Function<A>(List<T> x) Function<B extends core.int>() x22;
+  late B Function(List<Function> x) Function<B extends core.int>() x23;
+
+  U42({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
+  List<Function> m1({List<Function> x = const []}) => throw 'uncalled';
+  List<T> m2(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+  void m3(int x0, [int x1 = -1]) => throw 'uncalled';
+  A m4<A>(List<Function> x) => throw 'uncalled';
+  int Function({Function x}) m5<B extends core.int>() => throw 'uncalled';
+  int Function(List<T> x) m6<B extends core.int>() => throw 'uncalled';
+  Function Function(int, [Function x]) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function([core.List<core.int>]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int x, [int]) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int y, {List<Function> x})
+      m10<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function([int x]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(List<Function>) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x, [List<T>]) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, {Function x}) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function([List<T> x]) m15<B extends core.int>() => throw 'uncalled';
+  Function(int y, [Function x]) m16<B extends core.int>() => throw 'uncalled';
+  Function(int, [core.List<core.int>]) m17<B extends core.int>() =>
+      throw 'uncalled';
+  void Function({int x}) m18<B extends core.int>() => throw 'uncalled';
+  void Function(core.List<core.int> x) m19<B extends core.int>() =>
+      throw 'uncalled';
+  int Function<A>(List<Function> x) m20<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function<A>(core.List<core.int> x)
+      m21<B extends core.int>() => throw 'uncalled';
+  A Function<A>(List<T> x) m22<B extends core.int>() => throw 'uncalled';
+  B Function(List<Function> x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, {core.List<core.int> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {core.List<core.int> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function({List<Function> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({List<Function> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function({List<Function> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int x, [Function])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [Function]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int x, [Function]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, [int])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [int]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, [int]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// A Function<A>(List<Function> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<Function> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is A Function<A>(List<Function> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function({Function x}) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function({Function x}) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function({Function x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(List<T> x) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(List<T> x) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, [Function x]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [Function x]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([core.List<core.int>]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([core.List<core.int>]) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int x, [int]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [int]) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int x, [int])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, {List<Function> x}) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {List<Function> x})
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([int x]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([int x]) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([int x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(List<Function>) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<Function>) Function<B extends core.int>()
+        l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(List<Function>)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int x, [List<T>]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [List<T>])
+        Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int x, [List<T>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {Function x}) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {Function x}) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, {Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([List<T> x]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<T> x]) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function([List<T> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, [Function x]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [Function x]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int y, [Function x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [core.List<core.int>]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [core.List<core.int>]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function({int x}) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function({int x}) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function({int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(core.List<core.int> x) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(core.List<core.int> x) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<Function> x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<Function> x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(core.List<core.int> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<T> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<T> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is A Function<A>(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+
+  /// B Function(List<Function> x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(List<Function> x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is B Function(List<Function> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U42().runTests();
+  new U42<int>(tIsInt: true).runTests();
+  new U42<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type43_test.dart b/tests/language/function_type/function_type43_test.dart
new file mode 100644
index 0000000..86d8998
--- /dev/null
+++ b/tests/language/function_type/function_type43_test.dart
@@ -0,0 +1,979 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int y, {core.List<core.int> x});
+typedef F1<T> = List<Function> Function(int, {List<Function> x});
+typedef F2<T> = List<T> Function({Function x});
+typedef F3<T> = void Function(int x, [int]);
+typedef F4<T> = A Function<A>(core.List<core.int> x);
+typedef F5<T> = int Function({Function x}) Function<B extends core.int>(int x);
+typedef F6<T> = int Function(List<T> x) Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int, [Function x])
+    Function<B extends core.int>(int x);
+typedef F8<T> = Function Function([core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(int x, [int])
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(int y, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function([int x])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(List<Function>)
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function(int x, [List<T>])
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(int, {Function x})
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function([List<T> x]) Function<B extends core.int>(
+    int x);
+typedef F16<T> = Function(int y, [Function x]) Function<B extends core.int>(
+    int x);
+typedef F17<T> = Function(int, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F18<T> = void Function({int x}) Function<B extends core.int>(int x);
+typedef F19<T> = void Function(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F20<T> = int Function<A>(List<Function> x) Function<B extends core.int>(
+    int x);
+typedef F21<T> = core.List<core.int> Function<A>(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = A Function<A>(List<T> x) Function<B extends core.int>(int x);
+typedef F23<T> = B Function(List<Function> x) Function<B extends core.int>(
+    int x);
+
+int f0(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
+List<Function> f1(int x0, {List<Function> x = const []}) => throw 'uncalled';
+List<int> f2({Function x = _voidFunction}) => throw 'uncalled';
+void f3(int x, [int x0 = -1]) => throw 'uncalled';
+A f4<A>(core.List<core.int> x) => throw 'uncalled';
+int Function({Function x}) f5<B extends core.int>(int x) => throw 'uncalled';
+int Function(List<int> x) f6<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int, [Function x]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function([core.List<core.int>]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int x, [int]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int y, {List<Function> x}) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([int x]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(List<Function>) f12<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int x, [List<int>]) f13<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function(int, {Function x}) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function([List<int> x]) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int y, [Function x]) f16<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int, [core.List<core.int>]) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function({int x}) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(core.List<core.int> x) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function<A>(List<Function> x) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function<A>(core.List<core.int> x) f21<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+A Function<A>(List<int> x) f22<B extends core.int>(int x) => throw 'uncalled';
+B Function(List<Function> x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U43<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int y, {core.List<core.int> x}) x0;
+  late List<Function> Function(int, {List<Function> x}) x1;
+  late List<T> Function({Function x}) x2;
+  late void Function(int x, [int]) x3;
+  late A Function<A>(core.List<core.int> x) x4;
+  late int Function({Function x}) Function<B extends core.int>(int x) x5;
+  late int Function(List<T> x) Function<B extends core.int>(int x) x6;
+  late Function Function(int, [Function x]) Function<B extends core.int>(int x)
+      x7;
+  late Function Function([core.List<core.int>]) Function<B extends core.int>(
+      int x) x8;
+  late List<Function> Function(int x, [int]) Function<B extends core.int>(int x)
+      x9;
+  late List<Function> Function(int y, {List<Function> x})
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function([int x]) Function<B extends core.int>(int x)
+      x11;
+  late core.List<core.int> Function(List<Function>)
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function(int x, [List<T>])
+      Function<B extends core.int>(int x) x13;
+  late List<T> Function(int, {Function x}) Function<B extends core.int>(int x)
+      x14;
+  late List<T> Function([List<T> x]) Function<B extends core.int>(int x) x15;
+  late Function(int y, [Function x]) Function<B extends core.int>(int x) x16;
+  late Function(int, [core.List<core.int>]) Function<B extends core.int>(int x)
+      x17;
+  late void Function({int x}) Function<B extends core.int>(int x) x18;
+  late void Function(core.List<core.int> x) Function<B extends core.int>(int x)
+      x19;
+  late int Function<A>(List<Function> x) Function<B extends core.int>(int x)
+      x20;
+  late core.List<core.int> Function<A>(core.List<core.int> x)
+      Function<B extends core.int>(int x) x21;
+  late A Function<A>(List<T> x) Function<B extends core.int>(int x) x22;
+  late B Function(List<Function> x) Function<B extends core.int>(int x) x23;
+
+  U43({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
+  List<Function> m1(int x0, {List<Function> x = const []}) => throw 'uncalled';
+  List<T> m2({Function x = _voidFunction}) => throw 'uncalled';
+  void m3(int x, [int x0 = -1]) => throw 'uncalled';
+  A m4<A>(core.List<core.int> x) => throw 'uncalled';
+  int Function({Function x}) m5<B extends core.int>(int x) => throw 'uncalled';
+  int Function(List<T> x) m6<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(int, [Function x]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function([core.List<core.int>]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int x, [int]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, {List<Function> x}) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([int x]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(List<Function>) m12<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x, [List<T>]) m13<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function(int, {Function x}) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function([List<T> x]) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int y, [Function x]) m16<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int, [core.List<core.int>]) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function({int x}) m18<B extends core.int>(int x) => throw 'uncalled';
+  void Function(core.List<core.int> x) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function<A>(List<Function> x) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function<A>(core.List<core.int> x)
+      m21<B extends core.int>(int x) => throw 'uncalled';
+  A Function<A>(List<T> x) m22<B extends core.int>(int x) => throw 'uncalled';
+  B Function(List<Function> x) m23<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int y, {core.List<core.int> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {core.List<core.int> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int y, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, {List<Function> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {List<Function> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, {List<Function> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function({Function x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({Function x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function({Function x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int x, [int])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [int]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int x, [int]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// A Function<A>(core.List<core.int> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(core.List<core.int> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is A Function<A>(core.List<core.int> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function({Function x}) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function({Function x}) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function({Function x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(List<T> x) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(List<T> x) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(List<T> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, [Function x]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [Function x]) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([core.List<core.int>]) Function<B extends core.int>(int x)
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int x, [int]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [int]) Function<B extends core.int>(int x)
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int x, [int])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {List<Function> x})
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([int x]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([int x]) Function<B extends core.int>(int x)
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(List<Function>) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<Function>) Function<B extends core.int>(
+        int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(List<Function>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int x, [List<T>]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [List<T>]) Function<B extends core.int>(
+        int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int x, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {Function x}) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {Function x}) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([List<T> x]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<T> x]) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function([List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, [Function x]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [Function x]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [core.List<core.int>]) Function<B extends core.int>(int x)
+        l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function({int x}) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function({int x}) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function({int x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(core.List<core.int> x) Function<B extends core.int>(int x)
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<Function> x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<Function> x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<T> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<T> x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is A Function<A>(List<T> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+
+  /// B Function(List<Function> x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(List<Function> x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U43().runTests();
+  new U43<int>(tIsInt: true).runTests();
+  new U43<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type44_test.dart b/tests/language/function_type/function_type44_test.dart
new file mode 100644
index 0000000..a500615
--- /dev/null
+++ b/tests/language/function_type/function_type44_test.dart
@@ -0,0 +1,946 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(List<T> x);
+typedef F1<T> = List<Function> Function(int y, {List<Function> x});
+typedef F2<T> = List<T> Function(int, {Function x});
+typedef F3<T> = void Function({int x});
+typedef F4<T> = A Function<A>(List<T> x);
+typedef F5<T> = int Function(int, {Function x}) Function();
+typedef F6<T> = int Function([List<T> x]) Function();
+typedef F7<T> = Function Function(int y, [Function x]) Function();
+typedef F8<T> = Function Function(int, [core.List<core.int>]) Function();
+typedef F9<T> = List<Function> Function({int x}) Function();
+typedef F10<T> = List<Function> Function(core.List<core.int> x) Function();
+typedef F11<T> = core.List<core.int> Function(int, [int x]) Function();
+typedef F12<T> = core.List<core.int> Function([List<Function>]) Function();
+typedef F13<T> = core.List<core.int> Function({List<T> x}) Function();
+typedef F14<T> = List<T> Function(int y, {Function x}) Function();
+typedef F15<T> = List<T> Function(int, [List<T> x]) Function();
+typedef F16<T> = Function(Function) Function();
+typedef F17<T> = Function(int x, [core.List<core.int>]) Function();
+typedef F18<T> = void Function(int, {int x}) Function();
+typedef F19<T> = void Function([core.List<core.int> x]) Function();
+typedef F20<T> = int Function<A>(core.List<core.int> x) Function();
+typedef F21<T> = core.List<core.int> Function<A>(List<T> x) Function();
+typedef F22<T> = A Function<A>() Function();
+typedef F23<T> = B Function(core.List<core.int> x)
+    Function<B extends core.int>();
+
+int f0(List<int> x) => throw 'uncalled';
+List<Function> f1(int y, {List<Function> x = const []}) => throw 'uncalled';
+List<int> f2(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+void f3({int x = -1}) => throw 'uncalled';
+A f4<A>(List<int> x) => throw 'uncalled';
+int Function(int, {Function x}) f5() => throw 'uncalled';
+int Function([List<int> x]) f6() => throw 'uncalled';
+Function Function(int y, [Function x]) f7() => throw 'uncalled';
+Function Function(int, [core.List<core.int>]) f8() => throw 'uncalled';
+List<Function> Function({int x}) f9() => throw 'uncalled';
+List<Function> Function(core.List<core.int> x) f10() => throw 'uncalled';
+core.List<core.int> Function(int, [int x]) f11() => throw 'uncalled';
+core.List<core.int> Function([List<Function>]) f12() => throw 'uncalled';
+core.List<core.int> Function({List<int> x}) f13() => throw 'uncalled';
+List<int> Function(int y, {Function x}) f14() => throw 'uncalled';
+List<int> Function(int, [List<int> x]) f15() => throw 'uncalled';
+Function(Function) f16() => throw 'uncalled';
+Function(int x, [core.List<core.int>]) f17() => throw 'uncalled';
+void Function(int, {int x}) f18() => throw 'uncalled';
+void Function([core.List<core.int> x]) f19() => throw 'uncalled';
+int Function<A>(core.List<core.int> x) f20() => throw 'uncalled';
+core.List<core.int> Function<A>(List<int> x) f21() => throw 'uncalled';
+A Function<A>() f22() => throw 'uncalled';
+B Function(core.List<core.int> x) f23<B extends core.int>() => throw 'uncalled';
+
+class U44<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(List<T> x) x0;
+  late List<Function> Function(int y, {List<Function> x}) x1;
+  late List<T> Function(int, {Function x}) x2;
+  late void Function({int x}) x3;
+  late A Function<A>(List<T> x) x4;
+  late int Function(int, {Function x}) Function() x5;
+  late int Function([List<T> x]) Function() x6;
+  late Function Function(int y, [Function x]) Function() x7;
+  late Function Function(int, [core.List<core.int>]) Function() x8;
+  late List<Function> Function({int x}) Function() x9;
+  late List<Function> Function(core.List<core.int> x) Function() x10;
+  late core.List<core.int> Function(int, [int x]) Function() x11;
+  late core.List<core.int> Function([List<Function>]) Function() x12;
+  late core.List<core.int> Function({List<T> x}) Function() x13;
+  late List<T> Function(int y, {Function x}) Function() x14;
+  late List<T> Function(int, [List<T> x]) Function() x15;
+  late Function(Function) Function() x16;
+  late Function(int x, [core.List<core.int>]) Function() x17;
+  late void Function(int, {int x}) Function() x18;
+  late void Function([core.List<core.int> x]) Function() x19;
+  late int Function<A>(core.List<core.int> x) Function() x20;
+  late core.List<core.int> Function<A>(List<T> x) Function() x21;
+  late A Function<A>() Function() x22;
+  late B Function(core.List<core.int> x) Function<B extends core.int>() x23;
+
+  U44({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(List<T> x) => throw 'uncalled';
+  List<Function> m1(int y, {List<Function> x = const []}) => throw 'uncalled';
+  List<T> m2(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+  void m3({int x = -1}) => throw 'uncalled';
+  A m4<A>(List<T> x) => throw 'uncalled';
+  int Function(int, {Function x}) m5() => throw 'uncalled';
+  int Function([List<T> x]) m6() => throw 'uncalled';
+  Function Function(int y, [Function x]) m7() => throw 'uncalled';
+  Function Function(int, [core.List<core.int>]) m8() => throw 'uncalled';
+  List<Function> Function({int x}) m9() => throw 'uncalled';
+  List<Function> Function(core.List<core.int> x) m10() => throw 'uncalled';
+  core.List<core.int> Function(int, [int x]) m11() => throw 'uncalled';
+  core.List<core.int> Function([List<Function>]) m12() => throw 'uncalled';
+  core.List<core.int> Function({List<T> x}) m13() => throw 'uncalled';
+  List<T> Function(int y, {Function x}) m14() => throw 'uncalled';
+  List<T> Function(int, [List<T> x]) m15() => throw 'uncalled';
+  Function(Function) m16() => throw 'uncalled';
+  Function(int x, [core.List<core.int>]) m17() => throw 'uncalled';
+  void Function(int, {int x}) m18() => throw 'uncalled';
+  void Function([core.List<core.int> x]) m19() => throw 'uncalled';
+  int Function<A>(core.List<core.int> x) m20() => throw 'uncalled';
+  core.List<core.int> Function<A>(List<T> x) m21() => throw 'uncalled';
+  A Function<A>() m22() => throw 'uncalled';
+  B Function(core.List<core.int> x) m23<B extends core.int>() =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(List<T> x)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(List<T> x) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(List<T> x));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function(int y, {List<Function> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {List<Function> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int y, {List<Function> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, {Function x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {Function x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, {Function x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function({int x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function({int x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function({int x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// A Function<A>(List<T> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<T> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is A Function<A>(List<T> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m4 is F4<int>);
+      Expect.equals(true, m4 is F4<bool>);
+      Expect.equals(true, confuse(m4) is F4<int>);
+      Expect.equals(true, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function(int, {Function x}) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {Function x}) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, {Function x}) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([List<T> x]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([List<T> x]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([List<T> x]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int y, [Function x]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [Function x]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, [Function x]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [core.List<core.int>]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [core.List<core.int>]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function({int x}) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({int x}) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function({int x}) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(core.List<core.int> x) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(core.List<core.int> x) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, [int x]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [int x]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, [int x]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([List<Function>]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<Function>]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function([List<Function>]) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function({List<T> x}) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({List<T> x}) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function({List<T> x}) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {Function x}) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {Function x}) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, {Function x}) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<T> x]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<T> x]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [List<T> x]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(Function) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(Function) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(Function) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [core.List<core.int>]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [core.List<core.int>]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int x, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, {int x}) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {int x}) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, {int x}) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([core.List<core.int> x]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([core.List<core.int> x]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(core.List<core.int> x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(core.List<core.int> x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<T> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<T> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(List<T> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// A Function<A>() Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>() Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>() Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// B Function(core.List<core.int> x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(core.List<core.int> x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U44().runTests();
+  new U44<int>(tIsInt: true).runTests();
+  new U44<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type45_test.dart b/tests/language/function_type/function_type45_test.dart
new file mode 100644
index 0000000..5cdf875
--- /dev/null
+++ b/tests/language/function_type/function_type45_test.dart
@@ -0,0 +1,929 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function([List<T> x]);
+typedef F1<T> = List<Function> Function(core.List<core.int> x);
+typedef F2<T> = List<T> Function(int y, {Function x});
+typedef F3<T> = void Function(int, {int x});
+typedef F4<T> = A Function<A>();
+typedef F5<T> = int Function(int, {Function x}) Function(int x);
+typedef F6<T> = int Function([List<T> x]) Function(int x);
+typedef F7<T> = Function Function(int y, [Function x]) Function(int x);
+typedef F8<T> = Function Function(int, [core.List<core.int>]) Function(int x);
+typedef F9<T> = List<Function> Function({int x}) Function(int x);
+typedef F10<T> = List<Function> Function(core.List<core.int> x) Function(int x);
+typedef F11<T> = core.List<core.int> Function(int, [int x]) Function(int x);
+typedef F12<T> = core.List<core.int> Function([List<Function>]) Function(int x);
+typedef F13<T> = core.List<core.int> Function({List<T> x}) Function(int x);
+typedef F14<T> = List<T> Function(int y, {Function x}) Function(int x);
+typedef F15<T> = List<T> Function(int, [List<T> x]) Function(int x);
+typedef F16<T> = Function(Function) Function(int x);
+typedef F17<T> = Function(int x, [core.List<core.int>]) Function(int x);
+typedef F18<T> = void Function(int, {int x}) Function(int x);
+typedef F19<T> = void Function([core.List<core.int> x]) Function(int x);
+typedef F20<T> = int Function<A>(core.List<core.int> x) Function(int x);
+typedef F21<T> = core.List<core.int> Function<A>(List<T> x) Function(int x);
+typedef F22<T> = A Function<A>() Function(int x);
+typedef F23<T> = B Function(core.List<core.int> x) Function<B extends core.int>(
+    int x);
+
+int f0([List<int> x = const []]) => throw 'uncalled';
+List<Function> f1(core.List<core.int> x) => throw 'uncalled';
+List<int> f2(int y, {Function x = _voidFunction}) => throw 'uncalled';
+void f3(int x0, {int x = -1}) => throw 'uncalled';
+A f4<A>() => throw 'uncalled';
+int Function(int, {Function x}) f5(int x) => throw 'uncalled';
+int Function([List<int> x]) f6(int x) => throw 'uncalled';
+Function Function(int y, [Function x]) f7(int x) => throw 'uncalled';
+Function Function(int, [core.List<core.int>]) f8(int x) => throw 'uncalled';
+List<Function> Function({int x}) f9(int x) => throw 'uncalled';
+List<Function> Function(core.List<core.int> x) f10(int x) => throw 'uncalled';
+core.List<core.int> Function(int, [int x]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function([List<Function>]) f12(int x) => throw 'uncalled';
+core.List<core.int> Function({List<int> x}) f13(int x) => throw 'uncalled';
+List<int> Function(int y, {Function x}) f14(int x) => throw 'uncalled';
+List<int> Function(int, [List<int> x]) f15(int x) => throw 'uncalled';
+Function(Function) f16(int x) => throw 'uncalled';
+Function(int x, [core.List<core.int>]) f17(int x) => throw 'uncalled';
+void Function(int, {int x}) f18(int x) => throw 'uncalled';
+void Function([core.List<core.int> x]) f19(int x) => throw 'uncalled';
+int Function<A>(core.List<core.int> x) f20(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(List<int> x) f21(int x) => throw 'uncalled';
+A Function<A>() f22(int x) => throw 'uncalled';
+B Function(core.List<core.int> x) f23<B extends core.int>(int x) =>
+    throw 'uncalled';
+
+class U45<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function([List<T> x]) x0;
+  late List<Function> Function(core.List<core.int> x) x1;
+  late List<T> Function(int y, {Function x}) x2;
+  late void Function(int, {int x}) x3;
+  late A Function<A>() x4;
+  late int Function(int, {Function x}) Function(int x) x5;
+  late int Function([List<T> x]) Function(int x) x6;
+  late Function Function(int y, [Function x]) Function(int x) x7;
+  late Function Function(int, [core.List<core.int>]) Function(int x) x8;
+  late List<Function> Function({int x}) Function(int x) x9;
+  late List<Function> Function(core.List<core.int> x) Function(int x) x10;
+  late core.List<core.int> Function(int, [int x]) Function(int x) x11;
+  late core.List<core.int> Function([List<Function>]) Function(int x) x12;
+  late core.List<core.int> Function({List<T> x}) Function(int x) x13;
+  late List<T> Function(int y, {Function x}) Function(int x) x14;
+  late List<T> Function(int, [List<T> x]) Function(int x) x15;
+  late Function(Function) Function(int x) x16;
+  late Function(int x, [core.List<core.int>]) Function(int x) x17;
+  late void Function(int, {int x}) Function(int x) x18;
+  late void Function([core.List<core.int> x]) Function(int x) x19;
+  late int Function<A>(core.List<core.int> x) Function(int x) x20;
+  late core.List<core.int> Function<A>(List<T> x) Function(int x) x21;
+  late A Function<A>() Function(int x) x22;
+  late B Function(core.List<core.int> x) Function<B extends core.int>(int x)
+      x23;
+
+  U45({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0([List<T> x = const []]) => throw 'uncalled';
+  List<Function> m1(core.List<core.int> x) => throw 'uncalled';
+  List<T> m2(int y, {Function x = _voidFunction}) => throw 'uncalled';
+  void m3(int x0, {int x = -1}) => throw 'uncalled';
+  A m4<A>() => throw 'uncalled';
+  int Function(int, {Function x}) m5(int x) => throw 'uncalled';
+  int Function([List<T> x]) m6(int x) => throw 'uncalled';
+  Function Function(int y, [Function x]) m7(int x) => throw 'uncalled';
+  Function Function(int, [core.List<core.int>]) m8(int x) => throw 'uncalled';
+  List<Function> Function({int x}) m9(int x) => throw 'uncalled';
+  List<Function> Function(core.List<core.int> x) m10(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, [int x]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function([List<Function>]) m12(int x) => throw 'uncalled';
+  core.List<core.int> Function({List<T> x}) m13(int x) => throw 'uncalled';
+  List<T> Function(int y, {Function x}) m14(int x) => throw 'uncalled';
+  List<T> Function(int, [List<T> x]) m15(int x) => throw 'uncalled';
+  Function(Function) m16(int x) => throw 'uncalled';
+  Function(int x, [core.List<core.int>]) m17(int x) => throw 'uncalled';
+  void Function(int, {int x}) m18(int x) => throw 'uncalled';
+  void Function([core.List<core.int> x]) m19(int x) => throw 'uncalled';
+  int Function<A>(core.List<core.int> x) m20(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(List<T> x) m21(int x) => throw 'uncalled';
+  A Function<A>() m22(int x) => throw 'uncalled';
+  B Function(core.List<core.int> x) m23<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function([List<T> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function([List<T> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function([List<T> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function(core.List<core.int> x)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(core.List<core.int> x) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(core.List<core.int> x));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int y, {Function x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {Function x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int y, {Function x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, {int x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {int x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, {int x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// A Function<A>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    A Function<A>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is A Function<A>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {Function x}) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {Function x}) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([List<T> x]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([List<T> x]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int y, [Function x]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [Function x]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [core.List<core.int>]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [core.List<core.int>]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int, [core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function({int x}) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({int x}) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function({int x}) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(core.List<core.int> x) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(core.List<core.int> x) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, [int x]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [int x]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int, [int x]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([List<Function>]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<Function>]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function([List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function({List<T> x}) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({List<T> x}) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function({List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {Function x}) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {Function x}) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<T> x]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<T> x]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(Function) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(Function) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(Function) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [core.List<core.int>]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [core.List<core.int>]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int x, [core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, {int x}) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {int x}) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, {int x}) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([core.List<core.int> x]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([core.List<core.int> x]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function([core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(core.List<core.int> x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(core.List<core.int> x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is int Function<A>(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<T> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<T> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is core.List<core.int> Function<A>(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// A Function<A>() Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>() Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>() Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// B Function(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(core.List<core.int> x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U45().runTests();
+  new U45<int>(tIsInt: true).runTests();
+  new U45<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type46_test.dart b/tests/language/function_type/function_type46_test.dart
new file mode 100644
index 0000000..ebd19bf
--- /dev/null
+++ b/tests/language/function_type/function_type46_test.dart
@@ -0,0 +1,1007 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, [List<T> x]);
+typedef F1<T> = List<Function> Function([core.List<core.int> x]);
+typedef F2<T> = List<T> Function(List<Function> x);
+typedef F3<T> = void Function(int y, {int x});
+typedef F4<T> = A Function<A>(A x);
+typedef F5<T> = int Function(int, {Function x}) Function<B extends core.int>();
+typedef F6<T> = int Function([List<T> x]) Function<B extends core.int>();
+typedef F7<T> = Function Function(int y, [Function x])
+    Function<B extends core.int>();
+typedef F8<T> = Function Function(int, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function({int x}) Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(int, [int x])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function([List<Function>])
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function({List<T> x})
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int y, {Function x})
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int, [List<T> x])
+    Function<B extends core.int>();
+typedef F16<T> = Function(Function) Function<B extends core.int>();
+typedef F17<T> = Function(int x, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F18<T> = void Function(int, {int x}) Function<B extends core.int>();
+typedef F19<T> = void Function([core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F20<T> = int Function<A>(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F21<T> = core.List<core.int> Function<A>(List<T> x)
+    Function<B extends core.int>();
+typedef F22<T> = A Function<A>() Function<B extends core.int>();
+typedef F23<T> = B Function(List<T> x) Function<B extends core.int>();
+
+int f0(int x0, [List<int> x = const []]) => throw 'uncalled';
+List<Function> f1([core.List<core.int> x = const []]) => throw 'uncalled';
+List<int> f2(List<Function> x) => throw 'uncalled';
+void f3(int y, {int x = -1}) => throw 'uncalled';
+A f4<A>(A x) => throw 'uncalled';
+int Function(int, {Function x}) f5<B extends core.int>() => throw 'uncalled';
+int Function([List<int> x]) f6<B extends core.int>() => throw 'uncalled';
+Function Function(int y, [Function x]) f7<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int, [core.List<core.int>]) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function({int x}) f9<B extends core.int>() => throw 'uncalled';
+List<Function> Function(core.List<core.int> x) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [int x]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function([List<Function>]) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function({List<int> x}) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int y, {Function x}) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, [List<int> x]) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function(Function) f16<B extends core.int>() => throw 'uncalled';
+Function(int x, [core.List<core.int>]) f17<B extends core.int>() =>
+    throw 'uncalled';
+void Function(int, {int x}) f18<B extends core.int>() => throw 'uncalled';
+void Function([core.List<core.int> x]) f19<B extends core.int>() =>
+    throw 'uncalled';
+int Function<A>(core.List<core.int> x) f20<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function<A>(List<int> x) f21<B extends core.int>() =>
+    throw 'uncalled';
+A Function<A>() f22<B extends core.int>() => throw 'uncalled';
+B Function(List<int> x) f23<B extends core.int>() => throw 'uncalled';
+
+class U46<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, [List<T> x]) x0;
+  late List<Function> Function([core.List<core.int> x]) x1;
+  late List<T> Function(List<Function> x) x2;
+  late void Function(int y, {int x}) x3;
+  late A Function<A>(A x) x4;
+  late int Function(int, {Function x}) Function<B extends core.int>() x5;
+  late int Function([List<T> x]) Function<B extends core.int>() x6;
+  late Function Function(int y, [Function x]) Function<B extends core.int>() x7;
+  late Function Function(int, [core.List<core.int>])
+      Function<B extends core.int>() x8;
+  late List<Function> Function({int x}) Function<B extends core.int>() x9;
+  late List<Function> Function(core.List<core.int> x)
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function(int, [int x]) Function<B extends core.int>()
+      x11;
+  late core.List<core.int> Function([List<Function>])
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function({List<T> x}) Function<B extends core.int>()
+      x13;
+  late List<T> Function(int y, {Function x}) Function<B extends core.int>() x14;
+  late List<T> Function(int, [List<T> x]) Function<B extends core.int>() x15;
+  late Function(Function) Function<B extends core.int>() x16;
+  late Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+      x17;
+  late void Function(int, {int x}) Function<B extends core.int>() x18;
+  late void Function([core.List<core.int> x]) Function<B extends core.int>()
+      x19;
+  late int Function<A>(core.List<core.int> x) Function<B extends core.int>()
+      x20;
+  late core.List<core.int> Function<A>(List<T> x) Function<B extends core.int>()
+      x21;
+  late A Function<A>() Function<B extends core.int>() x22;
+  late B Function(List<T> x) Function<B extends core.int>() x23;
+
+  U46({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, [List<T> x = const []]) => throw 'uncalled';
+  List<Function> m1([core.List<core.int> x = const []]) => throw 'uncalled';
+  List<T> m2(List<Function> x) => throw 'uncalled';
+  void m3(int y, {int x = -1}) => throw 'uncalled';
+  A m4<A>(A x) => throw 'uncalled';
+  int Function(int, {Function x}) m5<B extends core.int>() => throw 'uncalled';
+  int Function([List<T> x]) m6<B extends core.int>() => throw 'uncalled';
+  Function Function(int y, [Function x]) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int, [core.List<core.int>]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function({int x}) m9<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(core.List<core.int> x) m10<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [int x]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function([List<Function>]) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function({List<T> x}) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int y, {Function x}) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, [List<T> x]) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function(Function) m16<B extends core.int>() => throw 'uncalled';
+  Function(int x, [core.List<core.int>]) m17<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int, {int x}) m18<B extends core.int>() => throw 'uncalled';
+  void Function([core.List<core.int> x]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  int Function<A>(core.List<core.int> x) m20<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function<A>(List<T> x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  A Function<A>() m22<B extends core.int>() => throw 'uncalled';
+  B Function(List<T> x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, [List<T> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<T> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, [List<T> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function([core.List<core.int> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([core.List<core.int> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function([core.List<core.int> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(List<Function> x)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<Function> x) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(List<Function> x));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int y, {int x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {int x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int y, {int x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// A Function<A>(A x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(A x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is A Function<A>(A x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {Function x}) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {Function x}) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int, {Function x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([List<T> x]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([List<T> x]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function([List<T> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int y, [Function x]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [Function x]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, [Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [core.List<core.int>]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [core.List<core.int>]) Function<B extends core.int>()
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function({int x}) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({int x}) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function({int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(core.List<core.int> x) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(core.List<core.int> x)
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, [int x]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [int x]) Function<B extends core.int>()
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, [int x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([List<Function>]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<Function>])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function({List<T> x}) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({List<T> x}) Function<B extends core.int>()
+        l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function({List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {Function x}) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {Function x}) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, {Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<T> x]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<T> x]) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(Function) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(Function) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(Function) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [core.List<core.int>]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int x, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, {int x}) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {int x}) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int, {int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([core.List<core.int> x]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([core.List<core.int> x]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(core.List<core.int> x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(core.List<core.int> x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<T> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<T> x) Function<B extends core.int>()
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(List<T> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// A Function<A>() Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>() Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>() Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// B Function(List<T> x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(List<T> x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+    // The static function has its T always set to int.
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isFalse(f23 is F23<bool>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    Expect.isFalse(confuse(f23) is F23<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        x23 = confuse(f23);
+      });
+      Expect.throws(() {
+        l23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        l23 = confuse(f23);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m23 is F23<int>);
+      Expect.equals(tIsBool, m23 is F23<bool>);
+      Expect.equals(tIsInt, confuse(m23) is F23<int>);
+      Expect.equals(tIsBool, confuse(m23) is F23<bool>);
+    }
+  }
+}
+
+void main() {
+  new U46().runTests();
+  new U46<int>(tIsInt: true).runTests();
+  new U46<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type47_test.dart b/tests/language/function_type/function_type47_test.dart
new file mode 100644
index 0000000..cec7699
--- /dev/null
+++ b/tests/language/function_type/function_type47_test.dart
@@ -0,0 +1,1029 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int y, [List<T> x]);
+typedef F1<T> = List<Function> Function(int, [core.List<core.int> x]);
+typedef F2<T> = List<T> Function([List<Function> x]);
+typedef F3<T> = void Function(Function x);
+typedef F4<T> = A Function<A>(List<A> x);
+typedef F5<T> = int Function(int, {Function x}) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function([List<T> x]) Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int y, [Function x])
+    Function<B extends core.int>(int x);
+typedef F8<T> = Function Function(int, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function({int x}) Function<B extends core.int>(
+    int x);
+typedef F10<T> = List<Function> Function(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(int, [int x])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function([List<Function>])
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function({List<T> x})
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(int y, {Function x})
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function(int, [List<T> x])
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function(Function) Function<B extends core.int>(int x);
+typedef F17<T> = Function(int x, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F18<T> = void Function(int, {int x}) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function([core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F20<T> = int Function<A>(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F21<T> = core.List<core.int> Function<A>(List<T> x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = A Function<A>() Function<B extends core.int>(int x);
+typedef F23<T> = B Function(List<T> x) Function<B extends core.int>(int x);
+
+int f0(int y, [List<int> x = const []]) => throw 'uncalled';
+List<Function> f1(int x0, [core.List<core.int> x = const []]) =>
+    throw 'uncalled';
+List<int> f2([List<Function> x = const []]) => throw 'uncalled';
+void f3(Function x) => throw 'uncalled';
+A f4<A>(List<A> x) => throw 'uncalled';
+int Function(int, {Function x}) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function([List<int> x]) f6<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int y, [Function x]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, [core.List<core.int>]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function({int x}) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(core.List<core.int> x) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [int x]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([List<Function>]) f12<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function({List<int> x}) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int y, {Function x}) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, [List<int> x]) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(Function) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(int x, [core.List<core.int>]) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int, {int x}) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function([core.List<core.int> x]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function<A>(core.List<core.int> x) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function<A>(List<int> x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+A Function<A>() f22<B extends core.int>(int x) => throw 'uncalled';
+B Function(List<int> x) f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U47<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int y, [List<T> x]) x0;
+  late List<Function> Function(int, [core.List<core.int> x]) x1;
+  late List<T> Function([List<Function> x]) x2;
+  late void Function(Function x) x3;
+  late A Function<A>(List<A> x) x4;
+  late int Function(int, {Function x}) Function<B extends core.int>(int x) x5;
+  late int Function([List<T> x]) Function<B extends core.int>(int x) x6;
+  late Function Function(int y, [Function x]) Function<B extends core.int>(
+      int x) x7;
+  late Function Function(int, [core.List<core.int>])
+      Function<B extends core.int>(int x) x8;
+  late List<Function> Function({int x}) Function<B extends core.int>(int x) x9;
+  late List<Function> Function(core.List<core.int> x)
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function(int, [int x]) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function([List<Function>])
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function({List<T> x}) Function<B extends core.int>(
+      int x) x13;
+  late List<T> Function(int y, {Function x}) Function<B extends core.int>(int x)
+      x14;
+  late List<T> Function(int, [List<T> x]) Function<B extends core.int>(int x)
+      x15;
+  late Function(Function) Function<B extends core.int>(int x) x16;
+  late Function(int x, [core.List<core.int>]) Function<B extends core.int>(
+      int x) x17;
+  late void Function(int, {int x}) Function<B extends core.int>(int x) x18;
+  late void Function([core.List<core.int> x]) Function<B extends core.int>(
+      int x) x19;
+  late int Function<A>(core.List<core.int> x) Function<B extends core.int>(
+      int x) x20;
+  late core.List<core.int> Function<A>(List<T> x) Function<B extends core.int>(
+      int x) x21;
+  late A Function<A>() Function<B extends core.int>(int x) x22;
+  late B Function(List<T> x) Function<B extends core.int>(int x) x23;
+
+  U47({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int y, [List<T> x = const []]) => throw 'uncalled';
+  List<Function> m1(int x0, [core.List<core.int> x = const []]) =>
+      throw 'uncalled';
+  List<T> m2([List<Function> x = const []]) => throw 'uncalled';
+  void m3(Function x) => throw 'uncalled';
+  A m4<A>(List<A> x) => throw 'uncalled';
+  int Function(int, {Function x}) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function([List<T> x]) m6<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(int y, [Function x]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, [core.List<core.int>]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function({int x}) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(core.List<core.int> x) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [int x]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([List<Function>]) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function({List<T> x}) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, {Function x}) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [List<T> x]) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(Function) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(int x, [core.List<core.int>]) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int, {int x}) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function([core.List<core.int> x]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function<A>(core.List<core.int> x) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function<A>(List<T> x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  A Function<A>() m22<B extends core.int>(int x) => throw 'uncalled';
+  B Function(List<T> x) m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int y, [List<T> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [List<T> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int y, [List<T> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, [core.List<core.int> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [core.List<core.int> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function([List<Function> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<Function> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function([List<Function> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(Function x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(Function x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(Function x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// A Function<A>(List<A> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<A> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is A Function<A>(List<A> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {Function x}) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {Function x}) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([List<T> x]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([List<T> x]) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function([List<T> x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int y, [Function x]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [Function x]) Function<B extends core.int>(int x)
+        l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [core.List<core.int>]) Function<B extends core.int>(
+        int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function({int x}) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({int x}) Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function({int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(core.List<core.int> x) Function<B extends core.int>(
+        int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, [int x]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [int x]) Function<B extends core.int>(
+        int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, [int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([List<Function>]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<Function>]) Function<B extends core.int>(
+        int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function({List<T> x}) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({List<T> x}) Function<B extends core.int>(
+        int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function({List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {Function x}) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {Function x}) Function<B extends core.int>(int x)
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<T> x]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<T> x]) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(Function) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(Function) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(Function) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [core.List<core.int>]) Function<B extends core.int>(int x)
+        l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int x, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int, {int x}) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {int x}) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int, {int x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+        l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<T> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<T> x) Function<B extends core.int>(
+        int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(List<T> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// A Function<A>() Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>() Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// B Function(List<T> x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function(List<T> x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is B Function(List<T> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+    // The static function has its T always set to int.
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isFalse(f23 is F23<bool>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    Expect.isFalse(confuse(f23) is F23<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        x23 = confuse(f23);
+      });
+      Expect.throws(() {
+        l23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        l23 = confuse(f23);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m23 is F23<int>);
+      Expect.equals(tIsBool, m23 is F23<bool>);
+      Expect.equals(tIsInt, confuse(m23) is F23<int>);
+      Expect.equals(tIsBool, confuse(m23) is F23<bool>);
+    }
+  }
+}
+
+void main() {
+  new U47().runTests();
+  new U47<int>(tIsInt: true).runTests();
+  new U47<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type48_test.dart b/tests/language/function_type/function_type48_test.dart
new file mode 100644
index 0000000..c500094
--- /dev/null
+++ b/tests/language/function_type/function_type48_test.dart
@@ -0,0 +1,924 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(List<T>);
+typedef F1<T> = List<Function> Function(int y, [core.List<core.int> x]);
+typedef F2<T> = List<T> Function(int, [List<Function> x]);
+typedef F3<T> = void Function([Function x]);
+typedef F4<T> = List<A> Function<A>(int x);
+typedef F5<T> = int Function(int y, {Function x}) Function();
+typedef F6<T> = int Function(int, [List<T> x]) Function();
+typedef F7<T> = Function Function(Function) Function();
+typedef F8<T> = Function Function(int x, [core.List<core.int>]) Function();
+typedef F9<T> = List<Function> Function(int, {int x}) Function();
+typedef F10<T> = List<Function> Function([core.List<core.int> x]) Function();
+typedef F11<T> = core.List<core.int> Function(int y, [int x]) Function();
+typedef F12<T> = core.List<core.int> Function(int, [List<Function>]) Function();
+typedef F13<T> = core.List<core.int> Function(int, {List<T> x}) Function();
+typedef F14<T> = List<T> Function(List<Function> x) Function();
+typedef F15<T> = List<T> Function(int y, [List<T> x]) Function();
+typedef F16<T> = Function([Function]) Function();
+typedef F17<T> = Function({core.List<core.int> x}) Function();
+typedef F18<T> = void Function(int y, {int x}) Function();
+typedef F19<T> = void Function(int, [core.List<core.int> x]) Function();
+typedef F20<T> = int Function<A>(List<T> x) Function();
+typedef F21<T> = core.List<core.int> Function<A>() Function();
+typedef F22<T> = A Function<A>(A x) Function();
+typedef F23<T> = B Function() Function<B extends core.int>();
+
+int f0(List<int> x0) => throw 'uncalled';
+List<Function> f1(int y, [core.List<core.int> x = const []]) =>
+    throw 'uncalled';
+List<int> f2(int x0, [List<Function> x = const []]) => throw 'uncalled';
+void f3([Function x = _voidFunction]) => throw 'uncalled';
+List<A> f4<A>(int x) => throw 'uncalled';
+int Function(int y, {Function x}) f5() => throw 'uncalled';
+int Function(int, [List<int> x]) f6() => throw 'uncalled';
+Function Function(Function) f7() => throw 'uncalled';
+Function Function(int x, [core.List<core.int>]) f8() => throw 'uncalled';
+List<Function> Function(int, {int x}) f9() => throw 'uncalled';
+List<Function> Function([core.List<core.int> x]) f10() => throw 'uncalled';
+core.List<core.int> Function(int y, [int x]) f11() => throw 'uncalled';
+core.List<core.int> Function(int, [List<Function>]) f12() => throw 'uncalled';
+core.List<core.int> Function(int, {List<int> x}) f13() => throw 'uncalled';
+List<int> Function(List<Function> x) f14() => throw 'uncalled';
+List<int> Function(int y, [List<int> x]) f15() => throw 'uncalled';
+Function([Function]) f16() => throw 'uncalled';
+Function({core.List<core.int> x}) f17() => throw 'uncalled';
+void Function(int y, {int x}) f18() => throw 'uncalled';
+void Function(int, [core.List<core.int> x]) f19() => throw 'uncalled';
+int Function<A>(List<int> x) f20() => throw 'uncalled';
+core.List<core.int> Function<A>() f21() => throw 'uncalled';
+A Function<A>(A x) f22() => throw 'uncalled';
+B Function() f23<B extends core.int>() => throw 'uncalled';
+
+class U48<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(List<T>) x0;
+  late List<Function> Function(int y, [core.List<core.int> x]) x1;
+  late List<T> Function(int, [List<Function> x]) x2;
+  late void Function([Function x]) x3;
+  late List<A> Function<A>(int x) x4;
+  late int Function(int y, {Function x}) Function() x5;
+  late int Function(int, [List<T> x]) Function() x6;
+  late Function Function(Function) Function() x7;
+  late Function Function(int x, [core.List<core.int>]) Function() x8;
+  late List<Function> Function(int, {int x}) Function() x9;
+  late List<Function> Function([core.List<core.int> x]) Function() x10;
+  late core.List<core.int> Function(int y, [int x]) Function() x11;
+  late core.List<core.int> Function(int, [List<Function>]) Function() x12;
+  late core.List<core.int> Function(int, {List<T> x}) Function() x13;
+  late List<T> Function(List<Function> x) Function() x14;
+  late List<T> Function(int y, [List<T> x]) Function() x15;
+  late Function([Function]) Function() x16;
+  late Function({core.List<core.int> x}) Function() x17;
+  late void Function(int y, {int x}) Function() x18;
+  late void Function(int, [core.List<core.int> x]) Function() x19;
+  late int Function<A>(List<T> x) Function() x20;
+  late core.List<core.int> Function<A>() Function() x21;
+  late A Function<A>(A x) Function() x22;
+  late B Function() Function<B extends core.int>() x23;
+
+  U48({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(List<T> x0) => throw 'uncalled';
+  List<Function> m1(int y, [core.List<core.int> x = const []]) =>
+      throw 'uncalled';
+  List<T> m2(int x0, [List<Function> x = const []]) => throw 'uncalled';
+  void m3([Function x = _voidFunction]) => throw 'uncalled';
+  List<A> m4<A>(int x) => throw 'uncalled';
+  int Function(int y, {Function x}) m5() => throw 'uncalled';
+  int Function(int, [List<T> x]) m6() => throw 'uncalled';
+  Function Function(Function) m7() => throw 'uncalled';
+  Function Function(int x, [core.List<core.int>]) m8() => throw 'uncalled';
+  List<Function> Function(int, {int x}) m9() => throw 'uncalled';
+  List<Function> Function([core.List<core.int> x]) m10() => throw 'uncalled';
+  core.List<core.int> Function(int y, [int x]) m11() => throw 'uncalled';
+  core.List<core.int> Function(int, [List<Function>]) m12() => throw 'uncalled';
+  core.List<core.int> Function(int, {List<T> x}) m13() => throw 'uncalled';
+  List<T> Function(List<Function> x) m14() => throw 'uncalled';
+  List<T> Function(int y, [List<T> x]) m15() => throw 'uncalled';
+  Function([Function]) m16() => throw 'uncalled';
+  Function({core.List<core.int> x}) m17() => throw 'uncalled';
+  void Function(int y, {int x}) m18() => throw 'uncalled';
+  void Function(int, [core.List<core.int> x]) m19() => throw 'uncalled';
+  int Function<A>(List<T> x) m20() => throw 'uncalled';
+  core.List<core.int> Function<A>() m21() => throw 'uncalled';
+  A Function<A>(A x) m22() => throw 'uncalled';
+  B Function() m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(List<T>)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(List<T>) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(List<T>));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function(int y, [core.List<core.int> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [core.List<core.int> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(
+        m1 is List<Function> Function(int y, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, [List<Function> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<Function> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, [List<Function> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function([Function x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function([Function x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function([Function x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<A> Function<A>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<A> Function<A>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {Function x}) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {Function x}) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, {Function x}) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [List<T> x]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<T> x]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [List<T> x]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(Function) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(Function) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(Function) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [core.List<core.int>]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [core.List<core.int>]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int x, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, {int x}) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {int x}) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, {int x}) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([core.List<core.int> x]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([core.List<core.int> x]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function([core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int y, [int x]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [int x]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int y, [int x]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [List<Function>]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<Function>]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(int, [List<Function>]) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, {List<T> x}) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {List<T> x}) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(int, {List<T> x}) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(List<Function> x) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<Function> x) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(List<Function> x) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [List<T> x]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [List<T> x]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, [List<T> x]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([Function]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([Function]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([Function]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({core.List<core.int> x}) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({core.List<core.int> x}) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function({core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int y, {int x}) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {int x}) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, {int x}) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [core.List<core.int> x]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [core.List<core.int> x]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int, [core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<T> x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<T> x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(List<T> x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function<A>() Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>() Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>() Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(A x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(A x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(A x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// B Function() Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function() Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function() Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U48().runTests();
+  new U48<int>(tIsInt: true).runTests();
+  new U48<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type49_test.dart b/tests/language/function_type/function_type49_test.dart
new file mode 100644
index 0000000..04c1f3e
--- /dev/null
+++ b/tests/language/function_type/function_type49_test.dart
@@ -0,0 +1,926 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function([List<T>]);
+typedef F1<T> = List<Function> Function(core.List<core.int>);
+typedef F2<T> = List<T> Function(int y, [List<Function> x]);
+typedef F3<T> = void Function(int, [Function x]);
+typedef F4<T> = List<A> Function<A>(Function x);
+typedef F5<T> = int Function(int y, {Function x}) Function(int x);
+typedef F6<T> = int Function(int, [List<T> x]) Function(int x);
+typedef F7<T> = Function Function(Function) Function(int x);
+typedef F8<T> = Function Function(int x, [core.List<core.int>]) Function(int x);
+typedef F9<T> = List<Function> Function(int, {int x}) Function(int x);
+typedef F10<T> = List<Function> Function([core.List<core.int> x]) Function(
+    int x);
+typedef F11<T> = core.List<core.int> Function(int y, [int x]) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int, [List<Function>]) Function(
+    int x);
+typedef F13<T> = core.List<core.int> Function(int, {List<T> x}) Function(int x);
+typedef F14<T> = List<T> Function(List<Function> x) Function(int x);
+typedef F15<T> = List<T> Function(int y, [List<T> x]) Function(int x);
+typedef F16<T> = Function([Function]) Function(int x);
+typedef F17<T> = Function({core.List<core.int> x}) Function(int x);
+typedef F18<T> = void Function(int y, {int x}) Function(int x);
+typedef F19<T> = void Function(int, [core.List<core.int> x]) Function(int x);
+typedef F20<T> = int Function<A>(List<T> x) Function(int x);
+typedef F21<T> = core.List<core.int> Function<A>() Function(int x);
+typedef F22<T> = A Function<A>(A x) Function(int x);
+typedef F23<T> = B Function() Function<B extends core.int>(int x);
+
+int f0([List<int> x0 = const []]) => throw 'uncalled';
+List<Function> f1(core.List<core.int> x0) => throw 'uncalled';
+List<int> f2(int y, [List<Function> x = const []]) => throw 'uncalled';
+void f3(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+List<A> f4<A>(Function x) => throw 'uncalled';
+int Function(int y, {Function x}) f5(int x) => throw 'uncalled';
+int Function(int, [List<int> x]) f6(int x) => throw 'uncalled';
+Function Function(Function) f7(int x) => throw 'uncalled';
+Function Function(int x, [core.List<core.int>]) f8(int x) => throw 'uncalled';
+List<Function> Function(int, {int x}) f9(int x) => throw 'uncalled';
+List<Function> Function([core.List<core.int> x]) f10(int x) => throw 'uncalled';
+core.List<core.int> Function(int y, [int x]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int, [List<Function>]) f12(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {List<int> x}) f13(int x) => throw 'uncalled';
+List<int> Function(List<Function> x) f14(int x) => throw 'uncalled';
+List<int> Function(int y, [List<int> x]) f15(int x) => throw 'uncalled';
+Function([Function]) f16(int x) => throw 'uncalled';
+Function({core.List<core.int> x}) f17(int x) => throw 'uncalled';
+void Function(int y, {int x}) f18(int x) => throw 'uncalled';
+void Function(int, [core.List<core.int> x]) f19(int x) => throw 'uncalled';
+int Function<A>(List<int> x) f20(int x) => throw 'uncalled';
+core.List<core.int> Function<A>() f21(int x) => throw 'uncalled';
+A Function<A>(A x) f22(int x) => throw 'uncalled';
+B Function() f23<B extends core.int>(int x) => throw 'uncalled';
+
+class U49<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function([List<T>]) x0;
+  late List<Function> Function(core.List<core.int>) x1;
+  late List<T> Function(int y, [List<Function> x]) x2;
+  late void Function(int, [Function x]) x3;
+  late List<A> Function<A>(Function x) x4;
+  late int Function(int y, {Function x}) Function(int x) x5;
+  late int Function(int, [List<T> x]) Function(int x) x6;
+  late Function Function(Function) Function(int x) x7;
+  late Function Function(int x, [core.List<core.int>]) Function(int x) x8;
+  late List<Function> Function(int, {int x}) Function(int x) x9;
+  late List<Function> Function([core.List<core.int> x]) Function(int x) x10;
+  late core.List<core.int> Function(int y, [int x]) Function(int x) x11;
+  late core.List<core.int> Function(int, [List<Function>]) Function(int x) x12;
+  late core.List<core.int> Function(int, {List<T> x}) Function(int x) x13;
+  late List<T> Function(List<Function> x) Function(int x) x14;
+  late List<T> Function(int y, [List<T> x]) Function(int x) x15;
+  late Function([Function]) Function(int x) x16;
+  late Function({core.List<core.int> x}) Function(int x) x17;
+  late void Function(int y, {int x}) Function(int x) x18;
+  late void Function(int, [core.List<core.int> x]) Function(int x) x19;
+  late int Function<A>(List<T> x) Function(int x) x20;
+  late core.List<core.int> Function<A>() Function(int x) x21;
+  late A Function<A>(A x) Function(int x) x22;
+  late B Function() Function<B extends core.int>(int x) x23;
+
+  U49({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0([List<T> x0 = const []]) => throw 'uncalled';
+  List<Function> m1(core.List<core.int> x0) => throw 'uncalled';
+  List<T> m2(int y, [List<Function> x = const []]) => throw 'uncalled';
+  void m3(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+  List<A> m4<A>(Function x) => throw 'uncalled';
+  int Function(int y, {Function x}) m5(int x) => throw 'uncalled';
+  int Function(int, [List<T> x]) m6(int x) => throw 'uncalled';
+  Function Function(Function) m7(int x) => throw 'uncalled';
+  Function Function(int x, [core.List<core.int>]) m8(int x) => throw 'uncalled';
+  List<Function> Function(int, {int x}) m9(int x) => throw 'uncalled';
+  List<Function> Function([core.List<core.int> x]) m10(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [int x]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, [List<Function>]) m12(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {List<T> x}) m13(int x) => throw 'uncalled';
+  List<T> Function(List<Function> x) m14(int x) => throw 'uncalled';
+  List<T> Function(int y, [List<T> x]) m15(int x) => throw 'uncalled';
+  Function([Function]) m16(int x) => throw 'uncalled';
+  Function({core.List<core.int> x}) m17(int x) => throw 'uncalled';
+  void Function(int y, {int x}) m18(int x) => throw 'uncalled';
+  void Function(int, [core.List<core.int> x]) m19(int x) => throw 'uncalled';
+  int Function<A>(List<T> x) m20(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>() m21(int x) => throw 'uncalled';
+  A Function<A>(A x) m22(int x) => throw 'uncalled';
+  B Function() m23<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function([List<T>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function([List<T>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function([List<T>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function(core.List<core.int>)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(core.List<core.int>) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(core.List<core.int>));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int y, [List<Function> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [List<Function> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int y, [List<Function> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, [Function x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [Function x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, [Function x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<A> Function<A>(Function x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(Function x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<A> Function<A>(Function x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {Function x}) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {Function x}) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [List<T> x]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<T> x]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(Function) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(Function) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(Function) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [core.List<core.int>]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [core.List<core.int>]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int x, [core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, {int x}) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {int x}) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, {int x}) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([core.List<core.int> x]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([core.List<core.int> x]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([core.List<core.int> x])
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int y, [int x]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [int x]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int y, [int x]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [List<Function>]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<Function>]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, [List<Function>])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, {List<T> x}) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {List<T> x}) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(int, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(List<Function> x) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<Function> x) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [List<T> x]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [List<T> x]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([Function]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([Function]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([Function]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({core.List<core.int> x}) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({core.List<core.int> x}) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function({core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int y, {int x}) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {int x}) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, {int x}) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [core.List<core.int> x]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [core.List<core.int> x]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int, [core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<T> x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<T> x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function<A>() Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>() Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>() Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(A x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(A x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(A x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// B Function() Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    B Function() Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is B Function() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U49().runTests();
+  new U49<int>(tIsInt: true).runTests();
+  new U49<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type4_test.dart b/tests/language/function_type/function_type4_test.dart
new file mode 100644
index 0000000..77b3d2b
--- /dev/null
+++ b/tests/language/function_type/function_type4_test.dart
@@ -0,0 +1,953 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int);
+typedef F1<T> = Function Function(List<T>);
+typedef F2<T> = core.List<core.int> Function(int y, [core.List<core.int> x]);
+typedef F3<T> = Function(int, [List<Function> x]);
+typedef F4<T> = Function Function<A>(List<T> x);
+typedef F5<T> = int Function(int y, {int x}) Function();
+typedef F6<T> = int Function(int, [core.List<core.int> x]) Function();
+typedef F7<T> = Function Function(int) Function();
+typedef F8<T> = Function Function(int x, [List<Function>]) Function();
+typedef F9<T> = Function Function(int y, {List<T> x}) Function();
+typedef F10<T> = List<Function> Function([List<Function> x]) Function();
+typedef F11<T> = List<Function> Function(List<T>) Function();
+typedef F12<T> = core.List<core.int> Function(int, [Function]) Function();
+typedef F13<T> = core.List<core.int> Function(int, {core.List<core.int> x})
+    Function();
+typedef F14<T> = List<T> Function(Function x) Function();
+typedef F15<T> = List<T> Function(int y, [core.List<core.int> x]) Function();
+typedef F16<T> = Function([int]) Function();
+typedef F17<T> = Function({List<Function> x}) Function();
+typedef F18<T> = Function() Function();
+typedef F19<T> = void Function(int, [List<Function> x]) Function();
+typedef F20<T> = void Function([List<T>]) Function();
+typedef F21<T> = List<Function> Function<A>(List<Function> x) Function();
+typedef F22<T> = Function<A>(core.List<core.int> x) Function();
+typedef F23<T> = void Function<A>(List<T> x) Function();
+
+int f0(int x0) => throw 'uncalled';
+Function f1(List<int> x0) => throw 'uncalled';
+core.List<core.int> f2(int y, [core.List<core.int> x = const []]) =>
+    throw 'uncalled';
+f3(int x0, [List<Function> x = const []]) => throw 'uncalled';
+Function f4<A>(List<int> x) => throw 'uncalled';
+int Function(int y, {int x}) f5() => throw 'uncalled';
+int Function(int, [core.List<core.int> x]) f6() => throw 'uncalled';
+Function Function(int) f7() => throw 'uncalled';
+Function Function(int x, [List<Function>]) f8() => throw 'uncalled';
+Function Function(int y, {List<int> x}) f9() => throw 'uncalled';
+List<Function> Function([List<Function> x]) f10() => throw 'uncalled';
+List<Function> Function(List<int>) f11() => throw 'uncalled';
+core.List<core.int> Function(int, [Function]) f12() => throw 'uncalled';
+core.List<core.int> Function(int, {core.List<core.int> x}) f13() =>
+    throw 'uncalled';
+List<int> Function(Function x) f14() => throw 'uncalled';
+List<int> Function(int y, [core.List<core.int> x]) f15() => throw 'uncalled';
+Function([int]) f16() => throw 'uncalled';
+Function({List<Function> x}) f17() => throw 'uncalled';
+Function() f18() => throw 'uncalled';
+void Function(int, [List<Function> x]) f19() => throw 'uncalled';
+void Function([List<int>]) f20() => throw 'uncalled';
+List<Function> Function<A>(List<Function> x) f21() => throw 'uncalled';
+Function<A>(core.List<core.int> x) f22() => throw 'uncalled';
+void Function<A>(List<int> x) f23() => throw 'uncalled';
+
+class U4<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int) x0;
+  late Function Function(List<T>) x1;
+  late core.List<core.int> Function(int y, [core.List<core.int> x]) x2;
+  late Function(int, [List<Function> x]) x3;
+  late Function Function<A>(List<T> x) x4;
+  late int Function(int y, {int x}) Function() x5;
+  late int Function(int, [core.List<core.int> x]) Function() x6;
+  late Function Function(int) Function() x7;
+  late Function Function(int x, [List<Function>]) Function() x8;
+  late Function Function(int y, {List<T> x}) Function() x9;
+  late List<Function> Function([List<Function> x]) Function() x10;
+  late List<Function> Function(List<T>) Function() x11;
+  late core.List<core.int> Function(int, [Function]) Function() x12;
+  late core.List<core.int> Function(int, {core.List<core.int> x}) Function()
+      x13;
+  late List<T> Function(Function x) Function() x14;
+  late List<T> Function(int y, [core.List<core.int> x]) Function() x15;
+  late Function([int]) Function() x16;
+  late Function({List<Function> x}) Function() x17;
+  late Function() Function() x18;
+  late void Function(int, [List<Function> x]) Function() x19;
+  late void Function([List<T>]) Function() x20;
+  late List<Function> Function<A>(List<Function> x) Function() x21;
+  late Function<A>(core.List<core.int> x) Function() x22;
+  late void Function<A>(List<T> x) Function() x23;
+
+  U4({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0) => throw 'uncalled';
+  Function m1(List<T> x0) => throw 'uncalled';
+  core.List<core.int> m2(int y, [core.List<core.int> x = const []]) =>
+      throw 'uncalled';
+  m3(int x0, [List<Function> x = const []]) => throw 'uncalled';
+  Function m4<A>(List<T> x) => throw 'uncalled';
+  int Function(int y, {int x}) m5() => throw 'uncalled';
+  int Function(int, [core.List<core.int> x]) m6() => throw 'uncalled';
+  Function Function(int) m7() => throw 'uncalled';
+  Function Function(int x, [List<Function>]) m8() => throw 'uncalled';
+  Function Function(int y, {List<T> x}) m9() => throw 'uncalled';
+  List<Function> Function([List<Function> x]) m10() => throw 'uncalled';
+  List<Function> Function(List<T>) m11() => throw 'uncalled';
+  core.List<core.int> Function(int, [Function]) m12() => throw 'uncalled';
+  core.List<core.int> Function(int, {core.List<core.int> x}) m13() =>
+      throw 'uncalled';
+  List<T> Function(Function x) m14() => throw 'uncalled';
+  List<T> Function(int y, [core.List<core.int> x]) m15() => throw 'uncalled';
+  Function([int]) m16() => throw 'uncalled';
+  Function({List<Function> x}) m17() => throw 'uncalled';
+  Function() m18() => throw 'uncalled';
+  void Function(int, [List<Function> x]) m19() => throw 'uncalled';
+  void Function([List<T>]) m20() => throw 'uncalled';
+  List<Function> Function<A>(List<Function> x) m21() => throw 'uncalled';
+  Function<A>(core.List<core.int> x) m22() => throw 'uncalled';
+  void Function<A>(List<T> x) m23() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function(List<T>)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<T>) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function(List<T>));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int y, [core.List<core.int> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [core.List<core.int> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(
+        m2 is core.List<core.int> Function(int y, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function(int, [List<Function> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<Function> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int, [List<Function> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function Function<A>(List<T> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<T> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function Function<A>(List<T> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m4 is F4<int>);
+      Expect.equals(true, m4 is F4<bool>);
+      Expect.equals(true, confuse(m4) is F4<int>);
+      Expect.equals(true, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function(int y, {int x}) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {int x}) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, {int x}) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [core.List<core.int> x]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [core.List<core.int> x]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [List<Function>]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [List<Function>]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int x, [List<Function>]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function(int y, {List<T> x}) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {List<T> x}) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function(int y, {List<T> x}) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+    // The static function has its T always set to int.
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isFalse(f9 is F9<bool>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    Expect.isFalse(confuse(f9) is F9<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        x9 = confuse(f9);
+      });
+      Expect.throws(() {
+        l9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        l9 = confuse(f9);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m9 is F9<int>);
+      Expect.equals(tIsBool, m9 is F9<bool>);
+      Expect.equals(tIsInt, confuse(m9) is F9<int>);
+      Expect.equals(tIsBool, confuse(m9) is F9<bool>);
+    }
+  }
+
+  /// List<Function> Function([List<Function> x]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<Function> x]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function([List<Function> x]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(List<T>) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<T>) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(List<T>) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, [Function]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [Function]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(int, [Function]) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, {core.List<core.int> x}) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {core.List<core.int> x}) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int,
+            {core.List<core.int> x})
+        Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(Function x) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(Function x) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(Function x) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [core.List<core.int> x]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [core.List<core.int> x]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int y, [core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([int]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([int]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([int]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({List<Function> x}) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({List<Function> x}) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function({List<Function> x}) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// Function() Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    Function() Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is Function() Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<Function> x]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<Function> x]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function([List<T>]) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function([List<T>]) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function([List<T>]) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<Function> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<Function> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<Function> Function<A>(List<Function> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(core.List<core.int> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(core.List<core.int> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(List<T> x) Function()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<T> x) Function() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>(List<T> x) Function());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+    // The static function has its T always set to int.
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isFalse(f23 is F23<bool>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    Expect.isFalse(confuse(f23) is F23<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        x23 = confuse(f23);
+      });
+      Expect.throws(() {
+        l23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        l23 = confuse(f23);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m23 is F23<int>);
+      Expect.equals(tIsBool, m23 is F23<bool>);
+      Expect.equals(tIsInt, confuse(m23) is F23<int>);
+      Expect.equals(tIsBool, confuse(m23) is F23<bool>);
+    }
+  }
+}
+
+void main() {
+  new U4().runTests();
+  new U4<int>(tIsInt: true).runTests();
+  new U4<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type50_test.dart b/tests/language/function_type/function_type50_test.dart
new file mode 100644
index 0000000..cc83722
--- /dev/null
+++ b/tests/language/function_type/function_type50_test.dart
@@ -0,0 +1,947 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, [List<T>]);
+typedef F1<T> = List<Function> Function([core.List<core.int>]);
+typedef F2<T> = List<T> Function(List<Function>);
+typedef F3<T> = void Function(int y, [Function x]);
+typedef F4<T> = List<A> Function<A>(List<Function> x);
+typedef F5<T> = int Function(int y, {Function x})
+    Function<B extends core.int>();
+typedef F6<T> = int Function(int, [List<T> x]) Function<B extends core.int>();
+typedef F7<T> = Function Function(Function) Function<B extends core.int>();
+typedef F8<T> = Function Function(int x, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int, {int x})
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function([core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(int y, [int x])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int, [List<Function>])
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function(int, {List<T> x})
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(List<Function> x)
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int y, [List<T> x])
+    Function<B extends core.int>();
+typedef F16<T> = Function([Function]) Function<B extends core.int>();
+typedef F17<T> = Function({core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F18<T> = void Function(int y, {int x}) Function<B extends core.int>();
+typedef F19<T> = void Function(int, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F20<T> = int Function<A>(List<T> x) Function<B extends core.int>();
+typedef F21<T> = core.List<core.int> Function<A>()
+    Function<B extends core.int>();
+typedef F22<T> = A Function<A>(A x) Function<B extends core.int>();
+
+int f0(int x0, [List<int> x1 = const []]) => throw 'uncalled';
+List<Function> f1([core.List<core.int> x0 = const []]) => throw 'uncalled';
+List<int> f2(List<Function> x0) => throw 'uncalled';
+void f3(int y, [Function x = _voidFunction]) => throw 'uncalled';
+List<A> f4<A>(List<Function> x) => throw 'uncalled';
+int Function(int y, {Function x}) f5<B extends core.int>() => throw 'uncalled';
+int Function(int, [List<int> x]) f6<B extends core.int>() => throw 'uncalled';
+Function Function(Function) f7<B extends core.int>() => throw 'uncalled';
+Function Function(int x, [core.List<core.int>]) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, {int x}) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function([core.List<core.int> x]) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, [int x]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [List<Function>]) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {List<int> x}) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(List<Function> x) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int y, [List<int> x]) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function([Function]) f16<B extends core.int>() => throw 'uncalled';
+Function({core.List<core.int> x}) f17<B extends core.int>() => throw 'uncalled';
+void Function(int y, {int x}) f18<B extends core.int>() => throw 'uncalled';
+void Function(int, [core.List<core.int> x]) f19<B extends core.int>() =>
+    throw 'uncalled';
+int Function<A>(List<int> x) f20<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function<A>() f21<B extends core.int>() => throw 'uncalled';
+A Function<A>(A x) f22<B extends core.int>() => throw 'uncalled';
+
+class U50<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, [List<T>]) x0;
+  late List<Function> Function([core.List<core.int>]) x1;
+  late List<T> Function(List<Function>) x2;
+  late void Function(int y, [Function x]) x3;
+  late List<A> Function<A>(List<Function> x) x4;
+  late int Function(int y, {Function x}) Function<B extends core.int>() x5;
+  late int Function(int, [List<T> x]) Function<B extends core.int>() x6;
+  late Function Function(Function) Function<B extends core.int>() x7;
+  late Function Function(int x, [core.List<core.int>])
+      Function<B extends core.int>() x8;
+  late List<Function> Function(int, {int x}) Function<B extends core.int>() x9;
+  late List<Function> Function([core.List<core.int> x])
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function(int y, [int x])
+      Function<B extends core.int>() x11;
+  late core.List<core.int> Function(int, [List<Function>])
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function(int, {List<T> x})
+      Function<B extends core.int>() x13;
+  late List<T> Function(List<Function> x) Function<B extends core.int>() x14;
+  late List<T> Function(int y, [List<T> x]) Function<B extends core.int>() x15;
+  late Function([Function]) Function<B extends core.int>() x16;
+  late Function({core.List<core.int> x}) Function<B extends core.int>() x17;
+  late void Function(int y, {int x}) Function<B extends core.int>() x18;
+  late void Function(int, [core.List<core.int> x])
+      Function<B extends core.int>() x19;
+  late int Function<A>(List<T> x) Function<B extends core.int>() x20;
+  late core.List<core.int> Function<A>() Function<B extends core.int>() x21;
+  late A Function<A>(A x) Function<B extends core.int>() x22;
+
+  U50({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, [List<T> x1 = const []]) => throw 'uncalled';
+  List<Function> m1([core.List<core.int> x0 = const []]) => throw 'uncalled';
+  List<T> m2(List<Function> x0) => throw 'uncalled';
+  void m3(int y, [Function x = _voidFunction]) => throw 'uncalled';
+  List<A> m4<A>(List<Function> x) => throw 'uncalled';
+  int Function(int y, {Function x}) m5<B extends core.int>() =>
+      throw 'uncalled';
+  int Function(int, [List<T> x]) m6<B extends core.int>() => throw 'uncalled';
+  Function Function(Function) m7<B extends core.int>() => throw 'uncalled';
+  Function Function(int x, [core.List<core.int>]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, {int x}) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function([core.List<core.int> x]) m10<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [int x]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [List<Function>])
+      m12<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function(int, {List<T> x}) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(List<Function> x) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int y, [List<T> x]) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function([Function]) m16<B extends core.int>() => throw 'uncalled';
+  Function({core.List<core.int> x}) m17<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int y, {int x}) m18<B extends core.int>() => throw 'uncalled';
+  void Function(int, [core.List<core.int> x]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  int Function<A>(List<T> x) m20<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function<A>() m21<B extends core.int>() =>
+      throw 'uncalled';
+  A Function<A>(A x) m22<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// int Function(int, [List<T>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<T>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, [List<T>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function([core.List<core.int>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([core.List<core.int>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function([core.List<core.int>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(List<Function>)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<Function>) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(List<Function>));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int y, [Function x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [Function x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int y, [Function x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<A> Function<A>(List<Function> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<Function> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<A> Function<A>(List<Function> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {Function x}) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {Function x}) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int y, {Function x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [List<T> x]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<T> x]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int, [List<T> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(Function) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(Function) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(Function) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [core.List<core.int>])
+        Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int x, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, {int x}) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {int x}) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, {int x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([core.List<core.int> x]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([core.List<core.int> x])
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int y, [int x]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [int x]) Function<B extends core.int>()
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int y, [int x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [List<Function>]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<Function>])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, {List<T> x}) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {List<T> x})
+        Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int, {List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(List<Function> x) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<Function> x) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [List<T> x]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [List<T> x]) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, [List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([Function]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([Function]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({core.List<core.int> x}) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({core.List<core.int> x}) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function({core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int y, {int x}) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {int x}) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int y, {int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<T> x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<T> x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is int Function<A>(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function<A>() Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>() Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>()
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(A x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(A x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(A x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U50().runTests();
+  new U50<int>(tIsInt: true).runTests();
+  new U50<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type51_test.dart b/tests/language/function_type/function_type51_test.dart
new file mode 100644
index 0000000..d77cc17
--- /dev/null
+++ b/tests/language/function_type/function_type51_test.dart
@@ -0,0 +1,974 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int x, [List<T>]);
+typedef F1<T> = List<Function> Function(int, [core.List<core.int>]);
+typedef F2<T> = List<T> Function([List<Function>]);
+typedef F3<T> = void Function(Function);
+typedef F4<T> = List<A> Function<A>(core.List<core.int> x);
+typedef F5<T> = int Function(int y, {Function x}) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function(int, [List<T> x]) Function<B extends core.int>(
+    int x);
+typedef F7<T> = Function Function(Function) Function<B extends core.int>(int x);
+typedef F8<T> = Function Function(int x, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(int, {int x})
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function([core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(int y, [int x])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function(int, {List<T> x})
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(List<Function> x)
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function(int y, [List<T> x])
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function([Function]) Function<B extends core.int>(int x);
+typedef F17<T> = Function({core.List<core.int> x}) Function<B extends core.int>(
+    int x);
+typedef F18<T> = void Function(int y, {int x}) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function(int, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F20<T> = int Function<A>(List<T> x) Function<B extends core.int>(int x);
+typedef F21<T> = core.List<core.int> Function<A>() Function<B extends core.int>(
+    int x);
+typedef F22<T> = A Function<A>(A x) Function<B extends core.int>(int x);
+
+int f0(int x, [List<int> x0 = const []]) => throw 'uncalled';
+List<Function> f1(int x0, [core.List<core.int> x1 = const []]) =>
+    throw 'uncalled';
+List<int> f2([List<Function> x0 = const []]) => throw 'uncalled';
+void f3(Function x0) => throw 'uncalled';
+List<A> f4<A>(core.List<core.int> x) => throw 'uncalled';
+int Function(int y, {Function x}) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function(int, [List<int> x]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(Function) f7<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int x, [core.List<core.int>]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, {int x}) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function([core.List<core.int> x]) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, [int x]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [List<Function>]) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {List<int> x}) f13<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function(List<Function> x) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int y, [List<int> x]) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function([Function]) f16<B extends core.int>(int x) => throw 'uncalled';
+Function({core.List<core.int> x}) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int y, {int x}) f18<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int, [core.List<core.int> x]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function<A>(List<int> x) f20<B extends core.int>(int x) => throw 'uncalled';
+core.List<core.int> Function<A>() f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+A Function<A>(A x) f22<B extends core.int>(int x) => throw 'uncalled';
+
+class U51<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int x, [List<T>]) x0;
+  late List<Function> Function(int, [core.List<core.int>]) x1;
+  late List<T> Function([List<Function>]) x2;
+  late void Function(Function) x3;
+  late List<A> Function<A>(core.List<core.int> x) x4;
+  late int Function(int y, {Function x}) Function<B extends core.int>(int x) x5;
+  late int Function(int, [List<T> x]) Function<B extends core.int>(int x) x6;
+  late Function Function(Function) Function<B extends core.int>(int x) x7;
+  late Function Function(int x, [core.List<core.int>])
+      Function<B extends core.int>(int x) x8;
+  late List<Function> Function(int, {int x}) Function<B extends core.int>(int x)
+      x9;
+  late List<Function> Function([core.List<core.int> x])
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function(int y, [int x])
+      Function<B extends core.int>(int x) x11;
+  late core.List<core.int> Function(int, [List<Function>])
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function(int, {List<T> x})
+      Function<B extends core.int>(int x) x13;
+  late List<T> Function(List<Function> x) Function<B extends core.int>(int x)
+      x14;
+  late List<T> Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+      x15;
+  late Function([Function]) Function<B extends core.int>(int x) x16;
+  late Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+      x17;
+  late void Function(int y, {int x}) Function<B extends core.int>(int x) x18;
+  late void Function(int, [core.List<core.int> x]) Function<B extends core.int>(
+      int x) x19;
+  late int Function<A>(List<T> x) Function<B extends core.int>(int x) x20;
+  late core.List<core.int> Function<A>() Function<B extends core.int>(int x)
+      x21;
+  late A Function<A>(A x) Function<B extends core.int>(int x) x22;
+
+  U51({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x, [List<T> x0 = const []]) => throw 'uncalled';
+  List<Function> m1(int x0, [core.List<core.int> x1 = const []]) =>
+      throw 'uncalled';
+  List<T> m2([List<Function> x0 = const []]) => throw 'uncalled';
+  void m3(Function x0) => throw 'uncalled';
+  List<A> m4<A>(core.List<core.int> x) => throw 'uncalled';
+  int Function(int y, {Function x}) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int, [List<T> x]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(Function) m7<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(int x, [core.List<core.int>]) m8<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, {int x}) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function([core.List<core.int> x]) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [int x]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [List<Function>]) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {List<T> x}) m13<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function(List<Function> x) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, [List<T> x]) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function([Function]) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function({core.List<core.int> x}) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int y, {int x}) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int, [core.List<core.int> x]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function<A>(List<T> x) m20<B extends core.int>(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>() m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  A Function<A>(A x) m22<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// int Function(int x, [List<T>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [List<T>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int x, [List<T>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, [core.List<core.int>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [core.List<core.int>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, [core.List<core.int>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function([List<Function>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<Function>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function([List<Function>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(Function)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(Function) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(Function));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<A> Function<A>(core.List<core.int> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(core.List<core.int> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<A> Function<A>(core.List<core.int> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {Function x}) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {Function x}) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [List<T> x]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<T> x]) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(Function) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(Function) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(Function) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [core.List<core.int>])
+        Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int x, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int, {int x}) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {int x}) Function<B extends core.int>(int x)
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, {int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([core.List<core.int> x])
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int y, [int x]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [int x]) Function<B extends core.int>(
+        int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int y, [int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [List<Function>]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<Function>])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, {List<T> x}) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {List<T> x}) Function<B extends core.int>(
+        int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(List<Function> x) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<Function> x) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+        l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([Function]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([Function]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function([Function]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({core.List<core.int> x}) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function({core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int y, {int x}) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {int x}) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, {int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [core.List<core.int> x]) Function<B extends core.int>(
+        int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<T> x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<T> x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is int Function<A>(List<T> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function<A>() Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>() Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>()
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(A x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(A x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is A Function<A>(A x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U51().runTests();
+  new U51<int>(tIsInt: true).runTests();
+  new U51<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type52_test.dart b/tests/language/function_type/function_type52_test.dart
new file mode 100644
index 0000000..9e3ad9f
--- /dev/null
+++ b/tests/language/function_type/function_type52_test.dart
@@ -0,0 +1,896 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function({List<T> x});
+typedef F1<T> = List<Function> Function(int x, [core.List<core.int>]);
+typedef F2<T> = List<T> Function(int, [List<Function>]);
+typedef F3<T> = void Function([Function]);
+typedef F4<T> = List<A> Function<A>(List<T> x);
+typedef F5<T> = int Function(List<Function> x) Function();
+typedef F6<T> = int Function(int y, [List<T> x]) Function();
+typedef F7<T> = Function Function([Function]) Function();
+typedef F8<T> = Function Function({core.List<core.int> x}) Function();
+typedef F9<T> = List<Function> Function(int y, {int x}) Function();
+typedef F10<T> = List<Function> Function(int, [core.List<core.int> x])
+    Function();
+typedef F11<T> = core.List<core.int> Function(int) Function();
+typedef F12<T> = core.List<core.int> Function(int x, [List<Function>])
+    Function();
+typedef F13<T> = core.List<core.int> Function(int y, {List<T> x}) Function();
+typedef F14<T> = List<T> Function([List<Function> x]) Function();
+typedef F15<T> = List<T> Function(List<T>) Function();
+typedef F16<T> = Function(int, [Function]) Function();
+typedef F17<T> = Function(int, {core.List<core.int> x}) Function();
+typedef F18<T> = void Function(Function x) Function();
+typedef F19<T> = void Function(int y, [core.List<core.int> x]) Function();
+typedef F20<T> = int Function<A>() Function();
+typedef F21<T> = core.List<core.int> Function<A>(A x) Function();
+typedef F22<T> = A Function<A>(List<A> x) Function();
+
+int f0({List<int> x = const []}) => throw 'uncalled';
+List<Function> f1(int x, [core.List<core.int> x0 = const []]) =>
+    throw 'uncalled';
+List<int> f2(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+void f3([Function x0 = _voidFunction]) => throw 'uncalled';
+List<A> f4<A>(List<int> x) => throw 'uncalled';
+int Function(List<Function> x) f5() => throw 'uncalled';
+int Function(int y, [List<int> x]) f6() => throw 'uncalled';
+Function Function([Function]) f7() => throw 'uncalled';
+Function Function({core.List<core.int> x}) f8() => throw 'uncalled';
+List<Function> Function(int y, {int x}) f9() => throw 'uncalled';
+List<Function> Function(int, [core.List<core.int> x]) f10() => throw 'uncalled';
+core.List<core.int> Function(int) f11() => throw 'uncalled';
+core.List<core.int> Function(int x, [List<Function>]) f12() => throw 'uncalled';
+core.List<core.int> Function(int y, {List<int> x}) f13() => throw 'uncalled';
+List<int> Function([List<Function> x]) f14() => throw 'uncalled';
+List<int> Function(List<int>) f15() => throw 'uncalled';
+Function(int, [Function]) f16() => throw 'uncalled';
+Function(int, {core.List<core.int> x}) f17() => throw 'uncalled';
+void Function(Function x) f18() => throw 'uncalled';
+void Function(int y, [core.List<core.int> x]) f19() => throw 'uncalled';
+int Function<A>() f20() => throw 'uncalled';
+core.List<core.int> Function<A>(A x) f21() => throw 'uncalled';
+A Function<A>(List<A> x) f22() => throw 'uncalled';
+
+class U52<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function({List<T> x}) x0;
+  late List<Function> Function(int x, [core.List<core.int>]) x1;
+  late List<T> Function(int, [List<Function>]) x2;
+  late void Function([Function]) x3;
+  late List<A> Function<A>(List<T> x) x4;
+  late int Function(List<Function> x) Function() x5;
+  late int Function(int y, [List<T> x]) Function() x6;
+  late Function Function([Function]) Function() x7;
+  late Function Function({core.List<core.int> x}) Function() x8;
+  late List<Function> Function(int y, {int x}) Function() x9;
+  late List<Function> Function(int, [core.List<core.int> x]) Function() x10;
+  late core.List<core.int> Function(int) Function() x11;
+  late core.List<core.int> Function(int x, [List<Function>]) Function() x12;
+  late core.List<core.int> Function(int y, {List<T> x}) Function() x13;
+  late List<T> Function([List<Function> x]) Function() x14;
+  late List<T> Function(List<T>) Function() x15;
+  late Function(int, [Function]) Function() x16;
+  late Function(int, {core.List<core.int> x}) Function() x17;
+  late void Function(Function x) Function() x18;
+  late void Function(int y, [core.List<core.int> x]) Function() x19;
+  late int Function<A>() Function() x20;
+  late core.List<core.int> Function<A>(A x) Function() x21;
+  late A Function<A>(List<A> x) Function() x22;
+
+  U52({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0({List<T> x = const []}) => throw 'uncalled';
+  List<Function> m1(int x, [core.List<core.int> x0 = const []]) =>
+      throw 'uncalled';
+  List<T> m2(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+  void m3([Function x0 = _voidFunction]) => throw 'uncalled';
+  List<A> m4<A>(List<T> x) => throw 'uncalled';
+  int Function(List<Function> x) m5() => throw 'uncalled';
+  int Function(int y, [List<T> x]) m6() => throw 'uncalled';
+  Function Function([Function]) m7() => throw 'uncalled';
+  Function Function({core.List<core.int> x}) m8() => throw 'uncalled';
+  List<Function> Function(int y, {int x}) m9() => throw 'uncalled';
+  List<Function> Function(int, [core.List<core.int> x]) m10() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int) m11() => throw 'uncalled';
+  core.List<core.int> Function(int x, [List<Function>]) m12() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {List<T> x}) m13() => throw 'uncalled';
+  List<T> Function([List<Function> x]) m14() => throw 'uncalled';
+  List<T> Function(List<T>) m15() => throw 'uncalled';
+  Function(int, [Function]) m16() => throw 'uncalled';
+  Function(int, {core.List<core.int> x}) m17() => throw 'uncalled';
+  void Function(Function x) m18() => throw 'uncalled';
+  void Function(int y, [core.List<core.int> x]) m19() => throw 'uncalled';
+  int Function<A>() m20() => throw 'uncalled';
+  core.List<core.int> Function<A>(A x) m21() => throw 'uncalled';
+  A Function<A>(List<A> x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// int Function({List<T> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function({List<T> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function({List<T> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function(int x, [core.List<core.int>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [core.List<core.int>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int x, [core.List<core.int>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, [List<Function>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<Function>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, [List<Function>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function([Function])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function([Function]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function([Function]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<A> Function<A>(List<T> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<T> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<A> Function<A>(List<T> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m4 is F4<int>);
+      Expect.equals(true, m4 is F4<bool>);
+      Expect.equals(true, confuse(m4) is F4<int>);
+      Expect.equals(true, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function(List<Function> x) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(List<Function> x) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(List<Function> x) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, [List<T> x]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [List<T> x]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int y, [List<T> x]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function([Function]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([Function]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([Function]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({core.List<core.int> x}) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({core.List<core.int> x}) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function({core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int y, {int x}) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {int x}) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int y, {int x}) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [core.List<core.int> x]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [core.List<core.int> x]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [core.List<core.int> x])
+        Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int x, [List<Function>]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [List<Function>]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int x, [List<Function>])
+        Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, {List<T> x}) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {List<T> x}) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function(int y, {List<T> x}) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([List<Function> x]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<Function> x]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([List<Function> x]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(List<T>) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<T>) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(List<T>) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [Function]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [Function]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [Function]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {core.List<core.int> x}) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {core.List<core.int> x}) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, {core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(Function x) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(Function x) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(Function x) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [core.List<core.int> x]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [core.List<core.int> x]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int y, [core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>() Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>() Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>() Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(A x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(A x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(A x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<A> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<A> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(List<A> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U52().runTests();
+  new U52<int>(tIsInt: true).runTests();
+  new U52<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type53_test.dart b/tests/language/function_type/function_type53_test.dart
new file mode 100644
index 0000000..9bf4d02
--- /dev/null
+++ b/tests/language/function_type/function_type53_test.dart
@@ -0,0 +1,879 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, {List<T> x});
+typedef F1<T> = List<Function> Function({core.List<core.int> x});
+typedef F2<T> = List<T> Function(int x, [List<Function>]);
+typedef F3<T> = void Function(int, [Function]);
+typedef F4<T> = List<A> Function<A>();
+typedef F5<T> = int Function(List<Function> x) Function(int x);
+typedef F6<T> = int Function(int y, [List<T> x]) Function(int x);
+typedef F7<T> = Function Function([Function]) Function(int x);
+typedef F8<T> = Function Function({core.List<core.int> x}) Function(int x);
+typedef F9<T> = List<Function> Function(int y, {int x}) Function(int x);
+typedef F10<T> = List<Function> Function(int, [core.List<core.int> x]) Function(
+    int x);
+typedef F11<T> = core.List<core.int> Function(int) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int x, [List<Function>]) Function(
+    int x);
+typedef F13<T> = core.List<core.int> Function(int y, {List<T> x}) Function(
+    int x);
+typedef F14<T> = List<T> Function([List<Function> x]) Function(int x);
+typedef F15<T> = List<T> Function(List<T>) Function(int x);
+typedef F16<T> = Function(int, [Function]) Function(int x);
+typedef F17<T> = Function(int, {core.List<core.int> x}) Function(int x);
+typedef F18<T> = void Function(Function x) Function(int x);
+typedef F19<T> = void Function(int y, [core.List<core.int> x]) Function(int x);
+typedef F20<T> = int Function<A>() Function(int x);
+typedef F21<T> = core.List<core.int> Function<A>(A x) Function(int x);
+typedef F22<T> = A Function<A>(List<A> x) Function(int x);
+
+int f0(int x0, {List<int> x = const []}) => throw 'uncalled';
+List<Function> f1({core.List<core.int> x = const []}) => throw 'uncalled';
+List<int> f2(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+void f3(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+List<A> f4<A>() => throw 'uncalled';
+int Function(List<Function> x) f5(int x) => throw 'uncalled';
+int Function(int y, [List<int> x]) f6(int x) => throw 'uncalled';
+Function Function([Function]) f7(int x) => throw 'uncalled';
+Function Function({core.List<core.int> x}) f8(int x) => throw 'uncalled';
+List<Function> Function(int y, {int x}) f9(int x) => throw 'uncalled';
+List<Function> Function(int, [core.List<core.int> x]) f10(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int x, [List<Function>]) f12(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, {List<int> x}) f13(int x) =>
+    throw 'uncalled';
+List<int> Function([List<Function> x]) f14(int x) => throw 'uncalled';
+List<int> Function(List<int>) f15(int x) => throw 'uncalled';
+Function(int, [Function]) f16(int x) => throw 'uncalled';
+Function(int, {core.List<core.int> x}) f17(int x) => throw 'uncalled';
+void Function(Function x) f18(int x) => throw 'uncalled';
+void Function(int y, [core.List<core.int> x]) f19(int x) => throw 'uncalled';
+int Function<A>() f20(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(A x) f21(int x) => throw 'uncalled';
+A Function<A>(List<A> x) f22(int x) => throw 'uncalled';
+
+class U53<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, {List<T> x}) x0;
+  late List<Function> Function({core.List<core.int> x}) x1;
+  late List<T> Function(int x, [List<Function>]) x2;
+  late void Function(int, [Function]) x3;
+  late List<A> Function<A>() x4;
+  late int Function(List<Function> x) Function(int x) x5;
+  late int Function(int y, [List<T> x]) Function(int x) x6;
+  late Function Function([Function]) Function(int x) x7;
+  late Function Function({core.List<core.int> x}) Function(int x) x8;
+  late List<Function> Function(int y, {int x}) Function(int x) x9;
+  late List<Function> Function(int, [core.List<core.int> x]) Function(int x)
+      x10;
+  late core.List<core.int> Function(int) Function(int x) x11;
+  late core.List<core.int> Function(int x, [List<Function>]) Function(int x)
+      x12;
+  late core.List<core.int> Function(int y, {List<T> x}) Function(int x) x13;
+  late List<T> Function([List<Function> x]) Function(int x) x14;
+  late List<T> Function(List<T>) Function(int x) x15;
+  late Function(int, [Function]) Function(int x) x16;
+  late Function(int, {core.List<core.int> x}) Function(int x) x17;
+  late void Function(Function x) Function(int x) x18;
+  late void Function(int y, [core.List<core.int> x]) Function(int x) x19;
+  late int Function<A>() Function(int x) x20;
+  late core.List<core.int> Function<A>(A x) Function(int x) x21;
+  late A Function<A>(List<A> x) Function(int x) x22;
+
+  U53({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, {List<T> x = const []}) => throw 'uncalled';
+  List<Function> m1({core.List<core.int> x = const []}) => throw 'uncalled';
+  List<T> m2(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+  void m3(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+  List<A> m4<A>() => throw 'uncalled';
+  int Function(List<Function> x) m5(int x) => throw 'uncalled';
+  int Function(int y, [List<T> x]) m6(int x) => throw 'uncalled';
+  Function Function([Function]) m7(int x) => throw 'uncalled';
+  Function Function({core.List<core.int> x}) m8(int x) => throw 'uncalled';
+  List<Function> Function(int y, {int x}) m9(int x) => throw 'uncalled';
+  List<Function> Function(int, [core.List<core.int> x]) m10(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int x, [List<Function>]) m12(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {List<T> x}) m13(int x) =>
+      throw 'uncalled';
+  List<T> Function([List<Function> x]) m14(int x) => throw 'uncalled';
+  List<T> Function(List<T>) m15(int x) => throw 'uncalled';
+  Function(int, [Function]) m16(int x) => throw 'uncalled';
+  Function(int, {core.List<core.int> x}) m17(int x) => throw 'uncalled';
+  void Function(Function x) m18(int x) => throw 'uncalled';
+  void Function(int y, [core.List<core.int> x]) m19(int x) => throw 'uncalled';
+  int Function<A>() m20(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(A x) m21(int x) => throw 'uncalled';
+  A Function<A>(List<A> x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// int Function(int, {List<T> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {List<T> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, {List<T> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function({core.List<core.int> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({core.List<core.int> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function({core.List<core.int> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int x, [List<Function>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [List<Function>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int x, [List<Function>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, [Function])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [Function]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, [Function]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<A> Function<A>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<A> Function<A>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(List<Function> x) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(List<Function> x) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, [List<T> x]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [List<T> x]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int y, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function([Function]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([Function]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([Function]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({core.List<core.int> x}) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({core.List<core.int> x}) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function({core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int y, {int x}) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {int x}) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int y, {int x}) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [core.List<core.int> x]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [core.List<core.int> x]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [core.List<core.int> x])
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int x, [List<Function>]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [List<Function>]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int x, [List<Function>])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, {List<T> x}) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {List<T> x}) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int y, {List<T> x})
+        Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([List<Function> x]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<Function> x]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(List<T>) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<T>) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(List<T>) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [Function]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [Function]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [Function]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {core.List<core.int> x}) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {core.List<core.int> x}) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int, {core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(Function x) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(Function x) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(Function x) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [core.List<core.int> x]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [core.List<core.int> x]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int y, [core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>() Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>() Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>() Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(A x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(A x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(A x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<A> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<A> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is A Function<A>(List<A> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U53().runTests();
+  new U53<int>(tIsInt: true).runTests();
+  new U53<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type54_test.dart b/tests/language/function_type/function_type54_test.dart
new file mode 100644
index 0000000..1e3208c
--- /dev/null
+++ b/tests/language/function_type/function_type54_test.dart
@@ -0,0 +1,921 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int y, {List<T> x});
+typedef F1<T> = List<Function> Function(int, {core.List<core.int> x});
+typedef F2<T> = List<T> Function({List<Function> x});
+typedef F3<T> = void Function(int x, [Function]);
+typedef F4<T> = List<A> Function<A>(A x);
+typedef F5<T> = int Function(List<Function> x) Function<B extends core.int>();
+typedef F6<T> = int Function(int y, [List<T> x]) Function<B extends core.int>();
+typedef F7<T> = Function Function([Function]) Function<B extends core.int>();
+typedef F8<T> = Function Function({core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int y, {int x})
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(int)
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int x, [List<Function>])
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function(int y, {List<T> x})
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function([List<Function> x])
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(List<T>) Function<B extends core.int>();
+typedef F16<T> = Function(int, [Function]) Function<B extends core.int>();
+typedef F17<T> = Function(int, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F18<T> = void Function(Function x) Function<B extends core.int>();
+typedef F19<T> = void Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F20<T> = int Function<A>() Function<B extends core.int>();
+typedef F21<T> = core.List<core.int> Function<A>(A x)
+    Function<B extends core.int>();
+typedef F22<T> = A Function<A>(List<A> x) Function<B extends core.int>();
+
+int f0(int y, {List<int> x = const []}) => throw 'uncalled';
+List<Function> f1(int x0, {core.List<core.int> x = const []}) =>
+    throw 'uncalled';
+List<int> f2({List<Function> x = const []}) => throw 'uncalled';
+void f3(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+List<A> f4<A>(A x) => throw 'uncalled';
+int Function(List<Function> x) f5<B extends core.int>() => throw 'uncalled';
+int Function(int y, [List<int> x]) f6<B extends core.int>() => throw 'uncalled';
+Function Function([Function]) f7<B extends core.int>() => throw 'uncalled';
+Function Function({core.List<core.int> x}) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int y, {int x}) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, [core.List<core.int> x])
+    f10<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function(int) f11<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function(int x, [List<Function>])
+    f12<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function(int y, {List<int> x}) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function([List<Function> x]) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(List<int>) f15<B extends core.int>() => throw 'uncalled';
+Function(int, [Function]) f16<B extends core.int>() => throw 'uncalled';
+Function(int, {core.List<core.int> x}) f17<B extends core.int>() =>
+    throw 'uncalled';
+void Function(Function x) f18<B extends core.int>() => throw 'uncalled';
+void Function(int y, [core.List<core.int> x]) f19<B extends core.int>() =>
+    throw 'uncalled';
+int Function<A>() f20<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function<A>(A x) f21<B extends core.int>() =>
+    throw 'uncalled';
+A Function<A>(List<A> x) f22<B extends core.int>() => throw 'uncalled';
+
+class U54<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int y, {List<T> x}) x0;
+  late List<Function> Function(int, {core.List<core.int> x}) x1;
+  late List<T> Function({List<Function> x}) x2;
+  late void Function(int x, [Function]) x3;
+  late List<A> Function<A>(A x) x4;
+  late int Function(List<Function> x) Function<B extends core.int>() x5;
+  late int Function(int y, [List<T> x]) Function<B extends core.int>() x6;
+  late Function Function([Function]) Function<B extends core.int>() x7;
+  late Function Function({core.List<core.int> x}) Function<B extends core.int>()
+      x8;
+  late List<Function> Function(int y, {int x}) Function<B extends core.int>()
+      x9;
+  late List<Function> Function(int, [core.List<core.int> x])
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function(int) Function<B extends core.int>() x11;
+  late core.List<core.int> Function(int x, [List<Function>])
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function(int y, {List<T> x})
+      Function<B extends core.int>() x13;
+  late List<T> Function([List<Function> x]) Function<B extends core.int>() x14;
+  late List<T> Function(List<T>) Function<B extends core.int>() x15;
+  late Function(int, [Function]) Function<B extends core.int>() x16;
+  late Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+      x17;
+  late void Function(Function x) Function<B extends core.int>() x18;
+  late void Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>() x19;
+  late int Function<A>() Function<B extends core.int>() x20;
+  late core.List<core.int> Function<A>(A x) Function<B extends core.int>() x21;
+  late A Function<A>(List<A> x) Function<B extends core.int>() x22;
+
+  U54({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int y, {List<T> x = const []}) => throw 'uncalled';
+  List<Function> m1(int x0, {core.List<core.int> x = const []}) =>
+      throw 'uncalled';
+  List<T> m2({List<Function> x = const []}) => throw 'uncalled';
+  void m3(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+  List<A> m4<A>(A x) => throw 'uncalled';
+  int Function(List<Function> x) m5<B extends core.int>() => throw 'uncalled';
+  int Function(int y, [List<T> x]) m6<B extends core.int>() => throw 'uncalled';
+  Function Function([Function]) m7<B extends core.int>() => throw 'uncalled';
+  Function Function({core.List<core.int> x}) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int y, {int x}) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, [core.List<core.int> x])
+      m10<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function(int) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x, [List<Function>])
+      m12<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function(int y, {List<T> x}) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function([List<Function> x]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(List<T>) m15<B extends core.int>() => throw 'uncalled';
+  Function(int, [Function]) m16<B extends core.int>() => throw 'uncalled';
+  Function(int, {core.List<core.int> x}) m17<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(Function x) m18<B extends core.int>() => throw 'uncalled';
+  void Function(int y, [core.List<core.int> x]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  int Function<A>() m20<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function<A>(A x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  A Function<A>(List<A> x) m22<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// int Function(int y, {List<T> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {List<T> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int y, {List<T> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+    // The static function has its T always set to int.
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isFalse(f0 is F0<bool>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    Expect.isFalse(confuse(f0) is F0<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        x0 = confuse(f0);
+      });
+      Expect.throws(() {
+        l0 = (f0 as dynamic);
+      });
+      Expect.throws(() {
+        l0 = confuse(f0);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m0 is F0<int>);
+      Expect.equals(true, m0 is F0<bool>);
+      Expect.equals(true, confuse(m0) is F0<int>);
+      Expect.equals(true, confuse(m0) is F0<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, {core.List<core.int> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {core.List<core.int> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function({List<Function> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({List<Function> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function({List<Function> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int x, [Function])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [Function]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int x, [Function]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<A> Function<A>(A x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(A x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<A> Function<A>(A x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(List<Function> x) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(List<Function> x) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(List<Function> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, [List<T> x]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [List<T> x]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int y, [List<T> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function([Function]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([Function]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function([Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({core.List<core.int> x}) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({core.List<core.int> x}) Function<B extends core.int>()
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function({core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int y, {int x}) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {int x}) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int y, {int x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [core.List<core.int> x])
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int x, [List<Function>]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [List<Function>])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int x, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, {List<T> x}) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {List<T> x})
+        Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int y, {List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([List<Function> x]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<Function> x]) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(List<T>) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<T>) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(List<T>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [Function]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [Function]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int, [Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {core.List<core.int> x}) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(Function x) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(Function x) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [core.List<core.int> x]) Function<B extends core.int>()
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>() Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>() Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>() Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(A x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(A x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(A x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<A> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<A> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is A Function<A>(List<A> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U54().runTests();
+  new U54<int>(tIsInt: true).runTests();
+  new U54<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type55_test.dart b/tests/language/function_type/function_type55_test.dart
new file mode 100644
index 0000000..5722ccb
--- /dev/null
+++ b/tests/language/function_type/function_type55_test.dart
@@ -0,0 +1,921 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function();
+typedef F1<T> = List<Function> Function(int y, {core.List<core.int> x});
+typedef F2<T> = List<T> Function(int, {List<Function> x});
+typedef F3<T> = void Function({Function x});
+typedef F4<T> = List<A> Function<A>(List<A> x);
+typedef F5<T> = int Function(List<Function> x) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function(int y, [List<T> x]) Function<B extends core.int>(
+    int x);
+typedef F7<T> = Function Function([Function]) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function({core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(int y, {int x})
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(int, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(int) Function<B extends core.int>(
+    int x);
+typedef F12<T> = core.List<core.int> Function(int x, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function(int y, {List<T> x})
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function([List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function(List<T>) Function<B extends core.int>(int x);
+typedef F16<T> = Function(int, [Function]) Function<B extends core.int>(int x);
+typedef F17<T> = Function(int, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F18<T> = void Function(Function x) Function<B extends core.int>(int x);
+typedef F19<T> = void Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F20<T> = int Function<A>() Function<B extends core.int>(int x);
+typedef F21<T> = core.List<core.int> Function<A>(A x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = A Function<A>(List<A> x) Function<B extends core.int>(int x);
+
+int f0() => throw 'uncalled';
+List<Function> f1(int y, {core.List<core.int> x = const []}) =>
+    throw 'uncalled';
+List<int> f2(int x0, {List<Function> x = const []}) => throw 'uncalled';
+void f3({Function x = _voidFunction}) => throw 'uncalled';
+List<A> f4<A>(List<A> x) => throw 'uncalled';
+int Function(List<Function> x) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function(int y, [List<int> x]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function([Function]) f7<B extends core.int>(int x) => throw 'uncalled';
+Function Function({core.List<core.int> x}) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int y, {int x}) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, [core.List<core.int> x]) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int x, [List<Function>]) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, {List<int> x}) f13<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function([List<Function> x]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(List<int>) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int, [Function]) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(int, {core.List<core.int> x}) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(Function x) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(int y, [core.List<core.int> x]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function<A>() f20<B extends core.int>(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(A x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+A Function<A>(List<A> x) f22<B extends core.int>(int x) => throw 'uncalled';
+
+class U55<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function() x0;
+  late List<Function> Function(int y, {core.List<core.int> x}) x1;
+  late List<T> Function(int, {List<Function> x}) x2;
+  late void Function({Function x}) x3;
+  late List<A> Function<A>(List<A> x) x4;
+  late int Function(List<Function> x) Function<B extends core.int>(int x) x5;
+  late int Function(int y, [List<T> x]) Function<B extends core.int>(int x) x6;
+  late Function Function([Function]) Function<B extends core.int>(int x) x7;
+  late Function Function({core.List<core.int> x}) Function<B extends core.int>(
+      int x) x8;
+  late List<Function> Function(int y, {int x}) Function<B extends core.int>(
+      int x) x9;
+  late List<Function> Function(int, [core.List<core.int> x])
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function(int) Function<B extends core.int>(int x)
+      x11;
+  late core.List<core.int> Function(int x, [List<Function>])
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function(int y, {List<T> x})
+      Function<B extends core.int>(int x) x13;
+  late List<T> Function([List<Function> x]) Function<B extends core.int>(int x)
+      x14;
+  late List<T> Function(List<T>) Function<B extends core.int>(int x) x15;
+  late Function(int, [Function]) Function<B extends core.int>(int x) x16;
+  late Function(int, {core.List<core.int> x}) Function<B extends core.int>(
+      int x) x17;
+  late void Function(Function x) Function<B extends core.int>(int x) x18;
+  late void Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>(int x) x19;
+  late int Function<A>() Function<B extends core.int>(int x) x20;
+  late core.List<core.int> Function<A>(A x) Function<B extends core.int>(int x)
+      x21;
+  late A Function<A>(List<A> x) Function<B extends core.int>(int x) x22;
+
+  U55({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0() => throw 'uncalled';
+  List<Function> m1(int y, {core.List<core.int> x = const []}) =>
+      throw 'uncalled';
+  List<T> m2(int x0, {List<Function> x = const []}) => throw 'uncalled';
+  void m3({Function x = _voidFunction}) => throw 'uncalled';
+  List<A> m4<A>(List<A> x) => throw 'uncalled';
+  int Function(List<Function> x) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int y, [List<T> x]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function([Function]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function({core.List<core.int> x}) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, {int x}) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, [core.List<core.int> x]) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x, [List<Function>]) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {List<T> x}) m13<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function([List<Function> x]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(List<T>) m15<B extends core.int>(int x) => throw 'uncalled';
+  Function(int, [Function]) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(int, {core.List<core.int> x}) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(Function x) m18<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int y, [core.List<core.int> x]) m19<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  int Function<A>() m20<B extends core.int>(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(A x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  A Function<A>(List<A> x) m22<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// int Function()
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function() l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function());
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int y, {core.List<core.int> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {core.List<core.int> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(
+        m1 is List<Function> Function(int y, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, {List<Function> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {List<Function> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, {List<Function> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function({Function x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function({Function x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function({Function x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<A> Function<A>(List<A> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<A> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<A> Function<A>(List<A> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(List<Function> x) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(List<Function> x) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [List<T> x]) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int y, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function([Function]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([Function]) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({core.List<core.int> x}) Function<B extends core.int>(
+        int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function({core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(int y, {int x}) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {int x}) Function<B extends core.int>(int x)
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int y, {int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [core.List<core.int> x])
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int) Function<B extends core.int>(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [List<Function>])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int x, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {List<T> x})
+        Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int y, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([List<Function> x]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<Function> x]) Function<B extends core.int>(int x)
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(List<T>) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<T>) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(List<T>) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [Function]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [Function]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int, [Function]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {core.List<core.int> x}) Function<B extends core.int>(int x)
+        l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(Function x) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(Function x) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(Function x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [core.List<core.int> x]) Function<B extends core.int>(
+        int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>() Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>() Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(A x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(A x) Function<B extends core.int>(int x)
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(A x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// A Function<A>(List<A> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    A Function<A>(List<A> x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is A Function<A>(List<A> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U55().runTests();
+  new U55<int>(tIsInt: true).runTests();
+  new U55<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type56_test.dart b/tests/language/function_type/function_type56_test.dart
new file mode 100644
index 0000000..0ba9a93
--- /dev/null
+++ b/tests/language/function_type/function_type56_test.dart
@@ -0,0 +1,842 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int x);
+typedef F1<T> = List<Function> Function(List<T> x);
+typedef F2<T> = List<T> Function(int y, {List<Function> x});
+typedef F3<T> = void Function(int, {Function x});
+typedef F4<T> = void Function<A>(int x);
+typedef F5<T> = int Function([List<Function> x]) Function();
+typedef F6<T> = int Function(List<T>) Function();
+typedef F7<T> = Function Function(int, [Function]) Function();
+typedef F8<T> = Function Function(int, {core.List<core.int> x}) Function();
+typedef F9<T> = List<Function> Function(Function x) Function();
+typedef F10<T> = List<Function> Function(int y, [core.List<core.int> x])
+    Function();
+typedef F11<T> = core.List<core.int> Function([int]) Function();
+typedef F12<T> = core.List<core.int> Function({List<Function> x}) Function();
+typedef F13<T> = core.List<core.int> Function() Function();
+typedef F14<T> = List<T> Function(int, [List<Function> x]) Function();
+typedef F15<T> = List<T> Function([List<T>]) Function();
+typedef F16<T> = Function(int x, [Function]) Function();
+typedef F17<T> = Function(int y, {core.List<core.int> x}) Function();
+typedef F18<T> = void Function([Function x]) Function();
+typedef F19<T> = void Function(core.List<core.int>) Function();
+typedef F20<T> = int Function<A>(A x) Function();
+typedef F21<T> = core.List<core.int> Function<A>(List<A> x) Function();
+typedef F22<T> = List<A> Function<A>(int x) Function();
+
+Function f0(int x) => throw 'uncalled';
+List<Function> f1(List<int> x) => throw 'uncalled';
+List<int> f2(int y, {List<Function> x = const []}) => throw 'uncalled';
+void f3(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+void f4<A>(int x) => throw 'uncalled';
+int Function([List<Function> x]) f5() => throw 'uncalled';
+int Function(List<int>) f6() => throw 'uncalled';
+Function Function(int, [Function]) f7() => throw 'uncalled';
+Function Function(int, {core.List<core.int> x}) f8() => throw 'uncalled';
+List<Function> Function(Function x) f9() => throw 'uncalled';
+List<Function> Function(int y, [core.List<core.int> x]) f10() =>
+    throw 'uncalled';
+core.List<core.int> Function([int]) f11() => throw 'uncalled';
+core.List<core.int> Function({List<Function> x}) f12() => throw 'uncalled';
+core.List<core.int> Function() f13() => throw 'uncalled';
+List<int> Function(int, [List<Function> x]) f14() => throw 'uncalled';
+List<int> Function([List<int>]) f15() => throw 'uncalled';
+Function(int x, [Function]) f16() => throw 'uncalled';
+Function(int y, {core.List<core.int> x}) f17() => throw 'uncalled';
+void Function([Function x]) f18() => throw 'uncalled';
+void Function(core.List<core.int>) f19() => throw 'uncalled';
+int Function<A>(A x) f20() => throw 'uncalled';
+core.List<core.int> Function<A>(List<A> x) f21() => throw 'uncalled';
+List<A> Function<A>(int x) f22() => throw 'uncalled';
+
+class U56<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int x) x0;
+  late List<Function> Function(List<T> x) x1;
+  late List<T> Function(int y, {List<Function> x}) x2;
+  late void Function(int, {Function x}) x3;
+  late void Function<A>(int x) x4;
+  late int Function([List<Function> x]) Function() x5;
+  late int Function(List<T>) Function() x6;
+  late Function Function(int, [Function]) Function() x7;
+  late Function Function(int, {core.List<core.int> x}) Function() x8;
+  late List<Function> Function(Function x) Function() x9;
+  late List<Function> Function(int y, [core.List<core.int> x]) Function() x10;
+  late core.List<core.int> Function([int]) Function() x11;
+  late core.List<core.int> Function({List<Function> x}) Function() x12;
+  late core.List<core.int> Function() Function() x13;
+  late List<T> Function(int, [List<Function> x]) Function() x14;
+  late List<T> Function([List<T>]) Function() x15;
+  late Function(int x, [Function]) Function() x16;
+  late Function(int y, {core.List<core.int> x}) Function() x17;
+  late void Function([Function x]) Function() x18;
+  late void Function(core.List<core.int>) Function() x19;
+  late int Function<A>(A x) Function() x20;
+  late core.List<core.int> Function<A>(List<A> x) Function() x21;
+  late List<A> Function<A>(int x) Function() x22;
+
+  U56({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x) => throw 'uncalled';
+  List<Function> m1(List<T> x) => throw 'uncalled';
+  List<T> m2(int y, {List<Function> x = const []}) => throw 'uncalled';
+  void m3(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+  void m4<A>(int x) => throw 'uncalled';
+  int Function([List<Function> x]) m5() => throw 'uncalled';
+  int Function(List<T>) m6() => throw 'uncalled';
+  Function Function(int, [Function]) m7() => throw 'uncalled';
+  Function Function(int, {core.List<core.int> x}) m8() => throw 'uncalled';
+  List<Function> Function(Function x) m9() => throw 'uncalled';
+  List<Function> Function(int y, [core.List<core.int> x]) m10() =>
+      throw 'uncalled';
+  core.List<core.int> Function([int]) m11() => throw 'uncalled';
+  core.List<core.int> Function({List<Function> x}) m12() => throw 'uncalled';
+  core.List<core.int> Function() m13() => throw 'uncalled';
+  List<T> Function(int, [List<Function> x]) m14() => throw 'uncalled';
+  List<T> Function([List<T>]) m15() => throw 'uncalled';
+  Function(int x, [Function]) m16() => throw 'uncalled';
+  Function(int y, {core.List<core.int> x}) m17() => throw 'uncalled';
+  void Function([Function x]) m18() => throw 'uncalled';
+  void Function(core.List<core.int>) m19() => throw 'uncalled';
+  int Function<A>(A x) m20() => throw 'uncalled';
+  core.List<core.int> Function<A>(List<A> x) m21() => throw 'uncalled';
+  List<A> Function<A>(int x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int x)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int x));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(List<T> x)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<T> x) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(List<T> x));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {List<Function> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {List<Function> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int y, {List<Function> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, {Function x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {Function x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, {Function x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// void Function<A>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is void Function<A>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([List<Function> x]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([List<Function> x]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function([List<Function> x]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(List<T>) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(List<T>) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(List<T>) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, [Function]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [Function]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [Function]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, {core.List<core.int> x}) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {core.List<core.int> x}) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int, {core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(Function x) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(Function x) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(Function x) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, [core.List<core.int> x]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [core.List<core.int> x]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, [core.List<core.int> x])
+        Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([int]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([int]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([int]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function({List<Function> x}) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({List<Function> x}) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function({List<Function> x}) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function() Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function() Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function() Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(int, [List<Function> x]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<Function> x]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([List<T>]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<T>]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function([List<T>]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int x, [Function]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [Function]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int x, [Function]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, {core.List<core.int> x}) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {core.List<core.int> x}) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, {core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([Function x]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([Function x]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function([Function x]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(core.List<core.int>) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(core.List<core.int>) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(core.List<core.int>) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(A x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(A x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(A x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<A> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<A> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(List<A> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// List<A> Function<A>(int x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(int x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(int x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U56().runTests();
+  new U56<int>(tIsInt: true).runTests();
+  new U56<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type57_test.dart b/tests/language/function_type/function_type57_test.dart
new file mode 100644
index 0000000..127cf18
--- /dev/null
+++ b/tests/language/function_type/function_type57_test.dart
@@ -0,0 +1,848 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function([int x]);
+typedef F1<T> = List<Function> Function([List<T> x]);
+typedef F2<T> = List<T> Function(core.List<core.int> x);
+typedef F3<T> = void Function(int y, {Function x});
+typedef F4<T> = void Function<A>(Function x);
+typedef F5<T> = int Function([List<Function> x]) Function(int x);
+typedef F6<T> = int Function(List<T>) Function(int x);
+typedef F7<T> = Function Function(int, [Function]) Function(int x);
+typedef F8<T> = Function Function(int, {core.List<core.int> x}) Function(int x);
+typedef F9<T> = List<Function> Function(Function x) Function(int x);
+typedef F10<T> = List<Function> Function(int y, [core.List<core.int> x])
+    Function(int x);
+typedef F11<T> = core.List<core.int> Function([int]) Function(int x);
+typedef F12<T> = core.List<core.int> Function({List<Function> x}) Function(
+    int x);
+typedef F13<T> = core.List<core.int> Function() Function(int x);
+typedef F14<T> = List<T> Function(int, [List<Function> x]) Function(int x);
+typedef F15<T> = List<T> Function([List<T>]) Function(int x);
+typedef F16<T> = Function(int x, [Function]) Function(int x);
+typedef F17<T> = Function(int y, {core.List<core.int> x}) Function(int x);
+typedef F18<T> = void Function([Function x]) Function(int x);
+typedef F19<T> = void Function(core.List<core.int>) Function(int x);
+typedef F20<T> = int Function<A>(A x) Function(int x);
+typedef F21<T> = core.List<core.int> Function<A>(List<A> x) Function(int x);
+typedef F22<T> = List<A> Function<A>(int x) Function(int x);
+
+Function f0([int x = -1]) => throw 'uncalled';
+List<Function> f1([List<int> x = const []]) => throw 'uncalled';
+List<int> f2(core.List<core.int> x) => throw 'uncalled';
+void f3(int y, {Function x = _voidFunction}) => throw 'uncalled';
+void f4<A>(Function x) => throw 'uncalled';
+int Function([List<Function> x]) f5(int x) => throw 'uncalled';
+int Function(List<int>) f6(int x) => throw 'uncalled';
+Function Function(int, [Function]) f7(int x) => throw 'uncalled';
+Function Function(int, {core.List<core.int> x}) f8(int x) => throw 'uncalled';
+List<Function> Function(Function x) f9(int x) => throw 'uncalled';
+List<Function> Function(int y, [core.List<core.int> x]) f10(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([int]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function({List<Function> x}) f12(int x) => throw 'uncalled';
+core.List<core.int> Function() f13(int x) => throw 'uncalled';
+List<int> Function(int, [List<Function> x]) f14(int x) => throw 'uncalled';
+List<int> Function([List<int>]) f15(int x) => throw 'uncalled';
+Function(int x, [Function]) f16(int x) => throw 'uncalled';
+Function(int y, {core.List<core.int> x}) f17(int x) => throw 'uncalled';
+void Function([Function x]) f18(int x) => throw 'uncalled';
+void Function(core.List<core.int>) f19(int x) => throw 'uncalled';
+int Function<A>(A x) f20(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(List<A> x) f21(int x) => throw 'uncalled';
+List<A> Function<A>(int x) f22(int x) => throw 'uncalled';
+
+class U57<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function([int x]) x0;
+  late List<Function> Function([List<T> x]) x1;
+  late List<T> Function(core.List<core.int> x) x2;
+  late void Function(int y, {Function x}) x3;
+  late void Function<A>(Function x) x4;
+  late int Function([List<Function> x]) Function(int x) x5;
+  late int Function(List<T>) Function(int x) x6;
+  late Function Function(int, [Function]) Function(int x) x7;
+  late Function Function(int, {core.List<core.int> x}) Function(int x) x8;
+  late List<Function> Function(Function x) Function(int x) x9;
+  late List<Function> Function(int y, [core.List<core.int> x]) Function(int x)
+      x10;
+  late core.List<core.int> Function([int]) Function(int x) x11;
+  late core.List<core.int> Function({List<Function> x}) Function(int x) x12;
+  late core.List<core.int> Function() Function(int x) x13;
+  late List<T> Function(int, [List<Function> x]) Function(int x) x14;
+  late List<T> Function([List<T>]) Function(int x) x15;
+  late Function(int x, [Function]) Function(int x) x16;
+  late Function(int y, {core.List<core.int> x}) Function(int x) x17;
+  late void Function([Function x]) Function(int x) x18;
+  late void Function(core.List<core.int>) Function(int x) x19;
+  late int Function<A>(A x) Function(int x) x20;
+  late core.List<core.int> Function<A>(List<A> x) Function(int x) x21;
+  late List<A> Function<A>(int x) Function(int x) x22;
+
+  U57({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0([int x = -1]) => throw 'uncalled';
+  List<Function> m1([List<T> x = const []]) => throw 'uncalled';
+  List<T> m2(core.List<core.int> x) => throw 'uncalled';
+  void m3(int y, {Function x = _voidFunction}) => throw 'uncalled';
+  void m4<A>(Function x) => throw 'uncalled';
+  int Function([List<Function> x]) m5(int x) => throw 'uncalled';
+  int Function(List<T>) m6(int x) => throw 'uncalled';
+  Function Function(int, [Function]) m7(int x) => throw 'uncalled';
+  Function Function(int, {core.List<core.int> x}) m8(int x) => throw 'uncalled';
+  List<Function> Function(Function x) m9(int x) => throw 'uncalled';
+  List<Function> Function(int y, [core.List<core.int> x]) m10(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([int]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function({List<Function> x}) m12(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function() m13(int x) => throw 'uncalled';
+  List<T> Function(int, [List<Function> x]) m14(int x) => throw 'uncalled';
+  List<T> Function([List<T>]) m15(int x) => throw 'uncalled';
+  Function(int x, [Function]) m16(int x) => throw 'uncalled';
+  Function(int y, {core.List<core.int> x}) m17(int x) => throw 'uncalled';
+  void Function([Function x]) m18(int x) => throw 'uncalled';
+  void Function(core.List<core.int>) m19(int x) => throw 'uncalled';
+  int Function<A>(A x) m20(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(List<A> x) m21(int x) => throw 'uncalled';
+  List<A> Function<A>(int x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function([int x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function([int x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function([int x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function([List<T> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<T> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function([List<T> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function(core.List<core.int> x)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(core.List<core.int> x) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(core.List<core.int> x));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int y, {Function x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {Function x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int y, {Function x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// void Function<A>(Function x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(Function x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is void Function<A>(Function x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([List<Function> x]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([List<Function> x]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function([List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(List<T>) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(List<T>) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(List<T>) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, [Function]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [Function]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [Function]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, {core.List<core.int> x}) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {core.List<core.int> x}) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int, {core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(Function x) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(Function x) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(Function x) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, [core.List<core.int> x]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [core.List<core.int> x]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, [core.List<core.int> x])
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([int]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([int]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([int]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function({List<Function> x}) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({List<Function> x}) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function({List<Function> x})
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function() Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function() Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function() Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(int, [List<Function> x]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<Function> x]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(int, [List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([List<T>]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<T>]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function([List<T>]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int x, [Function]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [Function]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int x, [Function]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, {core.List<core.int> x}) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {core.List<core.int> x}) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int y, {core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([Function x]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([Function x]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function([Function x]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(core.List<core.int>) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(core.List<core.int>) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(core.List<core.int>) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(A x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(A x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(A x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<A> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<A> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is core.List<core.int> Function<A>(List<A> x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// List<A> Function<A>(int x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(int x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(int x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U57().runTests();
+  new U57<int>(tIsInt: true).runTests();
+  new U57<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type58_test.dart b/tests/language/function_type/function_type58_test.dart
new file mode 100644
index 0000000..55dcc02
--- /dev/null
+++ b/tests/language/function_type/function_type58_test.dart
@@ -0,0 +1,892 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, [int x]);
+typedef F1<T> = List<Function> Function(int, [List<T> x]);
+typedef F2<T> = List<T> Function([core.List<core.int> x]);
+typedef F3<T> = void Function(List<Function> x);
+typedef F4<T> = void Function<A>(List<Function> x);
+typedef F5<T> = int Function([List<Function> x]) Function<B extends core.int>();
+typedef F6<T> = int Function(List<T>) Function<B extends core.int>();
+typedef F7<T> = Function Function(int, [Function])
+    Function<B extends core.int>();
+typedef F8<T> = Function Function(int, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(Function x)
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function([int])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function({List<Function> x})
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function() Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int, [List<Function> x])
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function([List<T>]) Function<B extends core.int>();
+typedef F16<T> = Function(int x, [Function]) Function<B extends core.int>();
+typedef F17<T> = Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F18<T> = void Function([Function x]) Function<B extends core.int>();
+typedef F19<T> = void Function(core.List<core.int>)
+    Function<B extends core.int>();
+typedef F20<T> = int Function<A>(A x) Function<B extends core.int>();
+typedef F21<T> = core.List<core.int> Function<A>(List<A> x)
+    Function<B extends core.int>();
+typedef F22<T> = List<A> Function<A>(int x) Function<B extends core.int>();
+
+Function f0(int x0, [int x = -1]) => throw 'uncalled';
+List<Function> f1(int x0, [List<int> x = const []]) => throw 'uncalled';
+List<int> f2([core.List<core.int> x = const []]) => throw 'uncalled';
+void f3(List<Function> x) => throw 'uncalled';
+void f4<A>(List<Function> x) => throw 'uncalled';
+int Function([List<Function> x]) f5<B extends core.int>() => throw 'uncalled';
+int Function(List<int>) f6<B extends core.int>() => throw 'uncalled';
+Function Function(int, [Function]) f7<B extends core.int>() => throw 'uncalled';
+Function Function(int, {core.List<core.int> x}) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(Function x) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int y, [core.List<core.int> x])
+    f10<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function([int]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function({List<Function> x}) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function() f13<B extends core.int>() => throw 'uncalled';
+List<int> Function(int, [List<Function> x]) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function([List<int>]) f15<B extends core.int>() => throw 'uncalled';
+Function(int x, [Function]) f16<B extends core.int>() => throw 'uncalled';
+Function(int y, {core.List<core.int> x}) f17<B extends core.int>() =>
+    throw 'uncalled';
+void Function([Function x]) f18<B extends core.int>() => throw 'uncalled';
+void Function(core.List<core.int>) f19<B extends core.int>() =>
+    throw 'uncalled';
+int Function<A>(A x) f20<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function<A>(List<A> x) f21<B extends core.int>() =>
+    throw 'uncalled';
+List<A> Function<A>(int x) f22<B extends core.int>() => throw 'uncalled';
+
+class U58<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, [int x]) x0;
+  late List<Function> Function(int, [List<T> x]) x1;
+  late List<T> Function([core.List<core.int> x]) x2;
+  late void Function(List<Function> x) x3;
+  late void Function<A>(List<Function> x) x4;
+  late int Function([List<Function> x]) Function<B extends core.int>() x5;
+  late int Function(List<T>) Function<B extends core.int>() x6;
+  late Function Function(int, [Function]) Function<B extends core.int>() x7;
+  late Function Function(int, {core.List<core.int> x})
+      Function<B extends core.int>() x8;
+  late List<Function> Function(Function x) Function<B extends core.int>() x9;
+  late List<Function> Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function([int]) Function<B extends core.int>() x11;
+  late core.List<core.int> Function({List<Function> x})
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function() Function<B extends core.int>() x13;
+  late List<T> Function(int, [List<Function> x]) Function<B extends core.int>()
+      x14;
+  late List<T> Function([List<T>]) Function<B extends core.int>() x15;
+  late Function(int x, [Function]) Function<B extends core.int>() x16;
+  late Function(int y, {core.List<core.int> x}) Function<B extends core.int>()
+      x17;
+  late void Function([Function x]) Function<B extends core.int>() x18;
+  late void Function(core.List<core.int>) Function<B extends core.int>() x19;
+  late int Function<A>(A x) Function<B extends core.int>() x20;
+  late core.List<core.int> Function<A>(List<A> x) Function<B extends core.int>()
+      x21;
+  late List<A> Function<A>(int x) Function<B extends core.int>() x22;
+
+  U58({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, [int x = -1]) => throw 'uncalled';
+  List<Function> m1(int x0, [List<T> x = const []]) => throw 'uncalled';
+  List<T> m2([core.List<core.int> x = const []]) => throw 'uncalled';
+  void m3(List<Function> x) => throw 'uncalled';
+  void m4<A>(List<Function> x) => throw 'uncalled';
+  int Function([List<Function> x]) m5<B extends core.int>() => throw 'uncalled';
+  int Function(List<T>) m6<B extends core.int>() => throw 'uncalled';
+  Function Function(int, [Function]) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int, {core.List<core.int> x}) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(Function x) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int y, [core.List<core.int> x])
+      m10<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function([int]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function({List<Function> x}) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function() m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int, [List<Function> x]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function([List<T>]) m15<B extends core.int>() => throw 'uncalled';
+  Function(int x, [Function]) m16<B extends core.int>() => throw 'uncalled';
+  Function(int y, {core.List<core.int> x}) m17<B extends core.int>() =>
+      throw 'uncalled';
+  void Function([Function x]) m18<B extends core.int>() => throw 'uncalled';
+  void Function(core.List<core.int>) m19<B extends core.int>() =>
+      throw 'uncalled';
+  int Function<A>(A x) m20<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function<A>(List<A> x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  List<A> Function<A>(int x) m22<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, [int x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [int x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, [int x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, [List<T> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<T> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, [List<T> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function([core.List<core.int> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([core.List<core.int> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function([core.List<core.int> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(List<Function> x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(List<Function> x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(List<Function> x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// void Function<A>(List<Function> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<Function> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is void Function<A>(List<Function> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([List<Function> x]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([List<Function> x]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function([List<Function> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(List<T>) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(List<T>) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(List<T>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, [Function]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [Function]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [Function])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {core.List<core.int> x})
+        Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(Function x) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(Function x) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(Function x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([int]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([int]) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([int])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function({List<Function> x}) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({List<Function> x})
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function({List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function() Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function() Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is core.List<core.int> Function() Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(int, [List<Function> x]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<Function> x]) Function<B extends core.int>()
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([List<T>]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<T>]) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function([List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int x, [Function]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [Function]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int x, [Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {core.List<core.int> x}) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([Function x]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([Function x]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function([Function x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(core.List<core.int>) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(core.List<core.int>) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(core.List<core.int>)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(A x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(A x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(A x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<A> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<A> x) Function<B extends core.int>()
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(List<A> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// List<A> Function<A>(int x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(int x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is List<A> Function<A>(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U58().runTests();
+  new U58<int>(tIsInt: true).runTests();
+  new U58<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type59_test.dart b/tests/language/function_type/function_type59_test.dart
new file mode 100644
index 0000000..8903d02
--- /dev/null
+++ b/tests/language/function_type/function_type59_test.dart
@@ -0,0 +1,917 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int y, [int x]);
+typedef F1<T> = List<Function> Function(int y, [List<T> x]);
+typedef F2<T> = List<T> Function(int, [core.List<core.int> x]);
+typedef F3<T> = void Function([List<Function> x]);
+typedef F4<T> = void Function<A>(core.List<core.int> x);
+typedef F5<T> = int Function([List<Function> x]) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function(List<T>) Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int, [Function]) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function(int, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(Function x)
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function([int])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function({List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function() Function<B extends core.int>(
+    int x);
+typedef F14<T> = List<T> Function(int, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function([List<T>]) Function<B extends core.int>(
+    int x);
+typedef F16<T> = Function(int x, [Function]) Function<B extends core.int>(
+    int x);
+typedef F17<T> = Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F18<T> = void Function([Function x]) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function(core.List<core.int>)
+    Function<B extends core.int>(int x);
+typedef F20<T> = int Function<A>(A x) Function<B extends core.int>(int x);
+typedef F21<T> = core.List<core.int> Function<A>(List<A> x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = List<A> Function<A>(int x) Function<B extends core.int>(int x);
+
+Function f0(int y, [int x = -1]) => throw 'uncalled';
+List<Function> f1(int y, [List<int> x = const []]) => throw 'uncalled';
+List<int> f2(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
+void f3([List<Function> x = const []]) => throw 'uncalled';
+void f4<A>(core.List<core.int> x) => throw 'uncalled';
+int Function([List<Function> x]) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function(List<int>) f6<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int, [Function]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, {core.List<core.int> x}) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(Function x) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int y, [core.List<core.int> x]) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([int]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function({List<Function> x}) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function() f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, [List<Function> x]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function([List<int>]) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int x, [Function]) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(int y, {core.List<core.int> x}) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function([Function x]) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(core.List<core.int>) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function<A>(A x) f20<B extends core.int>(int x) => throw 'uncalled';
+core.List<core.int> Function<A>(List<A> x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<A> Function<A>(int x) f22<B extends core.int>(int x) => throw 'uncalled';
+
+class U59<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int y, [int x]) x0;
+  late List<Function> Function(int y, [List<T> x]) x1;
+  late List<T> Function(int, [core.List<core.int> x]) x2;
+  late void Function([List<Function> x]) x3;
+  late void Function<A>(core.List<core.int> x) x4;
+  late int Function([List<Function> x]) Function<B extends core.int>(int x) x5;
+  late int Function(List<T>) Function<B extends core.int>(int x) x6;
+  late Function Function(int, [Function]) Function<B extends core.int>(int x)
+      x7;
+  late Function Function(int, {core.List<core.int> x})
+      Function<B extends core.int>(int x) x8;
+  late List<Function> Function(Function x) Function<B extends core.int>(int x)
+      x9;
+  late List<Function> Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function([int]) Function<B extends core.int>(int x)
+      x11;
+  late core.List<core.int> Function({List<Function> x})
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function() Function<B extends core.int>(int x) x13;
+  late List<T> Function(int, [List<Function> x]) Function<B extends core.int>(
+      int x) x14;
+  late List<T> Function([List<T>]) Function<B extends core.int>(int x) x15;
+  late Function(int x, [Function]) Function<B extends core.int>(int x) x16;
+  late Function(int y, {core.List<core.int> x}) Function<B extends core.int>(
+      int x) x17;
+  late void Function([Function x]) Function<B extends core.int>(int x) x18;
+  late void Function(core.List<core.int>) Function<B extends core.int>(int x)
+      x19;
+  late int Function<A>(A x) Function<B extends core.int>(int x) x20;
+  late core.List<core.int> Function<A>(List<A> x) Function<B extends core.int>(
+      int x) x21;
+  late List<A> Function<A>(int x) Function<B extends core.int>(int x) x22;
+
+  U59({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int y, [int x = -1]) => throw 'uncalled';
+  List<Function> m1(int y, [List<T> x = const []]) => throw 'uncalled';
+  List<T> m2(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
+  void m3([List<Function> x = const []]) => throw 'uncalled';
+  void m4<A>(core.List<core.int> x) => throw 'uncalled';
+  int Function([List<Function> x]) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(List<T>) m6<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(int, [Function]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, {core.List<core.int> x}) m8<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<Function> Function(Function x) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, [core.List<core.int> x])
+      m10<B extends core.int>(int x) => throw 'uncalled';
+  core.List<core.int> Function([int]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function({List<Function> x}) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function() m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [List<Function> x]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function([List<T>]) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int x, [Function]) m16<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int y, {core.List<core.int> x}) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function([Function x]) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(core.List<core.int>) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function<A>(A x) m20<B extends core.int>(int x) => throw 'uncalled';
+  core.List<core.int> Function<A>(List<A> x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<A> Function<A>(int x) m22<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int y, [int x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [int x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int y, [int x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int y, [List<T> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [List<T> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int y, [List<T> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [core.List<core.int> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [core.List<core.int> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function([List<Function> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function([List<Function> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function([List<Function> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// void Function<A>(core.List<core.int> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(core.List<core.int> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is void Function<A>(core.List<core.int> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([List<Function> x]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([List<Function> x]) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function([List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(List<T>) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(List<T>) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(List<T>) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, [Function]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [Function]) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {core.List<core.int> x})
+        Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function(Function x) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(Function x) Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(Function x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([int]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([int]) Function<B extends core.int>(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([int])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function({List<Function> x}) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({List<Function> x})
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function({List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function() Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function() Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function()
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<Function> x]) Function<B extends core.int>(
+        int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function([List<T>]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<T>]) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function([List<T>]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int x, [Function]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [Function]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int x, [Function]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {core.List<core.int> x}) Function<B extends core.int>(int x)
+        l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function([Function x]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([Function x]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function([Function x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(core.List<core.int>) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(core.List<core.int>) Function<B extends core.int>(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(core.List<core.int>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(A x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(A x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is int Function<A>(A x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// core.List<core.int> Function<A>(List<A> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function<A>(List<A> x) Function<B extends core.int>(
+        int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is core.List<core.int> Function<A>(List<A> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// List<A> Function<A>(int x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(int x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is List<A> Function<A>(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U59().runTests();
+  new U59<int>(tIsInt: true).runTests();
+  new U59<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type5_test.dart b/tests/language/function_type/function_type5_test.dart
new file mode 100644
index 0000000..43c4b84
--- /dev/null
+++ b/tests/language/function_type/function_type5_test.dart
@@ -0,0 +1,932 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function([int]);
+typedef F1<T> = Function Function([List<T>]);
+typedef F2<T> = core.List<core.int> Function(core.List<core.int>);
+typedef F3<T> = Function(int y, [List<Function> x]);
+typedef F4<T> = Function Function<A>();
+typedef F5<T> = int Function(int y, {int x}) Function(int x);
+typedef F6<T> = int Function(int, [core.List<core.int> x]) Function(int x);
+typedef F7<T> = Function Function(int) Function(int x);
+typedef F8<T> = Function Function(int x, [List<Function>]) Function(int x);
+typedef F9<T> = Function Function(int y, {List<T> x}) Function(int x);
+typedef F10<T> = List<Function> Function([List<Function> x]) Function(int x);
+typedef F11<T> = List<Function> Function(List<T>) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int, [Function]) Function(int x);
+typedef F13<T> = core.List<core.int> Function(int, {core.List<core.int> x})
+    Function(int x);
+typedef F14<T> = List<T> Function(Function x) Function(int x);
+typedef F15<T> = List<T> Function(int y, [core.List<core.int> x]) Function(
+    int x);
+typedef F16<T> = Function([int]) Function(int x);
+typedef F17<T> = Function({List<Function> x}) Function(int x);
+typedef F18<T> = Function() Function(int x);
+typedef F19<T> = void Function(int, [List<Function> x]) Function(int x);
+typedef F20<T> = void Function([List<T>]) Function(int x);
+typedef F21<T> = List<Function> Function<A>(List<Function> x) Function(int x);
+typedef F22<T> = Function<A>(core.List<core.int> x) Function(int x);
+typedef F23<T> = void Function<A>(List<T> x) Function(int x);
+
+int f0([int x0 = -1]) => throw 'uncalled';
+Function f1([List<int> x0 = const []]) => throw 'uncalled';
+core.List<core.int> f2(core.List<core.int> x0) => throw 'uncalled';
+f3(int y, [List<Function> x = const []]) => throw 'uncalled';
+Function f4<A>() => throw 'uncalled';
+int Function(int y, {int x}) f5(int x) => throw 'uncalled';
+int Function(int, [core.List<core.int> x]) f6(int x) => throw 'uncalled';
+Function Function(int) f7(int x) => throw 'uncalled';
+Function Function(int x, [List<Function>]) f8(int x) => throw 'uncalled';
+Function Function(int y, {List<int> x}) f9(int x) => throw 'uncalled';
+List<Function> Function([List<Function> x]) f10(int x) => throw 'uncalled';
+List<Function> Function(List<int>) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int, [Function]) f12(int x) => throw 'uncalled';
+core.List<core.int> Function(int, {core.List<core.int> x}) f13(int x) =>
+    throw 'uncalled';
+List<int> Function(Function x) f14(int x) => throw 'uncalled';
+List<int> Function(int y, [core.List<core.int> x]) f15(int x) =>
+    throw 'uncalled';
+Function([int]) f16(int x) => throw 'uncalled';
+Function({List<Function> x}) f17(int x) => throw 'uncalled';
+Function() f18(int x) => throw 'uncalled';
+void Function(int, [List<Function> x]) f19(int x) => throw 'uncalled';
+void Function([List<int>]) f20(int x) => throw 'uncalled';
+List<Function> Function<A>(List<Function> x) f21(int x) => throw 'uncalled';
+Function<A>(core.List<core.int> x) f22(int x) => throw 'uncalled';
+void Function<A>(List<int> x) f23(int x) => throw 'uncalled';
+
+class U5<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function([int]) x0;
+  late Function Function([List<T>]) x1;
+  late core.List<core.int> Function(core.List<core.int>) x2;
+  late Function(int y, [List<Function> x]) x3;
+  late Function Function<A>() x4;
+  late int Function(int y, {int x}) Function(int x) x5;
+  late int Function(int, [core.List<core.int> x]) Function(int x) x6;
+  late Function Function(int) Function(int x) x7;
+  late Function Function(int x, [List<Function>]) Function(int x) x8;
+  late Function Function(int y, {List<T> x}) Function(int x) x9;
+  late List<Function> Function([List<Function> x]) Function(int x) x10;
+  late List<Function> Function(List<T>) Function(int x) x11;
+  late core.List<core.int> Function(int, [Function]) Function(int x) x12;
+  late core.List<core.int> Function(int, {core.List<core.int> x}) Function(
+      int x) x13;
+  late List<T> Function(Function x) Function(int x) x14;
+  late List<T> Function(int y, [core.List<core.int> x]) Function(int x) x15;
+  late Function([int]) Function(int x) x16;
+  late Function({List<Function> x}) Function(int x) x17;
+  late Function() Function(int x) x18;
+  late void Function(int, [List<Function> x]) Function(int x) x19;
+  late void Function([List<T>]) Function(int x) x20;
+  late List<Function> Function<A>(List<Function> x) Function(int x) x21;
+  late Function<A>(core.List<core.int> x) Function(int x) x22;
+  late void Function<A>(List<T> x) Function(int x) x23;
+
+  U5({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0([int x0 = -1]) => throw 'uncalled';
+  Function m1([List<T> x0 = const []]) => throw 'uncalled';
+  core.List<core.int> m2(core.List<core.int> x0) => throw 'uncalled';
+  m3(int y, [List<Function> x = const []]) => throw 'uncalled';
+  Function m4<A>() => throw 'uncalled';
+  int Function(int y, {int x}) m5(int x) => throw 'uncalled';
+  int Function(int, [core.List<core.int> x]) m6(int x) => throw 'uncalled';
+  Function Function(int) m7(int x) => throw 'uncalled';
+  Function Function(int x, [List<Function>]) m8(int x) => throw 'uncalled';
+  Function Function(int y, {List<T> x}) m9(int x) => throw 'uncalled';
+  List<Function> Function([List<Function> x]) m10(int x) => throw 'uncalled';
+  List<Function> Function(List<T>) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, [Function]) m12(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, {core.List<core.int> x}) m13(int x) =>
+      throw 'uncalled';
+  List<T> Function(Function x) m14(int x) => throw 'uncalled';
+  List<T> Function(int y, [core.List<core.int> x]) m15(int x) =>
+      throw 'uncalled';
+  Function([int]) m16(int x) => throw 'uncalled';
+  Function({List<Function> x}) m17(int x) => throw 'uncalled';
+  Function() m18(int x) => throw 'uncalled';
+  void Function(int, [List<Function> x]) m19(int x) => throw 'uncalled';
+  void Function([List<T>]) m20(int x) => throw 'uncalled';
+  List<Function> Function<A>(List<Function> x) m21(int x) => throw 'uncalled';
+  Function<A>(core.List<core.int> x) m22(int x) => throw 'uncalled';
+  void Function<A>(List<T> x) m23(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function([int])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function([int]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function([int]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function([List<T>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<T>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function([List<T>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(core.List<core.int>)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(core.List<core.int>) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function(core.List<core.int>));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function(int y, [List<Function> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [List<Function> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int y, [List<Function> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function Function<A>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function Function<A>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {int x}) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {int x}) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, {int x}) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [core.List<core.int> x]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [core.List<core.int> x]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int, [core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [List<Function>]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [List<Function>]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int x, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function(int y, {List<T> x}) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {List<T> x}) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function(int y, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+    // The static function has its T always set to int.
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isFalse(f9 is F9<bool>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    Expect.isFalse(confuse(f9) is F9<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        x9 = confuse(f9);
+      });
+      Expect.throws(() {
+        l9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        l9 = confuse(f9);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m9 is F9<int>);
+      Expect.equals(tIsBool, m9 is F9<bool>);
+      Expect.equals(tIsInt, confuse(m9) is F9<int>);
+      Expect.equals(tIsBool, confuse(m9) is F9<bool>);
+    }
+  }
+
+  /// List<Function> Function([List<Function> x]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<Function> x]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function([List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(List<T>) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<T>) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(List<T>) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, [Function]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [Function]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(int, [Function]) Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, {core.List<core.int> x}) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {core.List<core.int> x}) Function(int x)
+        l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int,
+            {core.List<core.int> x})
+        Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(Function x) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(Function x) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(Function x) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [core.List<core.int> x]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [core.List<core.int> x]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, [core.List<core.int> x])
+        Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([int]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([int]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([int]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({List<Function> x}) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({List<Function> x}) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function({List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// Function() Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    Function() Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is Function() Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<Function> x]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<Function> x]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int, [List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function([List<T>]) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function([List<T>]) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function([List<T>]) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<Function> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<Function> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<Function> Function<A>(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(core.List<core.int> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(core.List<core.int> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(List<T> x) Function(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<T> x) Function(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+    // The static function has its T always set to int.
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isFalse(f23 is F23<bool>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    Expect.isFalse(confuse(f23) is F23<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        x23 = confuse(f23);
+      });
+      Expect.throws(() {
+        l23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        l23 = confuse(f23);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m23 is F23<int>);
+      Expect.equals(tIsBool, m23 is F23<bool>);
+      Expect.equals(tIsInt, confuse(m23) is F23<int>);
+      Expect.equals(tIsBool, confuse(m23) is F23<bool>);
+    }
+  }
+}
+
+void main() {
+  new U5().runTests();
+  new U5<int>(tIsInt: true).runTests();
+  new U5<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type60_test.dart b/tests/language/function_type/function_type60_test.dart
new file mode 100644
index 0000000..c42ce16
--- /dev/null
+++ b/tests/language/function_type/function_type60_test.dart
@@ -0,0 +1,942 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int);
+typedef F1<T> = List<Function> Function(List<T>);
+typedef F2<T> = List<T> Function(int y, [core.List<core.int> x]);
+typedef F3<T> = void Function(int, [List<Function> x]);
+typedef F4<T> = void Function<A>(List<T> x);
+typedef F5<T> = int Function(int, [List<Function> x]) Function();
+typedef F6<T> = int Function([List<T>]) Function();
+typedef F7<T> = Function Function(int x, [Function]) Function();
+typedef F8<T> = Function Function(int y, {core.List<core.int> x}) Function();
+typedef F9<T> = List<Function> Function([Function x]) Function();
+typedef F10<T> = List<Function> Function(core.List<core.int>) Function();
+typedef F11<T> = core.List<core.int> Function(int, [int]) Function();
+typedef F12<T> = core.List<core.int> Function(int, {List<Function> x})
+    Function();
+typedef F13<T> = List<T> Function(int x) Function();
+typedef F14<T> = List<T> Function(int y, [List<Function> x]) Function();
+typedef F15<T> = List<T> Function(int, [List<T>]) Function();
+typedef F16<T> = Function({Function x}) Function();
+typedef F17<T> = Function(List<T> x) Function();
+typedef F18<T> = void Function(int, [Function x]) Function();
+typedef F19<T> = void Function([core.List<core.int>]) Function();
+typedef F20<T> = int Function<A>(List<A> x) Function();
+typedef F21<T> = List<T> Function<A>(int x) Function();
+typedef F22<T> = List<A> Function<A>(Function x) Function();
+
+Function f0(int x0) => throw 'uncalled';
+List<Function> f1(List<int> x0) => throw 'uncalled';
+List<int> f2(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
+void f3(int x0, [List<Function> x = const []]) => throw 'uncalled';
+void f4<A>(List<int> x) => throw 'uncalled';
+int Function(int, [List<Function> x]) f5() => throw 'uncalled';
+int Function([List<int>]) f6() => throw 'uncalled';
+Function Function(int x, [Function]) f7() => throw 'uncalled';
+Function Function(int y, {core.List<core.int> x}) f8() => throw 'uncalled';
+List<Function> Function([Function x]) f9() => throw 'uncalled';
+List<Function> Function(core.List<core.int>) f10() => throw 'uncalled';
+core.List<core.int> Function(int, [int]) f11() => throw 'uncalled';
+core.List<core.int> Function(int, {List<Function> x}) f12() => throw 'uncalled';
+List<int> Function(int x) f13() => throw 'uncalled';
+List<int> Function(int y, [List<Function> x]) f14() => throw 'uncalled';
+List<int> Function(int, [List<int>]) f15() => throw 'uncalled';
+Function({Function x}) f16() => throw 'uncalled';
+Function(List<int> x) f17() => throw 'uncalled';
+void Function(int, [Function x]) f18() => throw 'uncalled';
+void Function([core.List<core.int>]) f19() => throw 'uncalled';
+int Function<A>(List<A> x) f20() => throw 'uncalled';
+List<int> Function<A>(int x) f21() => throw 'uncalled';
+List<A> Function<A>(Function x) f22() => throw 'uncalled';
+
+class U60<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int) x0;
+  late List<Function> Function(List<T>) x1;
+  late List<T> Function(int y, [core.List<core.int> x]) x2;
+  late void Function(int, [List<Function> x]) x3;
+  late void Function<A>(List<T> x) x4;
+  late int Function(int, [List<Function> x]) Function() x5;
+  late int Function([List<T>]) Function() x6;
+  late Function Function(int x, [Function]) Function() x7;
+  late Function Function(int y, {core.List<core.int> x}) Function() x8;
+  late List<Function> Function([Function x]) Function() x9;
+  late List<Function> Function(core.List<core.int>) Function() x10;
+  late core.List<core.int> Function(int, [int]) Function() x11;
+  late core.List<core.int> Function(int, {List<Function> x}) Function() x12;
+  late List<T> Function(int x) Function() x13;
+  late List<T> Function(int y, [List<Function> x]) Function() x14;
+  late List<T> Function(int, [List<T>]) Function() x15;
+  late Function({Function x}) Function() x16;
+  late Function(List<T> x) Function() x17;
+  late void Function(int, [Function x]) Function() x18;
+  late void Function([core.List<core.int>]) Function() x19;
+  late int Function<A>(List<A> x) Function() x20;
+  late List<T> Function<A>(int x) Function() x21;
+  late List<A> Function<A>(Function x) Function() x22;
+
+  U60({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0) => throw 'uncalled';
+  List<Function> m1(List<T> x0) => throw 'uncalled';
+  List<T> m2(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
+  void m3(int x0, [List<Function> x = const []]) => throw 'uncalled';
+  void m4<A>(List<T> x) => throw 'uncalled';
+  int Function(int, [List<Function> x]) m5() => throw 'uncalled';
+  int Function([List<T>]) m6() => throw 'uncalled';
+  Function Function(int x, [Function]) m7() => throw 'uncalled';
+  Function Function(int y, {core.List<core.int> x}) m8() => throw 'uncalled';
+  List<Function> Function([Function x]) m9() => throw 'uncalled';
+  List<Function> Function(core.List<core.int>) m10() => throw 'uncalled';
+  core.List<core.int> Function(int, [int]) m11() => throw 'uncalled';
+  core.List<core.int> Function(int, {List<Function> x}) m12() =>
+      throw 'uncalled';
+  List<T> Function(int x) m13() => throw 'uncalled';
+  List<T> Function(int y, [List<Function> x]) m14() => throw 'uncalled';
+  List<T> Function(int, [List<T>]) m15() => throw 'uncalled';
+  Function({Function x}) m16() => throw 'uncalled';
+  Function(List<T> x) m17() => throw 'uncalled';
+  void Function(int, [Function x]) m18() => throw 'uncalled';
+  void Function([core.List<core.int>]) m19() => throw 'uncalled';
+  int Function<A>(List<A> x) m20() => throw 'uncalled';
+  List<T> Function<A>(int x) m21() => throw 'uncalled';
+  List<A> Function<A>(Function x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(List<T>)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<T>) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(List<T>));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [core.List<core.int> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [core.List<core.int> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int y, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, [List<Function> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<Function> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, [List<Function> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// void Function<A>(List<T> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<T> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is void Function<A>(List<T> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+    // The static function has its T always set to int.
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isFalse(f4 is F4<bool>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    Expect.isFalse(confuse(f4) is F4<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        x4 = confuse(f4);
+      });
+      Expect.throws(() {
+        l4 = (f4 as dynamic);
+      });
+      Expect.throws(() {
+        l4 = confuse(f4);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m4 is F4<int>);
+      Expect.equals(true, m4 is F4<bool>);
+      Expect.equals(true, confuse(m4) is F4<int>);
+      Expect.equals(true, confuse(m4) is F4<bool>);
+    }
+  }
+
+  /// int Function(int, [List<Function> x]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<Function> x]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([List<T>]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([List<T>]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([List<T>]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int x, [Function]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [Function]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int x, [Function]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, {core.List<core.int> x}) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {core.List<core.int> x}) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int y, {core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([Function x]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([Function x]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([Function x]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(core.List<core.int>) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(core.List<core.int>) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(core.List<core.int>) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, [int]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [int]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, [int]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, {List<Function> x}) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {List<Function> x}) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, {List<Function> x})
+        Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int x) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int x) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [List<Function> x]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [List<Function> x]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(int y, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<T>]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<T>]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [List<T>]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function({Function x}) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function({Function x}) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function({Function x}) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(List<T> x) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(List<T> x) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(List<T> x) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, [Function x]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [Function x]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, [Function x]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([core.List<core.int>]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([core.List<core.int>]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<A> x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<A> x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(List<A> x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(int x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(int x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(int x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(Function x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(Function x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(Function x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U60().runTests();
+  new U60<int>(tIsInt: true).runTests();
+  new U60<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type61_test.dart b/tests/language/function_type/function_type61_test.dart
new file mode 100644
index 0000000..1d6bb68
--- /dev/null
+++ b/tests/language/function_type/function_type61_test.dart
@@ -0,0 +1,922 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function([int]);
+typedef F1<T> = List<Function> Function([List<T>]);
+typedef F2<T> = List<T> Function(core.List<core.int>);
+typedef F3<T> = void Function(int y, [List<Function> x]);
+typedef F4<T> = void Function<A>();
+typedef F5<T> = int Function(int, [List<Function> x]) Function(int x);
+typedef F6<T> = int Function([List<T>]) Function(int x);
+typedef F7<T> = Function Function(int x, [Function]) Function(int x);
+typedef F8<T> = Function Function(int y, {core.List<core.int> x}) Function(
+    int x);
+typedef F9<T> = List<Function> Function([Function x]) Function(int x);
+typedef F10<T> = List<Function> Function(core.List<core.int>) Function(int x);
+typedef F11<T> = core.List<core.int> Function(int, [int]) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int, {List<Function> x}) Function(
+    int x);
+typedef F13<T> = List<T> Function(int x) Function(int x);
+typedef F14<T> = List<T> Function(int y, [List<Function> x]) Function(int x);
+typedef F15<T> = List<T> Function(int, [List<T>]) Function(int x);
+typedef F16<T> = Function({Function x}) Function(int x);
+typedef F17<T> = Function(List<T> x) Function(int x);
+typedef F18<T> = void Function(int, [Function x]) Function(int x);
+typedef F19<T> = void Function([core.List<core.int>]) Function(int x);
+typedef F20<T> = int Function<A>(List<A> x) Function(int x);
+typedef F21<T> = List<T> Function<A>(int x) Function(int x);
+typedef F22<T> = List<A> Function<A>(Function x) Function(int x);
+
+Function f0([int x0 = -1]) => throw 'uncalled';
+List<Function> f1([List<int> x0 = const []]) => throw 'uncalled';
+List<int> f2(core.List<core.int> x0) => throw 'uncalled';
+void f3(int y, [List<Function> x = const []]) => throw 'uncalled';
+void f4<A>() => throw 'uncalled';
+int Function(int, [List<Function> x]) f5(int x) => throw 'uncalled';
+int Function([List<int>]) f6(int x) => throw 'uncalled';
+Function Function(int x, [Function]) f7(int x) => throw 'uncalled';
+Function Function(int y, {core.List<core.int> x}) f8(int x) => throw 'uncalled';
+List<Function> Function([Function x]) f9(int x) => throw 'uncalled';
+List<Function> Function(core.List<core.int>) f10(int x) => throw 'uncalled';
+core.List<core.int> Function(int, [int]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int, {List<Function> x}) f12(int x) =>
+    throw 'uncalled';
+List<int> Function(int x) f13(int x) => throw 'uncalled';
+List<int> Function(int y, [List<Function> x]) f14(int x) => throw 'uncalled';
+List<int> Function(int, [List<int>]) f15(int x) => throw 'uncalled';
+Function({Function x}) f16(int x) => throw 'uncalled';
+Function(List<int> x) f17(int x) => throw 'uncalled';
+void Function(int, [Function x]) f18(int x) => throw 'uncalled';
+void Function([core.List<core.int>]) f19(int x) => throw 'uncalled';
+int Function<A>(List<A> x) f20(int x) => throw 'uncalled';
+List<int> Function<A>(int x) f21(int x) => throw 'uncalled';
+List<A> Function<A>(Function x) f22(int x) => throw 'uncalled';
+
+class U61<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function([int]) x0;
+  late List<Function> Function([List<T>]) x1;
+  late List<T> Function(core.List<core.int>) x2;
+  late void Function(int y, [List<Function> x]) x3;
+  late void Function<A>() x4;
+  late int Function(int, [List<Function> x]) Function(int x) x5;
+  late int Function([List<T>]) Function(int x) x6;
+  late Function Function(int x, [Function]) Function(int x) x7;
+  late Function Function(int y, {core.List<core.int> x}) Function(int x) x8;
+  late List<Function> Function([Function x]) Function(int x) x9;
+  late List<Function> Function(core.List<core.int>) Function(int x) x10;
+  late core.List<core.int> Function(int, [int]) Function(int x) x11;
+  late core.List<core.int> Function(int, {List<Function> x}) Function(int x)
+      x12;
+  late List<T> Function(int x) Function(int x) x13;
+  late List<T> Function(int y, [List<Function> x]) Function(int x) x14;
+  late List<T> Function(int, [List<T>]) Function(int x) x15;
+  late Function({Function x}) Function(int x) x16;
+  late Function(List<T> x) Function(int x) x17;
+  late void Function(int, [Function x]) Function(int x) x18;
+  late void Function([core.List<core.int>]) Function(int x) x19;
+  late int Function<A>(List<A> x) Function(int x) x20;
+  late List<T> Function<A>(int x) Function(int x) x21;
+  late List<A> Function<A>(Function x) Function(int x) x22;
+
+  U61({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0([int x0 = -1]) => throw 'uncalled';
+  List<Function> m1([List<T> x0 = const []]) => throw 'uncalled';
+  List<T> m2(core.List<core.int> x0) => throw 'uncalled';
+  void m3(int y, [List<Function> x = const []]) => throw 'uncalled';
+  void m4<A>() => throw 'uncalled';
+  int Function(int, [List<Function> x]) m5(int x) => throw 'uncalled';
+  int Function([List<T>]) m6(int x) => throw 'uncalled';
+  Function Function(int x, [Function]) m7(int x) => throw 'uncalled';
+  Function Function(int y, {core.List<core.int> x}) m8(int x) =>
+      throw 'uncalled';
+  List<Function> Function([Function x]) m9(int x) => throw 'uncalled';
+  List<Function> Function(core.List<core.int>) m10(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, [int]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, {List<Function> x}) m12(int x) =>
+      throw 'uncalled';
+  List<T> Function(int x) m13(int x) => throw 'uncalled';
+  List<T> Function(int y, [List<Function> x]) m14(int x) => throw 'uncalled';
+  List<T> Function(int, [List<T>]) m15(int x) => throw 'uncalled';
+  Function({Function x}) m16(int x) => throw 'uncalled';
+  Function(List<T> x) m17(int x) => throw 'uncalled';
+  void Function(int, [Function x]) m18(int x) => throw 'uncalled';
+  void Function([core.List<core.int>]) m19(int x) => throw 'uncalled';
+  int Function<A>(List<A> x) m20(int x) => throw 'uncalled';
+  List<T> Function<A>(int x) m21(int x) => throw 'uncalled';
+  List<A> Function<A>(Function x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function([int])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function([int]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function([int]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function([List<T>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<T>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function([List<T>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function(core.List<core.int>)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(core.List<core.int>) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(core.List<core.int>));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int y, [List<Function> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [List<Function> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int y, [List<Function> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// void Function<A>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    void Function<A>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is void Function<A>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [List<Function> x]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<Function> x]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([List<T>]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([List<T>]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([List<T>]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int x, [Function]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [Function]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int x, [Function]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, {core.List<core.int> x}) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {core.List<core.int> x}) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, {core.List<core.int> x})
+        Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([Function x]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([Function x]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([Function x]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(core.List<core.int>) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(core.List<core.int>) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(core.List<core.int>) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, [int]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [int]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int, [int]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, {List<Function> x}) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {List<Function> x}) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, {List<Function> x})
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int x) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int x) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [List<Function> x]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [List<Function> x]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(int y, [List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<T>]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<T>]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function({Function x}) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function({Function x}) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function({Function x}) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(List<T> x) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(List<T> x) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, [Function x]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [Function x]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([core.List<core.int>]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([core.List<core.int>]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<A> x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<A> x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is int Function<A>(List<A> x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(int x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(int x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(int x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(Function x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(Function x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(Function x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U61().runTests();
+  new U61<int>(tIsInt: true).runTests();
+  new U61<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type62_test.dart b/tests/language/function_type/function_type62_test.dart
new file mode 100644
index 0000000..5cfc9ec
--- /dev/null
+++ b/tests/language/function_type/function_type62_test.dart
@@ -0,0 +1,967 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, [int]);
+typedef F1<T> = List<Function> Function(int, [List<T>]);
+typedef F2<T> = List<T> Function([core.List<core.int>]);
+typedef F3<T> = void Function(List<Function>);
+typedef F4<T> = void Function<A>(A x);
+typedef F5<T> = int Function(int, [List<Function> x])
+    Function<B extends core.int>();
+typedef F6<T> = int Function([List<T>]) Function<B extends core.int>();
+typedef F7<T> = Function Function(int x, [Function])
+    Function<B extends core.int>();
+typedef F8<T> = Function Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function([Function x])
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(core.List<core.int>)
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(int, [int])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int, {List<Function> x})
+    Function<B extends core.int>();
+typedef F13<T> = List<T> Function(int x) Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int y, [List<Function> x])
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int, [List<T>])
+    Function<B extends core.int>();
+typedef F16<T> = Function({Function x}) Function<B extends core.int>();
+typedef F17<T> = Function(List<T> x) Function<B extends core.int>();
+typedef F18<T> = void Function(int, [Function x])
+    Function<B extends core.int>();
+typedef F19<T> = void Function([core.List<core.int>])
+    Function<B extends core.int>();
+typedef F20<T> = int Function<A>(List<A> x) Function<B extends core.int>();
+typedef F21<T> = List<T> Function<A>(int x) Function<B extends core.int>();
+typedef F22<T> = List<A> Function<A>(Function x) Function<B extends core.int>();
+
+Function f0(int x0, [int x1 = -1]) => throw 'uncalled';
+List<Function> f1(int x0, [List<int> x1 = const []]) => throw 'uncalled';
+List<int> f2([core.List<core.int> x0 = const []]) => throw 'uncalled';
+void f3(List<Function> x0) => throw 'uncalled';
+void f4<A>(A x) => throw 'uncalled';
+int Function(int, [List<Function> x]) f5<B extends core.int>() =>
+    throw 'uncalled';
+int Function([List<int>]) f6<B extends core.int>() => throw 'uncalled';
+Function Function(int x, [Function]) f7<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int y, {core.List<core.int> x}) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function([Function x]) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(core.List<core.int>) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [int]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {List<Function> x})
+    f12<B extends core.int>() => throw 'uncalled';
+List<int> Function(int x) f13<B extends core.int>() => throw 'uncalled';
+List<int> Function(int y, [List<Function> x]) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, [List<int>]) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function({Function x}) f16<B extends core.int>() => throw 'uncalled';
+Function(List<int> x) f17<B extends core.int>() => throw 'uncalled';
+void Function(int, [Function x]) f18<B extends core.int>() => throw 'uncalled';
+void Function([core.List<core.int>]) f19<B extends core.int>() =>
+    throw 'uncalled';
+int Function<A>(List<A> x) f20<B extends core.int>() => throw 'uncalled';
+List<int> Function<A>(int x) f21<B extends core.int>() => throw 'uncalled';
+List<A> Function<A>(Function x) f22<B extends core.int>() => throw 'uncalled';
+
+class U62<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, [int]) x0;
+  late List<Function> Function(int, [List<T>]) x1;
+  late List<T> Function([core.List<core.int>]) x2;
+  late void Function(List<Function>) x3;
+  late void Function<A>(A x) x4;
+  late int Function(int, [List<Function> x]) Function<B extends core.int>() x5;
+  late int Function([List<T>]) Function<B extends core.int>() x6;
+  late Function Function(int x, [Function]) Function<B extends core.int>() x7;
+  late Function Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>() x8;
+  late List<Function> Function([Function x]) Function<B extends core.int>() x9;
+  late List<Function> Function(core.List<core.int>)
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function(int, [int]) Function<B extends core.int>()
+      x11;
+  late core.List<core.int> Function(int, {List<Function> x})
+      Function<B extends core.int>() x12;
+  late List<T> Function(int x) Function<B extends core.int>() x13;
+  late List<T> Function(int y, [List<Function> x])
+      Function<B extends core.int>() x14;
+  late List<T> Function(int, [List<T>]) Function<B extends core.int>() x15;
+  late Function({Function x}) Function<B extends core.int>() x16;
+  late Function(List<T> x) Function<B extends core.int>() x17;
+  late void Function(int, [Function x]) Function<B extends core.int>() x18;
+  late void Function([core.List<core.int>]) Function<B extends core.int>() x19;
+  late int Function<A>(List<A> x) Function<B extends core.int>() x20;
+  late List<T> Function<A>(int x) Function<B extends core.int>() x21;
+  late List<A> Function<A>(Function x) Function<B extends core.int>() x22;
+
+  U62({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, [int x1 = -1]) => throw 'uncalled';
+  List<Function> m1(int x0, [List<T> x1 = const []]) => throw 'uncalled';
+  List<T> m2([core.List<core.int> x0 = const []]) => throw 'uncalled';
+  void m3(List<Function> x0) => throw 'uncalled';
+  void m4<A>(A x) => throw 'uncalled';
+  int Function(int, [List<Function> x]) m5<B extends core.int>() =>
+      throw 'uncalled';
+  int Function([List<T>]) m6<B extends core.int>() => throw 'uncalled';
+  Function Function(int x, [Function]) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int y, {core.List<core.int> x}) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function([Function x]) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(core.List<core.int>) m10<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [int]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {List<Function> x})
+      m12<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int x) m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int y, [List<Function> x]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, [List<T>]) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function({Function x}) m16<B extends core.int>() => throw 'uncalled';
+  Function(List<T> x) m17<B extends core.int>() => throw 'uncalled';
+  void Function(int, [Function x]) m18<B extends core.int>() =>
+      throw 'uncalled';
+  void Function([core.List<core.int>]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  int Function<A>(List<A> x) m20<B extends core.int>() => throw 'uncalled';
+  List<T> Function<A>(int x) m21<B extends core.int>() => throw 'uncalled';
+  List<A> Function<A>(Function x) m22<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, [int])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [int]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, [int]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, [List<T>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<T>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, [List<T>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function([core.List<core.int>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([core.List<core.int>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function([core.List<core.int>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(List<Function>)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(List<Function>) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(List<Function>));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// void Function<A>(A x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(A x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is void Function<A>(A x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [List<Function> x]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<Function> x]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([List<T>]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([List<T>]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function([List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int x, [Function]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [Function]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int x, [Function])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([Function x]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([Function x]) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(core.List<core.int>) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(core.List<core.int>) Function<B extends core.int>()
+        l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(core.List<core.int>)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, [int]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [int]) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, [int])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, {List<Function> x}) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {List<Function> x})
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int x) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [List<Function> x]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [List<Function> x]) Function<B extends core.int>()
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<T>]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<T>]) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function(int, [List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function({Function x}) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function({Function x}) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function({Function x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(List<T> x) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(List<T> x) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, [Function x]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [Function x]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int, [Function x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([core.List<core.int>]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([core.List<core.int>]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<A> x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<A> x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is int Function<A>(List<A> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(int x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(int x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<T> Function<A>(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(Function x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(Function x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is List<A> Function<A>(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U62().runTests();
+  new U62<int>(tIsInt: true).runTests();
+  new U62<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type63_test.dart b/tests/language/function_type/function_type63_test.dart
new file mode 100644
index 0000000..9950b66
--- /dev/null
+++ b/tests/language/function_type/function_type63_test.dart
@@ -0,0 +1,986 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int x, [int]);
+typedef F1<T> = List<Function> Function(int x, [List<T>]);
+typedef F2<T> = List<T> Function(int, [core.List<core.int>]);
+typedef F3<T> = void Function([List<Function>]);
+typedef F4<T> = void Function<A>(List<A> x);
+typedef F5<T> = int Function(int, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F6<T> = int Function([List<T>]) Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int x, [Function])
+    Function<B extends core.int>(int x);
+typedef F8<T> = Function Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function([Function x])
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(core.List<core.int>)
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(int, [int])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F13<T> = List<T> Function(int x) Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(int y, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function(int, [List<T>]) Function<B extends core.int>(
+    int x);
+typedef F16<T> = Function({Function x}) Function<B extends core.int>(int x);
+typedef F17<T> = Function(List<T> x) Function<B extends core.int>(int x);
+typedef F18<T> = void Function(int, [Function x]) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function([core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F20<T> = int Function<A>(List<A> x) Function<B extends core.int>(int x);
+typedef F21<T> = List<T> Function<A>(int x) Function<B extends core.int>(int x);
+typedef F22<T> = List<A> Function<A>(Function x) Function<B extends core.int>(
+    int x);
+
+Function f0(int x, [int x0 = -1]) => throw 'uncalled';
+List<Function> f1(int x, [List<int> x0 = const []]) => throw 'uncalled';
+List<int> f2(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
+void f3([List<Function> x0 = const []]) => throw 'uncalled';
+void f4<A>(List<A> x) => throw 'uncalled';
+int Function(int, [List<Function> x]) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function([List<int>]) f6<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int x, [Function]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int y, {core.List<core.int> x}) f8<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<Function> Function([Function x]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(core.List<core.int>) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [int]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {List<Function> x}) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function(int x) f13<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function(int y, [List<Function> x]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, [List<int>]) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function({Function x}) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(List<int> x) f17<B extends core.int>(int x) => throw 'uncalled';
+void Function(int, [Function x]) f18<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function([core.List<core.int>]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function<A>(List<A> x) f20<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function<A>(int x) f21<B extends core.int>(int x) => throw 'uncalled';
+List<A> Function<A>(Function x) f22<B extends core.int>(int x) =>
+    throw 'uncalled';
+
+class U63<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int x, [int]) x0;
+  late List<Function> Function(int x, [List<T>]) x1;
+  late List<T> Function(int, [core.List<core.int>]) x2;
+  late void Function([List<Function>]) x3;
+  late void Function<A>(List<A> x) x4;
+  late int Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+      x5;
+  late int Function([List<T>]) Function<B extends core.int>(int x) x6;
+  late Function Function(int x, [Function]) Function<B extends core.int>(int x)
+      x7;
+  late Function Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>(int x) x8;
+  late List<Function> Function([Function x]) Function<B extends core.int>(int x)
+      x9;
+  late List<Function> Function(core.List<core.int>)
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function(int, [int]) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function(int, {List<Function> x})
+      Function<B extends core.int>(int x) x12;
+  late List<T> Function(int x) Function<B extends core.int>(int x) x13;
+  late List<T> Function(int y, [List<Function> x]) Function<B extends core.int>(
+      int x) x14;
+  late List<T> Function(int, [List<T>]) Function<B extends core.int>(int x) x15;
+  late Function({Function x}) Function<B extends core.int>(int x) x16;
+  late Function(List<T> x) Function<B extends core.int>(int x) x17;
+  late void Function(int, [Function x]) Function<B extends core.int>(int x) x18;
+  late void Function([core.List<core.int>]) Function<B extends core.int>(int x)
+      x19;
+  late int Function<A>(List<A> x) Function<B extends core.int>(int x) x20;
+  late List<T> Function<A>(int x) Function<B extends core.int>(int x) x21;
+  late List<A> Function<A>(Function x) Function<B extends core.int>(int x) x22;
+
+  U63({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x, [int x0 = -1]) => throw 'uncalled';
+  List<Function> m1(int x, [List<T> x0 = const []]) => throw 'uncalled';
+  List<T> m2(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
+  void m3([List<Function> x0 = const []]) => throw 'uncalled';
+  void m4<A>(List<A> x) => throw 'uncalled';
+  int Function(int, [List<Function> x]) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function([List<T>]) m6<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(int x, [Function]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int y, {core.List<core.int> x}) m8<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<Function> Function([Function x]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(core.List<core.int>) m10<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [int]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {List<Function> x}) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function(int x) m13<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function(int y, [List<Function> x]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [List<T>]) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function({Function x}) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(List<T> x) m17<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int, [Function x]) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function([core.List<core.int>]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function<A>(List<A> x) m20<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function<A>(int x) m21<B extends core.int>(int x) => throw 'uncalled';
+  List<A> Function<A>(Function x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int x, [int])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [int]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int x, [int]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int x, [List<T>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [List<T>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int x, [List<T>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [core.List<core.int>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [core.List<core.int>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, [core.List<core.int>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function([List<Function>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function([List<Function>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function([List<Function>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// void Function<A>(List<A> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<A> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is void Function<A>(List<A> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+        l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function([List<T>]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function([List<T>]) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function([List<T>]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int x, [Function]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [Function]) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int x, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// List<Function> Function([Function x]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([Function x]) Function<B extends core.int>(int x)
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(core.List<core.int>) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(core.List<core.int>) Function<B extends core.int>(
+        int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(core.List<core.int>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, [int]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [int]) Function<B extends core.int>(int x)
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, [int])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {List<Function> x})
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int x) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x) Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [List<Function> x]) Function<B extends core.int>(
+        int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<T>]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<T>]) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function({Function x}) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function({Function x}) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function({Function x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(List<T> x) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(List<T> x) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(List<T> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, [Function x]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [Function x]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([core.List<core.int>]) Function<B extends core.int>(int x)
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// int Function<A>(List<A> x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<A> x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is int Function<A>(List<A> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(int x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(int x) Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<T> Function<A>(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(Function x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(Function x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(Function x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U63().runTests();
+  new U63<int>(tIsInt: true).runTests();
+  new U63<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type64_test.dart b/tests/language/function_type/function_type64_test.dart
new file mode 100644
index 0000000..56e5697
--- /dev/null
+++ b/tests/language/function_type/function_type64_test.dart
@@ -0,0 +1,941 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function({int x});
+typedef F1<T> = List<Function> Function({List<T> x});
+typedef F2<T> = List<T> Function(int x, [core.List<core.int>]);
+typedef F3<T> = void Function(int, [List<Function>]);
+typedef F4<T> = int Function(int x) Function();
+typedef F5<T> = int Function(int y, [List<Function> x]) Function();
+typedef F6<T> = int Function(int, [List<T>]) Function();
+typedef F7<T> = Function Function({Function x}) Function();
+typedef F8<T> = Function Function(List<T> x) Function();
+typedef F9<T> = List<Function> Function(int, [Function x]) Function();
+typedef F10<T> = List<Function> Function([core.List<core.int>]) Function();
+typedef F11<T> = core.List<core.int> Function(int x, [int]) Function();
+typedef F12<T> = core.List<core.int> Function(int y, {List<Function> x})
+    Function();
+typedef F13<T> = List<T> Function([int x]) Function();
+typedef F14<T> = List<T> Function(List<Function>) Function();
+typedef F15<T> = List<T> Function(int x, [List<T>]) Function();
+typedef F16<T> = Function(int, {Function x}) Function();
+typedef F17<T> = Function([List<T> x]) Function();
+typedef F18<T> = void Function(int y, [Function x]) Function();
+typedef F19<T> = void Function(int, [core.List<core.int>]) Function();
+typedef F20<T> = Function Function<A>(int x) Function();
+typedef F21<T> = List<T> Function<A>(Function x) Function();
+typedef F22<T> = List<A> Function<A>(List<Function> x) Function();
+
+Function f0({int x = -1}) => throw 'uncalled';
+List<Function> f1({List<int> x = const []}) => throw 'uncalled';
+List<int> f2(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
+void f3(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+int Function(int x) f4() => throw 'uncalled';
+int Function(int y, [List<Function> x]) f5() => throw 'uncalled';
+int Function(int, [List<int>]) f6() => throw 'uncalled';
+Function Function({Function x}) f7() => throw 'uncalled';
+Function Function(List<int> x) f8() => throw 'uncalled';
+List<Function> Function(int, [Function x]) f9() => throw 'uncalled';
+List<Function> Function([core.List<core.int>]) f10() => throw 'uncalled';
+core.List<core.int> Function(int x, [int]) f11() => throw 'uncalled';
+core.List<core.int> Function(int y, {List<Function> x}) f12() =>
+    throw 'uncalled';
+List<int> Function([int x]) f13() => throw 'uncalled';
+List<int> Function(List<Function>) f14() => throw 'uncalled';
+List<int> Function(int x, [List<int>]) f15() => throw 'uncalled';
+Function(int, {Function x}) f16() => throw 'uncalled';
+Function([List<int> x]) f17() => throw 'uncalled';
+void Function(int y, [Function x]) f18() => throw 'uncalled';
+void Function(int, [core.List<core.int>]) f19() => throw 'uncalled';
+Function Function<A>(int x) f20() => throw 'uncalled';
+List<int> Function<A>(Function x) f21() => throw 'uncalled';
+List<A> Function<A>(List<Function> x) f22() => throw 'uncalled';
+
+class U64<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function({int x}) x0;
+  late List<Function> Function({List<T> x}) x1;
+  late List<T> Function(int x, [core.List<core.int>]) x2;
+  late void Function(int, [List<Function>]) x3;
+  late int Function(int x) Function() x4;
+  late int Function(int y, [List<Function> x]) Function() x5;
+  late int Function(int, [List<T>]) Function() x6;
+  late Function Function({Function x}) Function() x7;
+  late Function Function(List<T> x) Function() x8;
+  late List<Function> Function(int, [Function x]) Function() x9;
+  late List<Function> Function([core.List<core.int>]) Function() x10;
+  late core.List<core.int> Function(int x, [int]) Function() x11;
+  late core.List<core.int> Function(int y, {List<Function> x}) Function() x12;
+  late List<T> Function([int x]) Function() x13;
+  late List<T> Function(List<Function>) Function() x14;
+  late List<T> Function(int x, [List<T>]) Function() x15;
+  late Function(int, {Function x}) Function() x16;
+  late Function([List<T> x]) Function() x17;
+  late void Function(int y, [Function x]) Function() x18;
+  late void Function(int, [core.List<core.int>]) Function() x19;
+  late Function Function<A>(int x) Function() x20;
+  late List<T> Function<A>(Function x) Function() x21;
+  late List<A> Function<A>(List<Function> x) Function() x22;
+
+  U64({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0({int x = -1}) => throw 'uncalled';
+  List<Function> m1({List<T> x = const []}) => throw 'uncalled';
+  List<T> m2(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
+  void m3(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+  int Function(int x) m4() => throw 'uncalled';
+  int Function(int y, [List<Function> x]) m5() => throw 'uncalled';
+  int Function(int, [List<T>]) m6() => throw 'uncalled';
+  Function Function({Function x}) m7() => throw 'uncalled';
+  Function Function(List<T> x) m8() => throw 'uncalled';
+  List<Function> Function(int, [Function x]) m9() => throw 'uncalled';
+  List<Function> Function([core.List<core.int>]) m10() => throw 'uncalled';
+  core.List<core.int> Function(int x, [int]) m11() => throw 'uncalled';
+  core.List<core.int> Function(int y, {List<Function> x}) m12() =>
+      throw 'uncalled';
+  List<T> Function([int x]) m13() => throw 'uncalled';
+  List<T> Function(List<Function>) m14() => throw 'uncalled';
+  List<T> Function(int x, [List<T>]) m15() => throw 'uncalled';
+  Function(int, {Function x}) m16() => throw 'uncalled';
+  Function([List<T> x]) m17() => throw 'uncalled';
+  void Function(int y, [Function x]) m18() => throw 'uncalled';
+  void Function(int, [core.List<core.int>]) m19() => throw 'uncalled';
+  Function Function<A>(int x) m20() => throw 'uncalled';
+  List<T> Function<A>(Function x) m21() => throw 'uncalled';
+  List<A> Function<A>(List<Function> x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function({int x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function({int x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function({int x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function({List<T> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({List<T> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function({List<T> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [core.List<core.int>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [core.List<core.int>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int x, [core.List<core.int>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, [List<Function>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<Function>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, [List<Function>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int x) Function()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int x) Function() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int x) Function());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, [List<Function> x]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [List<Function> x]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [List<T>]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<T>]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [List<T>]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function({Function x}) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function({Function x}) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function({Function x}) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(List<T> x) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<T> x) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(List<T> x) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, [Function x]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [Function x]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [Function x]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([core.List<core.int>]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([core.List<core.int>]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function([core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int x, [int]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [int]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int x, [int]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, {List<Function> x}) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {List<Function> x}) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, {List<Function> x})
+        Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function([int x]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([int x]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function([int x]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(List<Function>) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<Function>) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(List<Function>) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [List<T>]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [List<T>]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int x, [List<T>]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, {Function x}) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, {Function x}) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, {Function x}) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([List<T> x]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([List<T> x]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([List<T> x]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int y, [Function x]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [Function x]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, [Function x]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [core.List<core.int>]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [core.List<core.int>]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(int x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(int x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(int x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(Function x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(Function x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(Function x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<Function> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<Function> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(List<Function> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U64().runTests();
+  new U64<int>(tIsInt: true).runTests();
+  new U64<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type65_test.dart b/tests/language/function_type/function_type65_test.dart
new file mode 100644
index 0000000..e3bef3e
--- /dev/null
+++ b/tests/language/function_type/function_type65_test.dart
@@ -0,0 +1,946 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, {int x});
+typedef F1<T> = List<Function> Function(int, {List<T> x});
+typedef F2<T> = List<T> Function({core.List<core.int> x});
+typedef F3<T> = void Function(int x, [List<Function>]);
+typedef F4<T> = int Function(int x) Function(int x);
+typedef F5<T> = int Function(int y, [List<Function> x]) Function(int x);
+typedef F6<T> = int Function(int, [List<T>]) Function(int x);
+typedef F7<T> = Function Function({Function x}) Function(int x);
+typedef F8<T> = Function Function(List<T> x) Function(int x);
+typedef F9<T> = List<Function> Function(int, [Function x]) Function(int x);
+typedef F10<T> = List<Function> Function([core.List<core.int>]) Function(int x);
+typedef F11<T> = core.List<core.int> Function(int x, [int]) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int y, {List<Function> x})
+    Function(int x);
+typedef F13<T> = List<T> Function([int x]) Function(int x);
+typedef F14<T> = List<T> Function(List<Function>) Function(int x);
+typedef F15<T> = List<T> Function(int x, [List<T>]) Function(int x);
+typedef F16<T> = Function(int, {Function x}) Function(int x);
+typedef F17<T> = Function([List<T> x]) Function(int x);
+typedef F18<T> = void Function(int y, [Function x]) Function(int x);
+typedef F19<T> = void Function(int, [core.List<core.int>]) Function(int x);
+typedef F20<T> = Function Function<A>(int x) Function(int x);
+typedef F21<T> = List<T> Function<A>(Function x) Function(int x);
+typedef F22<T> = List<A> Function<A>(List<Function> x) Function(int x);
+
+Function f0(int x0, {int x = -1}) => throw 'uncalled';
+List<Function> f1(int x0, {List<int> x = const []}) => throw 'uncalled';
+List<int> f2({core.List<core.int> x = const []}) => throw 'uncalled';
+void f3(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+int Function(int x) f4(int x) => throw 'uncalled';
+int Function(int y, [List<Function> x]) f5(int x) => throw 'uncalled';
+int Function(int, [List<int>]) f6(int x) => throw 'uncalled';
+Function Function({Function x}) f7(int x) => throw 'uncalled';
+Function Function(List<int> x) f8(int x) => throw 'uncalled';
+List<Function> Function(int, [Function x]) f9(int x) => throw 'uncalled';
+List<Function> Function([core.List<core.int>]) f10(int x) => throw 'uncalled';
+core.List<core.int> Function(int x, [int]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int y, {List<Function> x}) f12(int x) =>
+    throw 'uncalled';
+List<int> Function([int x]) f13(int x) => throw 'uncalled';
+List<int> Function(List<Function>) f14(int x) => throw 'uncalled';
+List<int> Function(int x, [List<int>]) f15(int x) => throw 'uncalled';
+Function(int, {Function x}) f16(int x) => throw 'uncalled';
+Function([List<int> x]) f17(int x) => throw 'uncalled';
+void Function(int y, [Function x]) f18(int x) => throw 'uncalled';
+void Function(int, [core.List<core.int>]) f19(int x) => throw 'uncalled';
+Function Function<A>(int x) f20(int x) => throw 'uncalled';
+List<int> Function<A>(Function x) f21(int x) => throw 'uncalled';
+List<A> Function<A>(List<Function> x) f22(int x) => throw 'uncalled';
+
+class U65<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, {int x}) x0;
+  late List<Function> Function(int, {List<T> x}) x1;
+  late List<T> Function({core.List<core.int> x}) x2;
+  late void Function(int x, [List<Function>]) x3;
+  late int Function(int x) Function(int x) x4;
+  late int Function(int y, [List<Function> x]) Function(int x) x5;
+  late int Function(int, [List<T>]) Function(int x) x6;
+  late Function Function({Function x}) Function(int x) x7;
+  late Function Function(List<T> x) Function(int x) x8;
+  late List<Function> Function(int, [Function x]) Function(int x) x9;
+  late List<Function> Function([core.List<core.int>]) Function(int x) x10;
+  late core.List<core.int> Function(int x, [int]) Function(int x) x11;
+  late core.List<core.int> Function(int y, {List<Function> x}) Function(int x)
+      x12;
+  late List<T> Function([int x]) Function(int x) x13;
+  late List<T> Function(List<Function>) Function(int x) x14;
+  late List<T> Function(int x, [List<T>]) Function(int x) x15;
+  late Function(int, {Function x}) Function(int x) x16;
+  late Function([List<T> x]) Function(int x) x17;
+  late void Function(int y, [Function x]) Function(int x) x18;
+  late void Function(int, [core.List<core.int>]) Function(int x) x19;
+  late Function Function<A>(int x) Function(int x) x20;
+  late List<T> Function<A>(Function x) Function(int x) x21;
+  late List<A> Function<A>(List<Function> x) Function(int x) x22;
+
+  U65({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, {int x = -1}) => throw 'uncalled';
+  List<Function> m1(int x0, {List<T> x = const []}) => throw 'uncalled';
+  List<T> m2({core.List<core.int> x = const []}) => throw 'uncalled';
+  void m3(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+  int Function(int x) m4(int x) => throw 'uncalled';
+  int Function(int y, [List<Function> x]) m5(int x) => throw 'uncalled';
+  int Function(int, [List<T>]) m6(int x) => throw 'uncalled';
+  Function Function({Function x}) m7(int x) => throw 'uncalled';
+  Function Function(List<T> x) m8(int x) => throw 'uncalled';
+  List<Function> Function(int, [Function x]) m9(int x) => throw 'uncalled';
+  List<Function> Function([core.List<core.int>]) m10(int x) => throw 'uncalled';
+  core.List<core.int> Function(int x, [int]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int y, {List<Function> x}) m12(int x) =>
+      throw 'uncalled';
+  List<T> Function([int x]) m13(int x) => throw 'uncalled';
+  List<T> Function(List<Function>) m14(int x) => throw 'uncalled';
+  List<T> Function(int x, [List<T>]) m15(int x) => throw 'uncalled';
+  Function(int, {Function x}) m16(int x) => throw 'uncalled';
+  Function([List<T> x]) m17(int x) => throw 'uncalled';
+  void Function(int y, [Function x]) m18(int x) => throw 'uncalled';
+  void Function(int, [core.List<core.int>]) m19(int x) => throw 'uncalled';
+  Function Function<A>(int x) m20(int x) => throw 'uncalled';
+  List<T> Function<A>(Function x) m21(int x) => throw 'uncalled';
+  List<A> Function<A>(List<Function> x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, {int x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {int x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, {int x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int, {List<T> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {List<T> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int, {List<T> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function({core.List<core.int> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({core.List<core.int> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function({core.List<core.int> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int x, [List<Function>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [List<Function>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int x, [List<Function>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int x) Function(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int x) Function(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int x) Function(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, [List<Function> x]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [List<Function> x]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int y, [List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [List<T>]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<T>]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function({Function x}) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function({Function x}) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function({Function x}) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(List<T> x) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<T> x) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, [Function x]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [Function x]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([core.List<core.int>]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([core.List<core.int>]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function([core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int x, [int]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [int]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int x, [int]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, {List<Function> x}) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {List<Function> x}) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, {List<Function> x})
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function([int x]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([int x]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function([int x]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(List<Function>) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<Function>) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(List<Function>) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [List<T>]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [List<T>]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int x, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, {Function x}) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, {Function x}) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([List<T> x]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([List<T> x]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int y, [Function x]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [Function x]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [core.List<core.int>]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [core.List<core.int>]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int, [core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(int x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(int x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(int x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(Function x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(Function x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(Function x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<Function> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<Function> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U65().runTests();
+  new U65<int>(tIsInt: true).runTests();
+  new U65<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type66_test.dart b/tests/language/function_type/function_type66_test.dart
new file mode 100644
index 0000000..1de0e6a
--- /dev/null
+++ b/tests/language/function_type/function_type66_test.dart
@@ -0,0 +1,994 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int y, {int x});
+typedef F1<T> = List<Function> Function(int y, {List<T> x});
+typedef F2<T> = List<T> Function(int, {core.List<core.int> x});
+typedef F3<T> = void Function({List<Function> x});
+typedef F4<T> = int Function(int x) Function<B extends core.int>();
+typedef F5<T> = int Function(int y, [List<Function> x])
+    Function<B extends core.int>();
+typedef F6<T> = int Function(int, [List<T>]) Function<B extends core.int>();
+typedef F7<T> = Function Function({Function x}) Function<B extends core.int>();
+typedef F8<T> = Function Function(List<T> x) Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int, [Function x])
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function([core.List<core.int>])
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(int x, [int])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int y, {List<Function> x})
+    Function<B extends core.int>();
+typedef F13<T> = List<T> Function([int x]) Function<B extends core.int>();
+typedef F14<T> = List<T> Function(List<Function>)
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int x, [List<T>])
+    Function<B extends core.int>();
+typedef F16<T> = Function(int, {Function x}) Function<B extends core.int>();
+typedef F17<T> = Function([List<T> x]) Function<B extends core.int>();
+typedef F18<T> = void Function(int y, [Function x])
+    Function<B extends core.int>();
+typedef F19<T> = void Function(int, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F20<T> = Function Function<A>(int x) Function<B extends core.int>();
+typedef F21<T> = List<T> Function<A>(Function x) Function<B extends core.int>();
+typedef F22<T> = List<A> Function<A>(List<Function> x)
+    Function<B extends core.int>();
+
+Function f0(int y, {int x = -1}) => throw 'uncalled';
+List<Function> f1(int y, {List<int> x = const []}) => throw 'uncalled';
+List<int> f2(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
+void f3({List<Function> x = const []}) => throw 'uncalled';
+int Function(int x) f4<B extends core.int>() => throw 'uncalled';
+int Function(int y, [List<Function> x]) f5<B extends core.int>() =>
+    throw 'uncalled';
+int Function(int, [List<int>]) f6<B extends core.int>() => throw 'uncalled';
+Function Function({Function x}) f7<B extends core.int>() => throw 'uncalled';
+Function Function(List<int> x) f8<B extends core.int>() => throw 'uncalled';
+List<Function> Function(int, [Function x]) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function([core.List<core.int>]) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int x, [int]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, {List<Function> x})
+    f12<B extends core.int>() => throw 'uncalled';
+List<int> Function([int x]) f13<B extends core.int>() => throw 'uncalled';
+List<int> Function(List<Function>) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int x, [List<int>]) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function(int, {Function x}) f16<B extends core.int>() => throw 'uncalled';
+Function([List<int> x]) f17<B extends core.int>() => throw 'uncalled';
+void Function(int y, [Function x]) f18<B extends core.int>() =>
+    throw 'uncalled';
+void Function(int, [core.List<core.int>]) f19<B extends core.int>() =>
+    throw 'uncalled';
+Function Function<A>(int x) f20<B extends core.int>() => throw 'uncalled';
+List<int> Function<A>(Function x) f21<B extends core.int>() => throw 'uncalled';
+List<A> Function<A>(List<Function> x) f22<B extends core.int>() =>
+    throw 'uncalled';
+
+class U66<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int y, {int x}) x0;
+  late List<Function> Function(int y, {List<T> x}) x1;
+  late List<T> Function(int, {core.List<core.int> x}) x2;
+  late void Function({List<Function> x}) x3;
+  late int Function(int x) Function<B extends core.int>() x4;
+  late int Function(int y, [List<Function> x]) Function<B extends core.int>()
+      x5;
+  late int Function(int, [List<T>]) Function<B extends core.int>() x6;
+  late Function Function({Function x}) Function<B extends core.int>() x7;
+  late Function Function(List<T> x) Function<B extends core.int>() x8;
+  late List<Function> Function(int, [Function x]) Function<B extends core.int>()
+      x9;
+  late List<Function> Function([core.List<core.int>])
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function(int x, [int]) Function<B extends core.int>()
+      x11;
+  late core.List<core.int> Function(int y, {List<Function> x})
+      Function<B extends core.int>() x12;
+  late List<T> Function([int x]) Function<B extends core.int>() x13;
+  late List<T> Function(List<Function>) Function<B extends core.int>() x14;
+  late List<T> Function(int x, [List<T>]) Function<B extends core.int>() x15;
+  late Function(int, {Function x}) Function<B extends core.int>() x16;
+  late Function([List<T> x]) Function<B extends core.int>() x17;
+  late void Function(int y, [Function x]) Function<B extends core.int>() x18;
+  late void Function(int, [core.List<core.int>]) Function<B extends core.int>()
+      x19;
+  late Function Function<A>(int x) Function<B extends core.int>() x20;
+  late List<T> Function<A>(Function x) Function<B extends core.int>() x21;
+  late List<A> Function<A>(List<Function> x) Function<B extends core.int>() x22;
+
+  U66({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int y, {int x = -1}) => throw 'uncalled';
+  List<Function> m1(int y, {List<T> x = const []}) => throw 'uncalled';
+  List<T> m2(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
+  void m3({List<Function> x = const []}) => throw 'uncalled';
+  int Function(int x) m4<B extends core.int>() => throw 'uncalled';
+  int Function(int y, [List<Function> x]) m5<B extends core.int>() =>
+      throw 'uncalled';
+  int Function(int, [List<T>]) m6<B extends core.int>() => throw 'uncalled';
+  Function Function({Function x}) m7<B extends core.int>() => throw 'uncalled';
+  Function Function(List<T> x) m8<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(int, [Function x]) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function([core.List<core.int>]) m10<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x, [int]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {List<Function> x})
+      m12<B extends core.int>() => throw 'uncalled';
+  List<T> Function([int x]) m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function(List<Function>) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int x, [List<T>]) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int, {Function x}) m16<B extends core.int>() => throw 'uncalled';
+  Function([List<T> x]) m17<B extends core.int>() => throw 'uncalled';
+  void Function(int y, [Function x]) m18<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int, [core.List<core.int>]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function<A>(int x) m20<B extends core.int>() => throw 'uncalled';
+  List<T> Function<A>(Function x) m21<B extends core.int>() => throw 'uncalled';
+  List<A> Function<A>(List<Function> x) m22<B extends core.int>() =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int y, {int x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {int x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int y, {int x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function(int y, {List<T> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {List<T> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function(int y, {List<T> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {core.List<core.int> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {core.List<core.int> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function({List<Function> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function({List<Function> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function({List<Function> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int x) Function<B extends core.int>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int x) Function<B extends core.int>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, [List<Function> x]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [List<Function> x]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [List<T>]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<T>]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int, [List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function({Function x}) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function({Function x}) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function({Function x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(List<T> x) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<T> x) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, [Function x]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [Function x]) Function<B extends core.int>()
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([core.List<core.int>]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([core.List<core.int>])
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int x, [int]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [int]) Function<B extends core.int>()
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int x, [int])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, {List<Function> x}) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {List<Function> x})
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function([int x]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([int x]) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function([int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(List<Function>) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<Function>) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(List<Function>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [List<T>]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [List<T>]) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int x, [List<T>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, {Function x}) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, {Function x}) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int, {Function x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([List<T> x]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([List<T> x]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([List<T> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int y, [Function x]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [Function x]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, [Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [core.List<core.int>]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [core.List<core.int>]) Function<B extends core.int>()
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(int x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(int x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(Function x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(Function x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<T> Function<A>(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<Function> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<Function> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U66().runTests();
+  new U66<int>(tIsInt: true).runTests();
+  new U66<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type67_test.dart b/tests/language/function_type/function_type67_test.dart
new file mode 100644
index 0000000..0875a3d
--- /dev/null
+++ b/tests/language/function_type/function_type67_test.dart
@@ -0,0 +1,994 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(Function x);
+typedef F1<T> = List<Function> Function();
+typedef F2<T> = List<T> Function(int y, {core.List<core.int> x});
+typedef F3<T> = void Function(int, {List<Function> x});
+typedef F4<T> = int Function(int x) Function<B extends core.int>(int x);
+typedef F5<T> = int Function(int y, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F6<T> = int Function(int, [List<T>]) Function<B extends core.int>(
+    int x);
+typedef F7<T> = Function Function({Function x}) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function(List<T> x) Function<B extends core.int>(
+    int x);
+typedef F9<T> = List<Function> Function(int, [Function x])
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function([core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(int x, [int])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int y, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F13<T> = List<T> Function([int x]) Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(List<Function>) Function<B extends core.int>(
+    int x);
+typedef F15<T> = List<T> Function(int x, [List<T>])
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function(int, {Function x}) Function<B extends core.int>(
+    int x);
+typedef F17<T> = Function([List<T> x]) Function<B extends core.int>(int x);
+typedef F18<T> = void Function(int y, [Function x])
+    Function<B extends core.int>(int x);
+typedef F19<T> = void Function(int, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F20<T> = Function Function<A>(int x) Function<B extends core.int>(
+    int x);
+typedef F21<T> = List<T> Function<A>(Function x) Function<B extends core.int>(
+    int x);
+typedef F22<T> = List<A> Function<A>(List<Function> x)
+    Function<B extends core.int>(int x);
+
+Function f0(Function x) => throw 'uncalled';
+List<Function> f1() => throw 'uncalled';
+List<int> f2(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
+void f3(int x0, {List<Function> x = const []}) => throw 'uncalled';
+int Function(int x) f4<B extends core.int>(int x) => throw 'uncalled';
+int Function(int y, [List<Function> x]) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function(int, [List<int>]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function({Function x}) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(List<int> x) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, [Function x]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function([core.List<core.int>]) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int x, [int]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, {List<Function> x}) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function([int x]) f13<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function(List<Function>) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int x, [List<int>]) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int, {Function x}) f16<B extends core.int>(int x) => throw 'uncalled';
+Function([List<int> x]) f17<B extends core.int>(int x) => throw 'uncalled';
+void Function(int y, [Function x]) f18<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int, [core.List<core.int>]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function<A>(int x) f20<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function<A>(Function x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<A> Function<A>(List<Function> x) f22<B extends core.int>(int x) =>
+    throw 'uncalled';
+
+class U67<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(Function x) x0;
+  late List<Function> Function() x1;
+  late List<T> Function(int y, {core.List<core.int> x}) x2;
+  late void Function(int, {List<Function> x}) x3;
+  late int Function(int x) Function<B extends core.int>(int x) x4;
+  late int Function(int y, [List<Function> x]) Function<B extends core.int>(
+      int x) x5;
+  late int Function(int, [List<T>]) Function<B extends core.int>(int x) x6;
+  late Function Function({Function x}) Function<B extends core.int>(int x) x7;
+  late Function Function(List<T> x) Function<B extends core.int>(int x) x8;
+  late List<Function> Function(int, [Function x]) Function<B extends core.int>(
+      int x) x9;
+  late List<Function> Function([core.List<core.int>])
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function(int x, [int]) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function(int y, {List<Function> x})
+      Function<B extends core.int>(int x) x12;
+  late List<T> Function([int x]) Function<B extends core.int>(int x) x13;
+  late List<T> Function(List<Function>) Function<B extends core.int>(int x) x14;
+  late List<T> Function(int x, [List<T>]) Function<B extends core.int>(int x)
+      x15;
+  late Function(int, {Function x}) Function<B extends core.int>(int x) x16;
+  late Function([List<T> x]) Function<B extends core.int>(int x) x17;
+  late void Function(int y, [Function x]) Function<B extends core.int>(int x)
+      x18;
+  late void Function(int, [core.List<core.int>]) Function<B extends core.int>(
+      int x) x19;
+  late Function Function<A>(int x) Function<B extends core.int>(int x) x20;
+  late List<T> Function<A>(Function x) Function<B extends core.int>(int x) x21;
+  late List<A> Function<A>(List<Function> x) Function<B extends core.int>(int x)
+      x22;
+
+  U67({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(Function x) => throw 'uncalled';
+  List<Function> m1() => throw 'uncalled';
+  List<T> m2(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
+  void m3(int x0, {List<Function> x = const []}) => throw 'uncalled';
+  int Function(int x) m4<B extends core.int>(int x) => throw 'uncalled';
+  int Function(int y, [List<Function> x]) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int, [List<T>]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function({Function x}) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(List<T> x) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, [Function x]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function([core.List<core.int>]) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x, [int]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {List<Function> x})
+      m12<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function([int x]) m13<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function(List<Function>) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int x, [List<T>]) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int, {Function x}) m16<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function([List<T> x]) m17<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int y, [Function x]) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int, [core.List<core.int>]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function<A>(int x) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function<A>(Function x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<A> Function<A>(List<Function> x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(Function x)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(Function x) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(Function x));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// List<Function> Function()
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function() l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is List<Function> Function());
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int y, {core.List<core.int> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {core.List<core.int> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int y, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, {List<Function> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {List<Function> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, {List<Function> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int x) Function<B extends core.int>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int x) Function<B extends core.int>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [List<Function> x]) Function<B extends core.int>(int x)
+        l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [List<T>]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<T>]) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int, [List<T>]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function({Function x}) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function({Function x}) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function({Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(List<T> x) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<T> x) Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(List<T> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, [Function x]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [Function x]) Function<B extends core.int>(
+        int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([core.List<core.int>]) Function<B extends core.int>(
+        int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int x, [int]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [int]) Function<B extends core.int>(
+        int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int x, [int])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {List<Function> x})
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function([int x]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([int x]) Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function([int x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(List<Function>) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<Function>) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(List<Function>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [List<T>]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [List<T>]) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int x, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, {Function x}) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, {Function x}) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int, {Function x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([List<T> x]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([List<T> x]) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function([List<T> x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int y, [Function x]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [Function x]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [core.List<core.int>]) Function<B extends core.int>(
+        int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(int x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(int x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(Function x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(Function x) Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(Function x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<Function> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<Function> x) Function<B extends core.int>(int x)
+        l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U67().runTests();
+  new U67<int>(tIsInt: true).runTests();
+  new U67<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type68_test.dart b/tests/language/function_type/function_type68_test.dart
new file mode 100644
index 0000000..1f28348
--- /dev/null
+++ b/tests/language/function_type/function_type68_test.dart
@@ -0,0 +1,915 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function([Function x]);
+typedef F1<T> = core.List<core.int> Function(int x);
+typedef F2<T> = List<T> Function(List<T> x);
+typedef F3<T> = void Function(int y, {List<Function> x});
+typedef F4<T> = int Function([int x]) Function();
+typedef F5<T> = int Function(List<Function>) Function();
+typedef F6<T> = int Function(int x, [List<T>]) Function();
+typedef F7<T> = Function Function(int, {Function x}) Function();
+typedef F8<T> = Function Function([List<T> x]) Function();
+typedef F9<T> = List<Function> Function(int y, [Function x]) Function();
+typedef F10<T> = List<Function> Function(int, [core.List<core.int>]) Function();
+typedef F11<T> = core.List<core.int> Function({int x}) Function();
+typedef F12<T> = core.List<core.int> Function(core.List<core.int> x) Function();
+typedef F13<T> = List<T> Function(int, [int x]) Function();
+typedef F14<T> = List<T> Function([List<Function>]) Function();
+typedef F15<T> = List<T> Function({List<T> x}) Function();
+typedef F16<T> = Function(int y, {Function x}) Function();
+typedef F17<T> = Function(int, [List<T> x]) Function();
+typedef F18<T> = void Function(Function) Function();
+typedef F19<T> = void Function(int x, [core.List<core.int>]) Function();
+typedef F20<T> = Function Function<A>(Function x) Function();
+typedef F21<T> = List<T> Function<A>(List<Function> x) Function();
+typedef F22<T> = List<A> Function<A>(core.List<core.int> x) Function();
+
+Function f0([Function x = _voidFunction]) => throw 'uncalled';
+core.List<core.int> f1(int x) => throw 'uncalled';
+List<int> f2(List<int> x) => throw 'uncalled';
+void f3(int y, {List<Function> x = const []}) => throw 'uncalled';
+int Function([int x]) f4() => throw 'uncalled';
+int Function(List<Function>) f5() => throw 'uncalled';
+int Function(int x, [List<int>]) f6() => throw 'uncalled';
+Function Function(int, {Function x}) f7() => throw 'uncalled';
+Function Function([List<int> x]) f8() => throw 'uncalled';
+List<Function> Function(int y, [Function x]) f9() => throw 'uncalled';
+List<Function> Function(int, [core.List<core.int>]) f10() => throw 'uncalled';
+core.List<core.int> Function({int x}) f11() => throw 'uncalled';
+core.List<core.int> Function(core.List<core.int> x) f12() => throw 'uncalled';
+List<int> Function(int, [int x]) f13() => throw 'uncalled';
+List<int> Function([List<Function>]) f14() => throw 'uncalled';
+List<int> Function({List<int> x}) f15() => throw 'uncalled';
+Function(int y, {Function x}) f16() => throw 'uncalled';
+Function(int, [List<int> x]) f17() => throw 'uncalled';
+void Function(Function) f18() => throw 'uncalled';
+void Function(int x, [core.List<core.int>]) f19() => throw 'uncalled';
+Function Function<A>(Function x) f20() => throw 'uncalled';
+List<int> Function<A>(List<Function> x) f21() => throw 'uncalled';
+List<A> Function<A>(core.List<core.int> x) f22() => throw 'uncalled';
+
+class U68<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function([Function x]) x0;
+  late core.List<core.int> Function(int x) x1;
+  late List<T> Function(List<T> x) x2;
+  late void Function(int y, {List<Function> x}) x3;
+  late int Function([int x]) Function() x4;
+  late int Function(List<Function>) Function() x5;
+  late int Function(int x, [List<T>]) Function() x6;
+  late Function Function(int, {Function x}) Function() x7;
+  late Function Function([List<T> x]) Function() x8;
+  late List<Function> Function(int y, [Function x]) Function() x9;
+  late List<Function> Function(int, [core.List<core.int>]) Function() x10;
+  late core.List<core.int> Function({int x}) Function() x11;
+  late core.List<core.int> Function(core.List<core.int> x) Function() x12;
+  late List<T> Function(int, [int x]) Function() x13;
+  late List<T> Function([List<Function>]) Function() x14;
+  late List<T> Function({List<T> x}) Function() x15;
+  late Function(int y, {Function x}) Function() x16;
+  late Function(int, [List<T> x]) Function() x17;
+  late void Function(Function) Function() x18;
+  late void Function(int x, [core.List<core.int>]) Function() x19;
+  late Function Function<A>(Function x) Function() x20;
+  late List<T> Function<A>(List<Function> x) Function() x21;
+  late List<A> Function<A>(core.List<core.int> x) Function() x22;
+
+  U68({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0([Function x = _voidFunction]) => throw 'uncalled';
+  core.List<core.int> m1(int x) => throw 'uncalled';
+  List<T> m2(List<T> x) => throw 'uncalled';
+  void m3(int y, {List<Function> x = const []}) => throw 'uncalled';
+  int Function([int x]) m4() => throw 'uncalled';
+  int Function(List<Function>) m5() => throw 'uncalled';
+  int Function(int x, [List<T>]) m6() => throw 'uncalled';
+  Function Function(int, {Function x}) m7() => throw 'uncalled';
+  Function Function([List<T> x]) m8() => throw 'uncalled';
+  List<Function> Function(int y, [Function x]) m9() => throw 'uncalled';
+  List<Function> Function(int, [core.List<core.int>]) m10() => throw 'uncalled';
+  core.List<core.int> Function({int x}) m11() => throw 'uncalled';
+  core.List<core.int> Function(core.List<core.int> x) m12() => throw 'uncalled';
+  List<T> Function(int, [int x]) m13() => throw 'uncalled';
+  List<T> Function([List<Function>]) m14() => throw 'uncalled';
+  List<T> Function({List<T> x}) m15() => throw 'uncalled';
+  Function(int y, {Function x}) m16() => throw 'uncalled';
+  Function(int, [List<T> x]) m17() => throw 'uncalled';
+  void Function(Function) m18() => throw 'uncalled';
+  void Function(int x, [core.List<core.int>]) m19() => throw 'uncalled';
+  Function Function<A>(Function x) m20() => throw 'uncalled';
+  List<T> Function<A>(List<Function> x) m21() => throw 'uncalled';
+  List<A> Function<A>(core.List<core.int> x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function([Function x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function([Function x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function([Function x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int x)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int x));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(List<T> x)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<T> x) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(List<T> x));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int y, {List<Function> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {List<Function> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int y, {List<Function> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function([int x]) Function()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function([int x]) Function() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function([int x]) Function());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(List<Function>) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(List<Function>) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(List<Function>) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int x, [List<T>]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [List<T>]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int x, [List<T>]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, {Function x}) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {Function x}) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, {Function x}) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([List<T> x]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<T> x]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([List<T> x]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int y, [Function x]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [Function x]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int y, [Function x]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [core.List<core.int>]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [core.List<core.int>]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(int, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function({int x}) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({int x}) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function({int x}) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(core.List<core.int> x) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(core.List<core.int> x) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, [int x]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [int x]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int, [int x]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([List<Function>]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<Function>]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([List<Function>]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function({List<T> x}) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({List<T> x}) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function({List<T> x}) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, {Function x}) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {Function x}) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, {Function x}) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [List<T> x]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<T> x]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [List<T> x]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(Function) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(Function) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(Function) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int x, [core.List<core.int>]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [core.List<core.int>]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int x, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(Function x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(Function x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(Function x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<Function> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<Function> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(List<Function> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(core.List<core.int> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(core.List<core.int> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U68().runTests();
+  new U68<int>(tIsInt: true).runTests();
+  new U68<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type69_test.dart b/tests/language/function_type/function_type69_test.dart
new file mode 100644
index 0000000..ad7b5cb
--- /dev/null
+++ b/tests/language/function_type/function_type69_test.dart
@@ -0,0 +1,922 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, [Function x]);
+typedef F1<T> = core.List<core.int> Function([int x]);
+typedef F2<T> = List<T> Function([List<T> x]);
+typedef F3<T> = void Function(core.List<core.int> x);
+typedef F4<T> = int Function([int x]) Function(int x);
+typedef F5<T> = int Function(List<Function>) Function(int x);
+typedef F6<T> = int Function(int x, [List<T>]) Function(int x);
+typedef F7<T> = Function Function(int, {Function x}) Function(int x);
+typedef F8<T> = Function Function([List<T> x]) Function(int x);
+typedef F9<T> = List<Function> Function(int y, [Function x]) Function(int x);
+typedef F10<T> = List<Function> Function(int, [core.List<core.int>]) Function(
+    int x);
+typedef F11<T> = core.List<core.int> Function({int x}) Function(int x);
+typedef F12<T> = core.List<core.int> Function(core.List<core.int> x) Function(
+    int x);
+typedef F13<T> = List<T> Function(int, [int x]) Function(int x);
+typedef F14<T> = List<T> Function([List<Function>]) Function(int x);
+typedef F15<T> = List<T> Function({List<T> x}) Function(int x);
+typedef F16<T> = Function(int y, {Function x}) Function(int x);
+typedef F17<T> = Function(int, [List<T> x]) Function(int x);
+typedef F18<T> = void Function(Function) Function(int x);
+typedef F19<T> = void Function(int x, [core.List<core.int>]) Function(int x);
+typedef F20<T> = Function Function<A>(Function x) Function(int x);
+typedef F21<T> = List<T> Function<A>(List<Function> x) Function(int x);
+typedef F22<T> = List<A> Function<A>(core.List<core.int> x) Function(int x);
+
+Function f0(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+core.List<core.int> f1([int x = -1]) => throw 'uncalled';
+List<int> f2([List<int> x = const []]) => throw 'uncalled';
+void f3(core.List<core.int> x) => throw 'uncalled';
+int Function([int x]) f4(int x) => throw 'uncalled';
+int Function(List<Function>) f5(int x) => throw 'uncalled';
+int Function(int x, [List<int>]) f6(int x) => throw 'uncalled';
+Function Function(int, {Function x}) f7(int x) => throw 'uncalled';
+Function Function([List<int> x]) f8(int x) => throw 'uncalled';
+List<Function> Function(int y, [Function x]) f9(int x) => throw 'uncalled';
+List<Function> Function(int, [core.List<core.int>]) f10(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function({int x}) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(core.List<core.int> x) f12(int x) =>
+    throw 'uncalled';
+List<int> Function(int, [int x]) f13(int x) => throw 'uncalled';
+List<int> Function([List<Function>]) f14(int x) => throw 'uncalled';
+List<int> Function({List<int> x}) f15(int x) => throw 'uncalled';
+Function(int y, {Function x}) f16(int x) => throw 'uncalled';
+Function(int, [List<int> x]) f17(int x) => throw 'uncalled';
+void Function(Function) f18(int x) => throw 'uncalled';
+void Function(int x, [core.List<core.int>]) f19(int x) => throw 'uncalled';
+Function Function<A>(Function x) f20(int x) => throw 'uncalled';
+List<int> Function<A>(List<Function> x) f21(int x) => throw 'uncalled';
+List<A> Function<A>(core.List<core.int> x) f22(int x) => throw 'uncalled';
+
+class U69<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, [Function x]) x0;
+  late core.List<core.int> Function([int x]) x1;
+  late List<T> Function([List<T> x]) x2;
+  late void Function(core.List<core.int> x) x3;
+  late int Function([int x]) Function(int x) x4;
+  late int Function(List<Function>) Function(int x) x5;
+  late int Function(int x, [List<T>]) Function(int x) x6;
+  late Function Function(int, {Function x}) Function(int x) x7;
+  late Function Function([List<T> x]) Function(int x) x8;
+  late List<Function> Function(int y, [Function x]) Function(int x) x9;
+  late List<Function> Function(int, [core.List<core.int>]) Function(int x) x10;
+  late core.List<core.int> Function({int x}) Function(int x) x11;
+  late core.List<core.int> Function(core.List<core.int> x) Function(int x) x12;
+  late List<T> Function(int, [int x]) Function(int x) x13;
+  late List<T> Function([List<Function>]) Function(int x) x14;
+  late List<T> Function({List<T> x}) Function(int x) x15;
+  late Function(int y, {Function x}) Function(int x) x16;
+  late Function(int, [List<T> x]) Function(int x) x17;
+  late void Function(Function) Function(int x) x18;
+  late void Function(int x, [core.List<core.int>]) Function(int x) x19;
+  late Function Function<A>(Function x) Function(int x) x20;
+  late List<T> Function<A>(List<Function> x) Function(int x) x21;
+  late List<A> Function<A>(core.List<core.int> x) Function(int x) x22;
+
+  U69({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+  core.List<core.int> m1([int x = -1]) => throw 'uncalled';
+  List<T> m2([List<T> x = const []]) => throw 'uncalled';
+  void m3(core.List<core.int> x) => throw 'uncalled';
+  int Function([int x]) m4(int x) => throw 'uncalled';
+  int Function(List<Function>) m5(int x) => throw 'uncalled';
+  int Function(int x, [List<T>]) m6(int x) => throw 'uncalled';
+  Function Function(int, {Function x}) m7(int x) => throw 'uncalled';
+  Function Function([List<T> x]) m8(int x) => throw 'uncalled';
+  List<Function> Function(int y, [Function x]) m9(int x) => throw 'uncalled';
+  List<Function> Function(int, [core.List<core.int>]) m10(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function({int x}) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(core.List<core.int> x) m12(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [int x]) m13(int x) => throw 'uncalled';
+  List<T> Function([List<Function>]) m14(int x) => throw 'uncalled';
+  List<T> Function({List<T> x}) m15(int x) => throw 'uncalled';
+  Function(int y, {Function x}) m16(int x) => throw 'uncalled';
+  Function(int, [List<T> x]) m17(int x) => throw 'uncalled';
+  void Function(Function) m18(int x) => throw 'uncalled';
+  void Function(int x, [core.List<core.int>]) m19(int x) => throw 'uncalled';
+  Function Function<A>(Function x) m20(int x) => throw 'uncalled';
+  List<T> Function<A>(List<Function> x) m21(int x) => throw 'uncalled';
+  List<A> Function<A>(core.List<core.int> x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, [Function x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [Function x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, [Function x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function([int x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([int x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function([int x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function([List<T> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<T> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function([List<T> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(core.List<core.int> x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(core.List<core.int> x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(core.List<core.int> x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function([int x]) Function(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function([int x]) Function(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function([int x]) Function(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(List<Function>) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(List<Function>) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(List<Function>) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int x, [List<T>]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [List<T>]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int x, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, {Function x}) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {Function x}) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([List<T> x]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<T> x]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int y, [Function x]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [Function x]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int y, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [core.List<core.int>]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [core.List<core.int>]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [core.List<core.int>])
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function({int x}) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({int x}) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function({int x}) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(core.List<core.int> x) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(core.List<core.int> x) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(core.List<core.int> x)
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, [int x]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [int x]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int, [int x]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([List<Function>]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<Function>]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function({List<T> x}) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({List<T> x}) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function({List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, {Function x}) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {Function x}) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [List<T> x]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<T> x]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(Function) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(Function) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(Function) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int x, [core.List<core.int>]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [core.List<core.int>]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int x, [core.List<core.int>]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(Function x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(Function x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(Function x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<Function> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<Function> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(core.List<core.int> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(core.List<core.int> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is List<A> Function<A>(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U69().runTests();
+  new U69<int>(tIsInt: true).runTests();
+  new U69<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type6_test.dart b/tests/language/function_type/function_type6_test.dart
new file mode 100644
index 0000000..7939e63
--- /dev/null
+++ b/tests/language/function_type/function_type6_test.dart
@@ -0,0 +1,981 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, [int]);
+typedef F1<T> = Function Function(int, [List<T>]);
+typedef F2<T> = core.List<core.int> Function([core.List<core.int>]);
+typedef F3<T> = Function(List<Function>);
+typedef F4<T> = Function Function<A>(A x);
+typedef F5<T> = int Function(int y, {int x}) Function<B extends core.int>();
+typedef F6<T> = int Function(int, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F7<T> = Function Function(int) Function<B extends core.int>();
+typedef F8<T> = Function Function(int x, [List<Function>])
+    Function<B extends core.int>();
+typedef F9<T> = Function Function(int y, {List<T> x})
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function([List<Function> x])
+    Function<B extends core.int>();
+typedef F11<T> = List<Function> Function(List<T>)
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int, [Function])
+    Function<B extends core.int>();
+typedef F13<T> = core.List<core.int> Function(int, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(Function x) Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F16<T> = Function([int]) Function<B extends core.int>();
+typedef F17<T> = Function({List<Function> x}) Function<B extends core.int>();
+typedef F18<T> = Function() Function<B extends core.int>();
+typedef F19<T> = void Function(int, [List<Function> x])
+    Function<B extends core.int>();
+typedef F20<T> = void Function([List<T>]) Function<B extends core.int>();
+typedef F21<T> = List<Function> Function<A>(List<Function> x)
+    Function<B extends core.int>();
+typedef F22<T> = Function<A>(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F23<T> = void Function<A>(List<T> x) Function<B extends core.int>();
+
+int f0(int x0, [int x1 = -1]) => throw 'uncalled';
+Function f1(int x0, [List<int> x1 = const []]) => throw 'uncalled';
+core.List<core.int> f2([core.List<core.int> x0 = const []]) => throw 'uncalled';
+f3(List<Function> x0) => throw 'uncalled';
+Function f4<A>(A x) => throw 'uncalled';
+int Function(int y, {int x}) f5<B extends core.int>() => throw 'uncalled';
+int Function(int, [core.List<core.int> x]) f6<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int) f7<B extends core.int>() => throw 'uncalled';
+Function Function(int x, [List<Function>]) f8<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int y, {List<int> x}) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function([List<Function> x]) f10<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(List<int>) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [Function]) f12<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {core.List<core.int> x})
+    f13<B extends core.int>() => throw 'uncalled';
+List<int> Function(Function x) f14<B extends core.int>() => throw 'uncalled';
+List<int> Function(int y, [core.List<core.int> x]) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function([int]) f16<B extends core.int>() => throw 'uncalled';
+Function({List<Function> x}) f17<B extends core.int>() => throw 'uncalled';
+Function() f18<B extends core.int>() => throw 'uncalled';
+void Function(int, [List<Function> x]) f19<B extends core.int>() =>
+    throw 'uncalled';
+void Function([List<int>]) f20<B extends core.int>() => throw 'uncalled';
+List<Function> Function<A>(List<Function> x) f21<B extends core.int>() =>
+    throw 'uncalled';
+Function<A>(core.List<core.int> x) f22<B extends core.int>() =>
+    throw 'uncalled';
+void Function<A>(List<int> x) f23<B extends core.int>() => throw 'uncalled';
+
+class U6<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, [int]) x0;
+  late Function Function(int, [List<T>]) x1;
+  late core.List<core.int> Function([core.List<core.int>]) x2;
+  late Function(List<Function>) x3;
+  late Function Function<A>(A x) x4;
+  late int Function(int y, {int x}) Function<B extends core.int>() x5;
+  late int Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+      x6;
+  late Function Function(int) Function<B extends core.int>() x7;
+  late Function Function(int x, [List<Function>]) Function<B extends core.int>()
+      x8;
+  late Function Function(int y, {List<T> x}) Function<B extends core.int>() x9;
+  late List<Function> Function([List<Function> x])
+      Function<B extends core.int>() x10;
+  late List<Function> Function(List<T>) Function<B extends core.int>() x11;
+  late core.List<core.int> Function(int, [Function])
+      Function<B extends core.int>() x12;
+  late core.List<core.int> Function(int, {core.List<core.int> x})
+      Function<B extends core.int>() x13;
+  late List<T> Function(Function x) Function<B extends core.int>() x14;
+  late List<T> Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>() x15;
+  late Function([int]) Function<B extends core.int>() x16;
+  late Function({List<Function> x}) Function<B extends core.int>() x17;
+  late Function() Function<B extends core.int>() x18;
+  late void Function(int, [List<Function> x]) Function<B extends core.int>()
+      x19;
+  late void Function([List<T>]) Function<B extends core.int>() x20;
+  late List<Function> Function<A>(List<Function> x)
+      Function<B extends core.int>() x21;
+  late Function<A>(core.List<core.int> x) Function<B extends core.int>() x22;
+  late void Function<A>(List<T> x) Function<B extends core.int>() x23;
+
+  U6({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, [int x1 = -1]) => throw 'uncalled';
+  Function m1(int x0, [List<T> x1 = const []]) => throw 'uncalled';
+  core.List<core.int> m2([core.List<core.int> x0 = const []]) =>
+      throw 'uncalled';
+  m3(List<Function> x0) => throw 'uncalled';
+  Function m4<A>(A x) => throw 'uncalled';
+  int Function(int y, {int x}) m5<B extends core.int>() => throw 'uncalled';
+  int Function(int, [core.List<core.int> x]) m6<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int) m7<B extends core.int>() => throw 'uncalled';
+  Function Function(int x, [List<Function>]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int y, {List<T> x}) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function([List<Function> x]) m10<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(List<T>) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [Function]) m12<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {core.List<core.int> x})
+      m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function(Function x) m14<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int y, [core.List<core.int> x]) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function([int]) m16<B extends core.int>() => throw 'uncalled';
+  Function({List<Function> x}) m17<B extends core.int>() => throw 'uncalled';
+  Function() m18<B extends core.int>() => throw 'uncalled';
+  void Function(int, [List<Function> x]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  void Function([List<T>]) m20<B extends core.int>() => throw 'uncalled';
+  List<Function> Function<A>(List<Function> x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  Function<A>(core.List<core.int> x) m22<B extends core.int>() =>
+      throw 'uncalled';
+  void Function<A>(List<T> x) m23<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, [int])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [int]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, [int]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function(int, [List<T>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<T>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function(int, [List<T>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function([core.List<core.int>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([core.List<core.int>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function([core.List<core.int>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function(List<Function>)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(List<Function>) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(List<Function>));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function Function<A>(A x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(A x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function Function<A>(A x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {int x}) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {int x}) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int y, {int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+        l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [List<Function>]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [List<Function>]) Function<B extends core.int>()
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int x, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function(int y, {List<T> x}) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {List<T> x}) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function(int y, {List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+    // The static function has its T always set to int.
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isFalse(f9 is F9<bool>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    Expect.isFalse(confuse(f9) is F9<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        x9 = confuse(f9);
+      });
+      Expect.throws(() {
+        l9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        l9 = confuse(f9);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m9 is F9<int>);
+      Expect.equals(tIsBool, m9 is F9<bool>);
+      Expect.equals(tIsInt, confuse(m9) is F9<int>);
+      Expect.equals(tIsBool, confuse(m9) is F9<bool>);
+    }
+  }
+
+  /// List<Function> Function([List<Function> x]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<Function> x]) Function<B extends core.int>()
+        l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(List<T>) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<T>) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is List<Function> Function(List<T>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, [Function]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [Function]) Function<B extends core.int>()
+        l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, [Function])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {core.List<core.int> x})
+        Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int,
+            {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(Function x) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(Function x) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([int]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([int]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({List<Function> x}) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({List<Function> x}) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function({List<Function> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// Function() Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    Function() Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is Function() Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<Function> x]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<Function> x]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function([List<T>]) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function([List<T>]) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is void Function([List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<Function> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<Function> x) Function<B extends core.int>()
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(core.List<core.int> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(core.List<core.int> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(List<T> x) Function<B extends core.int>()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<T> x) Function<B extends core.int>() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is void Function<A>(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+    // The static function has its T always set to int.
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isFalse(f23 is F23<bool>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    Expect.isFalse(confuse(f23) is F23<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        x23 = confuse(f23);
+      });
+      Expect.throws(() {
+        l23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        l23 = confuse(f23);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m23 is F23<int>);
+      Expect.equals(tIsBool, m23 is F23<bool>);
+      Expect.equals(tIsInt, confuse(m23) is F23<int>);
+      Expect.equals(tIsBool, confuse(m23) is F23<bool>);
+    }
+  }
+}
+
+void main() {
+  new U6().runTests();
+  new U6<int>(tIsInt: true).runTests();
+  new U6<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type70_test.dart b/tests/language/function_type/function_type70_test.dart
new file mode 100644
index 0000000..1c44dd1
--- /dev/null
+++ b/tests/language/function_type/function_type70_test.dart
@@ -0,0 +1,968 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int y, [Function x]);
+typedef F1<T> = core.List<core.int> Function(int, [int x]);
+typedef F2<T> = List<T> Function(int, [List<T> x]);
+typedef F3<T> = void Function([core.List<core.int> x]);
+typedef F4<T> = int Function([int x]) Function<B extends core.int>();
+typedef F5<T> = int Function(List<Function>) Function<B extends core.int>();
+typedef F6<T> = int Function(int x, [List<T>]) Function<B extends core.int>();
+typedef F7<T> = Function Function(int, {Function x})
+    Function<B extends core.int>();
+typedef F8<T> = Function Function([List<T> x]) Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int y, [Function x])
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function({int x})
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F13<T> = List<T> Function(int, [int x]) Function<B extends core.int>();
+typedef F14<T> = List<T> Function([List<Function>])
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function({List<T> x}) Function<B extends core.int>();
+typedef F16<T> = Function(int y, {Function x}) Function<B extends core.int>();
+typedef F17<T> = Function(int, [List<T> x]) Function<B extends core.int>();
+typedef F18<T> = void Function(Function) Function<B extends core.int>();
+typedef F19<T> = void Function(int x, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F20<T> = Function Function<A>(Function x)
+    Function<B extends core.int>();
+typedef F21<T> = List<T> Function<A>(List<Function> x)
+    Function<B extends core.int>();
+typedef F22<T> = List<A> Function<A>(core.List<core.int> x)
+    Function<B extends core.int>();
+
+Function f0(int y, [Function x = _voidFunction]) => throw 'uncalled';
+core.List<core.int> f1(int x0, [int x = -1]) => throw 'uncalled';
+List<int> f2(int x0, [List<int> x = const []]) => throw 'uncalled';
+void f3([core.List<core.int> x = const []]) => throw 'uncalled';
+int Function([int x]) f4<B extends core.int>() => throw 'uncalled';
+int Function(List<Function>) f5<B extends core.int>() => throw 'uncalled';
+int Function(int x, [List<int>]) f6<B extends core.int>() => throw 'uncalled';
+Function Function(int, {Function x}) f7<B extends core.int>() =>
+    throw 'uncalled';
+Function Function([List<int> x]) f8<B extends core.int>() => throw 'uncalled';
+List<Function> Function(int y, [Function x]) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, [core.List<core.int>]) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function({int x}) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(core.List<core.int> x) f12<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, [int x]) f13<B extends core.int>() => throw 'uncalled';
+List<int> Function([List<Function>]) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function({List<int> x}) f15<B extends core.int>() => throw 'uncalled';
+Function(int y, {Function x}) f16<B extends core.int>() => throw 'uncalled';
+Function(int, [List<int> x]) f17<B extends core.int>() => throw 'uncalled';
+void Function(Function) f18<B extends core.int>() => throw 'uncalled';
+void Function(int x, [core.List<core.int>]) f19<B extends core.int>() =>
+    throw 'uncalled';
+Function Function<A>(Function x) f20<B extends core.int>() => throw 'uncalled';
+List<int> Function<A>(List<Function> x) f21<B extends core.int>() =>
+    throw 'uncalled';
+List<A> Function<A>(core.List<core.int> x) f22<B extends core.int>() =>
+    throw 'uncalled';
+
+class U70<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int y, [Function x]) x0;
+  late core.List<core.int> Function(int, [int x]) x1;
+  late List<T> Function(int, [List<T> x]) x2;
+  late void Function([core.List<core.int> x]) x3;
+  late int Function([int x]) Function<B extends core.int>() x4;
+  late int Function(List<Function>) Function<B extends core.int>() x5;
+  late int Function(int x, [List<T>]) Function<B extends core.int>() x6;
+  late Function Function(int, {Function x}) Function<B extends core.int>() x7;
+  late Function Function([List<T> x]) Function<B extends core.int>() x8;
+  late List<Function> Function(int y, [Function x])
+      Function<B extends core.int>() x9;
+  late List<Function> Function(int, [core.List<core.int>])
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function({int x}) Function<B extends core.int>() x11;
+  late core.List<core.int> Function(core.List<core.int> x)
+      Function<B extends core.int>() x12;
+  late List<T> Function(int, [int x]) Function<B extends core.int>() x13;
+  late List<T> Function([List<Function>]) Function<B extends core.int>() x14;
+  late List<T> Function({List<T> x}) Function<B extends core.int>() x15;
+  late Function(int y, {Function x}) Function<B extends core.int>() x16;
+  late Function(int, [List<T> x]) Function<B extends core.int>() x17;
+  late void Function(Function) Function<B extends core.int>() x18;
+  late void Function(int x, [core.List<core.int>])
+      Function<B extends core.int>() x19;
+  late Function Function<A>(Function x) Function<B extends core.int>() x20;
+  late List<T> Function<A>(List<Function> x) Function<B extends core.int>() x21;
+  late List<A> Function<A>(core.List<core.int> x) Function<B extends core.int>()
+      x22;
+
+  U70({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int y, [Function x = _voidFunction]) => throw 'uncalled';
+  core.List<core.int> m1(int x0, [int x = -1]) => throw 'uncalled';
+  List<T> m2(int x0, [List<T> x = const []]) => throw 'uncalled';
+  void m3([core.List<core.int> x = const []]) => throw 'uncalled';
+  int Function([int x]) m4<B extends core.int>() => throw 'uncalled';
+  int Function(List<Function>) m5<B extends core.int>() => throw 'uncalled';
+  int Function(int x, [List<T>]) m6<B extends core.int>() => throw 'uncalled';
+  Function Function(int, {Function x}) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function([List<T> x]) m8<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(int y, [Function x]) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, [core.List<core.int>])
+      m10<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function({int x}) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(core.List<core.int> x)
+      m12<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int, [int x]) m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function([List<Function>]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function({List<T> x}) m15<B extends core.int>() => throw 'uncalled';
+  Function(int y, {Function x}) m16<B extends core.int>() => throw 'uncalled';
+  Function(int, [List<T> x]) m17<B extends core.int>() => throw 'uncalled';
+  void Function(Function) m18<B extends core.int>() => throw 'uncalled';
+  void Function(int x, [core.List<core.int>]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function<A>(Function x) m20<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function<A>(List<Function> x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  List<A> Function<A>(core.List<core.int> x) m22<B extends core.int>() =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int y, [Function x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [Function x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int y, [Function x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int, [int x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [int x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int, [int x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, [List<T> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<T> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, [List<T> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function([core.List<core.int> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function([core.List<core.int> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function([core.List<core.int> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function([int x]) Function<B extends core.int>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function([int x]) Function<B extends core.int>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function([int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(List<Function>) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(List<Function>) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(List<Function>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int x, [List<T>]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [List<T>]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int x, [List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, {Function x}) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {Function x}) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, {Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([List<T> x]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<T> x]) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function([List<T> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int y, [Function x]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [Function x]) Function<B extends core.int>()
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int y, [Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [core.List<core.int>]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [core.List<core.int>])
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function({int x}) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({int x}) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function({int x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(core.List<core.int> x) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(core.List<core.int> x)
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, [int x]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [int x]) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function(int, [int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([List<Function>]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<Function>]) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function({List<T> x}) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({List<T> x}) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function({List<T> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, {Function x}) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {Function x}) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int y, {Function x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [List<T> x]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<T> x]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int, [List<T> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(Function) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(Function) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(Function) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int x, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(Function x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(Function x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<Function> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<Function> x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(core.List<core.int> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(core.List<core.int> x) Function<B extends core.int>()
+        l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U70().runTests();
+  new U70<int>(tIsInt: true).runTests();
+  new U70<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type71_test.dart b/tests/language/function_type/function_type71_test.dart
new file mode 100644
index 0000000..61df998
--- /dev/null
+++ b/tests/language/function_type/function_type71_test.dart
@@ -0,0 +1,997 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(Function);
+typedef F1<T> = core.List<core.int> Function(int y, [int x]);
+typedef F2<T> = List<T> Function(int y, [List<T> x]);
+typedef F3<T> = void Function(int, [core.List<core.int> x]);
+typedef F4<T> = int Function([int x]) Function<B extends core.int>(int x);
+typedef F5<T> = int Function(List<Function>) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function(int x, [List<T>]) Function<B extends core.int>(
+    int x);
+typedef F7<T> = Function Function(int, {Function x})
+    Function<B extends core.int>(int x);
+typedef F8<T> = Function Function([List<T> x]) Function<B extends core.int>(
+    int x);
+typedef F9<T> = List<Function> Function(int y, [Function x])
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(int, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function({int x})
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F13<T> = List<T> Function(int, [int x]) Function<B extends core.int>(
+    int x);
+typedef F14<T> = List<T> Function([List<Function>])
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function({List<T> x}) Function<B extends core.int>(
+    int x);
+typedef F16<T> = Function(int y, {Function x}) Function<B extends core.int>(
+    int x);
+typedef F17<T> = Function(int, [List<T> x]) Function<B extends core.int>(int x);
+typedef F18<T> = void Function(Function) Function<B extends core.int>(int x);
+typedef F19<T> = void Function(int x, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F20<T> = Function Function<A>(Function x) Function<B extends core.int>(
+    int x);
+typedef F21<T> = List<T> Function<A>(List<Function> x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = List<A> Function<A>(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+
+Function f0(Function x0) => throw 'uncalled';
+core.List<core.int> f1(int y, [int x = -1]) => throw 'uncalled';
+List<int> f2(int y, [List<int> x = const []]) => throw 'uncalled';
+void f3(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
+int Function([int x]) f4<B extends core.int>(int x) => throw 'uncalled';
+int Function(List<Function>) f5<B extends core.int>(int x) => throw 'uncalled';
+int Function(int x, [List<int>]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, {Function x}) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function([List<int> x]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int y, [Function x]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, [core.List<core.int>]) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function({int x}) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(core.List<core.int> x) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function(int, [int x]) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function([List<Function>]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function({List<int> x}) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int y, {Function x}) f16<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int, [List<int> x]) f17<B extends core.int>(int x) => throw 'uncalled';
+void Function(Function) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(int x, [core.List<core.int>]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function<A>(Function x) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function<A>(List<Function> x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<A> Function<A>(core.List<core.int> x) f22<B extends core.int>(int x) =>
+    throw 'uncalled';
+
+class U71<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(Function) x0;
+  late core.List<core.int> Function(int y, [int x]) x1;
+  late List<T> Function(int y, [List<T> x]) x2;
+  late void Function(int, [core.List<core.int> x]) x3;
+  late int Function([int x]) Function<B extends core.int>(int x) x4;
+  late int Function(List<Function>) Function<B extends core.int>(int x) x5;
+  late int Function(int x, [List<T>]) Function<B extends core.int>(int x) x6;
+  late Function Function(int, {Function x}) Function<B extends core.int>(int x)
+      x7;
+  late Function Function([List<T> x]) Function<B extends core.int>(int x) x8;
+  late List<Function> Function(int y, [Function x])
+      Function<B extends core.int>(int x) x9;
+  late List<Function> Function(int, [core.List<core.int>])
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function({int x}) Function<B extends core.int>(int x)
+      x11;
+  late core.List<core.int> Function(core.List<core.int> x)
+      Function<B extends core.int>(int x) x12;
+  late List<T> Function(int, [int x]) Function<B extends core.int>(int x) x13;
+  late List<T> Function([List<Function>]) Function<B extends core.int>(int x)
+      x14;
+  late List<T> Function({List<T> x}) Function<B extends core.int>(int x) x15;
+  late Function(int y, {Function x}) Function<B extends core.int>(int x) x16;
+  late Function(int, [List<T> x]) Function<B extends core.int>(int x) x17;
+  late void Function(Function) Function<B extends core.int>(int x) x18;
+  late void Function(int x, [core.List<core.int>]) Function<B extends core.int>(
+      int x) x19;
+  late Function Function<A>(Function x) Function<B extends core.int>(int x) x20;
+  late List<T> Function<A>(List<Function> x) Function<B extends core.int>(int x)
+      x21;
+  late List<A> Function<A>(core.List<core.int> x) Function<B extends core.int>(
+      int x) x22;
+
+  U71({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(Function x0) => throw 'uncalled';
+  core.List<core.int> m1(int y, [int x = -1]) => throw 'uncalled';
+  List<T> m2(int y, [List<T> x = const []]) => throw 'uncalled';
+  void m3(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
+  int Function([int x]) m4<B extends core.int>(int x) => throw 'uncalled';
+  int Function(List<Function>) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int x, [List<T>]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, {Function x}) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function([List<T> x]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, [Function x]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, [core.List<core.int>]) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function({int x}) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(core.List<core.int> x) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [int x]) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function([List<Function>]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function({List<T> x}) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int y, {Function x}) m16<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int, [List<T> x]) m17<B extends core.int>(int x) => throw 'uncalled';
+  void Function(Function) m18<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int x, [core.List<core.int>]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function<A>(Function x) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function<A>(List<Function> x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<A> Function<A>(core.List<core.int> x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(Function)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(Function) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(Function));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int y, [int x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [int x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int y, [int x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int y, [List<T> x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [List<T> x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int y, [List<T> x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, [core.List<core.int> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [core.List<core.int> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function([int x]) Function<B extends core.int>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function([int x]) Function<B extends core.int>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function([int x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(List<Function>) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(List<Function>) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(List<Function>) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int x, [List<T>]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [List<T>]) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int x, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int, {Function x}) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {Function x}) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([List<T> x]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<T> x]) Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int y, [Function x]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, [Function x]) Function<B extends core.int>(
+        int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int y, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [core.List<core.int>])
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function({int x}) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({int x}) Function<B extends core.int>(int x)
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function({int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(core.List<core.int> x)
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, [int x]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [int x]) Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int, [int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([List<Function>]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<Function>]) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function({List<T> x}) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({List<T> x}) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function({List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int y, {Function x}) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {Function x}) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [List<T> x]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<T> x]) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int, [List<T> x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(Function) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(Function) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(Function) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int x, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [core.List<core.int>]) Function<B extends core.int>(
+        int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int x, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(Function x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(Function x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(Function x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<Function> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<Function> x) Function<B extends core.int>(int x)
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(core.List<core.int> x) Function<B extends core.int>(
+        int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U71().runTests();
+  new U71<int>(tIsInt: true).runTests();
+  new U71<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type72_test.dart b/tests/language/function_type/function_type72_test.dart
new file mode 100644
index 0000000..b33b49b
--- /dev/null
+++ b/tests/language/function_type/function_type72_test.dart
@@ -0,0 +1,942 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function([Function]);
+typedef F1<T> = core.List<core.int> Function(int);
+typedef F2<T> = List<T> Function(List<T>);
+typedef F3<T> = void Function(int y, [core.List<core.int> x]);
+typedef F4<T> = int Function(int, [int x]) Function();
+typedef F5<T> = int Function([List<Function>]) Function();
+typedef F6<T> = int Function({List<T> x}) Function();
+typedef F7<T> = Function Function(int y, {Function x}) Function();
+typedef F8<T> = Function Function(int, [List<T> x]) Function();
+typedef F9<T> = List<Function> Function(Function) Function();
+typedef F10<T> = List<Function> Function(int x, [core.List<core.int>])
+    Function();
+typedef F11<T> = core.List<core.int> Function(int, {int x}) Function();
+typedef F12<T> = core.List<core.int> Function([core.List<core.int> x])
+    Function();
+typedef F13<T> = List<T> Function(int y, [int x]) Function();
+typedef F14<T> = List<T> Function(int, [List<Function>]) Function();
+typedef F15<T> = List<T> Function(int, {List<T> x}) Function();
+typedef F16<T> = Function(List<Function> x) Function();
+typedef F17<T> = Function(int y, [List<T> x]) Function();
+typedef F18<T> = void Function([Function]) Function();
+typedef F19<T> = void Function({core.List<core.int> x}) Function();
+typedef F20<T> = Function Function<A>(List<Function> x) Function();
+typedef F21<T> = List<T> Function<A>(core.List<core.int> x) Function();
+typedef F22<T> = List<A> Function<A>(List<T> x) Function();
+
+Function f0([Function x0 = _voidFunction]) => throw 'uncalled';
+core.List<core.int> f1(int x0) => throw 'uncalled';
+List<int> f2(List<int> x0) => throw 'uncalled';
+void f3(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
+int Function(int, [int x]) f4() => throw 'uncalled';
+int Function([List<Function>]) f5() => throw 'uncalled';
+int Function({List<int> x}) f6() => throw 'uncalled';
+Function Function(int y, {Function x}) f7() => throw 'uncalled';
+Function Function(int, [List<int> x]) f8() => throw 'uncalled';
+List<Function> Function(Function) f9() => throw 'uncalled';
+List<Function> Function(int x, [core.List<core.int>]) f10() => throw 'uncalled';
+core.List<core.int> Function(int, {int x}) f11() => throw 'uncalled';
+core.List<core.int> Function([core.List<core.int> x]) f12() => throw 'uncalled';
+List<int> Function(int y, [int x]) f13() => throw 'uncalled';
+List<int> Function(int, [List<Function>]) f14() => throw 'uncalled';
+List<int> Function(int, {List<int> x}) f15() => throw 'uncalled';
+Function(List<Function> x) f16() => throw 'uncalled';
+Function(int y, [List<int> x]) f17() => throw 'uncalled';
+void Function([Function]) f18() => throw 'uncalled';
+void Function({core.List<core.int> x}) f19() => throw 'uncalled';
+Function Function<A>(List<Function> x) f20() => throw 'uncalled';
+List<int> Function<A>(core.List<core.int> x) f21() => throw 'uncalled';
+List<A> Function<A>(List<int> x) f22() => throw 'uncalled';
+
+class U72<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function([Function]) x0;
+  late core.List<core.int> Function(int) x1;
+  late List<T> Function(List<T>) x2;
+  late void Function(int y, [core.List<core.int> x]) x3;
+  late int Function(int, [int x]) Function() x4;
+  late int Function([List<Function>]) Function() x5;
+  late int Function({List<T> x}) Function() x6;
+  late Function Function(int y, {Function x}) Function() x7;
+  late Function Function(int, [List<T> x]) Function() x8;
+  late List<Function> Function(Function) Function() x9;
+  late List<Function> Function(int x, [core.List<core.int>]) Function() x10;
+  late core.List<core.int> Function(int, {int x}) Function() x11;
+  late core.List<core.int> Function([core.List<core.int> x]) Function() x12;
+  late List<T> Function(int y, [int x]) Function() x13;
+  late List<T> Function(int, [List<Function>]) Function() x14;
+  late List<T> Function(int, {List<T> x}) Function() x15;
+  late Function(List<Function> x) Function() x16;
+  late Function(int y, [List<T> x]) Function() x17;
+  late void Function([Function]) Function() x18;
+  late void Function({core.List<core.int> x}) Function() x19;
+  late Function Function<A>(List<Function> x) Function() x20;
+  late List<T> Function<A>(core.List<core.int> x) Function() x21;
+  late List<A> Function<A>(List<T> x) Function() x22;
+
+  U72({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0([Function x0 = _voidFunction]) => throw 'uncalled';
+  core.List<core.int> m1(int x0) => throw 'uncalled';
+  List<T> m2(List<T> x0) => throw 'uncalled';
+  void m3(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
+  int Function(int, [int x]) m4() => throw 'uncalled';
+  int Function([List<Function>]) m5() => throw 'uncalled';
+  int Function({List<T> x}) m6() => throw 'uncalled';
+  Function Function(int y, {Function x}) m7() => throw 'uncalled';
+  Function Function(int, [List<T> x]) m8() => throw 'uncalled';
+  List<Function> Function(Function) m9() => throw 'uncalled';
+  List<Function> Function(int x, [core.List<core.int>]) m10() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {int x}) m11() => throw 'uncalled';
+  core.List<core.int> Function([core.List<core.int> x]) m12() =>
+      throw 'uncalled';
+  List<T> Function(int y, [int x]) m13() => throw 'uncalled';
+  List<T> Function(int, [List<Function>]) m14() => throw 'uncalled';
+  List<T> Function(int, {List<T> x}) m15() => throw 'uncalled';
+  Function(List<Function> x) m16() => throw 'uncalled';
+  Function(int y, [List<T> x]) m17() => throw 'uncalled';
+  void Function([Function]) m18() => throw 'uncalled';
+  void Function({core.List<core.int> x}) m19() => throw 'uncalled';
+  Function Function<A>(List<Function> x) m20() => throw 'uncalled';
+  List<T> Function<A>(core.List<core.int> x) m21() => throw 'uncalled';
+  List<A> Function<A>(List<T> x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function([Function])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function([Function]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function([Function]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(List<T>)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(List<T>) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(List<T>));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int y, [core.List<core.int> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [core.List<core.int> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int y, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int, [int x]) Function()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [int x]) Function() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int, [int x]) Function());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([List<Function>]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([List<Function>]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function([List<Function>]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function({List<T> x}) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function({List<T> x}) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function({List<T> x}) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int y, {Function x}) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {Function x}) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, {Function x}) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<T> x]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<T> x]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [List<T> x]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(Function) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(Function) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(Function) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int x, [core.List<core.int>]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [core.List<core.int>]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int x, [core.List<core.int>])
+        Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, {int x}) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {int x}) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, {int x}) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([core.List<core.int> x]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([core.List<core.int> x]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([core.List<core.int> x])
+        Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int y, [int x]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [int x]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int y, [int x]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<Function>]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<Function>]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [List<Function>]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {List<T> x}) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {List<T> x}) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, {List<T> x}) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(List<Function> x) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(List<Function> x) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(List<Function> x) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, [List<T> x]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [List<T> x]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, [List<T> x]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function([Function]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([Function]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function([Function]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function({core.List<core.int> x}) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function({core.List<core.int> x}) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function({core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(List<Function> x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<Function> x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(List<Function> x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(core.List<core.int> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(core.List<core.int> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<T> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<T> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(List<T> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+}
+
+void main() {
+  new U72().runTests();
+  new U72<int>(tIsInt: true).runTests();
+  new U72<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type73_test.dart b/tests/language/function_type/function_type73_test.dart
new file mode 100644
index 0000000..605428e
--- /dev/null
+++ b/tests/language/function_type/function_type73_test.dart
@@ -0,0 +1,951 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, [Function]);
+typedef F1<T> = core.List<core.int> Function([int]);
+typedef F2<T> = List<T> Function([List<T>]);
+typedef F3<T> = void Function(core.List<core.int>);
+typedef F4<T> = int Function(int, [int x]) Function(int x);
+typedef F5<T> = int Function([List<Function>]) Function(int x);
+typedef F6<T> = int Function({List<T> x}) Function(int x);
+typedef F7<T> = Function Function(int y, {Function x}) Function(int x);
+typedef F8<T> = Function Function(int, [List<T> x]) Function(int x);
+typedef F9<T> = List<Function> Function(Function) Function(int x);
+typedef F10<T> = List<Function> Function(int x, [core.List<core.int>]) Function(
+    int x);
+typedef F11<T> = core.List<core.int> Function(int, {int x}) Function(int x);
+typedef F12<T> = core.List<core.int> Function([core.List<core.int> x]) Function(
+    int x);
+typedef F13<T> = List<T> Function(int y, [int x]) Function(int x);
+typedef F14<T> = List<T> Function(int, [List<Function>]) Function(int x);
+typedef F15<T> = List<T> Function(int, {List<T> x}) Function(int x);
+typedef F16<T> = Function(List<Function> x) Function(int x);
+typedef F17<T> = Function(int y, [List<T> x]) Function(int x);
+typedef F18<T> = void Function([Function]) Function(int x);
+typedef F19<T> = void Function({core.List<core.int> x}) Function(int x);
+typedef F20<T> = Function Function<A>(List<Function> x) Function(int x);
+typedef F21<T> = List<T> Function<A>(core.List<core.int> x) Function(int x);
+typedef F22<T> = List<A> Function<A>(List<T> x) Function(int x);
+
+Function f0(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+core.List<core.int> f1([int x0 = -1]) => throw 'uncalled';
+List<int> f2([List<int> x0 = const []]) => throw 'uncalled';
+void f3(core.List<core.int> x0) => throw 'uncalled';
+int Function(int, [int x]) f4(int x) => throw 'uncalled';
+int Function([List<Function>]) f5(int x) => throw 'uncalled';
+int Function({List<int> x}) f6(int x) => throw 'uncalled';
+Function Function(int y, {Function x}) f7(int x) => throw 'uncalled';
+Function Function(int, [List<int> x]) f8(int x) => throw 'uncalled';
+List<Function> Function(Function) f9(int x) => throw 'uncalled';
+List<Function> Function(int x, [core.List<core.int>]) f10(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {int x}) f11(int x) => throw 'uncalled';
+core.List<core.int> Function([core.List<core.int> x]) f12(int x) =>
+    throw 'uncalled';
+List<int> Function(int y, [int x]) f13(int x) => throw 'uncalled';
+List<int> Function(int, [List<Function>]) f14(int x) => throw 'uncalled';
+List<int> Function(int, {List<int> x}) f15(int x) => throw 'uncalled';
+Function(List<Function> x) f16(int x) => throw 'uncalled';
+Function(int y, [List<int> x]) f17(int x) => throw 'uncalled';
+void Function([Function]) f18(int x) => throw 'uncalled';
+void Function({core.List<core.int> x}) f19(int x) => throw 'uncalled';
+Function Function<A>(List<Function> x) f20(int x) => throw 'uncalled';
+List<int> Function<A>(core.List<core.int> x) f21(int x) => throw 'uncalled';
+List<A> Function<A>(List<int> x) f22(int x) => throw 'uncalled';
+
+class U73<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, [Function]) x0;
+  late core.List<core.int> Function([int]) x1;
+  late List<T> Function([List<T>]) x2;
+  late void Function(core.List<core.int>) x3;
+  late int Function(int, [int x]) Function(int x) x4;
+  late int Function([List<Function>]) Function(int x) x5;
+  late int Function({List<T> x}) Function(int x) x6;
+  late Function Function(int y, {Function x}) Function(int x) x7;
+  late Function Function(int, [List<T> x]) Function(int x) x8;
+  late List<Function> Function(Function) Function(int x) x9;
+  late List<Function> Function(int x, [core.List<core.int>]) Function(int x)
+      x10;
+  late core.List<core.int> Function(int, {int x}) Function(int x) x11;
+  late core.List<core.int> Function([core.List<core.int> x]) Function(int x)
+      x12;
+  late List<T> Function(int y, [int x]) Function(int x) x13;
+  late List<T> Function(int, [List<Function>]) Function(int x) x14;
+  late List<T> Function(int, {List<T> x}) Function(int x) x15;
+  late Function(List<Function> x) Function(int x) x16;
+  late Function(int y, [List<T> x]) Function(int x) x17;
+  late void Function([Function]) Function(int x) x18;
+  late void Function({core.List<core.int> x}) Function(int x) x19;
+  late Function Function<A>(List<Function> x) Function(int x) x20;
+  late List<T> Function<A>(core.List<core.int> x) Function(int x) x21;
+  late List<A> Function<A>(List<T> x) Function(int x) x22;
+
+  U73({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+  core.List<core.int> m1([int x0 = -1]) => throw 'uncalled';
+  List<T> m2([List<T> x0 = const []]) => throw 'uncalled';
+  void m3(core.List<core.int> x0) => throw 'uncalled';
+  int Function(int, [int x]) m4(int x) => throw 'uncalled';
+  int Function([List<Function>]) m5(int x) => throw 'uncalled';
+  int Function({List<T> x}) m6(int x) => throw 'uncalled';
+  Function Function(int y, {Function x}) m7(int x) => throw 'uncalled';
+  Function Function(int, [List<T> x]) m8(int x) => throw 'uncalled';
+  List<Function> Function(Function) m9(int x) => throw 'uncalled';
+  List<Function> Function(int x, [core.List<core.int>]) m10(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {int x}) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function([core.List<core.int> x]) m12(int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, [int x]) m13(int x) => throw 'uncalled';
+  List<T> Function(int, [List<Function>]) m14(int x) => throw 'uncalled';
+  List<T> Function(int, {List<T> x}) m15(int x) => throw 'uncalled';
+  Function(List<Function> x) m16(int x) => throw 'uncalled';
+  Function(int y, [List<T> x]) m17(int x) => throw 'uncalled';
+  void Function([Function]) m18(int x) => throw 'uncalled';
+  void Function({core.List<core.int> x}) m19(int x) => throw 'uncalled';
+  Function Function<A>(List<Function> x) m20(int x) => throw 'uncalled';
+  List<T> Function<A>(core.List<core.int> x) m21(int x) => throw 'uncalled';
+  List<A> Function<A>(List<T> x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, [Function])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [Function]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, [Function]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function([int])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([int]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function([int]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function([List<T>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([List<T>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function([List<T>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(core.List<core.int>)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(core.List<core.int>) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(core.List<core.int>));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int, [int x]) Function(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [int x]) Function(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int, [int x]) Function(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([List<Function>]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([List<Function>]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function([List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function({List<T> x}) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function({List<T> x}) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function({List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int y, {Function x}) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {Function x}) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<T> x]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<T> x]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(Function) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(Function) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(Function) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int x, [core.List<core.int>]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [core.List<core.int>]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int x, [core.List<core.int>])
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, {int x}) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {int x}) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int, {int x}) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([core.List<core.int> x]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([core.List<core.int> x]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([core.List<core.int> x])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int y, [int x]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [int x]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int y, [int x]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<Function>]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<Function>]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(int, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {List<T> x}) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {List<T> x}) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(List<Function> x) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(List<Function> x) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, [List<T> x]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [List<T> x]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function([Function]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([Function]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function([Function]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function({core.List<core.int> x}) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function({core.List<core.int> x}) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function({core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(List<Function> x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<Function> x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(core.List<core.int> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(core.List<core.int> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<T> Function<A>(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<T> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<T> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+}
+
+void main() {
+  new U73().runTests();
+  new U73<int>(tIsInt: true).runTests();
+  new U73<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type74_test.dart b/tests/language/function_type/function_type74_test.dart
new file mode 100644
index 0000000..110832e
--- /dev/null
+++ b/tests/language/function_type/function_type74_test.dart
@@ -0,0 +1,1001 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int x, [Function]);
+typedef F1<T> = core.List<core.int> Function(int, [int]);
+typedef F2<T> = List<T> Function(int, [List<T>]);
+typedef F3<T> = void Function([core.List<core.int>]);
+typedef F4<T> = int Function(int, [int x]) Function<B extends core.int>();
+typedef F5<T> = int Function([List<Function>]) Function<B extends core.int>();
+typedef F6<T> = int Function({List<T> x}) Function<B extends core.int>();
+typedef F7<T> = Function Function(int y, {Function x})
+    Function<B extends core.int>();
+typedef F8<T> = Function Function(int, [List<T> x])
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(Function)
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int x, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(int, {int x})
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function([core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F13<T> = List<T> Function(int y, [int x])
+    Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int, [List<Function>])
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int, {List<T> x})
+    Function<B extends core.int>();
+typedef F16<T> = Function(List<Function> x) Function<B extends core.int>();
+typedef F17<T> = Function(int y, [List<T> x]) Function<B extends core.int>();
+typedef F18<T> = void Function([Function]) Function<B extends core.int>();
+typedef F19<T> = void Function({core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F20<T> = Function Function<A>(List<Function> x)
+    Function<B extends core.int>();
+typedef F21<T> = List<T> Function<A>(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F22<T> = List<A> Function<A>(List<T> x) Function<B extends core.int>();
+
+Function f0(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+core.List<core.int> f1(int x0, [int x1 = -1]) => throw 'uncalled';
+List<int> f2(int x0, [List<int> x1 = const []]) => throw 'uncalled';
+void f3([core.List<core.int> x0 = const []]) => throw 'uncalled';
+int Function(int, [int x]) f4<B extends core.int>() => throw 'uncalled';
+int Function([List<Function>]) f5<B extends core.int>() => throw 'uncalled';
+int Function({List<int> x}) f6<B extends core.int>() => throw 'uncalled';
+Function Function(int y, {Function x}) f7<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int, [List<int> x]) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(Function) f9<B extends core.int>() => throw 'uncalled';
+List<Function> Function(int x, [core.List<core.int>])
+    f10<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function(int, {int x}) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function([core.List<core.int> x])
+    f12<B extends core.int>() => throw 'uncalled';
+List<int> Function(int y, [int x]) f13<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, [List<Function>]) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, {List<int> x}) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function(List<Function> x) f16<B extends core.int>() => throw 'uncalled';
+Function(int y, [List<int> x]) f17<B extends core.int>() => throw 'uncalled';
+void Function([Function]) f18<B extends core.int>() => throw 'uncalled';
+void Function({core.List<core.int> x}) f19<B extends core.int>() =>
+    throw 'uncalled';
+Function Function<A>(List<Function> x) f20<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function<A>(core.List<core.int> x) f21<B extends core.int>() =>
+    throw 'uncalled';
+List<A> Function<A>(List<int> x) f22<B extends core.int>() => throw 'uncalled';
+
+class U74<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int x, [Function]) x0;
+  late core.List<core.int> Function(int, [int]) x1;
+  late List<T> Function(int, [List<T>]) x2;
+  late void Function([core.List<core.int>]) x3;
+  late int Function(int, [int x]) Function<B extends core.int>() x4;
+  late int Function([List<Function>]) Function<B extends core.int>() x5;
+  late int Function({List<T> x}) Function<B extends core.int>() x6;
+  late Function Function(int y, {Function x}) Function<B extends core.int>() x7;
+  late Function Function(int, [List<T> x]) Function<B extends core.int>() x8;
+  late List<Function> Function(Function) Function<B extends core.int>() x9;
+  late List<Function> Function(int x, [core.List<core.int>])
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function(int, {int x}) Function<B extends core.int>()
+      x11;
+  late core.List<core.int> Function([core.List<core.int> x])
+      Function<B extends core.int>() x12;
+  late List<T> Function(int y, [int x]) Function<B extends core.int>() x13;
+  late List<T> Function(int, [List<Function>]) Function<B extends core.int>()
+      x14;
+  late List<T> Function(int, {List<T> x}) Function<B extends core.int>() x15;
+  late Function(List<Function> x) Function<B extends core.int>() x16;
+  late Function(int y, [List<T> x]) Function<B extends core.int>() x17;
+  late void Function([Function]) Function<B extends core.int>() x18;
+  late void Function({core.List<core.int> x}) Function<B extends core.int>()
+      x19;
+  late Function Function<A>(List<Function> x) Function<B extends core.int>()
+      x20;
+  late List<T> Function<A>(core.List<core.int> x) Function<B extends core.int>()
+      x21;
+  late List<A> Function<A>(List<T> x) Function<B extends core.int>() x22;
+
+  U74({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+  core.List<core.int> m1(int x0, [int x1 = -1]) => throw 'uncalled';
+  List<T> m2(int x0, [List<T> x1 = const []]) => throw 'uncalled';
+  void m3([core.List<core.int> x0 = const []]) => throw 'uncalled';
+  int Function(int, [int x]) m4<B extends core.int>() => throw 'uncalled';
+  int Function([List<Function>]) m5<B extends core.int>() => throw 'uncalled';
+  int Function({List<T> x}) m6<B extends core.int>() => throw 'uncalled';
+  Function Function(int y, {Function x}) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int, [List<T> x]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(Function) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int x, [core.List<core.int>])
+      m10<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function(int, {int x}) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function([core.List<core.int> x])
+      m12<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int y, [int x]) m13<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, [List<Function>]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, {List<T> x}) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function(List<Function> x) m16<B extends core.int>() => throw 'uncalled';
+  Function(int y, [List<T> x]) m17<B extends core.int>() => throw 'uncalled';
+  void Function([Function]) m18<B extends core.int>() => throw 'uncalled';
+  void Function({core.List<core.int> x}) m19<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function<A>(List<Function> x) m20<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function<A>(core.List<core.int> x) m21<B extends core.int>() =>
+      throw 'uncalled';
+  List<A> Function<A>(List<T> x) m22<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int x, [Function])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [Function]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int x, [Function]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int, [int])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [int]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int, [int]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, [List<T>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<T>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, [List<T>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function([core.List<core.int>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function([core.List<core.int>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function([core.List<core.int>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int, [int x]) Function<B extends core.int>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [int x]) Function<B extends core.int>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function(int, [int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([List<Function>]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([List<Function>]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function([List<Function>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function({List<T> x}) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function({List<T> x}) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function({List<T> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int y, {Function x}) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {Function x}) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, {Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<T> x]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<T> x]) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(Function) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(Function) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(Function) Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [core.List<core.int>])
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int x, [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, {int x}) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {int x}) Function<B extends core.int>()
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, {int x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([core.List<core.int> x]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([core.List<core.int> x])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int y, [int x]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [int x]) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function(int y, [int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<Function>]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<Function>]) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {List<T> x}) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {List<T> x}) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, {List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(List<Function> x) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(List<Function> x) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(List<Function> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, [List<T> x]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [List<T> x]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int y, [List<T> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function([Function]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([Function]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function([Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function({core.List<core.int> x}) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function({core.List<core.int> x}) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function({core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(List<Function> x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<Function> x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(core.List<core.int> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(core.List<core.int> x) Function<B extends core.int>()
+        l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<T> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<T> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is List<A> Function<A>(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+}
+
+void main() {
+  new U74().runTests();
+  new U74<int>(tIsInt: true).runTests();
+  new U74<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type75_test.dart b/tests/language/function_type/function_type75_test.dart
new file mode 100644
index 0000000..0f7938c
--- /dev/null
+++ b/tests/language/function_type/function_type75_test.dart
@@ -0,0 +1,1022 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function({Function x});
+typedef F1<T> = core.List<core.int> Function(int x, [int]);
+typedef F2<T> = List<T> Function(int x, [List<T>]);
+typedef F3<T> = void Function(int, [core.List<core.int>]);
+typedef F4<T> = int Function(int, [int x]) Function<B extends core.int>(int x);
+typedef F5<T> = int Function([List<Function>]) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function({List<T> x}) Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int y, {Function x})
+    Function<B extends core.int>(int x);
+typedef F8<T> = Function Function(int, [List<T> x])
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(Function) Function<B extends core.int>(
+    int x);
+typedef F10<T> = List<Function> Function(int x, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(int, {int x})
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function([core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F13<T> = List<T> Function(int y, [int x]) Function<B extends core.int>(
+    int x);
+typedef F14<T> = List<T> Function(int, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function(int, {List<T> x})
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function(List<Function> x) Function<B extends core.int>(int x);
+typedef F17<T> = Function(int y, [List<T> x]) Function<B extends core.int>(
+    int x);
+typedef F18<T> = void Function([Function]) Function<B extends core.int>(int x);
+typedef F19<T> = void Function({core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F20<T> = Function Function<A>(List<Function> x)
+    Function<B extends core.int>(int x);
+typedef F21<T> = List<T> Function<A>(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = List<A> Function<A>(List<T> x) Function<B extends core.int>(
+    int x);
+
+Function f0({Function x = _voidFunction}) => throw 'uncalled';
+core.List<core.int> f1(int x, [int x0 = -1]) => throw 'uncalled';
+List<int> f2(int x, [List<int> x0 = const []]) => throw 'uncalled';
+void f3(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
+int Function(int, [int x]) f4<B extends core.int>(int x) => throw 'uncalled';
+int Function([List<Function>]) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function({List<int> x}) f6<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int y, {Function x}) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, [List<int> x]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(Function) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int x, [core.List<core.int>]) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {int x}) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([core.List<core.int> x]) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function(int y, [int x]) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, [List<Function>]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, {List<int> x}) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(List<Function> x) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(int y, [List<int> x]) f17<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function([Function]) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function({core.List<core.int> x}) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function<A>(List<Function> x) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function<A>(core.List<core.int> x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<A> Function<A>(List<int> x) f22<B extends core.int>(int x) =>
+    throw 'uncalled';
+
+class U75<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function({Function x}) x0;
+  late core.List<core.int> Function(int x, [int]) x1;
+  late List<T> Function(int x, [List<T>]) x2;
+  late void Function(int, [core.List<core.int>]) x3;
+  late int Function(int, [int x]) Function<B extends core.int>(int x) x4;
+  late int Function([List<Function>]) Function<B extends core.int>(int x) x5;
+  late int Function({List<T> x}) Function<B extends core.int>(int x) x6;
+  late Function Function(int y, {Function x}) Function<B extends core.int>(
+      int x) x7;
+  late Function Function(int, [List<T> x]) Function<B extends core.int>(int x)
+      x8;
+  late List<Function> Function(Function) Function<B extends core.int>(int x) x9;
+  late List<Function> Function(int x, [core.List<core.int>])
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function(int, {int x}) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function([core.List<core.int> x])
+      Function<B extends core.int>(int x) x12;
+  late List<T> Function(int y, [int x]) Function<B extends core.int>(int x) x13;
+  late List<T> Function(int, [List<Function>]) Function<B extends core.int>(
+      int x) x14;
+  late List<T> Function(int, {List<T> x}) Function<B extends core.int>(int x)
+      x15;
+  late Function(List<Function> x) Function<B extends core.int>(int x) x16;
+  late Function(int y, [List<T> x]) Function<B extends core.int>(int x) x17;
+  late void Function([Function]) Function<B extends core.int>(int x) x18;
+  late void Function({core.List<core.int> x}) Function<B extends core.int>(
+      int x) x19;
+  late Function Function<A>(List<Function> x) Function<B extends core.int>(
+      int x) x20;
+  late List<T> Function<A>(core.List<core.int> x) Function<B extends core.int>(
+      int x) x21;
+  late List<A> Function<A>(List<T> x) Function<B extends core.int>(int x) x22;
+
+  U75({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0({Function x = _voidFunction}) => throw 'uncalled';
+  core.List<core.int> m1(int x, [int x0 = -1]) => throw 'uncalled';
+  List<T> m2(int x, [List<T> x0 = const []]) => throw 'uncalled';
+  void m3(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
+  int Function(int, [int x]) m4<B extends core.int>(int x) => throw 'uncalled';
+  int Function([List<Function>]) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function({List<T> x}) m6<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(int y, {Function x}) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, [List<T> x]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(Function) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int x, [core.List<core.int>]) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {int x}) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([core.List<core.int> x]) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, [int x]) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [List<Function>]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, {List<T> x}) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(List<Function> x) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(int y, [List<T> x]) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function([Function]) m18<B extends core.int>(int x) => throw 'uncalled';
+  void Function({core.List<core.int> x}) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function<A>(List<Function> x) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function<A>(core.List<core.int> x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<A> Function<A>(List<T> x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function({Function x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function({Function x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function({Function x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int x, [int])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [int]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int x, [int]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int x, [List<T>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [List<T>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int x, [List<T>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, [core.List<core.int>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [core.List<core.int>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, [core.List<core.int>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int, [int x]) Function<B extends core.int>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [int x]) Function<B extends core.int>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function(int, [int x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function([List<Function>]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function([List<Function>]) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function([List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function({List<T> x}) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function({List<T> x}) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function({List<T> x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(int y, {Function x}) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {Function x}) Function<B extends core.int>(int x)
+        l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<T> x]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<T> x]) Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(Function) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(Function) Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(Function)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int x, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [core.List<core.int>])
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int x, [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int, {int x}) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {int x}) Function<B extends core.int>(
+        int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, {int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([core.List<core.int> x])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int y, [int x]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [int x]) Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int y, [int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, [List<Function>]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [List<Function>]) Function<B extends core.int>(int x)
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {List<T> x}) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {List<T> x}) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(List<Function> x) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(List<Function> x) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(List<Function> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [List<T> x]) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int y, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function([Function]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function([Function]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function([Function]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function({core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(List<Function> x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<Function> x) Function<B extends core.int>(int x)
+        l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(core.List<core.int> x) Function<B extends core.int>(
+        int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<T> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<T> x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(List<T> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+}
+
+void main() {
+  new U75().runTests();
+  new U75<int>(tIsInt: true).runTests();
+  new U75<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type76_test.dart b/tests/language/function_type/function_type76_test.dart
new file mode 100644
index 0000000..0465785
--- /dev/null
+++ b/tests/language/function_type/function_type76_test.dart
@@ -0,0 +1,921 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, {Function x});
+typedef F1<T> = core.List<core.int> Function({int x});
+typedef F2<T> = List<T> Function({List<T> x});
+typedef F3<T> = void Function(int x, [core.List<core.int>]);
+typedef F4<T> = int Function(int y, [int x]) Function();
+typedef F5<T> = int Function(int, [List<Function>]) Function();
+typedef F6<T> = int Function(int, {List<T> x}) Function();
+typedef F7<T> = Function Function(List<Function> x) Function();
+typedef F8<T> = Function Function(int y, [List<T> x]) Function();
+typedef F9<T> = List<Function> Function([Function]) Function();
+typedef F10<T> = List<Function> Function({core.List<core.int> x}) Function();
+typedef F11<T> = core.List<core.int> Function(int y, {int x}) Function();
+typedef F12<T> = core.List<core.int> Function(int, [core.List<core.int> x])
+    Function();
+typedef F13<T> = List<T> Function(int) Function();
+typedef F14<T> = List<T> Function(int x, [List<Function>]) Function();
+typedef F15<T> = List<T> Function(int y, {List<T> x}) Function();
+typedef F16<T> = Function([List<Function> x]) Function();
+typedef F17<T> = Function(List<T>) Function();
+typedef F18<T> = void Function(int, [Function]) Function();
+typedef F19<T> = void Function(int, {core.List<core.int> x}) Function();
+typedef F20<T> = Function Function<A>(core.List<core.int> x) Function();
+typedef F21<T> = List<T> Function<A>(List<T> x) Function();
+typedef F22<T> = List<A> Function<A>() Function();
+
+Function f0(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+core.List<core.int> f1({int x = -1}) => throw 'uncalled';
+List<int> f2({List<int> x = const []}) => throw 'uncalled';
+void f3(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
+int Function(int y, [int x]) f4() => throw 'uncalled';
+int Function(int, [List<Function>]) f5() => throw 'uncalled';
+int Function(int, {List<int> x}) f6() => throw 'uncalled';
+Function Function(List<Function> x) f7() => throw 'uncalled';
+Function Function(int y, [List<int> x]) f8() => throw 'uncalled';
+List<Function> Function([Function]) f9() => throw 'uncalled';
+List<Function> Function({core.List<core.int> x}) f10() => throw 'uncalled';
+core.List<core.int> Function(int y, {int x}) f11() => throw 'uncalled';
+core.List<core.int> Function(int, [core.List<core.int> x]) f12() =>
+    throw 'uncalled';
+List<int> Function(int) f13() => throw 'uncalled';
+List<int> Function(int x, [List<Function>]) f14() => throw 'uncalled';
+List<int> Function(int y, {List<int> x}) f15() => throw 'uncalled';
+Function([List<Function> x]) f16() => throw 'uncalled';
+Function(List<int>) f17() => throw 'uncalled';
+void Function(int, [Function]) f18() => throw 'uncalled';
+void Function(int, {core.List<core.int> x}) f19() => throw 'uncalled';
+Function Function<A>(core.List<core.int> x) f20() => throw 'uncalled';
+List<int> Function<A>(List<int> x) f21() => throw 'uncalled';
+List<A> Function<A>() f22() => throw 'uncalled';
+
+class U76<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, {Function x}) x0;
+  late core.List<core.int> Function({int x}) x1;
+  late List<T> Function({List<T> x}) x2;
+  late void Function(int x, [core.List<core.int>]) x3;
+  late int Function(int y, [int x]) Function() x4;
+  late int Function(int, [List<Function>]) Function() x5;
+  late int Function(int, {List<T> x}) Function() x6;
+  late Function Function(List<Function> x) Function() x7;
+  late Function Function(int y, [List<T> x]) Function() x8;
+  late List<Function> Function([Function]) Function() x9;
+  late List<Function> Function({core.List<core.int> x}) Function() x10;
+  late core.List<core.int> Function(int y, {int x}) Function() x11;
+  late core.List<core.int> Function(int, [core.List<core.int> x]) Function()
+      x12;
+  late List<T> Function(int) Function() x13;
+  late List<T> Function(int x, [List<Function>]) Function() x14;
+  late List<T> Function(int y, {List<T> x}) Function() x15;
+  late Function([List<Function> x]) Function() x16;
+  late Function(List<T>) Function() x17;
+  late void Function(int, [Function]) Function() x18;
+  late void Function(int, {core.List<core.int> x}) Function() x19;
+  late Function Function<A>(core.List<core.int> x) Function() x20;
+  late List<T> Function<A>(List<T> x) Function() x21;
+  late List<A> Function<A>() Function() x22;
+
+  U76({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, {Function x = _voidFunction}) => throw 'uncalled';
+  core.List<core.int> m1({int x = -1}) => throw 'uncalled';
+  List<T> m2({List<T> x = const []}) => throw 'uncalled';
+  void m3(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
+  int Function(int y, [int x]) m4() => throw 'uncalled';
+  int Function(int, [List<Function>]) m5() => throw 'uncalled';
+  int Function(int, {List<T> x}) m6() => throw 'uncalled';
+  Function Function(List<Function> x) m7() => throw 'uncalled';
+  Function Function(int y, [List<T> x]) m8() => throw 'uncalled';
+  List<Function> Function([Function]) m9() => throw 'uncalled';
+  List<Function> Function({core.List<core.int> x}) m10() => throw 'uncalled';
+  core.List<core.int> Function(int y, {int x}) m11() => throw 'uncalled';
+  core.List<core.int> Function(int, [core.List<core.int> x]) m12() =>
+      throw 'uncalled';
+  List<T> Function(int) m13() => throw 'uncalled';
+  List<T> Function(int x, [List<Function>]) m14() => throw 'uncalled';
+  List<T> Function(int y, {List<T> x}) m15() => throw 'uncalled';
+  Function([List<Function> x]) m16() => throw 'uncalled';
+  Function(List<T>) m17() => throw 'uncalled';
+  void Function(int, [Function]) m18() => throw 'uncalled';
+  void Function(int, {core.List<core.int> x}) m19() => throw 'uncalled';
+  Function Function<A>(core.List<core.int> x) m20() => throw 'uncalled';
+  List<T> Function<A>(List<T> x) m21() => throw 'uncalled';
+  List<A> Function<A>() m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, {Function x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {Function x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, {Function x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function({int x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({int x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function({int x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function({List<T> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({List<T> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function({List<T> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int x, [core.List<core.int>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [core.List<core.int>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int x, [core.List<core.int>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int y, [int x]) Function()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [int x]) Function() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int y, [int x]) Function());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [List<Function>]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<Function>]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [List<Function>]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, {List<T> x}) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {List<T> x}) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, {List<T> x}) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(List<Function> x) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<Function> x) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(List<Function> x) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, [List<T> x]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [List<T> x]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, [List<T> x]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function([Function]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([Function]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([Function]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function({core.List<core.int> x}) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({core.List<core.int> x}) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function({core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int y, {int x}) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {int x}) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int y, {int x}) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [core.List<core.int> x]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [core.List<core.int> x]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int,
+            [core.List<core.int> x])
+        Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [List<Function>]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [List<Function>]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int x, [List<Function>]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {List<T> x}) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {List<T> x}) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, {List<T> x}) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([List<Function> x]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([List<Function> x]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([List<Function> x]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(List<T>) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(List<T>) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(List<T>) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, [Function]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [Function]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, [Function]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, {core.List<core.int> x}) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {core.List<core.int> x}) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int, {core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(core.List<core.int> x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(core.List<core.int> x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<T> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<T> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(List<T> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>() Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>() Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>() Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U76().runTests();
+  new U76<int>(tIsInt: true).runTests();
+  new U76<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type77_test.dart b/tests/language/function_type/function_type77_test.dart
new file mode 100644
index 0000000..e310c8f
--- /dev/null
+++ b/tests/language/function_type/function_type77_test.dart
@@ -0,0 +1,925 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int y, {Function x});
+typedef F1<T> = core.List<core.int> Function(int, {int x});
+typedef F2<T> = List<T> Function(int, {List<T> x});
+typedef F3<T> = void Function({core.List<core.int> x});
+typedef F4<T> = int Function(int y, [int x]) Function(int x);
+typedef F5<T> = int Function(int, [List<Function>]) Function(int x);
+typedef F6<T> = int Function(int, {List<T> x}) Function(int x);
+typedef F7<T> = Function Function(List<Function> x) Function(int x);
+typedef F8<T> = Function Function(int y, [List<T> x]) Function(int x);
+typedef F9<T> = List<Function> Function([Function]) Function(int x);
+typedef F10<T> = List<Function> Function({core.List<core.int> x}) Function(
+    int x);
+typedef F11<T> = core.List<core.int> Function(int y, {int x}) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int, [core.List<core.int> x])
+    Function(int x);
+typedef F13<T> = List<T> Function(int) Function(int x);
+typedef F14<T> = List<T> Function(int x, [List<Function>]) Function(int x);
+typedef F15<T> = List<T> Function(int y, {List<T> x}) Function(int x);
+typedef F16<T> = Function([List<Function> x]) Function(int x);
+typedef F17<T> = Function(List<T>) Function(int x);
+typedef F18<T> = void Function(int, [Function]) Function(int x);
+typedef F19<T> = void Function(int, {core.List<core.int> x}) Function(int x);
+typedef F20<T> = Function Function<A>(core.List<core.int> x) Function(int x);
+typedef F21<T> = List<T> Function<A>(List<T> x) Function(int x);
+typedef F22<T> = List<A> Function<A>() Function(int x);
+
+Function f0(int y, {Function x = _voidFunction}) => throw 'uncalled';
+core.List<core.int> f1(int x0, {int x = -1}) => throw 'uncalled';
+List<int> f2(int x0, {List<int> x = const []}) => throw 'uncalled';
+void f3({core.List<core.int> x = const []}) => throw 'uncalled';
+int Function(int y, [int x]) f4(int x) => throw 'uncalled';
+int Function(int, [List<Function>]) f5(int x) => throw 'uncalled';
+int Function(int, {List<int> x}) f6(int x) => throw 'uncalled';
+Function Function(List<Function> x) f7(int x) => throw 'uncalled';
+Function Function(int y, [List<int> x]) f8(int x) => throw 'uncalled';
+List<Function> Function([Function]) f9(int x) => throw 'uncalled';
+List<Function> Function({core.List<core.int> x}) f10(int x) => throw 'uncalled';
+core.List<core.int> Function(int y, {int x}) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int, [core.List<core.int> x]) f12(int x) =>
+    throw 'uncalled';
+List<int> Function(int) f13(int x) => throw 'uncalled';
+List<int> Function(int x, [List<Function>]) f14(int x) => throw 'uncalled';
+List<int> Function(int y, {List<int> x}) f15(int x) => throw 'uncalled';
+Function([List<Function> x]) f16(int x) => throw 'uncalled';
+Function(List<int>) f17(int x) => throw 'uncalled';
+void Function(int, [Function]) f18(int x) => throw 'uncalled';
+void Function(int, {core.List<core.int> x}) f19(int x) => throw 'uncalled';
+Function Function<A>(core.List<core.int> x) f20(int x) => throw 'uncalled';
+List<int> Function<A>(List<int> x) f21(int x) => throw 'uncalled';
+List<A> Function<A>() f22(int x) => throw 'uncalled';
+
+class U77<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int y, {Function x}) x0;
+  late core.List<core.int> Function(int, {int x}) x1;
+  late List<T> Function(int, {List<T> x}) x2;
+  late void Function({core.List<core.int> x}) x3;
+  late int Function(int y, [int x]) Function(int x) x4;
+  late int Function(int, [List<Function>]) Function(int x) x5;
+  late int Function(int, {List<T> x}) Function(int x) x6;
+  late Function Function(List<Function> x) Function(int x) x7;
+  late Function Function(int y, [List<T> x]) Function(int x) x8;
+  late List<Function> Function([Function]) Function(int x) x9;
+  late List<Function> Function({core.List<core.int> x}) Function(int x) x10;
+  late core.List<core.int> Function(int y, {int x}) Function(int x) x11;
+  late core.List<core.int> Function(int, [core.List<core.int> x]) Function(
+      int x) x12;
+  late List<T> Function(int) Function(int x) x13;
+  late List<T> Function(int x, [List<Function>]) Function(int x) x14;
+  late List<T> Function(int y, {List<T> x}) Function(int x) x15;
+  late Function([List<Function> x]) Function(int x) x16;
+  late Function(List<T>) Function(int x) x17;
+  late void Function(int, [Function]) Function(int x) x18;
+  late void Function(int, {core.List<core.int> x}) Function(int x) x19;
+  late Function Function<A>(core.List<core.int> x) Function(int x) x20;
+  late List<T> Function<A>(List<T> x) Function(int x) x21;
+  late List<A> Function<A>() Function(int x) x22;
+
+  U77({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int y, {Function x = _voidFunction}) => throw 'uncalled';
+  core.List<core.int> m1(int x0, {int x = -1}) => throw 'uncalled';
+  List<T> m2(int x0, {List<T> x = const []}) => throw 'uncalled';
+  void m3({core.List<core.int> x = const []}) => throw 'uncalled';
+  int Function(int y, [int x]) m4(int x) => throw 'uncalled';
+  int Function(int, [List<Function>]) m5(int x) => throw 'uncalled';
+  int Function(int, {List<T> x}) m6(int x) => throw 'uncalled';
+  Function Function(List<Function> x) m7(int x) => throw 'uncalled';
+  Function Function(int y, [List<T> x]) m8(int x) => throw 'uncalled';
+  List<Function> Function([Function]) m9(int x) => throw 'uncalled';
+  List<Function> Function({core.List<core.int> x}) m10(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {int x}) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, [core.List<core.int> x]) m12(int x) =>
+      throw 'uncalled';
+  List<T> Function(int) m13(int x) => throw 'uncalled';
+  List<T> Function(int x, [List<Function>]) m14(int x) => throw 'uncalled';
+  List<T> Function(int y, {List<T> x}) m15(int x) => throw 'uncalled';
+  Function([List<Function> x]) m16(int x) => throw 'uncalled';
+  Function(List<T>) m17(int x) => throw 'uncalled';
+  void Function(int, [Function]) m18(int x) => throw 'uncalled';
+  void Function(int, {core.List<core.int> x}) m19(int x) => throw 'uncalled';
+  Function Function<A>(core.List<core.int> x) m20(int x) => throw 'uncalled';
+  List<T> Function<A>(List<T> x) m21(int x) => throw 'uncalled';
+  List<A> Function<A>() m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int y, {Function x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {Function x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int y, {Function x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int, {int x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {int x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int, {int x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int, {List<T> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {List<T> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int, {List<T> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function({core.List<core.int> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function({core.List<core.int> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function({core.List<core.int> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int y, [int x]) Function(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [int x]) Function(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int y, [int x]) Function(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [List<Function>]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<Function>]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, {List<T> x}) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {List<T> x}) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(List<Function> x) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<Function> x) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, [List<T> x]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [List<T> x]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function([Function]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([Function]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([Function]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function({core.List<core.int> x}) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({core.List<core.int> x}) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function({core.List<core.int> x})
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int y, {int x}) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {int x}) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int y, {int x}) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [core.List<core.int> x]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [core.List<core.int> x]) Function(int x)
+        l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int,
+            [core.List<core.int> x])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [List<Function>]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [List<Function>]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(int x, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {List<T> x}) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {List<T> x}) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([List<Function> x]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([List<Function> x]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(List<T>) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(List<T>) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(List<T>) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, [Function]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [Function]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, [Function]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, {core.List<core.int> x}) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {core.List<core.int> x}) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int, {core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(core.List<core.int> x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(core.List<core.int> x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<T> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<T> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>() Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>() Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>() Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U77().runTests();
+  new U77<int>(tIsInt: true).runTests();
+  new U77<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type78_test.dart b/tests/language/function_type/function_type78_test.dart
new file mode 100644
index 0000000..bc3a0af
--- /dev/null
+++ b/tests/language/function_type/function_type78_test.dart
@@ -0,0 +1,974 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(List<Function> x);
+typedef F1<T> = core.List<core.int> Function(int y, {int x});
+typedef F2<T> = List<T> Function(int y, {List<T> x});
+typedef F3<T> = void Function(int, {core.List<core.int> x});
+typedef F4<T> = int Function(int y, [int x]) Function<B extends core.int>();
+typedef F5<T> = int Function(int, [List<Function>])
+    Function<B extends core.int>();
+typedef F6<T> = int Function(int, {List<T> x}) Function<B extends core.int>();
+typedef F7<T> = Function Function(List<Function> x)
+    Function<B extends core.int>();
+typedef F8<T> = Function Function(int y, [List<T> x])
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function([Function])
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function({core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(int y, {int x})
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F13<T> = List<T> Function(int) Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int x, [List<Function>])
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function(int y, {List<T> x})
+    Function<B extends core.int>();
+typedef F16<T> = Function([List<Function> x]) Function<B extends core.int>();
+typedef F17<T> = Function(List<T>) Function<B extends core.int>();
+typedef F18<T> = void Function(int, [Function]) Function<B extends core.int>();
+typedef F19<T> = void Function(int, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F20<T> = Function Function<A>(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F21<T> = List<T> Function<A>(List<T> x) Function<B extends core.int>();
+typedef F22<T> = List<A> Function<A>() Function<B extends core.int>();
+
+Function f0(List<Function> x) => throw 'uncalled';
+core.List<core.int> f1(int y, {int x = -1}) => throw 'uncalled';
+List<int> f2(int y, {List<int> x = const []}) => throw 'uncalled';
+void f3(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
+int Function(int y, [int x]) f4<B extends core.int>() => throw 'uncalled';
+int Function(int, [List<Function>]) f5<B extends core.int>() =>
+    throw 'uncalled';
+int Function(int, {List<int> x}) f6<B extends core.int>() => throw 'uncalled';
+Function Function(List<Function> x) f7<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int y, [List<int> x]) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function([Function]) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function({core.List<core.int> x}) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, {int x}) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [core.List<core.int> x])
+    f12<B extends core.int>() => throw 'uncalled';
+List<int> Function(int) f13<B extends core.int>() => throw 'uncalled';
+List<int> Function(int x, [List<Function>]) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int y, {List<int> x}) f15<B extends core.int>() =>
+    throw 'uncalled';
+Function([List<Function> x]) f16<B extends core.int>() => throw 'uncalled';
+Function(List<int>) f17<B extends core.int>() => throw 'uncalled';
+void Function(int, [Function]) f18<B extends core.int>() => throw 'uncalled';
+void Function(int, {core.List<core.int> x}) f19<B extends core.int>() =>
+    throw 'uncalled';
+Function Function<A>(core.List<core.int> x) f20<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function<A>(List<int> x) f21<B extends core.int>() =>
+    throw 'uncalled';
+List<A> Function<A>() f22<B extends core.int>() => throw 'uncalled';
+
+class U78<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(List<Function> x) x0;
+  late core.List<core.int> Function(int y, {int x}) x1;
+  late List<T> Function(int y, {List<T> x}) x2;
+  late void Function(int, {core.List<core.int> x}) x3;
+  late int Function(int y, [int x]) Function<B extends core.int>() x4;
+  late int Function(int, [List<Function>]) Function<B extends core.int>() x5;
+  late int Function(int, {List<T> x}) Function<B extends core.int>() x6;
+  late Function Function(List<Function> x) Function<B extends core.int>() x7;
+  late Function Function(int y, [List<T> x]) Function<B extends core.int>() x8;
+  late List<Function> Function([Function]) Function<B extends core.int>() x9;
+  late List<Function> Function({core.List<core.int> x})
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function(int y, {int x})
+      Function<B extends core.int>() x11;
+  late core.List<core.int> Function(int, [core.List<core.int> x])
+      Function<B extends core.int>() x12;
+  late List<T> Function(int) Function<B extends core.int>() x13;
+  late List<T> Function(int x, [List<Function>]) Function<B extends core.int>()
+      x14;
+  late List<T> Function(int y, {List<T> x}) Function<B extends core.int>() x15;
+  late Function([List<Function> x]) Function<B extends core.int>() x16;
+  late Function(List<T>) Function<B extends core.int>() x17;
+  late void Function(int, [Function]) Function<B extends core.int>() x18;
+  late void Function(int, {core.List<core.int> x})
+      Function<B extends core.int>() x19;
+  late Function Function<A>(core.List<core.int> x)
+      Function<B extends core.int>() x20;
+  late List<T> Function<A>(List<T> x) Function<B extends core.int>() x21;
+  late List<A> Function<A>() Function<B extends core.int>() x22;
+
+  U78({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(List<Function> x) => throw 'uncalled';
+  core.List<core.int> m1(int y, {int x = -1}) => throw 'uncalled';
+  List<T> m2(int y, {List<T> x = const []}) => throw 'uncalled';
+  void m3(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
+  int Function(int y, [int x]) m4<B extends core.int>() => throw 'uncalled';
+  int Function(int, [List<Function>]) m5<B extends core.int>() =>
+      throw 'uncalled';
+  int Function(int, {List<T> x}) m6<B extends core.int>() => throw 'uncalled';
+  Function Function(List<Function> x) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int y, [List<T> x]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function([Function]) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function({core.List<core.int> x}) m10<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {int x}) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [core.List<core.int> x])
+      m12<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int) m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int x, [List<Function>]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int y, {List<T> x}) m15<B extends core.int>() =>
+      throw 'uncalled';
+  Function([List<Function> x]) m16<B extends core.int>() => throw 'uncalled';
+  Function(List<T>) m17<B extends core.int>() => throw 'uncalled';
+  void Function(int, [Function]) m18<B extends core.int>() => throw 'uncalled';
+  void Function(int, {core.List<core.int> x}) m19<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function<A>(core.List<core.int> x) m20<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function<A>(List<T> x) m21<B extends core.int>() => throw 'uncalled';
+  List<A> Function<A>() m22<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(List<Function> x)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<Function> x) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(List<Function> x));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int y, {int x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {int x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int y, {int x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function(int y, {List<T> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {List<T> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function(int y, {List<T> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int, {core.List<core.int> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {core.List<core.int> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int y, [int x]) Function<B extends core.int>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [int x]) Function<B extends core.int>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function(int y, [int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [List<Function>]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<Function>]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, {List<T> x}) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {List<T> x}) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int, {List<T> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(List<Function> x) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<Function> x) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, [List<T> x]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [List<T> x]) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, [List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function([Function]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([Function]) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([Function])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function({core.List<core.int> x}) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({core.List<core.int> x})
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function({core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int y, {int x}) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {int x}) Function<B extends core.int>()
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int y, {int x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [core.List<core.int> x])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int,
+            [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int) Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [List<Function>]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [List<Function>]) Function<B extends core.int>()
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int x, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {List<T> x}) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {List<T> x}) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, {List<T> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([List<Function> x]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([List<Function> x]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function([List<Function> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(List<T>) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(List<T>) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(List<T>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, [Function]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [Function]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int, [Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(core.List<core.int> x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(core.List<core.int> x) Function<B extends core.int>()
+        l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<T> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<T> x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<T> Function<A>(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>() Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>() Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>() Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U78().runTests();
+  new U78<int>(tIsInt: true).runTests();
+  new U78<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type79_test.dart b/tests/language/function_type/function_type79_test.dart
new file mode 100644
index 0000000..7932960
--- /dev/null
+++ b/tests/language/function_type/function_type79_test.dart
@@ -0,0 +1,997 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function([List<Function> x]);
+typedef F1<T> = core.List<core.int> Function(Function x);
+typedef F2<T> = List<T> Function();
+typedef F3<T> = void Function(int y, {core.List<core.int> x});
+typedef F4<T> = int Function(int y, [int x]) Function<B extends core.int>(
+    int x);
+typedef F5<T> = int Function(int, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F6<T> = int Function(int, {List<T> x}) Function<B extends core.int>(
+    int x);
+typedef F7<T> = Function Function(List<Function> x)
+    Function<B extends core.int>(int x);
+typedef F8<T> = Function Function(int y, [List<T> x])
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function([Function])
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function({core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(int y, {int x})
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F13<T> = List<T> Function(int) Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(int x, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function(int y, {List<T> x})
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function([List<Function> x]) Function<B extends core.int>(
+    int x);
+typedef F17<T> = Function(List<T>) Function<B extends core.int>(int x);
+typedef F18<T> = void Function(int, [Function]) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function(int, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F20<T> = Function Function<A>(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F21<T> = List<T> Function<A>(List<T> x) Function<B extends core.int>(
+    int x);
+typedef F22<T> = List<A> Function<A>() Function<B extends core.int>(int x);
+
+Function f0([List<Function> x = const []]) => throw 'uncalled';
+core.List<core.int> f1(Function x) => throw 'uncalled';
+List<int> f2() => throw 'uncalled';
+void f3(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
+int Function(int y, [int x]) f4<B extends core.int>(int x) => throw 'uncalled';
+int Function(int, [List<Function>]) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function(int, {List<int> x}) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(List<Function> x) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int y, [List<int> x]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function([Function]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function({core.List<core.int> x}) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, {int x}) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [core.List<core.int> x])
+    f12<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function(int) f13<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function(int x, [List<Function>]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int y, {List<int> x}) f15<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function([List<Function> x]) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(List<int>) f17<B extends core.int>(int x) => throw 'uncalled';
+void Function(int, [Function]) f18<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int, {core.List<core.int> x}) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function<A>(core.List<core.int> x) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function<A>(List<int> x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<A> Function<A>() f22<B extends core.int>(int x) => throw 'uncalled';
+
+class U79<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function([List<Function> x]) x0;
+  late core.List<core.int> Function(Function x) x1;
+  late List<T> Function() x2;
+  late void Function(int y, {core.List<core.int> x}) x3;
+  late int Function(int y, [int x]) Function<B extends core.int>(int x) x4;
+  late int Function(int, [List<Function>]) Function<B extends core.int>(int x)
+      x5;
+  late int Function(int, {List<T> x}) Function<B extends core.int>(int x) x6;
+  late Function Function(List<Function> x) Function<B extends core.int>(int x)
+      x7;
+  late Function Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+      x8;
+  late List<Function> Function([Function]) Function<B extends core.int>(int x)
+      x9;
+  late List<Function> Function({core.List<core.int> x})
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function(int y, {int x})
+      Function<B extends core.int>(int x) x11;
+  late core.List<core.int> Function(int, [core.List<core.int> x])
+      Function<B extends core.int>(int x) x12;
+  late List<T> Function(int) Function<B extends core.int>(int x) x13;
+  late List<T> Function(int x, [List<Function>]) Function<B extends core.int>(
+      int x) x14;
+  late List<T> Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+      x15;
+  late Function([List<Function> x]) Function<B extends core.int>(int x) x16;
+  late Function(List<T>) Function<B extends core.int>(int x) x17;
+  late void Function(int, [Function]) Function<B extends core.int>(int x) x18;
+  late void Function(int, {core.List<core.int> x}) Function<B extends core.int>(
+      int x) x19;
+  late Function Function<A>(core.List<core.int> x) Function<B extends core.int>(
+      int x) x20;
+  late List<T> Function<A>(List<T> x) Function<B extends core.int>(int x) x21;
+  late List<A> Function<A>() Function<B extends core.int>(int x) x22;
+
+  U79({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0([List<Function> x = const []]) => throw 'uncalled';
+  core.List<core.int> m1(Function x) => throw 'uncalled';
+  List<T> m2() => throw 'uncalled';
+  void m3(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
+  int Function(int y, [int x]) m4<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int, [List<Function>]) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int, {List<T> x}) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(List<Function> x) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int y, [List<T> x]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function([Function]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function({core.List<core.int> x}) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {int x}) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [core.List<core.int> x])
+      m12<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function(int) m13<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function(int x, [List<Function>]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, {List<T> x}) m15<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function([List<Function> x]) m16<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(List<T>) m17<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int, [Function]) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int, {core.List<core.int> x}) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function<A>(core.List<core.int> x) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function<A>(List<T> x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<A> Function<A>() m22<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function([List<Function> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<Function> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function([List<Function> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(Function x)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(Function x) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(Function x));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// List<T> Function()
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    List<T> Function() l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is List<T> Function());
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+    // The static function has its T always set to int.
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isFalse(f2 is F2<bool>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    Expect.isFalse(confuse(f2) is F2<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        x2 = confuse(f2);
+      });
+      Expect.throws(() {
+        l2 = (f2 as dynamic);
+      });
+      Expect.throws(() {
+        l2 = confuse(f2);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m2 is F2<int>);
+      Expect.equals(tIsBool, m2 is F2<bool>);
+      Expect.equals(tIsInt, confuse(m2) is F2<int>);
+      Expect.equals(tIsBool, confuse(m2) is F2<bool>);
+    }
+  }
+
+  /// void Function(int y, {core.List<core.int> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {core.List<core.int> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int y, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int y, [int x]) Function<B extends core.int>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [int x]) Function<B extends core.int>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function(int y, [int x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, [List<Function>]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [List<Function>]) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, {List<T> x}) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {List<T> x}) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function(List<Function> x) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<Function> x) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+        l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int y, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function([Function]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([Function]) Function<B extends core.int>(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function([Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function({core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({core.List<core.int> x})
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function({core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(int y, {int x}) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {int x}) Function<B extends core.int>(
+        int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int y, {int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [core.List<core.int> x])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int,
+            [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int) Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function(int) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [List<Function>]) Function<B extends core.int>(
+        int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int x, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+        l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([List<Function> x]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([List<Function> x]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(List<T>) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(List<T>) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(List<T>) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, [Function]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [Function]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {core.List<core.int> x}) Function<B extends core.int>(
+        int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(core.List<core.int> x) Function<B extends core.int>(
+        int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<T> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<T> x) Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(List<T> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>() Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>() Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is List<A> Function<A>() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U79().runTests();
+  new U79<int>(tIsInt: true).runTests();
+  new U79<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type7_test.dart b/tests/language/function_type/function_type7_test.dart
new file mode 100644
index 0000000..eb38ae3
--- /dev/null
+++ b/tests/language/function_type/function_type7_test.dart
@@ -0,0 +1,1001 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int x, [int]);
+typedef F1<T> = Function Function(int x, [List<T>]);
+typedef F2<T> = core.List<core.int> Function(int, [core.List<core.int>]);
+typedef F3<T> = Function([List<Function>]);
+typedef F4<T> = Function Function<A>(List<A> x);
+typedef F5<T> = int Function(int y, {int x}) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function(int, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int) Function<B extends core.int>(int x);
+typedef F8<T> = Function Function(int x, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F9<T> = Function Function(int y, {List<T> x})
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function([List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F11<T> = List<Function> Function(List<T>) Function<B extends core.int>(
+    int x);
+typedef F12<T> = core.List<core.int> Function(int, [Function])
+    Function<B extends core.int>(int x);
+typedef F13<T> = core.List<core.int> Function(int, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(Function x) Function<B extends core.int>(
+    int x);
+typedef F15<T> = List<T> Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F16<T> = Function([int]) Function<B extends core.int>(int x);
+typedef F17<T> = Function({List<Function> x}) Function<B extends core.int>(
+    int x);
+typedef F18<T> = Function() Function<B extends core.int>(int x);
+typedef F19<T> = void Function(int, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F20<T> = void Function([List<T>]) Function<B extends core.int>(int x);
+typedef F21<T> = List<Function> Function<A>(List<Function> x)
+    Function<B extends core.int>(int x);
+typedef F22<T> = Function<A>(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F23<T> = void Function<A>(List<T> x) Function<B extends core.int>(
+    int x);
+
+int f0(int x, [int x0 = -1]) => throw 'uncalled';
+Function f1(int x, [List<int> x0 = const []]) => throw 'uncalled';
+core.List<core.int> f2(int x0, [core.List<core.int> x1 = const []]) =>
+    throw 'uncalled';
+f3([List<Function> x0 = const []]) => throw 'uncalled';
+Function f4<A>(List<A> x) => throw 'uncalled';
+int Function(int y, {int x}) f5<B extends core.int>(int x) => throw 'uncalled';
+int Function(int, [core.List<core.int> x]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int) f7<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int x, [List<Function>]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int y, {List<int> x}) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function([List<Function> x]) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(List<int>) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [Function]) f12<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, {core.List<core.int> x})
+    f13<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function(Function x) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int y, [core.List<core.int> x]) f15<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+Function([int]) f16<B extends core.int>(int x) => throw 'uncalled';
+Function({List<Function> x}) f17<B extends core.int>(int x) => throw 'uncalled';
+Function() f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(int, [List<Function> x]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function([List<int>]) f20<B extends core.int>(int x) => throw 'uncalled';
+List<Function> Function<A>(List<Function> x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function<A>(core.List<core.int> x) f22<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function<A>(List<int> x) f23<B extends core.int>(int x) =>
+    throw 'uncalled';
+
+class U7<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int x, [int]) x0;
+  late Function Function(int x, [List<T>]) x1;
+  late core.List<core.int> Function(int, [core.List<core.int>]) x2;
+  late Function([List<Function>]) x3;
+  late Function Function<A>(List<A> x) x4;
+  late int Function(int y, {int x}) Function<B extends core.int>(int x) x5;
+  late int Function(int, [core.List<core.int> x]) Function<B extends core.int>(
+      int x) x6;
+  late Function Function(int) Function<B extends core.int>(int x) x7;
+  late Function Function(int x, [List<Function>]) Function<B extends core.int>(
+      int x) x8;
+  late Function Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+      x9;
+  late List<Function> Function([List<Function> x]) Function<B extends core.int>(
+      int x) x10;
+  late List<Function> Function(List<T>) Function<B extends core.int>(int x) x11;
+  late core.List<core.int> Function(int, [Function])
+      Function<B extends core.int>(int x) x12;
+  late core.List<core.int> Function(int, {core.List<core.int> x})
+      Function<B extends core.int>(int x) x13;
+  late List<T> Function(Function x) Function<B extends core.int>(int x) x14;
+  late List<T> Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>(int x) x15;
+  late Function([int]) Function<B extends core.int>(int x) x16;
+  late Function({List<Function> x}) Function<B extends core.int>(int x) x17;
+  late Function() Function<B extends core.int>(int x) x18;
+  late void Function(int, [List<Function> x]) Function<B extends core.int>(
+      int x) x19;
+  late void Function([List<T>]) Function<B extends core.int>(int x) x20;
+  late List<Function> Function<A>(List<Function> x)
+      Function<B extends core.int>(int x) x21;
+  late Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+      x22;
+  late void Function<A>(List<T> x) Function<B extends core.int>(int x) x23;
+
+  U7({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x, [int x0 = -1]) => throw 'uncalled';
+  Function m1(int x, [List<T> x0 = const []]) => throw 'uncalled';
+  core.List<core.int> m2(int x0, [core.List<core.int> x1 = const []]) =>
+      throw 'uncalled';
+  m3([List<Function> x0 = const []]) => throw 'uncalled';
+  Function m4<A>(List<A> x) => throw 'uncalled';
+  int Function(int y, {int x}) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int, [core.List<core.int> x]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int) m7<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(int x, [List<Function>]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int y, {List<T> x}) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function([List<Function> x]) m10<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(List<T>) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [Function]) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, {core.List<core.int> x})
+      m13<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function(Function x) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, [core.List<core.int> x]) m15<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  Function([int]) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function({List<Function> x}) m17<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function() m18<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int, [List<Function> x]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function([List<T>]) m20<B extends core.int>(int x) => throw 'uncalled';
+  List<Function> Function<A>(List<Function> x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function<A>(core.List<core.int> x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function<A>(List<T> x) m23<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int x, [int])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [int]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int x, [int]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function(int x, [List<T>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [List<T>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function(int x, [List<T>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, [core.List<core.int>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [core.List<core.int>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(
+        m2 is core.List<core.int> Function(int, [core.List<core.int>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function([List<Function>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function([List<Function>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function([List<Function>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// Function Function<A>(List<A> x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<A> x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is Function Function<A>(List<A> x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {int x}) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {int x}) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int y, {int x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [core.List<core.int> x]) Function<B extends core.int>(
+        int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(int) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [List<Function>]) Function<B extends core.int>(
+        int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int x, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function(int y, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+    // The static function has its T always set to int.
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isFalse(f9 is F9<bool>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    Expect.isFalse(confuse(f9) is F9<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        x9 = confuse(f9);
+      });
+      Expect.throws(() {
+        l9 = (f9 as dynamic);
+      });
+      Expect.throws(() {
+        l9 = confuse(f9);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m9 is F9<int>);
+      Expect.equals(tIsBool, m9 is F9<bool>);
+      Expect.equals(tIsInt, confuse(m9) is F9<int>);
+      Expect.equals(tIsBool, confuse(m9) is F9<bool>);
+    }
+  }
+
+  /// List<Function> Function([List<Function> x]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<Function> x]) Function<B extends core.int>(
+        int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function(List<T>) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<T>) Function<B extends core.int>(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function(List<T>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, [Function]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [Function]) Function<B extends core.int>(
+        int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {core.List<core.int> x})
+        Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int,
+            {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function(Function x) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(Function x) Function<B extends core.int>(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(Function x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function([int]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([int]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({List<Function> x}) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({List<Function> x}) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function({List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// Function() Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    Function() Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is Function() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function([List<T>]) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function([List<T>]) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is void Function([List<T>]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(List<Function> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(List<Function> x) Function<B extends core.int>(
+        int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(core.List<core.int> x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+
+  /// void Function<A>(List<T> x) Function<B extends core.int>(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<T> x) Function<B extends core.int>(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(
+        m23 is void Function<A>(List<T> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+    // The static function has its T always set to int.
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isFalse(f23 is F23<bool>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    Expect.isFalse(confuse(f23) is F23<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        x23 = confuse(f23);
+      });
+      Expect.throws(() {
+        l23 = (f23 as dynamic);
+      });
+      Expect.throws(() {
+        l23 = confuse(f23);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m23 is F23<int>);
+      Expect.equals(tIsBool, m23 is F23<bool>);
+      Expect.equals(tIsInt, confuse(m23) is F23<int>);
+      Expect.equals(tIsBool, confuse(m23) is F23<bool>);
+    }
+  }
+}
+
+void main() {
+  new U7().runTests();
+  new U7<int>(tIsInt: true).runTests();
+  new U7<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type80_test.dart b/tests/language/function_type/function_type80_test.dart
new file mode 100644
index 0000000..1cb0d30
--- /dev/null
+++ b/tests/language/function_type/function_type80_test.dart
@@ -0,0 +1,946 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, [List<Function> x]);
+typedef F1<T> = core.List<core.int> Function([Function x]);
+typedef F2<T> = Function(int x);
+typedef F3<T> = void Function(List<T> x);
+typedef F4<T> = int Function(int) Function();
+typedef F5<T> = int Function(int x, [List<Function>]) Function();
+typedef F6<T> = int Function(int y, {List<T> x}) Function();
+typedef F7<T> = Function Function([List<Function> x]) Function();
+typedef F8<T> = Function Function(List<T>) Function();
+typedef F9<T> = List<Function> Function(int, [Function]) Function();
+typedef F10<T> = List<Function> Function(int, {core.List<core.int> x})
+    Function();
+typedef F11<T> = core.List<core.int> Function(Function x) Function();
+typedef F12<T> = core.List<core.int> Function(int y, [core.List<core.int> x])
+    Function();
+typedef F13<T> = List<T> Function([int]) Function();
+typedef F14<T> = List<T> Function({List<Function> x}) Function();
+typedef F15<T> = List<T> Function() Function();
+typedef F16<T> = Function(int, [List<Function> x]) Function();
+typedef F17<T> = Function([List<T>]) Function();
+typedef F18<T> = void Function(int x, [Function]) Function();
+typedef F19<T> = void Function(int y, {core.List<core.int> x}) Function();
+typedef F20<T> = Function Function<A>(List<T> x) Function();
+typedef F21<T> = List<T> Function<A>() Function();
+typedef F22<T> = List<A> Function<A>(A x) Function();
+
+Function f0(int x0, [List<Function> x = const []]) => throw 'uncalled';
+core.List<core.int> f1([Function x = _voidFunction]) => throw 'uncalled';
+f2(int x) => throw 'uncalled';
+void f3(List<int> x) => throw 'uncalled';
+int Function(int) f4() => throw 'uncalled';
+int Function(int x, [List<Function>]) f5() => throw 'uncalled';
+int Function(int y, {List<int> x}) f6() => throw 'uncalled';
+Function Function([List<Function> x]) f7() => throw 'uncalled';
+Function Function(List<int>) f8() => throw 'uncalled';
+List<Function> Function(int, [Function]) f9() => throw 'uncalled';
+List<Function> Function(int, {core.List<core.int> x}) f10() => throw 'uncalled';
+core.List<core.int> Function(Function x) f11() => throw 'uncalled';
+core.List<core.int> Function(int y, [core.List<core.int> x]) f12() =>
+    throw 'uncalled';
+List<int> Function([int]) f13() => throw 'uncalled';
+List<int> Function({List<Function> x}) f14() => throw 'uncalled';
+List<int> Function() f15() => throw 'uncalled';
+Function(int, [List<Function> x]) f16() => throw 'uncalled';
+Function([List<int>]) f17() => throw 'uncalled';
+void Function(int x, [Function]) f18() => throw 'uncalled';
+void Function(int y, {core.List<core.int> x}) f19() => throw 'uncalled';
+Function Function<A>(List<int> x) f20() => throw 'uncalled';
+List<int> Function<A>() f21() => throw 'uncalled';
+List<A> Function<A>(A x) f22() => throw 'uncalled';
+
+class U80<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, [List<Function> x]) x0;
+  late core.List<core.int> Function([Function x]) x1;
+  late Function(int x) x2;
+  late void Function(List<T> x) x3;
+  late int Function(int) Function() x4;
+  late int Function(int x, [List<Function>]) Function() x5;
+  late int Function(int y, {List<T> x}) Function() x6;
+  late Function Function([List<Function> x]) Function() x7;
+  late Function Function(List<T>) Function() x8;
+  late List<Function> Function(int, [Function]) Function() x9;
+  late List<Function> Function(int, {core.List<core.int> x}) Function() x10;
+  late core.List<core.int> Function(Function x) Function() x11;
+  late core.List<core.int> Function(int y, [core.List<core.int> x]) Function()
+      x12;
+  late List<T> Function([int]) Function() x13;
+  late List<T> Function({List<Function> x}) Function() x14;
+  late List<T> Function() Function() x15;
+  late Function(int, [List<Function> x]) Function() x16;
+  late Function([List<T>]) Function() x17;
+  late void Function(int x, [Function]) Function() x18;
+  late void Function(int y, {core.List<core.int> x}) Function() x19;
+  late Function Function<A>(List<T> x) Function() x20;
+  late List<T> Function<A>() Function() x21;
+  late List<A> Function<A>(A x) Function() x22;
+
+  U80({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, [List<Function> x = const []]) => throw 'uncalled';
+  core.List<core.int> m1([Function x = _voidFunction]) => throw 'uncalled';
+  m2(int x) => throw 'uncalled';
+  void m3(List<T> x) => throw 'uncalled';
+  int Function(int) m4() => throw 'uncalled';
+  int Function(int x, [List<Function>]) m5() => throw 'uncalled';
+  int Function(int y, {List<T> x}) m6() => throw 'uncalled';
+  Function Function([List<Function> x]) m7() => throw 'uncalled';
+  Function Function(List<T>) m8() => throw 'uncalled';
+  List<Function> Function(int, [Function]) m9() => throw 'uncalled';
+  List<Function> Function(int, {core.List<core.int> x}) m10() =>
+      throw 'uncalled';
+  core.List<core.int> Function(Function x) m11() => throw 'uncalled';
+  core.List<core.int> Function(int y, [core.List<core.int> x]) m12() =>
+      throw 'uncalled';
+  List<T> Function([int]) m13() => throw 'uncalled';
+  List<T> Function({List<Function> x}) m14() => throw 'uncalled';
+  List<T> Function() m15() => throw 'uncalled';
+  Function(int, [List<Function> x]) m16() => throw 'uncalled';
+  Function([List<T>]) m17() => throw 'uncalled';
+  void Function(int x, [Function]) m18() => throw 'uncalled';
+  void Function(int y, {core.List<core.int> x}) m19() => throw 'uncalled';
+  Function Function<A>(List<T> x) m20() => throw 'uncalled';
+  List<T> Function<A>() m21() => throw 'uncalled';
+  List<A> Function<A>(A x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, [List<Function> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<Function> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, [List<Function> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function([Function x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([Function x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function([Function x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int x)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int x) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int x));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function(List<T> x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(List<T> x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(List<T> x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function(int) Function()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int) Function() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int) Function());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int x, [List<Function>]) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [List<Function>]) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int x, [List<Function>]) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, {List<T> x}) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {List<T> x}) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int y, {List<T> x}) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function([List<Function> x]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<Function> x]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([List<Function> x]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(List<T>) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<T>) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(List<T>) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, [Function]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [Function]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [Function]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, {core.List<core.int> x}) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {core.List<core.int> x}) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, {core.List<core.int> x})
+        Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(Function x) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(Function x) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(Function x) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, [core.List<core.int> x]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [core.List<core.int> x]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y,
+            [core.List<core.int> x])
+        Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function([int]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([int]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function([int]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function({List<Function> x}) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({List<Function> x}) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function({List<Function> x}) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function() Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function() Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function() Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [List<Function> x]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<Function> x]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([List<T>]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([List<T>]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([List<T>]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int x, [Function]) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [Function]) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int x, [Function]) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, {core.List<core.int> x}) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {core.List<core.int> x}) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int y, {core.List<core.int> x}) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(List<T> x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<T> x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(List<T> x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<T> Function<A>() Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>() Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>() Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(A x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(A x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(A x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U80().runTests();
+  new U80<int>(tIsInt: true).runTests();
+  new U80<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type81_test.dart b/tests/language/function_type/function_type81_test.dart
new file mode 100644
index 0000000..0c89ae4
--- /dev/null
+++ b/tests/language/function_type/function_type81_test.dart
@@ -0,0 +1,953 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int y, [List<Function> x]);
+typedef F1<T> = core.List<core.int> Function(int, [Function x]);
+typedef F2<T> = Function([int x]);
+typedef F3<T> = void Function([List<T> x]);
+typedef F4<T> = int Function(int) Function(int x);
+typedef F5<T> = int Function(int x, [List<Function>]) Function(int x);
+typedef F6<T> = int Function(int y, {List<T> x}) Function(int x);
+typedef F7<T> = Function Function([List<Function> x]) Function(int x);
+typedef F8<T> = Function Function(List<T>) Function(int x);
+typedef F9<T> = List<Function> Function(int, [Function]) Function(int x);
+typedef F10<T> = List<Function> Function(int, {core.List<core.int> x}) Function(
+    int x);
+typedef F11<T> = core.List<core.int> Function(Function x) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int y, [core.List<core.int> x])
+    Function(int x);
+typedef F13<T> = List<T> Function([int]) Function(int x);
+typedef F14<T> = List<T> Function({List<Function> x}) Function(int x);
+typedef F15<T> = List<T> Function() Function(int x);
+typedef F16<T> = Function(int, [List<Function> x]) Function(int x);
+typedef F17<T> = Function([List<T>]) Function(int x);
+typedef F18<T> = void Function(int x, [Function]) Function(int x);
+typedef F19<T> = void Function(int y, {core.List<core.int> x}) Function(int x);
+typedef F20<T> = Function Function<A>(List<T> x) Function(int x);
+typedef F21<T> = List<T> Function<A>() Function(int x);
+typedef F22<T> = List<A> Function<A>(A x) Function(int x);
+
+Function f0(int y, [List<Function> x = const []]) => throw 'uncalled';
+core.List<core.int> f1(int x0, [Function x = _voidFunction]) =>
+    throw 'uncalled';
+f2([int x = -1]) => throw 'uncalled';
+void f3([List<int> x = const []]) => throw 'uncalled';
+int Function(int) f4(int x) => throw 'uncalled';
+int Function(int x, [List<Function>]) f5(int x) => throw 'uncalled';
+int Function(int y, {List<int> x}) f6(int x) => throw 'uncalled';
+Function Function([List<Function> x]) f7(int x) => throw 'uncalled';
+Function Function(List<int>) f8(int x) => throw 'uncalled';
+List<Function> Function(int, [Function]) f9(int x) => throw 'uncalled';
+List<Function> Function(int, {core.List<core.int> x}) f10(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(Function x) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int y, [core.List<core.int> x]) f12(int x) =>
+    throw 'uncalled';
+List<int> Function([int]) f13(int x) => throw 'uncalled';
+List<int> Function({List<Function> x}) f14(int x) => throw 'uncalled';
+List<int> Function() f15(int x) => throw 'uncalled';
+Function(int, [List<Function> x]) f16(int x) => throw 'uncalled';
+Function([List<int>]) f17(int x) => throw 'uncalled';
+void Function(int x, [Function]) f18(int x) => throw 'uncalled';
+void Function(int y, {core.List<core.int> x}) f19(int x) => throw 'uncalled';
+Function Function<A>(List<int> x) f20(int x) => throw 'uncalled';
+List<int> Function<A>() f21(int x) => throw 'uncalled';
+List<A> Function<A>(A x) f22(int x) => throw 'uncalled';
+
+class U81<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int y, [List<Function> x]) x0;
+  late core.List<core.int> Function(int, [Function x]) x1;
+  late Function([int x]) x2;
+  late void Function([List<T> x]) x3;
+  late int Function(int) Function(int x) x4;
+  late int Function(int x, [List<Function>]) Function(int x) x5;
+  late int Function(int y, {List<T> x}) Function(int x) x6;
+  late Function Function([List<Function> x]) Function(int x) x7;
+  late Function Function(List<T>) Function(int x) x8;
+  late List<Function> Function(int, [Function]) Function(int x) x9;
+  late List<Function> Function(int, {core.List<core.int> x}) Function(int x)
+      x10;
+  late core.List<core.int> Function(Function x) Function(int x) x11;
+  late core.List<core.int> Function(int y, [core.List<core.int> x]) Function(
+      int x) x12;
+  late List<T> Function([int]) Function(int x) x13;
+  late List<T> Function({List<Function> x}) Function(int x) x14;
+  late List<T> Function() Function(int x) x15;
+  late Function(int, [List<Function> x]) Function(int x) x16;
+  late Function([List<T>]) Function(int x) x17;
+  late void Function(int x, [Function]) Function(int x) x18;
+  late void Function(int y, {core.List<core.int> x}) Function(int x) x19;
+  late Function Function<A>(List<T> x) Function(int x) x20;
+  late List<T> Function<A>() Function(int x) x21;
+  late List<A> Function<A>(A x) Function(int x) x22;
+
+  U81({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int y, [List<Function> x = const []]) => throw 'uncalled';
+  core.List<core.int> m1(int x0, [Function x = _voidFunction]) =>
+      throw 'uncalled';
+  m2([int x = -1]) => throw 'uncalled';
+  void m3([List<T> x = const []]) => throw 'uncalled';
+  int Function(int) m4(int x) => throw 'uncalled';
+  int Function(int x, [List<Function>]) m5(int x) => throw 'uncalled';
+  int Function(int y, {List<T> x}) m6(int x) => throw 'uncalled';
+  Function Function([List<Function> x]) m7(int x) => throw 'uncalled';
+  Function Function(List<T>) m8(int x) => throw 'uncalled';
+  List<Function> Function(int, [Function]) m9(int x) => throw 'uncalled';
+  List<Function> Function(int, {core.List<core.int> x}) m10(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(Function x) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int y, [core.List<core.int> x]) m12(int x) =>
+      throw 'uncalled';
+  List<T> Function([int]) m13(int x) => throw 'uncalled';
+  List<T> Function({List<Function> x}) m14(int x) => throw 'uncalled';
+  List<T> Function() m15(int x) => throw 'uncalled';
+  Function(int, [List<Function> x]) m16(int x) => throw 'uncalled';
+  Function([List<T>]) m17(int x) => throw 'uncalled';
+  void Function(int x, [Function]) m18(int x) => throw 'uncalled';
+  void Function(int y, {core.List<core.int> x}) m19(int x) => throw 'uncalled';
+  Function Function<A>(List<T> x) m20(int x) => throw 'uncalled';
+  List<T> Function<A>() m21(int x) => throw 'uncalled';
+  List<A> Function<A>(A x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int y, [List<Function> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [List<Function> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int y, [List<Function> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int, [Function x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [Function x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int, [Function x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function([int x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function([int x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function([int x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function([List<T> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function([List<T> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function([List<T> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function(int) Function(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int) Function(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int) Function(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int x, [List<Function>]) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [List<Function>]) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int x, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, {List<T> x}) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {List<T> x}) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int y, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function([List<Function> x]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<Function> x]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(List<T>) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<T>) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(List<T>) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, [Function]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [Function]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int, [Function]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, {core.List<core.int> x}) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {core.List<core.int> x}) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, {core.List<core.int> x})
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(Function x) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(Function x) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(Function x) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, [core.List<core.int> x]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [core.List<core.int> x]) Function(int x)
+        l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y,
+            [core.List<core.int> x])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function([int]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([int]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function([int]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function({List<Function> x}) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({List<Function> x}) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function({List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function() Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function() Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function() Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [List<Function> x]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<Function> x]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([List<T>]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([List<T>]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([List<T>]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int x, [Function]) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [Function]) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int x, [Function]) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, {core.List<core.int> x}) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {core.List<core.int> x}) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int y, {core.List<core.int> x}) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(List<T> x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<T> x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<T> Function<A>() Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>() Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>() Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(A x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(A x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(A x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U81().runTests();
+  new U81<int>(tIsInt: true).runTests();
+  new U81<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type82_test.dart b/tests/language/function_type/function_type82_test.dart
new file mode 100644
index 0000000..ac0159d4
--- /dev/null
+++ b/tests/language/function_type/function_type82_test.dart
@@ -0,0 +1,989 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(List<Function>);
+typedef F1<T> = core.List<core.int> Function(int y, [Function x]);
+typedef F2<T> = Function(int, [int x]);
+typedef F3<T> = void Function(int, [List<T> x]);
+typedef F4<T> = int Function(int) Function<B extends core.int>();
+typedef F5<T> = int Function(int x, [List<Function>])
+    Function<B extends core.int>();
+typedef F6<T> = int Function(int y, {List<T> x}) Function<B extends core.int>();
+typedef F7<T> = Function Function([List<Function> x])
+    Function<B extends core.int>();
+typedef F8<T> = Function Function(List<T>) Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int, [Function])
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(Function x)
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F13<T> = List<T> Function([int]) Function<B extends core.int>();
+typedef F14<T> = List<T> Function({List<Function> x})
+    Function<B extends core.int>();
+typedef F15<T> = List<T> Function() Function<B extends core.int>();
+typedef F16<T> = Function(int, [List<Function> x])
+    Function<B extends core.int>();
+typedef F17<T> = Function([List<T>]) Function<B extends core.int>();
+typedef F18<T> = void Function(int x, [Function])
+    Function<B extends core.int>();
+typedef F19<T> = void Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F20<T> = Function Function<A>(List<T> x) Function<B extends core.int>();
+typedef F21<T> = List<T> Function<A>() Function<B extends core.int>();
+typedef F22<T> = List<A> Function<A>(A x) Function<B extends core.int>();
+
+Function f0(List<Function> x0) => throw 'uncalled';
+core.List<core.int> f1(int y, [Function x = _voidFunction]) => throw 'uncalled';
+f2(int x0, [int x = -1]) => throw 'uncalled';
+void f3(int x0, [List<int> x = const []]) => throw 'uncalled';
+int Function(int) f4<B extends core.int>() => throw 'uncalled';
+int Function(int x, [List<Function>]) f5<B extends core.int>() =>
+    throw 'uncalled';
+int Function(int y, {List<int> x}) f6<B extends core.int>() => throw 'uncalled';
+Function Function([List<Function> x]) f7<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(List<int>) f8<B extends core.int>() => throw 'uncalled';
+List<Function> Function(int, [Function]) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, {core.List<core.int> x})
+    f10<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function(Function x) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, [core.List<core.int> x])
+    f12<B extends core.int>() => throw 'uncalled';
+List<int> Function([int]) f13<B extends core.int>() => throw 'uncalled';
+List<int> Function({List<Function> x}) f14<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function() f15<B extends core.int>() => throw 'uncalled';
+Function(int, [List<Function> x]) f16<B extends core.int>() => throw 'uncalled';
+Function([List<int>]) f17<B extends core.int>() => throw 'uncalled';
+void Function(int x, [Function]) f18<B extends core.int>() => throw 'uncalled';
+void Function(int y, {core.List<core.int> x}) f19<B extends core.int>() =>
+    throw 'uncalled';
+Function Function<A>(List<int> x) f20<B extends core.int>() => throw 'uncalled';
+List<int> Function<A>() f21<B extends core.int>() => throw 'uncalled';
+List<A> Function<A>(A x) f22<B extends core.int>() => throw 'uncalled';
+
+class U82<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(List<Function>) x0;
+  late core.List<core.int> Function(int y, [Function x]) x1;
+  late Function(int, [int x]) x2;
+  late void Function(int, [List<T> x]) x3;
+  late int Function(int) Function<B extends core.int>() x4;
+  late int Function(int x, [List<Function>]) Function<B extends core.int>() x5;
+  late int Function(int y, {List<T> x}) Function<B extends core.int>() x6;
+  late Function Function([List<Function> x]) Function<B extends core.int>() x7;
+  late Function Function(List<T>) Function<B extends core.int>() x8;
+  late List<Function> Function(int, [Function]) Function<B extends core.int>()
+      x9;
+  late List<Function> Function(int, {core.List<core.int> x})
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function(Function x) Function<B extends core.int>()
+      x11;
+  late core.List<core.int> Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>() x12;
+  late List<T> Function([int]) Function<B extends core.int>() x13;
+  late List<T> Function({List<Function> x}) Function<B extends core.int>() x14;
+  late List<T> Function() Function<B extends core.int>() x15;
+  late Function(int, [List<Function> x]) Function<B extends core.int>() x16;
+  late Function([List<T>]) Function<B extends core.int>() x17;
+  late void Function(int x, [Function]) Function<B extends core.int>() x18;
+  late void Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>() x19;
+  late Function Function<A>(List<T> x) Function<B extends core.int>() x20;
+  late List<T> Function<A>() Function<B extends core.int>() x21;
+  late List<A> Function<A>(A x) Function<B extends core.int>() x22;
+
+  U82({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(List<Function> x0) => throw 'uncalled';
+  core.List<core.int> m1(int y, [Function x = _voidFunction]) =>
+      throw 'uncalled';
+  m2(int x0, [int x = -1]) => throw 'uncalled';
+  void m3(int x0, [List<T> x = const []]) => throw 'uncalled';
+  int Function(int) m4<B extends core.int>() => throw 'uncalled';
+  int Function(int x, [List<Function>]) m5<B extends core.int>() =>
+      throw 'uncalled';
+  int Function(int y, {List<T> x}) m6<B extends core.int>() => throw 'uncalled';
+  Function Function([List<Function> x]) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(List<T>) m8<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(int, [Function]) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, {core.List<core.int> x})
+      m10<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function(Function x) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [core.List<core.int> x])
+      m12<B extends core.int>() => throw 'uncalled';
+  List<T> Function([int]) m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function({List<Function> x}) m14<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function() m15<B extends core.int>() => throw 'uncalled';
+  Function(int, [List<Function> x]) m16<B extends core.int>() =>
+      throw 'uncalled';
+  Function([List<T>]) m17<B extends core.int>() => throw 'uncalled';
+  void Function(int x, [Function]) m18<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int y, {core.List<core.int> x}) m19<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function<A>(List<T> x) m20<B extends core.int>() => throw 'uncalled';
+  List<T> Function<A>() m21<B extends core.int>() => throw 'uncalled';
+  List<A> Function<A>(A x) m22<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(List<Function>)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<Function>) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(List<Function>));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int y, [Function x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [Function x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int y, [Function x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int, [int x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int, [int x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int, [int x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function(int, [List<T> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<T> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, [List<T> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function(int) Function<B extends core.int>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int) Function<B extends core.int>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int) Function<B extends core.int>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int x, [List<Function>]) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [List<Function>]) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int x, [List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, {List<T> x}) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {List<T> x}) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int y, {List<T> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function([List<Function> x]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<Function> x]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(List<T>) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<T>) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(List<T>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, [Function]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [Function]) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [Function])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {core.List<core.int> x})
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(Function x) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(Function x) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(Function x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, [core.List<core.int> x]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y,
+            [core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function([int]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([int]) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function([int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function({List<Function> x}) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({List<Function> x}) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function({List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function() Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function() Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function() Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [List<Function> x]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<Function> x]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([List<T>]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([List<T>]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function([List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int x, [Function]) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [Function]) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int x, [Function]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {core.List<core.int> x}) Function<B extends core.int>()
+        l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(List<T> x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<T> x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<T> Function<A>() Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>() Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>() Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(A x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(A x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is List<A> Function<A>(A x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U82().runTests();
+  new U82<int>(tIsInt: true).runTests();
+  new U82<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type83_test.dart b/tests/language/function_type/function_type83_test.dart
new file mode 100644
index 0000000..7cd2eb5
--- /dev/null
+++ b/tests/language/function_type/function_type83_test.dart
@@ -0,0 +1,1011 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function([List<Function>]);
+typedef F1<T> = core.List<core.int> Function(Function);
+typedef F2<T> = Function(int y, [int x]);
+typedef F3<T> = void Function(int y, [List<T> x]);
+typedef F4<T> = int Function(int) Function<B extends core.int>(int x);
+typedef F5<T> = int Function(int x, [List<Function>])
+    Function<B extends core.int>(int x);
+typedef F6<T> = int Function(int y, {List<T> x}) Function<B extends core.int>(
+    int x);
+typedef F7<T> = Function Function([List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F8<T> = Function Function(List<T>) Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(int, [Function])
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(int, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(Function x)
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int y, [core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F13<T> = List<T> Function([int]) Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function({List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F15<T> = List<T> Function() Function<B extends core.int>(int x);
+typedef F16<T> = Function(int, [List<Function> x]) Function<B extends core.int>(
+    int x);
+typedef F17<T> = Function([List<T>]) Function<B extends core.int>(int x);
+typedef F18<T> = void Function(int x, [Function]) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F20<T> = Function Function<A>(List<T> x) Function<B extends core.int>(
+    int x);
+typedef F21<T> = List<T> Function<A>() Function<B extends core.int>(int x);
+typedef F22<T> = List<A> Function<A>(A x) Function<B extends core.int>(int x);
+
+Function f0([List<Function> x0 = const []]) => throw 'uncalled';
+core.List<core.int> f1(Function x0) => throw 'uncalled';
+f2(int y, [int x = -1]) => throw 'uncalled';
+void f3(int y, [List<int> x = const []]) => throw 'uncalled';
+int Function(int) f4<B extends core.int>(int x) => throw 'uncalled';
+int Function(int x, [List<Function>]) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function(int y, {List<int> x}) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function([List<Function> x]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(List<int>) f8<B extends core.int>(int x) => throw 'uncalled';
+List<Function> Function(int, [Function]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, {core.List<core.int> x}) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(Function x) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, [core.List<core.int> x])
+    f12<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function([int]) f13<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function({List<Function> x}) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function() f15<B extends core.int>(int x) => throw 'uncalled';
+Function(int, [List<Function> x]) f16<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function([List<int>]) f17<B extends core.int>(int x) => throw 'uncalled';
+void Function(int x, [Function]) f18<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int y, {core.List<core.int> x}) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function<A>(List<int> x) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function<A>() f21<B extends core.int>(int x) => throw 'uncalled';
+List<A> Function<A>(A x) f22<B extends core.int>(int x) => throw 'uncalled';
+
+class U83<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function([List<Function>]) x0;
+  late core.List<core.int> Function(Function) x1;
+  late Function(int y, [int x]) x2;
+  late void Function(int y, [List<T> x]) x3;
+  late int Function(int) Function<B extends core.int>(int x) x4;
+  late int Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+      x5;
+  late int Function(int y, {List<T> x}) Function<B extends core.int>(int x) x6;
+  late Function Function([List<Function> x]) Function<B extends core.int>(int x)
+      x7;
+  late Function Function(List<T>) Function<B extends core.int>(int x) x8;
+  late List<Function> Function(int, [Function]) Function<B extends core.int>(
+      int x) x9;
+  late List<Function> Function(int, {core.List<core.int> x})
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function(Function x) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function(int y, [core.List<core.int> x])
+      Function<B extends core.int>(int x) x12;
+  late List<T> Function([int]) Function<B extends core.int>(int x) x13;
+  late List<T> Function({List<Function> x}) Function<B extends core.int>(int x)
+      x14;
+  late List<T> Function() Function<B extends core.int>(int x) x15;
+  late Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+      x16;
+  late Function([List<T>]) Function<B extends core.int>(int x) x17;
+  late void Function(int x, [Function]) Function<B extends core.int>(int x) x18;
+  late void Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>(int x) x19;
+  late Function Function<A>(List<T> x) Function<B extends core.int>(int x) x20;
+  late List<T> Function<A>() Function<B extends core.int>(int x) x21;
+  late List<A> Function<A>(A x) Function<B extends core.int>(int x) x22;
+
+  U83({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0([List<Function> x0 = const []]) => throw 'uncalled';
+  core.List<core.int> m1(Function x0) => throw 'uncalled';
+  m2(int y, [int x = -1]) => throw 'uncalled';
+  void m3(int y, [List<T> x = const []]) => throw 'uncalled';
+  int Function(int) m4<B extends core.int>(int x) => throw 'uncalled';
+  int Function(int x, [List<Function>]) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function(int y, {List<T> x}) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function([List<Function> x]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(List<T>) m8<B extends core.int>(int x) => throw 'uncalled';
+  List<Function> Function(int, [Function]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, {core.List<core.int> x}) m10<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(Function x) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [core.List<core.int> x])
+      m12<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function([int]) m13<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function({List<Function> x}) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function() m15<B extends core.int>(int x) => throw 'uncalled';
+  Function(int, [List<Function> x]) m16<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function([List<T>]) m17<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int x, [Function]) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int y, {core.List<core.int> x}) m19<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  Function Function<A>(List<T> x) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function<A>() m21<B extends core.int>(int x) => throw 'uncalled';
+  List<A> Function<A>(A x) m22<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function([List<Function>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<Function>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function([List<Function>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(Function)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(Function) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(Function));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int y, [int x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [int x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int y, [int x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function(int y, [List<T> x])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [List<T> x]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int y, [List<T> x]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function(int) Function<B extends core.int>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int) Function<B extends core.int>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [List<Function>]) Function<B extends core.int>(int x)
+        l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int x, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, {List<T> x}) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {List<T> x}) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function(int y, {List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+    // The static function has its T always set to int.
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isFalse(f6 is F6<bool>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    Expect.isFalse(confuse(f6) is F6<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        x6 = confuse(f6);
+      });
+      Expect.throws(() {
+        l6 = (f6 as dynamic);
+      });
+      Expect.throws(() {
+        l6 = confuse(f6);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m6 is F6<int>);
+      Expect.equals(tIsBool, m6 is F6<bool>);
+      Expect.equals(tIsInt, confuse(m6) is F6<int>);
+      Expect.equals(tIsBool, confuse(m6) is F6<bool>);
+    }
+  }
+
+  /// Function Function([List<Function> x]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<Function> x]) Function<B extends core.int>(int x)
+        l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(List<T>) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<T>) Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(List<T>) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, [Function]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [Function]) Function<B extends core.int>(int x)
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {core.List<core.int> x})
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function(Function x) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(Function x) Function<B extends core.int>(int x)
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(Function x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int y, [core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [core.List<core.int> x])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int y,
+            [core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function([int]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([int]) Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function([int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function({List<Function> x}) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({List<Function> x}) Function<B extends core.int>(int x)
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function({List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function() Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function() Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is List<T> Function() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<Function> x]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function([List<T>]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function([List<T>]) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function([List<T>]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int x, [Function]) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [Function]) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int x, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {core.List<core.int> x}) Function<B extends core.int>(
+        int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// Function Function<A>(List<T> x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<T> x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(List<T> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<T> Function<A>() Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>() Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<T> Function<A>() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(A x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(A x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is List<A> Function<A>(A x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U83().runTests();
+  new U83<int>(tIsInt: true).runTests();
+  new U83<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type84_test.dart b/tests/language/function_type/function_type84_test.dart
new file mode 100644
index 0000000..4c34ba2
--- /dev/null
+++ b/tests/language/function_type/function_type84_test.dart
@@ -0,0 +1,891 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, [List<Function>]);
+typedef F1<T> = core.List<core.int> Function([Function]);
+typedef F2<T> = Function(int);
+typedef F3<T> = void Function(List<T>);
+typedef F4<T> = int Function([int]) Function();
+typedef F5<T> = int Function({List<Function> x}) Function();
+typedef F6<T> = int Function() Function();
+typedef F7<T> = Function Function(int, [List<Function> x]) Function();
+typedef F8<T> = Function Function([List<T>]) Function();
+typedef F9<T> = List<Function> Function(int x, [Function]) Function();
+typedef F10<T> = List<Function> Function(int y, {core.List<core.int> x})
+    Function();
+typedef F11<T> = core.List<core.int> Function([Function x]) Function();
+typedef F12<T> = core.List<core.int> Function(core.List<core.int>) Function();
+typedef F13<T> = List<T> Function(int, [int]) Function();
+typedef F14<T> = List<T> Function(int, {List<Function> x}) Function();
+typedef F15<T> = Function(int x) Function();
+typedef F16<T> = Function(int y, [List<Function> x]) Function();
+typedef F17<T> = Function(int, [List<T>]) Function();
+typedef F18<T> = void Function({Function x}) Function();
+typedef F19<T> = void Function(List<T> x) Function();
+typedef F20<T> = Function Function<A>() Function();
+typedef F21<T> = List<T> Function<A>(A x) Function();
+typedef F22<T> = List<A> Function<A>(List<A> x) Function();
+
+Function f0(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+core.List<core.int> f1([Function x0 = _voidFunction]) => throw 'uncalled';
+f2(int x0) => throw 'uncalled';
+void f3(List<int> x0) => throw 'uncalled';
+int Function([int]) f4() => throw 'uncalled';
+int Function({List<Function> x}) f5() => throw 'uncalled';
+int Function() f6() => throw 'uncalled';
+Function Function(int, [List<Function> x]) f7() => throw 'uncalled';
+Function Function([List<int>]) f8() => throw 'uncalled';
+List<Function> Function(int x, [Function]) f9() => throw 'uncalled';
+List<Function> Function(int y, {core.List<core.int> x}) f10() =>
+    throw 'uncalled';
+core.List<core.int> Function([Function x]) f11() => throw 'uncalled';
+core.List<core.int> Function(core.List<core.int>) f12() => throw 'uncalled';
+List<int> Function(int, [int]) f13() => throw 'uncalled';
+List<int> Function(int, {List<Function> x}) f14() => throw 'uncalled';
+Function(int x) f15() => throw 'uncalled';
+Function(int y, [List<Function> x]) f16() => throw 'uncalled';
+Function(int, [List<int>]) f17() => throw 'uncalled';
+void Function({Function x}) f18() => throw 'uncalled';
+void Function(List<int> x) f19() => throw 'uncalled';
+Function Function<A>() f20() => throw 'uncalled';
+List<int> Function<A>(A x) f21() => throw 'uncalled';
+List<A> Function<A>(List<A> x) f22() => throw 'uncalled';
+
+class U84<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, [List<Function>]) x0;
+  late core.List<core.int> Function([Function]) x1;
+  late Function(int) x2;
+  late void Function(List<T>) x3;
+  late int Function([int]) Function() x4;
+  late int Function({List<Function> x}) Function() x5;
+  late int Function() Function() x6;
+  late Function Function(int, [List<Function> x]) Function() x7;
+  late Function Function([List<T>]) Function() x8;
+  late List<Function> Function(int x, [Function]) Function() x9;
+  late List<Function> Function(int y, {core.List<core.int> x}) Function() x10;
+  late core.List<core.int> Function([Function x]) Function() x11;
+  late core.List<core.int> Function(core.List<core.int>) Function() x12;
+  late List<T> Function(int, [int]) Function() x13;
+  late List<T> Function(int, {List<Function> x}) Function() x14;
+  late Function(int x) Function() x15;
+  late Function(int y, [List<Function> x]) Function() x16;
+  late Function(int, [List<T>]) Function() x17;
+  late void Function({Function x}) Function() x18;
+  late void Function(List<T> x) Function() x19;
+  late Function Function<A>() Function() x20;
+  late List<T> Function<A>(A x) Function() x21;
+  late List<A> Function<A>(List<A> x) Function() x22;
+
+  U84({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+  core.List<core.int> m1([Function x0 = _voidFunction]) => throw 'uncalled';
+  m2(int x0) => throw 'uncalled';
+  void m3(List<T> x0) => throw 'uncalled';
+  int Function([int]) m4() => throw 'uncalled';
+  int Function({List<Function> x}) m5() => throw 'uncalled';
+  int Function() m6() => throw 'uncalled';
+  Function Function(int, [List<Function> x]) m7() => throw 'uncalled';
+  Function Function([List<T>]) m8() => throw 'uncalled';
+  List<Function> Function(int x, [Function]) m9() => throw 'uncalled';
+  List<Function> Function(int y, {core.List<core.int> x}) m10() =>
+      throw 'uncalled';
+  core.List<core.int> Function([Function x]) m11() => throw 'uncalled';
+  core.List<core.int> Function(core.List<core.int>) m12() => throw 'uncalled';
+  List<T> Function(int, [int]) m13() => throw 'uncalled';
+  List<T> Function(int, {List<Function> x}) m14() => throw 'uncalled';
+  Function(int x) m15() => throw 'uncalled';
+  Function(int y, [List<Function> x]) m16() => throw 'uncalled';
+  Function(int, [List<T>]) m17() => throw 'uncalled';
+  void Function({Function x}) m18() => throw 'uncalled';
+  void Function(List<T> x) m19() => throw 'uncalled';
+  Function Function<A>() m20() => throw 'uncalled';
+  List<T> Function<A>(A x) m21() => throw 'uncalled';
+  List<A> Function<A>(List<A> x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, [List<Function>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<Function>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, [List<Function>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function([Function])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([Function]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function([Function]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function(List<T>)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(List<T>) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(List<T>));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function([int]) Function()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function([int]) Function() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function([int]) Function());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function({List<Function> x}) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function({List<Function> x}) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function({List<Function> x}) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function() Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function() Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function() Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, [List<Function> x]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<Function> x]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([List<T>]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<T>]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([List<T>]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int x, [Function]) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [Function]) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int x, [Function]) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, {core.List<core.int> x}) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {core.List<core.int> x}) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, {core.List<core.int> x})
+        Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([Function x]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([Function x]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([Function x]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(core.List<core.int>) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(core.List<core.int>) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(core.List<core.int>) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, [int]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [int]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int, [int]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {List<Function> x}) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {List<Function> x}) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int x) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int x) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function(int x) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(int y, [List<Function> x]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [List<Function> x]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [List<T>]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<T>]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [List<T>]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function({Function x}) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function({Function x}) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function({Function x}) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(List<T> x) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(List<T> x) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(List<T> x) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>() Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>() Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>() Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(A x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(A x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(A x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<A> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<A> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(List<A> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U84().runTests();
+  new U84<int>(tIsInt: true).runTests();
+  new U84<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type85_test.dart b/tests/language/function_type/function_type85_test.dart
new file mode 100644
index 0000000..a56fa37
--- /dev/null
+++ b/tests/language/function_type/function_type85_test.dart
@@ -0,0 +1,901 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int x, [List<Function>]);
+typedef F1<T> = core.List<core.int> Function(int, [Function]);
+typedef F2<T> = Function([int]);
+typedef F3<T> = void Function([List<T>]);
+typedef F4<T> = int Function([int]) Function(int x);
+typedef F5<T> = int Function({List<Function> x}) Function(int x);
+typedef F6<T> = int Function() Function(int x);
+typedef F7<T> = Function Function(int, [List<Function> x]) Function(int x);
+typedef F8<T> = Function Function([List<T>]) Function(int x);
+typedef F9<T> = List<Function> Function(int x, [Function]) Function(int x);
+typedef F10<T> = List<Function> Function(int y, {core.List<core.int> x})
+    Function(int x);
+typedef F11<T> = core.List<core.int> Function([Function x]) Function(int x);
+typedef F12<T> = core.List<core.int> Function(core.List<core.int>) Function(
+    int x);
+typedef F13<T> = List<T> Function(int, [int]) Function(int x);
+typedef F14<T> = List<T> Function(int, {List<Function> x}) Function(int x);
+typedef F15<T> = Function(int x) Function(int x);
+typedef F16<T> = Function(int y, [List<Function> x]) Function(int x);
+typedef F17<T> = Function(int, [List<T>]) Function(int x);
+typedef F18<T> = void Function({Function x}) Function(int x);
+typedef F19<T> = void Function(List<T> x) Function(int x);
+typedef F20<T> = Function Function<A>() Function(int x);
+typedef F21<T> = List<T> Function<A>(A x) Function(int x);
+typedef F22<T> = List<A> Function<A>(List<A> x) Function(int x);
+
+Function f0(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+core.List<core.int> f1(int x0, [Function x1 = _voidFunction]) =>
+    throw 'uncalled';
+f2([int x0 = -1]) => throw 'uncalled';
+void f3([List<int> x0 = const []]) => throw 'uncalled';
+int Function([int]) f4(int x) => throw 'uncalled';
+int Function({List<Function> x}) f5(int x) => throw 'uncalled';
+int Function() f6(int x) => throw 'uncalled';
+Function Function(int, [List<Function> x]) f7(int x) => throw 'uncalled';
+Function Function([List<int>]) f8(int x) => throw 'uncalled';
+List<Function> Function(int x, [Function]) f9(int x) => throw 'uncalled';
+List<Function> Function(int y, {core.List<core.int> x}) f10(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([Function x]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(core.List<core.int>) f12(int x) =>
+    throw 'uncalled';
+List<int> Function(int, [int]) f13(int x) => throw 'uncalled';
+List<int> Function(int, {List<Function> x}) f14(int x) => throw 'uncalled';
+Function(int x) f15(int x) => throw 'uncalled';
+Function(int y, [List<Function> x]) f16(int x) => throw 'uncalled';
+Function(int, [List<int>]) f17(int x) => throw 'uncalled';
+void Function({Function x}) f18(int x) => throw 'uncalled';
+void Function(List<int> x) f19(int x) => throw 'uncalled';
+Function Function<A>() f20(int x) => throw 'uncalled';
+List<int> Function<A>(A x) f21(int x) => throw 'uncalled';
+List<A> Function<A>(List<A> x) f22(int x) => throw 'uncalled';
+
+class U85<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int x, [List<Function>]) x0;
+  late core.List<core.int> Function(int, [Function]) x1;
+  late Function([int]) x2;
+  late void Function([List<T>]) x3;
+  late int Function([int]) Function(int x) x4;
+  late int Function({List<Function> x}) Function(int x) x5;
+  late int Function() Function(int x) x6;
+  late Function Function(int, [List<Function> x]) Function(int x) x7;
+  late Function Function([List<T>]) Function(int x) x8;
+  late List<Function> Function(int x, [Function]) Function(int x) x9;
+  late List<Function> Function(int y, {core.List<core.int> x}) Function(int x)
+      x10;
+  late core.List<core.int> Function([Function x]) Function(int x) x11;
+  late core.List<core.int> Function(core.List<core.int>) Function(int x) x12;
+  late List<T> Function(int, [int]) Function(int x) x13;
+  late List<T> Function(int, {List<Function> x}) Function(int x) x14;
+  late Function(int x) Function(int x) x15;
+  late Function(int y, [List<Function> x]) Function(int x) x16;
+  late Function(int, [List<T>]) Function(int x) x17;
+  late void Function({Function x}) Function(int x) x18;
+  late void Function(List<T> x) Function(int x) x19;
+  late Function Function<A>() Function(int x) x20;
+  late List<T> Function<A>(A x) Function(int x) x21;
+  late List<A> Function<A>(List<A> x) Function(int x) x22;
+
+  U85({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+  core.List<core.int> m1(int x0, [Function x1 = _voidFunction]) =>
+      throw 'uncalled';
+  m2([int x0 = -1]) => throw 'uncalled';
+  void m3([List<T> x0 = const []]) => throw 'uncalled';
+  int Function([int]) m4(int x) => throw 'uncalled';
+  int Function({List<Function> x}) m5(int x) => throw 'uncalled';
+  int Function() m6(int x) => throw 'uncalled';
+  Function Function(int, [List<Function> x]) m7(int x) => throw 'uncalled';
+  Function Function([List<T>]) m8(int x) => throw 'uncalled';
+  List<Function> Function(int x, [Function]) m9(int x) => throw 'uncalled';
+  List<Function> Function(int y, {core.List<core.int> x}) m10(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([Function x]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(core.List<core.int>) m12(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [int]) m13(int x) => throw 'uncalled';
+  List<T> Function(int, {List<Function> x}) m14(int x) => throw 'uncalled';
+  Function(int x) m15(int x) => throw 'uncalled';
+  Function(int y, [List<Function> x]) m16(int x) => throw 'uncalled';
+  Function(int, [List<T>]) m17(int x) => throw 'uncalled';
+  void Function({Function x}) m18(int x) => throw 'uncalled';
+  void Function(List<T> x) m19(int x) => throw 'uncalled';
+  Function Function<A>() m20(int x) => throw 'uncalled';
+  List<T> Function<A>(A x) m21(int x) => throw 'uncalled';
+  List<A> Function<A>(List<A> x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int x, [List<Function>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [List<Function>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int x, [List<Function>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int, [Function])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [Function]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int, [Function]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function([int])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function([int]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function([int]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function([List<T>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function([List<T>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function([List<T>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function([int]) Function(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function([int]) Function(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function([int]) Function(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function({List<Function> x}) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function({List<Function> x}) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function({List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function() Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function() Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function() Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, [List<Function> x]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<Function> x]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(int, [List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([List<T>]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<T>]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function([List<T>]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int x, [Function]) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [Function]) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int x, [Function]) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, {core.List<core.int> x}) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {core.List<core.int> x}) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, {core.List<core.int> x})
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([Function x]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([Function x]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function([Function x]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(core.List<core.int>) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(core.List<core.int>) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(core.List<core.int>)
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, [int]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [int]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int, [int]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {List<Function> x}) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {List<Function> x}) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(int, {List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int x) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int x) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function(int x) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(int y, [List<Function> x]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [List<Function> x]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, [List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [List<T>]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<T>]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function({Function x}) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function({Function x}) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function({Function x}) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(List<T> x) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(List<T> x) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>() Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>() Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>() Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(A x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(A x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(A x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<A> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<A> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(List<A> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U85().runTests();
+  new U85<int>(tIsInt: true).runTests();
+  new U85<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type86_test.dart b/tests/language/function_type/function_type86_test.dart
new file mode 100644
index 0000000..3961f324
--- /dev/null
+++ b/tests/language/function_type/function_type86_test.dart
@@ -0,0 +1,936 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function({List<Function> x});
+typedef F1<T> = core.List<core.int> Function(int x, [Function]);
+typedef F2<T> = Function(int, [int]);
+typedef F3<T> = void Function(int, [List<T>]);
+typedef F4<T> = int Function([int]) Function<B extends core.int>();
+typedef F5<T> = int Function({List<Function> x}) Function<B extends core.int>();
+typedef F6<T> = int Function() Function<B extends core.int>();
+typedef F7<T> = Function Function(int, [List<Function> x])
+    Function<B extends core.int>();
+typedef F8<T> = Function Function([List<T>]) Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int x, [Function])
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function([Function x])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(core.List<core.int>)
+    Function<B extends core.int>();
+typedef F13<T> = List<T> Function(int, [int]) Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int, {List<Function> x})
+    Function<B extends core.int>();
+typedef F15<T> = Function(int x) Function<B extends core.int>();
+typedef F16<T> = Function(int y, [List<Function> x])
+    Function<B extends core.int>();
+typedef F17<T> = Function(int, [List<T>]) Function<B extends core.int>();
+typedef F18<T> = void Function({Function x}) Function<B extends core.int>();
+typedef F19<T> = void Function(List<T> x) Function<B extends core.int>();
+typedef F20<T> = Function Function<A>() Function<B extends core.int>();
+typedef F21<T> = List<T> Function<A>(A x) Function<B extends core.int>();
+typedef F22<T> = List<A> Function<A>(List<A> x) Function<B extends core.int>();
+
+Function f0({List<Function> x = const []}) => throw 'uncalled';
+core.List<core.int> f1(int x, [Function x0 = _voidFunction]) =>
+    throw 'uncalled';
+f2(int x0, [int x1 = -1]) => throw 'uncalled';
+void f3(int x0, [List<int> x1 = const []]) => throw 'uncalled';
+int Function([int]) f4<B extends core.int>() => throw 'uncalled';
+int Function({List<Function> x}) f5<B extends core.int>() => throw 'uncalled';
+int Function() f6<B extends core.int>() => throw 'uncalled';
+Function Function(int, [List<Function> x]) f7<B extends core.int>() =>
+    throw 'uncalled';
+Function Function([List<int>]) f8<B extends core.int>() => throw 'uncalled';
+List<Function> Function(int x, [Function]) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int y, {core.List<core.int> x})
+    f10<B extends core.int>() => throw 'uncalled';
+core.List<core.int> Function([Function x]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(core.List<core.int>) f12<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int, [int]) f13<B extends core.int>() => throw 'uncalled';
+List<int> Function(int, {List<Function> x}) f14<B extends core.int>() =>
+    throw 'uncalled';
+Function(int x) f15<B extends core.int>() => throw 'uncalled';
+Function(int y, [List<Function> x]) f16<B extends core.int>() =>
+    throw 'uncalled';
+Function(int, [List<int>]) f17<B extends core.int>() => throw 'uncalled';
+void Function({Function x}) f18<B extends core.int>() => throw 'uncalled';
+void Function(List<int> x) f19<B extends core.int>() => throw 'uncalled';
+Function Function<A>() f20<B extends core.int>() => throw 'uncalled';
+List<int> Function<A>(A x) f21<B extends core.int>() => throw 'uncalled';
+List<A> Function<A>(List<A> x) f22<B extends core.int>() => throw 'uncalled';
+
+class U86<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function({List<Function> x}) x0;
+  late core.List<core.int> Function(int x, [Function]) x1;
+  late Function(int, [int]) x2;
+  late void Function(int, [List<T>]) x3;
+  late int Function([int]) Function<B extends core.int>() x4;
+  late int Function({List<Function> x}) Function<B extends core.int>() x5;
+  late int Function() Function<B extends core.int>() x6;
+  late Function Function(int, [List<Function> x]) Function<B extends core.int>()
+      x7;
+  late Function Function([List<T>]) Function<B extends core.int>() x8;
+  late List<Function> Function(int x, [Function]) Function<B extends core.int>()
+      x9;
+  late List<Function> Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>() x10;
+  late core.List<core.int> Function([Function x]) Function<B extends core.int>()
+      x11;
+  late core.List<core.int> Function(core.List<core.int>)
+      Function<B extends core.int>() x12;
+  late List<T> Function(int, [int]) Function<B extends core.int>() x13;
+  late List<T> Function(int, {List<Function> x}) Function<B extends core.int>()
+      x14;
+  late Function(int x) Function<B extends core.int>() x15;
+  late Function(int y, [List<Function> x]) Function<B extends core.int>() x16;
+  late Function(int, [List<T>]) Function<B extends core.int>() x17;
+  late void Function({Function x}) Function<B extends core.int>() x18;
+  late void Function(List<T> x) Function<B extends core.int>() x19;
+  late Function Function<A>() Function<B extends core.int>() x20;
+  late List<T> Function<A>(A x) Function<B extends core.int>() x21;
+  late List<A> Function<A>(List<A> x) Function<B extends core.int>() x22;
+
+  U86({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0({List<Function> x = const []}) => throw 'uncalled';
+  core.List<core.int> m1(int x, [Function x0 = _voidFunction]) =>
+      throw 'uncalled';
+  m2(int x0, [int x1 = -1]) => throw 'uncalled';
+  void m3(int x0, [List<T> x1 = const []]) => throw 'uncalled';
+  int Function([int]) m4<B extends core.int>() => throw 'uncalled';
+  int Function({List<Function> x}) m5<B extends core.int>() => throw 'uncalled';
+  int Function() m6<B extends core.int>() => throw 'uncalled';
+  Function Function(int, [List<Function> x]) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function([List<T>]) m8<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(int x, [Function]) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int y, {core.List<core.int> x})
+      m10<B extends core.int>() => throw 'uncalled';
+  core.List<core.int> Function([Function x]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(core.List<core.int>) m12<B extends core.int>() =>
+      throw 'uncalled';
+  List<T> Function(int, [int]) m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int, {List<Function> x}) m14<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int x) m15<B extends core.int>() => throw 'uncalled';
+  Function(int y, [List<Function> x]) m16<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int, [List<T>]) m17<B extends core.int>() => throw 'uncalled';
+  void Function({Function x}) m18<B extends core.int>() => throw 'uncalled';
+  void Function(List<T> x) m19<B extends core.int>() => throw 'uncalled';
+  Function Function<A>() m20<B extends core.int>() => throw 'uncalled';
+  List<T> Function<A>(A x) m21<B extends core.int>() => throw 'uncalled';
+  List<A> Function<A>(List<A> x) m22<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function({List<Function> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function({List<Function> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function({List<Function> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int x, [Function])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [Function]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int x, [Function]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int, [int])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int, [int]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int, [int]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function(int, [List<T>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<T>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, [List<T>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function([int]) Function<B extends core.int>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function([int]) Function<B extends core.int>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function([int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function({List<Function> x}) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function({List<Function> x}) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function({List<Function> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function() Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function() Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function() Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, [List<Function> x]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<Function> x]) Function<B extends core.int>()
+        l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([List<T>]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<T>]) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function([List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int x, [Function]) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [Function]) Function<B extends core.int>()
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int x, [Function])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, {core.List<core.int> x}) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([Function x]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([Function x]) Function<B extends core.int>()
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(core.List<core.int>) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(core.List<core.int>)
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(core.List<core.int>)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, [int]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [int]) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function(int, [int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {List<Function> x}) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {List<Function> x}) Function<B extends core.int>()
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int x) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int x) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(int y, [List<Function> x]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [List<Function> x]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [List<T>]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<T>]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int, [List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function({Function x}) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function({Function x}) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function({Function x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(List<T> x) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(List<T> x) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(List<T> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>() Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>() Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>() Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(A x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(A x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<T> Function<A>(A x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<A> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<A> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is List<A> Function<A>(List<A> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U86().runTests();
+  new U86<int>(tIsInt: true).runTests();
+  new U86<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type87_test.dart b/tests/language/function_type/function_type87_test.dart
new file mode 100644
index 0000000..c0da986
--- /dev/null
+++ b/tests/language/function_type/function_type87_test.dart
@@ -0,0 +1,954 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, {List<Function> x});
+typedef F1<T> = core.List<core.int> Function({Function x});
+typedef F2<T> = Function(int x, [int]);
+typedef F3<T> = void Function(int x, [List<T>]);
+typedef F4<T> = int Function([int]) Function<B extends core.int>(int x);
+typedef F5<T> = int Function({List<Function> x}) Function<B extends core.int>(
+    int x);
+typedef F6<T> = int Function() Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F8<T> = Function Function([List<T>]) Function<B extends core.int>(
+    int x);
+typedef F9<T> = List<Function> Function(int x, [Function])
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(int y, {core.List<core.int> x})
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function([Function x])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(core.List<core.int>)
+    Function<B extends core.int>(int x);
+typedef F13<T> = List<T> Function(int, [int]) Function<B extends core.int>(
+    int x);
+typedef F14<T> = List<T> Function(int, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F15<T> = Function(int x) Function<B extends core.int>(int x);
+typedef F16<T> = Function(int y, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F17<T> = Function(int, [List<T>]) Function<B extends core.int>(int x);
+typedef F18<T> = void Function({Function x}) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function(List<T> x) Function<B extends core.int>(int x);
+typedef F20<T> = Function Function<A>() Function<B extends core.int>(int x);
+typedef F21<T> = List<T> Function<A>(A x) Function<B extends core.int>(int x);
+typedef F22<T> = List<A> Function<A>(List<A> x) Function<B extends core.int>(
+    int x);
+
+Function f0(int x0, {List<Function> x = const []}) => throw 'uncalled';
+core.List<core.int> f1({Function x = _voidFunction}) => throw 'uncalled';
+f2(int x, [int x0 = -1]) => throw 'uncalled';
+void f3(int x, [List<int> x0 = const []]) => throw 'uncalled';
+int Function([int]) f4<B extends core.int>(int x) => throw 'uncalled';
+int Function({List<Function> x}) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+int Function() f6<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int, [List<Function> x]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function([List<int>]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int x, [Function]) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int y, {core.List<core.int> x}) f10<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([Function x]) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(core.List<core.int>) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function(int, [int]) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int, {List<Function> x}) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int x) f15<B extends core.int>(int x) => throw 'uncalled';
+Function(int y, [List<Function> x]) f16<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int, [List<int>]) f17<B extends core.int>(int x) => throw 'uncalled';
+void Function({Function x}) f18<B extends core.int>(int x) => throw 'uncalled';
+void Function(List<int> x) f19<B extends core.int>(int x) => throw 'uncalled';
+Function Function<A>() f20<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function<A>(A x) f21<B extends core.int>(int x) => throw 'uncalled';
+List<A> Function<A>(List<A> x) f22<B extends core.int>(int x) =>
+    throw 'uncalled';
+
+class U87<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, {List<Function> x}) x0;
+  late core.List<core.int> Function({Function x}) x1;
+  late Function(int x, [int]) x2;
+  late void Function(int x, [List<T>]) x3;
+  late int Function([int]) Function<B extends core.int>(int x) x4;
+  late int Function({List<Function> x}) Function<B extends core.int>(int x) x5;
+  late int Function() Function<B extends core.int>(int x) x6;
+  late Function Function(int, [List<Function> x]) Function<B extends core.int>(
+      int x) x7;
+  late Function Function([List<T>]) Function<B extends core.int>(int x) x8;
+  late List<Function> Function(int x, [Function]) Function<B extends core.int>(
+      int x) x9;
+  late List<Function> Function(int y, {core.List<core.int> x})
+      Function<B extends core.int>(int x) x10;
+  late core.List<core.int> Function([Function x]) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function(core.List<core.int>)
+      Function<B extends core.int>(int x) x12;
+  late List<T> Function(int, [int]) Function<B extends core.int>(int x) x13;
+  late List<T> Function(int, {List<Function> x}) Function<B extends core.int>(
+      int x) x14;
+  late Function(int x) Function<B extends core.int>(int x) x15;
+  late Function(int y, [List<Function> x]) Function<B extends core.int>(int x)
+      x16;
+  late Function(int, [List<T>]) Function<B extends core.int>(int x) x17;
+  late void Function({Function x}) Function<B extends core.int>(int x) x18;
+  late void Function(List<T> x) Function<B extends core.int>(int x) x19;
+  late Function Function<A>() Function<B extends core.int>(int x) x20;
+  late List<T> Function<A>(A x) Function<B extends core.int>(int x) x21;
+  late List<A> Function<A>(List<A> x) Function<B extends core.int>(int x) x22;
+
+  U87({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, {List<Function> x = const []}) => throw 'uncalled';
+  core.List<core.int> m1({Function x = _voidFunction}) => throw 'uncalled';
+  m2(int x, [int x0 = -1]) => throw 'uncalled';
+  void m3(int x, [List<T> x0 = const []]) => throw 'uncalled';
+  int Function([int]) m4<B extends core.int>(int x) => throw 'uncalled';
+  int Function({List<Function> x}) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  int Function() m6<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(int, [List<Function> x]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function([List<T>]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int x, [Function]) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, {core.List<core.int> x})
+      m10<B extends core.int>(int x) => throw 'uncalled';
+  core.List<core.int> Function([Function x]) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(core.List<core.int>) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function(int, [int]) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, {List<Function> x}) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int x) m15<B extends core.int>(int x) => throw 'uncalled';
+  Function(int y, [List<Function> x]) m16<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int, [List<T>]) m17<B extends core.int>(int x) => throw 'uncalled';
+  void Function({Function x}) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(List<T> x) m19<B extends core.int>(int x) => throw 'uncalled';
+  Function Function<A>() m20<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function<A>(A x) m21<B extends core.int>(int x) => throw 'uncalled';
+  List<A> Function<A>(List<A> x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, {List<Function> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {List<Function> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, {List<Function> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function({Function x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({Function x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function({Function x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int x, [int])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [int]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int x, [int]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function(int x, [List<T>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int x, [List<T>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int x, [List<T>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function([int]) Function<B extends core.int>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function([int]) Function<B extends core.int>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function([int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function({List<Function> x}) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function({List<Function> x}) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function({List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function() Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function() Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is int Function() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<Function> x]) Function<B extends core.int>(
+        int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function([List<T>]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<T>]) Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function([List<T>]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int x, [Function]) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int x, [Function]) Function<B extends core.int>(
+        int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int x, [Function])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int y, {core.List<core.int> x}) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int y, {core.List<core.int> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// core.List<core.int> Function([Function x]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([Function x]) Function<B extends core.int>(
+        int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function([Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(core.List<core.int>) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(core.List<core.int>)
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(core.List<core.int>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, [int]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, [int]) Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int, [int])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {List<Function> x}) Function<B extends core.int>(
+        int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int x) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int x) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(int y, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [List<Function> x]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int y, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, [List<T>]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<T>]) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int, [List<T>]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function({Function x}) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function({Function x}) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function({Function x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(List<T> x) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(List<T> x) Function<B extends core.int>(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(List<T> x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>() Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>() Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>() Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(A x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(A x) Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<T> Function<A>(A x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// List<A> Function<A>(List<A> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    List<A> Function<A>(List<A> x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is List<A> Function<A>(List<A> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U87().runTests();
+  new U87<int>(tIsInt: true).runTests();
+  new U87<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type88_test.dart b/tests/language/function_type/function_type88_test.dart
new file mode 100644
index 0000000..1544392
--- /dev/null
+++ b/tests/language/function_type/function_type88_test.dart
@@ -0,0 +1,917 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int y, {List<Function> x});
+typedef F1<T> = core.List<core.int> Function(int, {Function x});
+typedef F2<T> = Function({int x});
+typedef F3<T> = void Function({List<T> x});
+typedef F4<T> = int Function(int, [int]) Function();
+typedef F5<T> = int Function(int, {List<Function> x}) Function();
+typedef F6<T> = Function Function(int x) Function();
+typedef F7<T> = Function Function(int y, [List<Function> x]) Function();
+typedef F8<T> = Function Function(int, [List<T>]) Function();
+typedef F9<T> = List<Function> Function({Function x}) Function();
+typedef F10<T> = List<Function> Function(List<T> x) Function();
+typedef F11<T> = core.List<core.int> Function(int, [Function x]) Function();
+typedef F12<T> = core.List<core.int> Function([core.List<core.int>]) Function();
+typedef F13<T> = List<T> Function(int x, [int]) Function();
+typedef F14<T> = List<T> Function(int y, {List<Function> x}) Function();
+typedef F15<T> = Function([int x]) Function();
+typedef F16<T> = Function(List<Function>) Function();
+typedef F17<T> = Function(int x, [List<T>]) Function();
+typedef F18<T> = void Function(int, {Function x}) Function();
+typedef F19<T> = void Function([List<T> x]) Function();
+typedef F20<T> = Function Function<A>(A x) Function();
+typedef F21<T> = List<T> Function<A>(List<A> x) Function();
+typedef F22<T> = void Function<A>(int x) Function();
+
+Function f0(int y, {List<Function> x = const []}) => throw 'uncalled';
+core.List<core.int> f1(int x0, {Function x = _voidFunction}) =>
+    throw 'uncalled';
+f2({int x = -1}) => throw 'uncalled';
+void f3({List<int> x = const []}) => throw 'uncalled';
+int Function(int, [int]) f4() => throw 'uncalled';
+int Function(int, {List<Function> x}) f5() => throw 'uncalled';
+Function Function(int x) f6() => throw 'uncalled';
+Function Function(int y, [List<Function> x]) f7() => throw 'uncalled';
+Function Function(int, [List<int>]) f8() => throw 'uncalled';
+List<Function> Function({Function x}) f9() => throw 'uncalled';
+List<Function> Function(List<int> x) f10() => throw 'uncalled';
+core.List<core.int> Function(int, [Function x]) f11() => throw 'uncalled';
+core.List<core.int> Function([core.List<core.int>]) f12() => throw 'uncalled';
+List<int> Function(int x, [int]) f13() => throw 'uncalled';
+List<int> Function(int y, {List<Function> x}) f14() => throw 'uncalled';
+Function([int x]) f15() => throw 'uncalled';
+Function(List<Function>) f16() => throw 'uncalled';
+Function(int x, [List<int>]) f17() => throw 'uncalled';
+void Function(int, {Function x}) f18() => throw 'uncalled';
+void Function([List<int> x]) f19() => throw 'uncalled';
+Function Function<A>(A x) f20() => throw 'uncalled';
+List<int> Function<A>(List<A> x) f21() => throw 'uncalled';
+void Function<A>(int x) f22() => throw 'uncalled';
+
+class U88<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int y, {List<Function> x}) x0;
+  late core.List<core.int> Function(int, {Function x}) x1;
+  late Function({int x}) x2;
+  late void Function({List<T> x}) x3;
+  late int Function(int, [int]) Function() x4;
+  late int Function(int, {List<Function> x}) Function() x5;
+  late Function Function(int x) Function() x6;
+  late Function Function(int y, [List<Function> x]) Function() x7;
+  late Function Function(int, [List<T>]) Function() x8;
+  late List<Function> Function({Function x}) Function() x9;
+  late List<Function> Function(List<T> x) Function() x10;
+  late core.List<core.int> Function(int, [Function x]) Function() x11;
+  late core.List<core.int> Function([core.List<core.int>]) Function() x12;
+  late List<T> Function(int x, [int]) Function() x13;
+  late List<T> Function(int y, {List<Function> x}) Function() x14;
+  late Function([int x]) Function() x15;
+  late Function(List<Function>) Function() x16;
+  late Function(int x, [List<T>]) Function() x17;
+  late void Function(int, {Function x}) Function() x18;
+  late void Function([List<T> x]) Function() x19;
+  late Function Function<A>(A x) Function() x20;
+  late List<T> Function<A>(List<A> x) Function() x21;
+  late void Function<A>(int x) Function() x22;
+
+  U88({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int y, {List<Function> x = const []}) => throw 'uncalled';
+  core.List<core.int> m1(int x0, {Function x = _voidFunction}) =>
+      throw 'uncalled';
+  m2({int x = -1}) => throw 'uncalled';
+  void m3({List<T> x = const []}) => throw 'uncalled';
+  int Function(int, [int]) m4() => throw 'uncalled';
+  int Function(int, {List<Function> x}) m5() => throw 'uncalled';
+  Function Function(int x) m6() => throw 'uncalled';
+  Function Function(int y, [List<Function> x]) m7() => throw 'uncalled';
+  Function Function(int, [List<T>]) m8() => throw 'uncalled';
+  List<Function> Function({Function x}) m9() => throw 'uncalled';
+  List<Function> Function(List<T> x) m10() => throw 'uncalled';
+  core.List<core.int> Function(int, [Function x]) m11() => throw 'uncalled';
+  core.List<core.int> Function([core.List<core.int>]) m12() => throw 'uncalled';
+  List<T> Function(int x, [int]) m13() => throw 'uncalled';
+  List<T> Function(int y, {List<Function> x}) m14() => throw 'uncalled';
+  Function([int x]) m15() => throw 'uncalled';
+  Function(List<Function>) m16() => throw 'uncalled';
+  Function(int x, [List<T>]) m17() => throw 'uncalled';
+  void Function(int, {Function x}) m18() => throw 'uncalled';
+  void Function([List<T> x]) m19() => throw 'uncalled';
+  Function Function<A>(A x) m20() => throw 'uncalled';
+  List<T> Function<A>(List<A> x) m21() => throw 'uncalled';
+  void Function<A>(int x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int y, {List<Function> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {List<Function> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int y, {List<Function> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int, {Function x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {Function x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int, {Function x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function({int x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function({int x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function({int x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function({List<T> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function({List<T> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function({List<T> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function(int, [int]) Function()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [int]) Function() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int, [int]) Function());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {List<Function> x}) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {List<Function> x}) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function(int x) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is Function Function(int x) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, [List<Function> x]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [List<Function> x]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(int y, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<T>]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<T>]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [List<T>]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function({Function x}) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({Function x}) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function({Function x}) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(List<T> x) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<T> x) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(List<T> x) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, [Function x]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [Function x]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int, [Function x]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([core.List<core.int>]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([core.List<core.int>]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function([core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int x, [int]) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [int]) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int x, [int]) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {List<Function> x}) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {List<Function> x}) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(int y, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function([int x]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function([int x]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function([int x]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(List<Function>) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(List<Function>) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(List<Function>) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [List<T>]) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [List<T>]) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int x, [List<T>]) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, {Function x}) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {Function x}) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, {Function x}) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([List<T> x]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<T> x]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([List<T> x]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>(A x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(A x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(A x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<A> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<A> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(List<A> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// void Function<A>(int x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(int x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is void Function<A>(int x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U88().runTests();
+  new U88<int>(tIsInt: true).runTests();
+  new U88<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type89_test.dart b/tests/language/function_type/function_type89_test.dart
new file mode 100644
index 0000000..a1e892f
--- /dev/null
+++ b/tests/language/function_type/function_type89_test.dart
@@ -0,0 +1,921 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(core.List<core.int> x);
+typedef F1<T> = core.List<core.int> Function(int y, {Function x});
+typedef F2<T> = Function(int, {int x});
+typedef F3<T> = void Function(int, {List<T> x});
+typedef F4<T> = int Function(int, [int]) Function(int x);
+typedef F5<T> = int Function(int, {List<Function> x}) Function(int x);
+typedef F6<T> = Function Function(int x) Function(int x);
+typedef F7<T> = Function Function(int y, [List<Function> x]) Function(int x);
+typedef F8<T> = Function Function(int, [List<T>]) Function(int x);
+typedef F9<T> = List<Function> Function({Function x}) Function(int x);
+typedef F10<T> = List<Function> Function(List<T> x) Function(int x);
+typedef F11<T> = core.List<core.int> Function(int, [Function x]) Function(
+    int x);
+typedef F12<T> = core.List<core.int> Function([core.List<core.int>]) Function(
+    int x);
+typedef F13<T> = List<T> Function(int x, [int]) Function(int x);
+typedef F14<T> = List<T> Function(int y, {List<Function> x}) Function(int x);
+typedef F15<T> = Function([int x]) Function(int x);
+typedef F16<T> = Function(List<Function>) Function(int x);
+typedef F17<T> = Function(int x, [List<T>]) Function(int x);
+typedef F18<T> = void Function(int, {Function x}) Function(int x);
+typedef F19<T> = void Function([List<T> x]) Function(int x);
+typedef F20<T> = Function Function<A>(A x) Function(int x);
+typedef F21<T> = List<T> Function<A>(List<A> x) Function(int x);
+typedef F22<T> = void Function<A>(int x) Function(int x);
+
+Function f0(core.List<core.int> x) => throw 'uncalled';
+core.List<core.int> f1(int y, {Function x = _voidFunction}) => throw 'uncalled';
+f2(int x0, {int x = -1}) => throw 'uncalled';
+void f3(int x0, {List<int> x = const []}) => throw 'uncalled';
+int Function(int, [int]) f4(int x) => throw 'uncalled';
+int Function(int, {List<Function> x}) f5(int x) => throw 'uncalled';
+Function Function(int x) f6(int x) => throw 'uncalled';
+Function Function(int y, [List<Function> x]) f7(int x) => throw 'uncalled';
+Function Function(int, [List<int>]) f8(int x) => throw 'uncalled';
+List<Function> Function({Function x}) f9(int x) => throw 'uncalled';
+List<Function> Function(List<int> x) f10(int x) => throw 'uncalled';
+core.List<core.int> Function(int, [Function x]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function([core.List<core.int>]) f12(int x) =>
+    throw 'uncalled';
+List<int> Function(int x, [int]) f13(int x) => throw 'uncalled';
+List<int> Function(int y, {List<Function> x}) f14(int x) => throw 'uncalled';
+Function([int x]) f15(int x) => throw 'uncalled';
+Function(List<Function>) f16(int x) => throw 'uncalled';
+Function(int x, [List<int>]) f17(int x) => throw 'uncalled';
+void Function(int, {Function x}) f18(int x) => throw 'uncalled';
+void Function([List<int> x]) f19(int x) => throw 'uncalled';
+Function Function<A>(A x) f20(int x) => throw 'uncalled';
+List<int> Function<A>(List<A> x) f21(int x) => throw 'uncalled';
+void Function<A>(int x) f22(int x) => throw 'uncalled';
+
+class U89<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(core.List<core.int> x) x0;
+  late core.List<core.int> Function(int y, {Function x}) x1;
+  late Function(int, {int x}) x2;
+  late void Function(int, {List<T> x}) x3;
+  late int Function(int, [int]) Function(int x) x4;
+  late int Function(int, {List<Function> x}) Function(int x) x5;
+  late Function Function(int x) Function(int x) x6;
+  late Function Function(int y, [List<Function> x]) Function(int x) x7;
+  late Function Function(int, [List<T>]) Function(int x) x8;
+  late List<Function> Function({Function x}) Function(int x) x9;
+  late List<Function> Function(List<T> x) Function(int x) x10;
+  late core.List<core.int> Function(int, [Function x]) Function(int x) x11;
+  late core.List<core.int> Function([core.List<core.int>]) Function(int x) x12;
+  late List<T> Function(int x, [int]) Function(int x) x13;
+  late List<T> Function(int y, {List<Function> x}) Function(int x) x14;
+  late Function([int x]) Function(int x) x15;
+  late Function(List<Function>) Function(int x) x16;
+  late Function(int x, [List<T>]) Function(int x) x17;
+  late void Function(int, {Function x}) Function(int x) x18;
+  late void Function([List<T> x]) Function(int x) x19;
+  late Function Function<A>(A x) Function(int x) x20;
+  late List<T> Function<A>(List<A> x) Function(int x) x21;
+  late void Function<A>(int x) Function(int x) x22;
+
+  U89({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(core.List<core.int> x) => throw 'uncalled';
+  core.List<core.int> m1(int y, {Function x = _voidFunction}) =>
+      throw 'uncalled';
+  m2(int x0, {int x = -1}) => throw 'uncalled';
+  void m3(int x0, {List<T> x = const []}) => throw 'uncalled';
+  int Function(int, [int]) m4(int x) => throw 'uncalled';
+  int Function(int, {List<Function> x}) m5(int x) => throw 'uncalled';
+  Function Function(int x) m6(int x) => throw 'uncalled';
+  Function Function(int y, [List<Function> x]) m7(int x) => throw 'uncalled';
+  Function Function(int, [List<T>]) m8(int x) => throw 'uncalled';
+  List<Function> Function({Function x}) m9(int x) => throw 'uncalled';
+  List<Function> Function(List<T> x) m10(int x) => throw 'uncalled';
+  core.List<core.int> Function(int, [Function x]) m11(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([core.List<core.int>]) m12(int x) =>
+      throw 'uncalled';
+  List<T> Function(int x, [int]) m13(int x) => throw 'uncalled';
+  List<T> Function(int y, {List<Function> x}) m14(int x) => throw 'uncalled';
+  Function([int x]) m15(int x) => throw 'uncalled';
+  Function(List<Function>) m16(int x) => throw 'uncalled';
+  Function(int x, [List<T>]) m17(int x) => throw 'uncalled';
+  void Function(int, {Function x}) m18(int x) => throw 'uncalled';
+  void Function([List<T> x]) m19(int x) => throw 'uncalled';
+  Function Function<A>(A x) m20(int x) => throw 'uncalled';
+  List<T> Function<A>(List<A> x) m21(int x) => throw 'uncalled';
+  void Function<A>(int x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(core.List<core.int> x)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(core.List<core.int> x) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(core.List<core.int> x));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int y, {Function x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {Function x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int y, {Function x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int, {int x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int, {int x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int, {int x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function(int, {List<T> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {List<T> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int, {List<T> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function(int, [int]) Function(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [int]) Function(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int, [int]) Function(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {List<Function> x}) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {List<Function> x}) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, {List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function(int x) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is Function Function(int x) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, [List<Function> x]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [List<Function> x]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(int y, [List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<T>]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<T>]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function({Function x}) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({Function x}) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function({Function x}) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(List<T> x) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<T> x) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, [Function x]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [Function x]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int, [Function x]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([core.List<core.int>]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([core.List<core.int>]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([core.List<core.int>])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int x, [int]) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [int]) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int x, [int]) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {List<Function> x}) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {List<Function> x}) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(int y, {List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function([int x]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function([int x]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function([int x]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(List<Function>) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(List<Function>) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(List<Function>) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [List<T>]) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [List<T>]) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int x, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, {Function x}) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {Function x}) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([List<T> x]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<T> x]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function([List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>(A x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(A x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(A x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<A> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<A> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(List<A> x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// void Function<A>(int x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(int x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is void Function<A>(int x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U89().runTests();
+  new U89<int>(tIsInt: true).runTests();
+  new U89<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type8_test.dart b/tests/language/function_type/function_type8_test.dart
new file mode 100644
index 0000000..d5634fe
--- /dev/null
+++ b/tests/language/function_type/function_type8_test.dart
@@ -0,0 +1,903 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function({int x});
+typedef F1<T> = Function Function({List<T> x});
+typedef F2<T> = core.List<core.int> Function(int x, [core.List<core.int>]);
+typedef F3<T> = Function(int, [List<Function>]);
+typedef F4<T> = List<Function> Function<A>(int x);
+typedef F5<T> = int Function(Function x) Function();
+typedef F6<T> = int Function(int y, [core.List<core.int> x]) Function();
+typedef F7<T> = Function Function([int]) Function();
+typedef F8<T> = Function Function({List<Function> x}) Function();
+typedef F9<T> = Function Function() Function();
+typedef F10<T> = List<Function> Function(int, [List<Function> x]) Function();
+typedef F11<T> = List<Function> Function([List<T>]) Function();
+typedef F12<T> = core.List<core.int> Function(int x, [Function]) Function();
+typedef F13<T> = core.List<core.int> Function(int y, {core.List<core.int> x})
+    Function();
+typedef F14<T> = List<T> Function([Function x]) Function();
+typedef F15<T> = List<T> Function(core.List<core.int>) Function();
+typedef F16<T> = Function(int, [int]) Function();
+typedef F17<T> = Function(int, {List<Function> x}) Function();
+typedef F18<T> = void Function(int x) Function();
+typedef F19<T> = void Function(int y, [List<Function> x]) Function();
+typedef F20<T> = void Function(int, [List<T>]) Function();
+typedef F21<T> = List<Function> Function<A>(core.List<core.int> x) Function();
+typedef F22<T> = Function<A>(List<T> x) Function();
+typedef F23<T> = void Function<A>() Function();
+
+int f0({int x = -1}) => throw 'uncalled';
+Function f1({List<int> x = const []}) => throw 'uncalled';
+core.List<core.int> f2(int x, [core.List<core.int> x0 = const []]) =>
+    throw 'uncalled';
+f3(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+List<Function> f4<A>(int x) => throw 'uncalled';
+int Function(Function x) f5() => throw 'uncalled';
+int Function(int y, [core.List<core.int> x]) f6() => throw 'uncalled';
+Function Function([int]) f7() => throw 'uncalled';
+Function Function({List<Function> x}) f8() => throw 'uncalled';
+Function Function() f9() => throw 'uncalled';
+List<Function> Function(int, [List<Function> x]) f10() => throw 'uncalled';
+List<Function> Function([List<int>]) f11() => throw 'uncalled';
+core.List<core.int> Function(int x, [Function]) f12() => throw 'uncalled';
+core.List<core.int> Function(int y, {core.List<core.int> x}) f13() =>
+    throw 'uncalled';
+List<int> Function([Function x]) f14() => throw 'uncalled';
+List<int> Function(core.List<core.int>) f15() => throw 'uncalled';
+Function(int, [int]) f16() => throw 'uncalled';
+Function(int, {List<Function> x}) f17() => throw 'uncalled';
+void Function(int x) f18() => throw 'uncalled';
+void Function(int y, [List<Function> x]) f19() => throw 'uncalled';
+void Function(int, [List<int>]) f20() => throw 'uncalled';
+List<Function> Function<A>(core.List<core.int> x) f21() => throw 'uncalled';
+Function<A>(List<int> x) f22() => throw 'uncalled';
+void Function<A>() f23() => throw 'uncalled';
+
+class U8<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function({int x}) x0;
+  late Function Function({List<T> x}) x1;
+  late core.List<core.int> Function(int x, [core.List<core.int>]) x2;
+  late Function(int, [List<Function>]) x3;
+  late List<Function> Function<A>(int x) x4;
+  late int Function(Function x) Function() x5;
+  late int Function(int y, [core.List<core.int> x]) Function() x6;
+  late Function Function([int]) Function() x7;
+  late Function Function({List<Function> x}) Function() x8;
+  late Function Function() Function() x9;
+  late List<Function> Function(int, [List<Function> x]) Function() x10;
+  late List<Function> Function([List<T>]) Function() x11;
+  late core.List<core.int> Function(int x, [Function]) Function() x12;
+  late core.List<core.int> Function(int y, {core.List<core.int> x}) Function()
+      x13;
+  late List<T> Function([Function x]) Function() x14;
+  late List<T> Function(core.List<core.int>) Function() x15;
+  late Function(int, [int]) Function() x16;
+  late Function(int, {List<Function> x}) Function() x17;
+  late void Function(int x) Function() x18;
+  late void Function(int y, [List<Function> x]) Function() x19;
+  late void Function(int, [List<T>]) Function() x20;
+  late List<Function> Function<A>(core.List<core.int> x) Function() x21;
+  late Function<A>(List<T> x) Function() x22;
+  late void Function<A>() Function() x23;
+
+  U8({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0({int x = -1}) => throw 'uncalled';
+  Function m1({List<T> x = const []}) => throw 'uncalled';
+  core.List<core.int> m2(int x, [core.List<core.int> x0 = const []]) =>
+      throw 'uncalled';
+  m3(int x0, [List<Function> x1 = const []]) => throw 'uncalled';
+  List<Function> m4<A>(int x) => throw 'uncalled';
+  int Function(Function x) m5() => throw 'uncalled';
+  int Function(int y, [core.List<core.int> x]) m6() => throw 'uncalled';
+  Function Function([int]) m7() => throw 'uncalled';
+  Function Function({List<Function> x}) m8() => throw 'uncalled';
+  Function Function() m9() => throw 'uncalled';
+  List<Function> Function(int, [List<Function> x]) m10() => throw 'uncalled';
+  List<Function> Function([List<T>]) m11() => throw 'uncalled';
+  core.List<core.int> Function(int x, [Function]) m12() => throw 'uncalled';
+  core.List<core.int> Function(int y, {core.List<core.int> x}) m13() =>
+      throw 'uncalled';
+  List<T> Function([Function x]) m14() => throw 'uncalled';
+  List<T> Function(core.List<core.int>) m15() => throw 'uncalled';
+  Function(int, [int]) m16() => throw 'uncalled';
+  Function(int, {List<Function> x}) m17() => throw 'uncalled';
+  void Function(int x) m18() => throw 'uncalled';
+  void Function(int y, [List<Function> x]) m19() => throw 'uncalled';
+  void Function(int, [List<T>]) m20() => throw 'uncalled';
+  List<Function> Function<A>(core.List<core.int> x) m21() => throw 'uncalled';
+  Function<A>(List<T> x) m22() => throw 'uncalled';
+  void Function<A>() m23() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function({int x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function({int x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function({int x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function({List<T> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function({List<T> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function({List<T> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int x, [core.List<core.int>])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [core.List<core.int>]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(
+        m2 is core.List<core.int> Function(int x, [core.List<core.int>]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function(int, [List<Function>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<Function>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int, [List<Function>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<Function> Function<A>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<Function> Function<A>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(Function x) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(Function x) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(Function x) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, [core.List<core.int> x]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [core.List<core.int> x]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int y, [core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([int]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([int]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([int]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({List<Function> x}) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({List<Function> x}) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function({List<Function> x}) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function() Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function() Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function() Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<Function> x]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<Function> x]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(int, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function([List<T>]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<T>]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function([List<T>]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int x, [Function]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [Function]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(int x, [Function]) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, {core.List<core.int> x}) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {core.List<core.int> x}) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int y,
+            {core.List<core.int> x})
+        Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function([Function x]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([Function x]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([Function x]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(core.List<core.int>) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(core.List<core.int>) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(core.List<core.int>) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [int]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [int]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [int]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {List<Function> x}) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {List<Function> x}) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int x) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int x) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [List<Function> x]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [List<Function> x]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, [List<Function> x]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int, [List<T>]) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<T>]) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int, [List<T>]) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(core.List<core.int> x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(core.List<core.int> x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<Function> Function<A>(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<T> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<T> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(List<T> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+
+  /// void Function<A>() Function()
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>() Function() l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>() Function());
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U8().runTests();
+  new U8<int>(tIsInt: true).runTests();
+  new U8<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type90_test.dart b/tests/language/function_type/function_type90_test.dart
new file mode 100644
index 0000000..728530c
--- /dev/null
+++ b/tests/language/function_type/function_type90_test.dart
@@ -0,0 +1,963 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function([core.List<core.int> x]);
+typedef F1<T> = core.List<core.int> Function(List<Function> x);
+typedef F2<T> = Function(int y, {int x});
+typedef F3<T> = void Function(int y, {List<T> x});
+typedef F4<T> = int Function(int, [int]) Function<B extends core.int>();
+typedef F5<T> = int Function(int, {List<Function> x})
+    Function<B extends core.int>();
+typedef F6<T> = Function Function(int x) Function<B extends core.int>();
+typedef F7<T> = Function Function(int y, [List<Function> x])
+    Function<B extends core.int>();
+typedef F8<T> = Function Function(int, [List<T>])
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function({Function x})
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(List<T> x)
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(int, [Function x])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function([core.List<core.int>])
+    Function<B extends core.int>();
+typedef F13<T> = List<T> Function(int x, [int]) Function<B extends core.int>();
+typedef F14<T> = List<T> Function(int y, {List<Function> x})
+    Function<B extends core.int>();
+typedef F15<T> = Function([int x]) Function<B extends core.int>();
+typedef F16<T> = Function(List<Function>) Function<B extends core.int>();
+typedef F17<T> = Function(int x, [List<T>]) Function<B extends core.int>();
+typedef F18<T> = void Function(int, {Function x})
+    Function<B extends core.int>();
+typedef F19<T> = void Function([List<T> x]) Function<B extends core.int>();
+typedef F20<T> = Function Function<A>(A x) Function<B extends core.int>();
+typedef F21<T> = List<T> Function<A>(List<A> x) Function<B extends core.int>();
+typedef F22<T> = void Function<A>(int x) Function<B extends core.int>();
+
+Function f0([core.List<core.int> x = const []]) => throw 'uncalled';
+core.List<core.int> f1(List<Function> x) => throw 'uncalled';
+f2(int y, {int x = -1}) => throw 'uncalled';
+void f3(int y, {List<int> x = const []}) => throw 'uncalled';
+int Function(int, [int]) f4<B extends core.int>() => throw 'uncalled';
+int Function(int, {List<Function> x}) f5<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int x) f6<B extends core.int>() => throw 'uncalled';
+Function Function(int y, [List<Function> x]) f7<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int, [List<int>]) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function({Function x}) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(List<int> x) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [Function x]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function([core.List<core.int>]) f12<B extends core.int>() =>
+    throw 'uncalled';
+List<int> Function(int x, [int]) f13<B extends core.int>() => throw 'uncalled';
+List<int> Function(int y, {List<Function> x}) f14<B extends core.int>() =>
+    throw 'uncalled';
+Function([int x]) f15<B extends core.int>() => throw 'uncalled';
+Function(List<Function>) f16<B extends core.int>() => throw 'uncalled';
+Function(int x, [List<int>]) f17<B extends core.int>() => throw 'uncalled';
+void Function(int, {Function x}) f18<B extends core.int>() => throw 'uncalled';
+void Function([List<int> x]) f19<B extends core.int>() => throw 'uncalled';
+Function Function<A>(A x) f20<B extends core.int>() => throw 'uncalled';
+List<int> Function<A>(List<A> x) f21<B extends core.int>() => throw 'uncalled';
+void Function<A>(int x) f22<B extends core.int>() => throw 'uncalled';
+
+class U90<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function([core.List<core.int> x]) x0;
+  late core.List<core.int> Function(List<Function> x) x1;
+  late Function(int y, {int x}) x2;
+  late void Function(int y, {List<T> x}) x3;
+  late int Function(int, [int]) Function<B extends core.int>() x4;
+  late int Function(int, {List<Function> x}) Function<B extends core.int>() x5;
+  late Function Function(int x) Function<B extends core.int>() x6;
+  late Function Function(int y, [List<Function> x])
+      Function<B extends core.int>() x7;
+  late Function Function(int, [List<T>]) Function<B extends core.int>() x8;
+  late List<Function> Function({Function x}) Function<B extends core.int>() x9;
+  late List<Function> Function(List<T> x) Function<B extends core.int>() x10;
+  late core.List<core.int> Function(int, [Function x])
+      Function<B extends core.int>() x11;
+  late core.List<core.int> Function([core.List<core.int>])
+      Function<B extends core.int>() x12;
+  late List<T> Function(int x, [int]) Function<B extends core.int>() x13;
+  late List<T> Function(int y, {List<Function> x})
+      Function<B extends core.int>() x14;
+  late Function([int x]) Function<B extends core.int>() x15;
+  late Function(List<Function>) Function<B extends core.int>() x16;
+  late Function(int x, [List<T>]) Function<B extends core.int>() x17;
+  late void Function(int, {Function x}) Function<B extends core.int>() x18;
+  late void Function([List<T> x]) Function<B extends core.int>() x19;
+  late Function Function<A>(A x) Function<B extends core.int>() x20;
+  late List<T> Function<A>(List<A> x) Function<B extends core.int>() x21;
+  late void Function<A>(int x) Function<B extends core.int>() x22;
+
+  U90({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0([core.List<core.int> x = const []]) => throw 'uncalled';
+  core.List<core.int> m1(List<Function> x) => throw 'uncalled';
+  m2(int y, {int x = -1}) => throw 'uncalled';
+  void m3(int y, {List<T> x = const []}) => throw 'uncalled';
+  int Function(int, [int]) m4<B extends core.int>() => throw 'uncalled';
+  int Function(int, {List<Function> x}) m5<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int x) m6<B extends core.int>() => throw 'uncalled';
+  Function Function(int y, [List<Function> x]) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int, [List<T>]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function({Function x}) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(List<T> x) m10<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [Function x]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function([core.List<core.int>])
+      m12<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int x, [int]) m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int y, {List<Function> x}) m14<B extends core.int>() =>
+      throw 'uncalled';
+  Function([int x]) m15<B extends core.int>() => throw 'uncalled';
+  Function(List<Function>) m16<B extends core.int>() => throw 'uncalled';
+  Function(int x, [List<T>]) m17<B extends core.int>() => throw 'uncalled';
+  void Function(int, {Function x}) m18<B extends core.int>() =>
+      throw 'uncalled';
+  void Function([List<T> x]) m19<B extends core.int>() => throw 'uncalled';
+  Function Function<A>(A x) m20<B extends core.int>() => throw 'uncalled';
+  List<T> Function<A>(List<A> x) m21<B extends core.int>() => throw 'uncalled';
+  void Function<A>(int x) m22<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function([core.List<core.int> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function([core.List<core.int> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function([core.List<core.int> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(List<Function> x)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<Function> x) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(List<Function> x));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int y, {int x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int y, {int x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int y, {int x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function(int y, {List<T> x})
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {List<T> x}) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function(int y, {List<T> x}));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function(int, [int]) Function<B extends core.int>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [int]) Function<B extends core.int>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function(int, [int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {List<Function> x}) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {List<Function> x}) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function(int x) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is Function Function(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, [List<Function> x]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [List<Function> x]) Function<B extends core.int>()
+        l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, [List<Function> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<T>]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<T>]) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function(int, [List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function({Function x}) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({Function x}) Function<B extends core.int>() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function({Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(List<T> x) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<T> x) Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(List<T> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, [Function x]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [Function x])
+        Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, [Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([core.List<core.int>]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([core.List<core.int>])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int x, [int]) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [int]) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function(int x, [int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {List<Function> x}) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {List<Function> x}) Function<B extends core.int>()
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function([int x]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function([int x]) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function([int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(List<Function>) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(List<Function>) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(List<Function>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [List<T>]) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [List<T>]) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int x, [List<T>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, {Function x}) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {Function x}) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(int, {Function x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([List<T> x]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<T> x]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function([List<T> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>(A x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(A x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>(A x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<A> x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<A> x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is List<T> Function<A>(List<A> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// void Function<A>(int x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(int x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is void Function<A>(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U90().runTests();
+  new U90<int>(tIsInt: true).runTests();
+  new U90<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type91_test.dart b/tests/language/function_type/function_type91_test.dart
new file mode 100644
index 0000000..102e3de
--- /dev/null
+++ b/tests/language/function_type/function_type91_test.dart
@@ -0,0 +1,954 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, [core.List<core.int> x]);
+typedef F1<T> = core.List<core.int> Function([List<Function> x]);
+typedef F2<T> = Function(Function x);
+typedef F3<T> = void Function();
+typedef F4<T> = int Function(int, [int]) Function<B extends core.int>(int x);
+typedef F5<T> = int Function(int, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F6<T> = Function Function(int x) Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(int y, [List<Function> x])
+    Function<B extends core.int>(int x);
+typedef F8<T> = Function Function(int, [List<T>]) Function<B extends core.int>(
+    int x);
+typedef F9<T> = List<Function> Function({Function x})
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(List<T> x)
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(int, [Function x])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function([core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F13<T> = List<T> Function(int x, [int]) Function<B extends core.int>(
+    int x);
+typedef F14<T> = List<T> Function(int y, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F15<T> = Function([int x]) Function<B extends core.int>(int x);
+typedef F16<T> = Function(List<Function>) Function<B extends core.int>(int x);
+typedef F17<T> = Function(int x, [List<T>]) Function<B extends core.int>(int x);
+typedef F18<T> = void Function(int, {Function x}) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function([List<T> x]) Function<B extends core.int>(int x);
+typedef F20<T> = Function Function<A>(A x) Function<B extends core.int>(int x);
+typedef F21<T> = List<T> Function<A>(List<A> x) Function<B extends core.int>(
+    int x);
+typedef F22<T> = void Function<A>(int x) Function<B extends core.int>(int x);
+
+Function f0(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
+core.List<core.int> f1([List<Function> x = const []]) => throw 'uncalled';
+f2(Function x) => throw 'uncalled';
+void f3() => throw 'uncalled';
+int Function(int, [int]) f4<B extends core.int>(int x) => throw 'uncalled';
+int Function(int, {List<Function> x}) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int x) f6<B extends core.int>(int x) => throw 'uncalled';
+Function Function(int y, [List<Function> x]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, [List<int>]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function({Function x}) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(List<int> x) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [Function x]) f11<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function([core.List<core.int>]) f12<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+List<int> Function(int x, [int]) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function(int y, {List<Function> x}) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function([int x]) f15<B extends core.int>(int x) => throw 'uncalled';
+Function(List<Function>) f16<B extends core.int>(int x) => throw 'uncalled';
+Function(int x, [List<int>]) f17<B extends core.int>(int x) => throw 'uncalled';
+void Function(int, {Function x}) f18<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function([List<int> x]) f19<B extends core.int>(int x) => throw 'uncalled';
+Function Function<A>(A x) f20<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function<A>(List<A> x) f21<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function<A>(int x) f22<B extends core.int>(int x) => throw 'uncalled';
+
+class U91<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, [core.List<core.int> x]) x0;
+  late core.List<core.int> Function([List<Function> x]) x1;
+  late Function(Function x) x2;
+  late void Function() x3;
+  late int Function(int, [int]) Function<B extends core.int>(int x) x4;
+  late int Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+      x5;
+  late Function Function(int x) Function<B extends core.int>(int x) x6;
+  late Function Function(int y, [List<Function> x])
+      Function<B extends core.int>(int x) x7;
+  late Function Function(int, [List<T>]) Function<B extends core.int>(int x) x8;
+  late List<Function> Function({Function x}) Function<B extends core.int>(int x)
+      x9;
+  late List<Function> Function(List<T> x) Function<B extends core.int>(int x)
+      x10;
+  late core.List<core.int> Function(int, [Function x])
+      Function<B extends core.int>(int x) x11;
+  late core.List<core.int> Function([core.List<core.int>])
+      Function<B extends core.int>(int x) x12;
+  late List<T> Function(int x, [int]) Function<B extends core.int>(int x) x13;
+  late List<T> Function(int y, {List<Function> x}) Function<B extends core.int>(
+      int x) x14;
+  late Function([int x]) Function<B extends core.int>(int x) x15;
+  late Function(List<Function>) Function<B extends core.int>(int x) x16;
+  late Function(int x, [List<T>]) Function<B extends core.int>(int x) x17;
+  late void Function(int, {Function x}) Function<B extends core.int>(int x) x18;
+  late void Function([List<T> x]) Function<B extends core.int>(int x) x19;
+  late Function Function<A>(A x) Function<B extends core.int>(int x) x20;
+  late List<T> Function<A>(List<A> x) Function<B extends core.int>(int x) x21;
+  late void Function<A>(int x) Function<B extends core.int>(int x) x22;
+
+  U91({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, [core.List<core.int> x = const []]) => throw 'uncalled';
+  core.List<core.int> m1([List<Function> x = const []]) => throw 'uncalled';
+  m2(Function x) => throw 'uncalled';
+  void m3() => throw 'uncalled';
+  int Function(int, [int]) m4<B extends core.int>(int x) => throw 'uncalled';
+  int Function(int, {List<Function> x}) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int x) m6<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(int y, [List<Function> x]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, [List<T>]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function({Function x}) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(List<T> x) m10<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [Function x]) m11<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function([core.List<core.int>]) m12<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  List<T> Function(int x, [int]) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function(int y, {List<Function> x}) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function([int x]) m15<B extends core.int>(int x) => throw 'uncalled';
+  Function(List<Function>) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function(int x, [List<T>]) m17<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int, {Function x}) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function([List<T> x]) m19<B extends core.int>(int x) => throw 'uncalled';
+  Function Function<A>(A x) m20<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function<A>(List<A> x) m21<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function<A>(int x) m22<B extends core.int>(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, [core.List<core.int> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [core.List<core.int> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function([List<Function> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<Function> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function([List<Function> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(Function x)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(Function x) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(Function x));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// void Function()
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    void Function() l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is void Function());
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int, [int]) Function<B extends core.int>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int, [int]) Function<B extends core.int>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function(int, [int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {List<Function> x}) Function<B extends core.int>(int x)
+        l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function(int x) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is Function Function(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(int y, [List<Function> x]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [List<Function> x]) Function<B extends core.int>(
+        int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(int y, [List<Function> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int, [List<T>]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [List<T>]) Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function({Function x}) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function({Function x}) Function<B extends core.int>(int x)
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function({Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(List<T> x) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(List<T> x) Function<B extends core.int>(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(List<T> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int, [Function x]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [Function x])
+        Function<B extends core.int>(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function([core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([core.List<core.int>])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function([core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int x, [int]) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int x, [int]) Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int x, [int])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(int y, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int y, {List<Function> x}) Function<B extends core.int>(
+        int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(int y, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function([int x]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function([int x]) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function([int x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(List<Function>) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(List<Function>) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(List<Function>) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int x, [List<T>]) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [List<T>]) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int x, [List<T>]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int, {Function x}) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int, {Function x}) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function([List<T> x]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function([List<T> x]) Function<B extends core.int>(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function([List<T> x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>(A x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(A x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>(A x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// List<T> Function<A>(List<A> x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<T> Function<A>(List<A> x) Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<T> Function<A>(List<A> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+    // The static function has its T always set to int.
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isFalse(f21 is F21<bool>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    Expect.isFalse(confuse(f21) is F21<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        x21 = confuse(f21);
+      });
+      Expect.throws(() {
+        l21 = (f21 as dynamic);
+      });
+      Expect.throws(() {
+        l21 = confuse(f21);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m21 is F21<int>);
+      Expect.equals(tIsBool, m21 is F21<bool>);
+      Expect.equals(tIsInt, confuse(m21) is F21<int>);
+      Expect.equals(tIsBool, confuse(m21) is F21<bool>);
+    }
+  }
+
+  /// void Function<A>(int x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(int x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is void Function<A>(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U91().runTests();
+  new U91<int>(tIsInt: true).runTests();
+  new U91<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type92_test.dart b/tests/language/function_type/function_type92_test.dart
new file mode 100644
index 0000000..053e0f8
--- /dev/null
+++ b/tests/language/function_type/function_type92_test.dart
@@ -0,0 +1,868 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int y, [core.List<core.int> x]);
+typedef F1<T> = core.List<core.int> Function(int, [List<Function> x]);
+typedef F2<T> = Function([Function x]);
+typedef F3<T> = int Function<A>(int x);
+typedef F4<T> = int Function(int x, [int]) Function();
+typedef F5<T> = int Function(int y, {List<Function> x}) Function();
+typedef F6<T> = Function Function([int x]) Function();
+typedef F7<T> = Function Function(List<Function>) Function();
+typedef F8<T> = Function Function(int x, [List<T>]) Function();
+typedef F9<T> = List<Function> Function(int, {Function x}) Function();
+typedef F10<T> = List<Function> Function([List<T> x]) Function();
+typedef F11<T> = core.List<core.int> Function(int y, [Function x]) Function();
+typedef F12<T> = core.List<core.int> Function(int, [core.List<core.int>])
+    Function();
+typedef F13<T> = List<T> Function({int x}) Function();
+typedef F14<T> = List<T> Function(core.List<core.int> x) Function();
+typedef F15<T> = Function(int, [int x]) Function();
+typedef F16<T> = Function([List<Function>]) Function();
+typedef F17<T> = Function({List<T> x}) Function();
+typedef F18<T> = void Function(int y, {Function x}) Function();
+typedef F19<T> = void Function(int, [List<T> x]) Function();
+typedef F20<T> = Function Function<A>(List<A> x) Function();
+typedef F21<T> = Function<A>(int x) Function();
+typedef F22<T> = void Function<A>(Function x) Function();
+
+Function f0(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
+core.List<core.int> f1(int x0, [List<Function> x = const []]) =>
+    throw 'uncalled';
+f2([Function x = _voidFunction]) => throw 'uncalled';
+int f3<A>(int x) => throw 'uncalled';
+int Function(int x, [int]) f4() => throw 'uncalled';
+int Function(int y, {List<Function> x}) f5() => throw 'uncalled';
+Function Function([int x]) f6() => throw 'uncalled';
+Function Function(List<Function>) f7() => throw 'uncalled';
+Function Function(int x, [List<int>]) f8() => throw 'uncalled';
+List<Function> Function(int, {Function x}) f9() => throw 'uncalled';
+List<Function> Function([List<int> x]) f10() => throw 'uncalled';
+core.List<core.int> Function(int y, [Function x]) f11() => throw 'uncalled';
+core.List<core.int> Function(int, [core.List<core.int>]) f12() =>
+    throw 'uncalled';
+List<int> Function({int x}) f13() => throw 'uncalled';
+List<int> Function(core.List<core.int> x) f14() => throw 'uncalled';
+Function(int, [int x]) f15() => throw 'uncalled';
+Function([List<Function>]) f16() => throw 'uncalled';
+Function({List<int> x}) f17() => throw 'uncalled';
+void Function(int y, {Function x}) f18() => throw 'uncalled';
+void Function(int, [List<int> x]) f19() => throw 'uncalled';
+Function Function<A>(List<A> x) f20() => throw 'uncalled';
+Function<A>(int x) f21() => throw 'uncalled';
+void Function<A>(Function x) f22() => throw 'uncalled';
+
+class U92<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int y, [core.List<core.int> x]) x0;
+  late core.List<core.int> Function(int, [List<Function> x]) x1;
+  late Function([Function x]) x2;
+  late int Function<A>(int x) x3;
+  late int Function(int x, [int]) Function() x4;
+  late int Function(int y, {List<Function> x}) Function() x5;
+  late Function Function([int x]) Function() x6;
+  late Function Function(List<Function>) Function() x7;
+  late Function Function(int x, [List<T>]) Function() x8;
+  late List<Function> Function(int, {Function x}) Function() x9;
+  late List<Function> Function([List<T> x]) Function() x10;
+  late core.List<core.int> Function(int y, [Function x]) Function() x11;
+  late core.List<core.int> Function(int, [core.List<core.int>]) Function() x12;
+  late List<T> Function({int x}) Function() x13;
+  late List<T> Function(core.List<core.int> x) Function() x14;
+  late Function(int, [int x]) Function() x15;
+  late Function([List<Function>]) Function() x16;
+  late Function({List<T> x}) Function() x17;
+  late void Function(int y, {Function x}) Function() x18;
+  late void Function(int, [List<T> x]) Function() x19;
+  late Function Function<A>(List<A> x) Function() x20;
+  late Function<A>(int x) Function() x21;
+  late void Function<A>(Function x) Function() x22;
+
+  U92({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int y, [core.List<core.int> x = const []]) => throw 'uncalled';
+  core.List<core.int> m1(int x0, [List<Function> x = const []]) =>
+      throw 'uncalled';
+  m2([Function x = _voidFunction]) => throw 'uncalled';
+  int m3<A>(int x) => throw 'uncalled';
+  int Function(int x, [int]) m4() => throw 'uncalled';
+  int Function(int y, {List<Function> x}) m5() => throw 'uncalled';
+  Function Function([int x]) m6() => throw 'uncalled';
+  Function Function(List<Function>) m7() => throw 'uncalled';
+  Function Function(int x, [List<T>]) m8() => throw 'uncalled';
+  List<Function> Function(int, {Function x}) m9() => throw 'uncalled';
+  List<Function> Function([List<T> x]) m10() => throw 'uncalled';
+  core.List<core.int> Function(int y, [Function x]) m11() => throw 'uncalled';
+  core.List<core.int> Function(int, [core.List<core.int>]) m12() =>
+      throw 'uncalled';
+  List<T> Function({int x}) m13() => throw 'uncalled';
+  List<T> Function(core.List<core.int> x) m14() => throw 'uncalled';
+  Function(int, [int x]) m15() => throw 'uncalled';
+  Function([List<Function>]) m16() => throw 'uncalled';
+  Function({List<T> x}) m17() => throw 'uncalled';
+  void Function(int y, {Function x}) m18() => throw 'uncalled';
+  void Function(int, [List<T> x]) m19() => throw 'uncalled';
+  Function Function<A>(List<A> x) m20() => throw 'uncalled';
+  Function<A>(int x) m21() => throw 'uncalled';
+  void Function<A>(Function x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int y, [core.List<core.int> x])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, [core.List<core.int> x]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int y, [core.List<core.int> x]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int, [List<Function> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<Function> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int, [List<Function> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function([Function x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function([Function x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function([Function x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// int Function<A>(int x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(int x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is int Function<A>(int x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int x, [int]) Function()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [int]) Function() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int x, [int]) Function());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {List<Function> x}) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {List<Function> x}) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, {List<Function> x}) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function([int x]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function([int x]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is Function Function([int x]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(List<Function>) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<Function>) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(List<Function>) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [List<T>]) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [List<T>]) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int x, [List<T>]) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, {Function x}) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {Function x}) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, {Function x}) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([List<T> x]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<T> x]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([List<T> x]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int y, [Function x]) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [Function x]) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(int y, [Function x]) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [core.List<core.int>]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [core.List<core.int>]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12
+        is core.List<core.int> Function(int, [core.List<core.int>]) Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function({int x}) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({int x}) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function({int x}) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(core.List<core.int> x) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(core.List<core.int> x) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int, [int x]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int, [int x]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function(int, [int x]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function([List<Function>]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([List<Function>]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([List<Function>]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({List<T> x}) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({List<T> x}) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function({List<T> x}) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int y, {Function x}) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {Function x}) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, {Function x}) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<T> x]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<T> x]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [List<T> x]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>(List<A> x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<A> x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(List<A> x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// Function<A>(int x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    Function<A>(int x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is Function<A>(int x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// void Function<A>(Function x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(Function x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is void Function<A>(Function x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U92().runTests();
+  new U92<int>(tIsInt: true).runTests();
+  new U92<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type93_test.dart b/tests/language/function_type/function_type93_test.dart
new file mode 100644
index 0000000..e87c2ba
--- /dev/null
+++ b/tests/language/function_type/function_type93_test.dart
@@ -0,0 +1,878 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(core.List<core.int>);
+typedef F1<T> = core.List<core.int> Function(int y, [List<Function> x]);
+typedef F2<T> = Function(int, [Function x]);
+typedef F3<T> = int Function<A>(Function x);
+typedef F4<T> = int Function(int x, [int]) Function(int x);
+typedef F5<T> = int Function(int y, {List<Function> x}) Function(int x);
+typedef F6<T> = Function Function([int x]) Function(int x);
+typedef F7<T> = Function Function(List<Function>) Function(int x);
+typedef F8<T> = Function Function(int x, [List<T>]) Function(int x);
+typedef F9<T> = List<Function> Function(int, {Function x}) Function(int x);
+typedef F10<T> = List<Function> Function([List<T> x]) Function(int x);
+typedef F11<T> = core.List<core.int> Function(int y, [Function x]) Function(
+    int x);
+typedef F12<T> = core.List<core.int> Function(int, [core.List<core.int>])
+    Function(int x);
+typedef F13<T> = List<T> Function({int x}) Function(int x);
+typedef F14<T> = List<T> Function(core.List<core.int> x) Function(int x);
+typedef F15<T> = Function(int, [int x]) Function(int x);
+typedef F16<T> = Function([List<Function>]) Function(int x);
+typedef F17<T> = Function({List<T> x}) Function(int x);
+typedef F18<T> = void Function(int y, {Function x}) Function(int x);
+typedef F19<T> = void Function(int, [List<T> x]) Function(int x);
+typedef F20<T> = Function Function<A>(List<A> x) Function(int x);
+typedef F21<T> = Function<A>(int x) Function(int x);
+typedef F22<T> = void Function<A>(Function x) Function(int x);
+
+Function f0(core.List<core.int> x0) => throw 'uncalled';
+core.List<core.int> f1(int y, [List<Function> x = const []]) =>
+    throw 'uncalled';
+f2(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+int f3<A>(Function x) => throw 'uncalled';
+int Function(int x, [int]) f4(int x) => throw 'uncalled';
+int Function(int y, {List<Function> x}) f5(int x) => throw 'uncalled';
+Function Function([int x]) f6(int x) => throw 'uncalled';
+Function Function(List<Function>) f7(int x) => throw 'uncalled';
+Function Function(int x, [List<int>]) f8(int x) => throw 'uncalled';
+List<Function> Function(int, {Function x}) f9(int x) => throw 'uncalled';
+List<Function> Function([List<int> x]) f10(int x) => throw 'uncalled';
+core.List<core.int> Function(int y, [Function x]) f11(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [core.List<core.int>]) f12(int x) =>
+    throw 'uncalled';
+List<int> Function({int x}) f13(int x) => throw 'uncalled';
+List<int> Function(core.List<core.int> x) f14(int x) => throw 'uncalled';
+Function(int, [int x]) f15(int x) => throw 'uncalled';
+Function([List<Function>]) f16(int x) => throw 'uncalled';
+Function({List<int> x}) f17(int x) => throw 'uncalled';
+void Function(int y, {Function x}) f18(int x) => throw 'uncalled';
+void Function(int, [List<int> x]) f19(int x) => throw 'uncalled';
+Function Function<A>(List<A> x) f20(int x) => throw 'uncalled';
+Function<A>(int x) f21(int x) => throw 'uncalled';
+void Function<A>(Function x) f22(int x) => throw 'uncalled';
+
+class U93<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(core.List<core.int>) x0;
+  late core.List<core.int> Function(int y, [List<Function> x]) x1;
+  late Function(int, [Function x]) x2;
+  late int Function<A>(Function x) x3;
+  late int Function(int x, [int]) Function(int x) x4;
+  late int Function(int y, {List<Function> x}) Function(int x) x5;
+  late Function Function([int x]) Function(int x) x6;
+  late Function Function(List<Function>) Function(int x) x7;
+  late Function Function(int x, [List<T>]) Function(int x) x8;
+  late List<Function> Function(int, {Function x}) Function(int x) x9;
+  late List<Function> Function([List<T> x]) Function(int x) x10;
+  late core.List<core.int> Function(int y, [Function x]) Function(int x) x11;
+  late core.List<core.int> Function(int, [core.List<core.int>]) Function(int x)
+      x12;
+  late List<T> Function({int x}) Function(int x) x13;
+  late List<T> Function(core.List<core.int> x) Function(int x) x14;
+  late Function(int, [int x]) Function(int x) x15;
+  late Function([List<Function>]) Function(int x) x16;
+  late Function({List<T> x}) Function(int x) x17;
+  late void Function(int y, {Function x}) Function(int x) x18;
+  late void Function(int, [List<T> x]) Function(int x) x19;
+  late Function Function<A>(List<A> x) Function(int x) x20;
+  late Function<A>(int x) Function(int x) x21;
+  late void Function<A>(Function x) Function(int x) x22;
+
+  U93({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(core.List<core.int> x0) => throw 'uncalled';
+  core.List<core.int> m1(int y, [List<Function> x = const []]) =>
+      throw 'uncalled';
+  m2(int x0, [Function x = _voidFunction]) => throw 'uncalled';
+  int m3<A>(Function x) => throw 'uncalled';
+  int Function(int x, [int]) m4(int x) => throw 'uncalled';
+  int Function(int y, {List<Function> x}) m5(int x) => throw 'uncalled';
+  Function Function([int x]) m6(int x) => throw 'uncalled';
+  Function Function(List<Function>) m7(int x) => throw 'uncalled';
+  Function Function(int x, [List<T>]) m8(int x) => throw 'uncalled';
+  List<Function> Function(int, {Function x}) m9(int x) => throw 'uncalled';
+  List<Function> Function([List<T> x]) m10(int x) => throw 'uncalled';
+  core.List<core.int> Function(int y, [Function x]) m11(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [core.List<core.int>]) m12(int x) =>
+      throw 'uncalled';
+  List<T> Function({int x}) m13(int x) => throw 'uncalled';
+  List<T> Function(core.List<core.int> x) m14(int x) => throw 'uncalled';
+  Function(int, [int x]) m15(int x) => throw 'uncalled';
+  Function([List<Function>]) m16(int x) => throw 'uncalled';
+  Function({List<T> x}) m17(int x) => throw 'uncalled';
+  void Function(int y, {Function x}) m18(int x) => throw 'uncalled';
+  void Function(int, [List<T> x]) m19(int x) => throw 'uncalled';
+  Function Function<A>(List<A> x) m20(int x) => throw 'uncalled';
+  Function<A>(int x) m21(int x) => throw 'uncalled';
+  void Function<A>(Function x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(core.List<core.int>)
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(core.List<core.int>) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(core.List<core.int>));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int y, [List<Function> x])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [List<Function> x]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(
+        m1 is core.List<core.int> Function(int y, [List<Function> x]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int, [Function x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int, [Function x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int, [Function x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// int Function<A>(Function x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(Function x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is int Function<A>(Function x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int x, [int]) Function(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [int]) Function(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function(int x, [int]) Function(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {List<Function> x}) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {List<Function> x}) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(
+        m5 is int Function(int y, {List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function([int x]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function([int x]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is Function Function([int x]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(List<Function>) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<Function>) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(List<Function>) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [List<T>]) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [List<T>]) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int x, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, {Function x}) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {Function x}) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([List<T> x]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<T> x]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int y, [Function x]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [Function x]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int y, [Function x])
+        Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [core.List<core.int>]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [core.List<core.int>]) Function(int x)
+        l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int,
+            [core.List<core.int>])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function({int x}) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({int x}) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function({int x}) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(core.List<core.int> x) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(core.List<core.int> x) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int, [int x]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int, [int x]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function(int, [int x]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function([List<Function>]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([List<Function>]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function([List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({List<T> x}) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({List<T> x}) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function({List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int y, {Function x}) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {Function x}) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<T> x]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<T> x]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>(List<A> x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<A> x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(List<A> x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// Function<A>(int x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    Function<A>(int x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is Function<A>(int x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// void Function<A>(Function x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(Function x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is void Function<A>(Function x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U93().runTests();
+  new U93<int>(tIsInt: true).runTests();
+  new U93<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type94_test.dart b/tests/language/function_type/function_type94_test.dart
new file mode 100644
index 0000000..011496a
--- /dev/null
+++ b/tests/language/function_type/function_type94_test.dart
@@ -0,0 +1,912 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function([core.List<core.int>]);
+typedef F1<T> = core.List<core.int> Function(List<Function>);
+typedef F2<T> = Function(int y, [Function x]);
+typedef F3<T> = int Function<A>(List<Function> x);
+typedef F4<T> = int Function(int x, [int]) Function<B extends core.int>();
+typedef F5<T> = int Function(int y, {List<Function> x})
+    Function<B extends core.int>();
+typedef F6<T> = Function Function([int x]) Function<B extends core.int>();
+typedef F7<T> = Function Function(List<Function>)
+    Function<B extends core.int>();
+typedef F8<T> = Function Function(int x, [List<T>])
+    Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int, {Function x})
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function([List<T> x])
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(int y, [Function x])
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F13<T> = List<T> Function({int x}) Function<B extends core.int>();
+typedef F14<T> = List<T> Function(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F15<T> = Function(int, [int x]) Function<B extends core.int>();
+typedef F16<T> = Function([List<Function>]) Function<B extends core.int>();
+typedef F17<T> = Function({List<T> x}) Function<B extends core.int>();
+typedef F18<T> = void Function(int y, {Function x})
+    Function<B extends core.int>();
+typedef F19<T> = void Function(int, [List<T> x]) Function<B extends core.int>();
+typedef F20<T> = Function Function<A>(List<A> x) Function<B extends core.int>();
+typedef F21<T> = Function<A>(int x) Function<B extends core.int>();
+typedef F22<T> = void Function<A>(Function x) Function<B extends core.int>();
+
+Function f0([core.List<core.int> x0 = const []]) => throw 'uncalled';
+core.List<core.int> f1(List<Function> x0) => throw 'uncalled';
+f2(int y, [Function x = _voidFunction]) => throw 'uncalled';
+int f3<A>(List<Function> x) => throw 'uncalled';
+int Function(int x, [int]) f4<B extends core.int>() => throw 'uncalled';
+int Function(int y, {List<Function> x}) f5<B extends core.int>() =>
+    throw 'uncalled';
+Function Function([int x]) f6<B extends core.int>() => throw 'uncalled';
+Function Function(List<Function>) f7<B extends core.int>() => throw 'uncalled';
+Function Function(int x, [List<int>]) f8<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, {Function x}) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function([List<int> x]) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, [Function x]) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [core.List<core.int>])
+    f12<B extends core.int>() => throw 'uncalled';
+List<int> Function({int x}) f13<B extends core.int>() => throw 'uncalled';
+List<int> Function(core.List<core.int> x) f14<B extends core.int>() =>
+    throw 'uncalled';
+Function(int, [int x]) f15<B extends core.int>() => throw 'uncalled';
+Function([List<Function>]) f16<B extends core.int>() => throw 'uncalled';
+Function({List<int> x}) f17<B extends core.int>() => throw 'uncalled';
+void Function(int y, {Function x}) f18<B extends core.int>() =>
+    throw 'uncalled';
+void Function(int, [List<int> x]) f19<B extends core.int>() => throw 'uncalled';
+Function Function<A>(List<A> x) f20<B extends core.int>() => throw 'uncalled';
+Function<A>(int x) f21<B extends core.int>() => throw 'uncalled';
+void Function<A>(Function x) f22<B extends core.int>() => throw 'uncalled';
+
+class U94<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function([core.List<core.int>]) x0;
+  late core.List<core.int> Function(List<Function>) x1;
+  late Function(int y, [Function x]) x2;
+  late int Function<A>(List<Function> x) x3;
+  late int Function(int x, [int]) Function<B extends core.int>() x4;
+  late int Function(int y, {List<Function> x}) Function<B extends core.int>()
+      x5;
+  late Function Function([int x]) Function<B extends core.int>() x6;
+  late Function Function(List<Function>) Function<B extends core.int>() x7;
+  late Function Function(int x, [List<T>]) Function<B extends core.int>() x8;
+  late List<Function> Function(int, {Function x}) Function<B extends core.int>()
+      x9;
+  late List<Function> Function([List<T> x]) Function<B extends core.int>() x10;
+  late core.List<core.int> Function(int y, [Function x])
+      Function<B extends core.int>() x11;
+  late core.List<core.int> Function(int, [core.List<core.int>])
+      Function<B extends core.int>() x12;
+  late List<T> Function({int x}) Function<B extends core.int>() x13;
+  late List<T> Function(core.List<core.int> x) Function<B extends core.int>()
+      x14;
+  late Function(int, [int x]) Function<B extends core.int>() x15;
+  late Function([List<Function>]) Function<B extends core.int>() x16;
+  late Function({List<T> x}) Function<B extends core.int>() x17;
+  late void Function(int y, {Function x}) Function<B extends core.int>() x18;
+  late void Function(int, [List<T> x]) Function<B extends core.int>() x19;
+  late Function Function<A>(List<A> x) Function<B extends core.int>() x20;
+  late Function<A>(int x) Function<B extends core.int>() x21;
+  late void Function<A>(Function x) Function<B extends core.int>() x22;
+
+  U94({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0([core.List<core.int> x0 = const []]) => throw 'uncalled';
+  core.List<core.int> m1(List<Function> x0) => throw 'uncalled';
+  m2(int y, [Function x = _voidFunction]) => throw 'uncalled';
+  int m3<A>(List<Function> x) => throw 'uncalled';
+  int Function(int x, [int]) m4<B extends core.int>() => throw 'uncalled';
+  int Function(int y, {List<Function> x}) m5<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function([int x]) m6<B extends core.int>() => throw 'uncalled';
+  Function Function(List<Function>) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int x, [List<T>]) m8<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, {Function x}) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function([List<T> x]) m10<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [Function x]) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [core.List<core.int>])
+      m12<B extends core.int>() => throw 'uncalled';
+  List<T> Function({int x}) m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function(core.List<core.int> x) m14<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int, [int x]) m15<B extends core.int>() => throw 'uncalled';
+  Function([List<Function>]) m16<B extends core.int>() => throw 'uncalled';
+  Function({List<T> x}) m17<B extends core.int>() => throw 'uncalled';
+  void Function(int y, {Function x}) m18<B extends core.int>() =>
+      throw 'uncalled';
+  void Function(int, [List<T> x]) m19<B extends core.int>() => throw 'uncalled';
+  Function Function<A>(List<A> x) m20<B extends core.int>() => throw 'uncalled';
+  Function<A>(int x) m21<B extends core.int>() => throw 'uncalled';
+  void Function<A>(Function x) m22<B extends core.int>() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function([core.List<core.int>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function([core.List<core.int>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function([core.List<core.int>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(List<Function>)
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(List<Function>) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(List<Function>));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int y, [Function x])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [Function x]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int y, [Function x]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// int Function<A>(List<Function> x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<Function> x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is int Function<A>(List<Function> x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int x, [int]) Function<B extends core.int>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [int]) Function<B extends core.int>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function(int x, [int]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {List<Function> x}) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {List<Function> x}) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, {List<Function> x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function([int x]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function([int x]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is Function Function([int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(List<Function>) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<Function>) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(
+        m7 is Function Function(List<Function>) Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [List<T>]) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [List<T>]) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int x, [List<T>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, {Function x}) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {Function x}) Function<B extends core.int>()
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, {Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([List<T> x]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<T> x]) Function<B extends core.int>() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int y, [Function x]) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [Function x])
+        Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int y, [Function x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [core.List<core.int>]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [core.List<core.int>])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int,
+            [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function({int x}) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({int x}) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function({int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(core.List<core.int> x) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(core.List<core.int> x) Function<B extends core.int>() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int, [int x]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int, [int x]) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function(int, [int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function([List<Function>]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([List<Function>]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function([List<Function>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({List<T> x}) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({List<T> x}) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function({List<T> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int y, {Function x}) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {Function x}) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, {Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<T> x]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<T> x]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int, [List<T> x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>(List<A> x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<A> x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(
+        m20 is Function Function<A>(List<A> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// Function<A>(int x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    Function<A>(int x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is Function<A>(int x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// void Function<A>(Function x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(Function x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(
+        m22 is void Function<A>(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U94().runTests();
+  new U94<int>(tIsInt: true).runTests();
+  new U94<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type95_test.dart b/tests/language/function_type/function_type95_test.dart
new file mode 100644
index 0000000..e5be48e
--- /dev/null
+++ b/tests/language/function_type/function_type95_test.dart
@@ -0,0 +1,932 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, [core.List<core.int>]);
+typedef F1<T> = core.List<core.int> Function([List<Function>]);
+typedef F2<T> = Function(Function);
+typedef F3<T> = int Function<A>(core.List<core.int> x);
+typedef F4<T> = int Function(int x, [int]) Function<B extends core.int>(int x);
+typedef F5<T> = int Function(int y, {List<Function> x})
+    Function<B extends core.int>(int x);
+typedef F6<T> = Function Function([int x]) Function<B extends core.int>(int x);
+typedef F7<T> = Function Function(List<Function>) Function<B extends core.int>(
+    int x);
+typedef F8<T> = Function Function(int x, [List<T>])
+    Function<B extends core.int>(int x);
+typedef F9<T> = List<Function> Function(int, {Function x})
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function([List<T> x])
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(int y, [Function x])
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F13<T> = List<T> Function({int x}) Function<B extends core.int>(int x);
+typedef F14<T> = List<T> Function(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F15<T> = Function(int, [int x]) Function<B extends core.int>(int x);
+typedef F16<T> = Function([List<Function>]) Function<B extends core.int>(int x);
+typedef F17<T> = Function({List<T> x}) Function<B extends core.int>(int x);
+typedef F18<T> = void Function(int y, {Function x})
+    Function<B extends core.int>(int x);
+typedef F19<T> = void Function(int, [List<T> x]) Function<B extends core.int>(
+    int x);
+typedef F20<T> = Function Function<A>(List<A> x) Function<B extends core.int>(
+    int x);
+typedef F21<T> = Function<A>(int x) Function<B extends core.int>(int x);
+typedef F22<T> = void Function<A>(Function x) Function<B extends core.int>(
+    int x);
+
+Function f0(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
+core.List<core.int> f1([List<Function> x0 = const []]) => throw 'uncalled';
+f2(Function x0) => throw 'uncalled';
+int f3<A>(core.List<core.int> x) => throw 'uncalled';
+int Function(int x, [int]) f4<B extends core.int>(int x) => throw 'uncalled';
+int Function(int y, {List<Function> x}) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function([int x]) f6<B extends core.int>(int x) => throw 'uncalled';
+Function Function(List<Function>) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int x, [List<int>]) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, {Function x}) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function([List<int> x]) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int y, [Function x]) f11<B extends core.int>(
+        int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int, [core.List<core.int>])
+    f12<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function({int x}) f13<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function(core.List<core.int> x) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int, [int x]) f15<B extends core.int>(int x) => throw 'uncalled';
+Function([List<Function>]) f16<B extends core.int>(int x) => throw 'uncalled';
+Function({List<int> x}) f17<B extends core.int>(int x) => throw 'uncalled';
+void Function(int y, {Function x}) f18<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int, [List<int> x]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function<A>(List<A> x) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function<A>(int x) f21<B extends core.int>(int x) => throw 'uncalled';
+void Function<A>(Function x) f22<B extends core.int>(int x) => throw 'uncalled';
+
+class U95<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, [core.List<core.int>]) x0;
+  late core.List<core.int> Function([List<Function>]) x1;
+  late Function(Function) x2;
+  late int Function<A>(core.List<core.int> x) x3;
+  late int Function(int x, [int]) Function<B extends core.int>(int x) x4;
+  late int Function(int y, {List<Function> x}) Function<B extends core.int>(
+      int x) x5;
+  late Function Function([int x]) Function<B extends core.int>(int x) x6;
+  late Function Function(List<Function>) Function<B extends core.int>(int x) x7;
+  late Function Function(int x, [List<T>]) Function<B extends core.int>(int x)
+      x8;
+  late List<Function> Function(int, {Function x}) Function<B extends core.int>(
+      int x) x9;
+  late List<Function> Function([List<T> x]) Function<B extends core.int>(int x)
+      x10;
+  late core.List<core.int> Function(int y, [Function x])
+      Function<B extends core.int>(int x) x11;
+  late core.List<core.int> Function(int, [core.List<core.int>])
+      Function<B extends core.int>(int x) x12;
+  late List<T> Function({int x}) Function<B extends core.int>(int x) x13;
+  late List<T> Function(core.List<core.int> x) Function<B extends core.int>(
+      int x) x14;
+  late Function(int, [int x]) Function<B extends core.int>(int x) x15;
+  late Function([List<Function>]) Function<B extends core.int>(int x) x16;
+  late Function({List<T> x}) Function<B extends core.int>(int x) x17;
+  late void Function(int y, {Function x}) Function<B extends core.int>(int x)
+      x18;
+  late void Function(int, [List<T> x]) Function<B extends core.int>(int x) x19;
+  late Function Function<A>(List<A> x) Function<B extends core.int>(int x) x20;
+  late Function<A>(int x) Function<B extends core.int>(int x) x21;
+  late void Function<A>(Function x) Function<B extends core.int>(int x) x22;
+
+  U95({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, [core.List<core.int> x1 = const []]) => throw 'uncalled';
+  core.List<core.int> m1([List<Function> x0 = const []]) => throw 'uncalled';
+  m2(Function x0) => throw 'uncalled';
+  int m3<A>(core.List<core.int> x) => throw 'uncalled';
+  int Function(int x, [int]) m4<B extends core.int>(int x) => throw 'uncalled';
+  int Function(int y, {List<Function> x}) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function([int x]) m6<B extends core.int>(int x) => throw 'uncalled';
+  Function Function(List<Function>) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int x, [List<T>]) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, {Function x}) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function([List<T> x]) m10<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, [Function x]) m11<B extends core.int>(
+          int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int, [core.List<core.int>])
+      m12<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function({int x}) m13<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function(core.List<core.int> x) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int, [int x]) m15<B extends core.int>(int x) => throw 'uncalled';
+  Function([List<Function>]) m16<B extends core.int>(int x) => throw 'uncalled';
+  Function({List<T> x}) m17<B extends core.int>(int x) => throw 'uncalled';
+  void Function(int y, {Function x}) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int, [List<T> x]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function<A>(List<A> x) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function<A>(int x) m21<B extends core.int>(int x) => throw 'uncalled';
+  void Function<A>(Function x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, [core.List<core.int>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [core.List<core.int>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, [core.List<core.int>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function([List<Function>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function([List<Function>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function([List<Function>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(Function)
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(Function) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(Function));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// int Function<A>(core.List<core.int> x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(core.List<core.int> x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is int Function<A>(core.List<core.int> x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function(int x, [int]) Function<B extends core.int>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function(int x, [int]) Function<B extends core.int>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function(int x, [int]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(int y, {List<Function> x}) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, {List<Function> x}) Function<B extends core.int>(int x)
+        l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(int y, {List<Function> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function([int x]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function([int x]) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is Function Function([int x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function(List<Function>) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function(List<Function>) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function(List<Function>)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function(int x, [List<T>]) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [List<T>]) Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function(int x, [List<T>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int, {Function x}) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, {Function x}) Function<B extends core.int>(
+        int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function([List<T> x]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<T> x]) Function<B extends core.int>(int x)
+        l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function([List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int y, [Function x]) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, [Function x])
+        Function<B extends core.int>(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(int y, [Function x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [core.List<core.int>])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int,
+            [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function({int x}) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function({int x}) Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function({int x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(core.List<core.int> x) Function<B extends core.int>(int x)
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int, [int x]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int, [int x]) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is Function(int, [int x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function([List<Function>]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function([List<Function>]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function([List<Function>]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function({List<T> x}) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function({List<T> x}) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function({List<T> x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(int y, {Function x}) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, {Function x}) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int y, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int, [List<T> x]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<T> x]) Function<B extends core.int>(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// Function Function<A>(List<A> x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    Function Function<A>(List<A> x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is Function Function<A>(List<A> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// Function<A>(int x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    Function<A>(int x) Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is Function<A>(int x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// void Function<A>(Function x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(Function x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is void Function<A>(Function x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U95().runTests();
+  new U95<int>(tIsInt: true).runTests();
+  new U95<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type96_test.dart b/tests/language/function_type/function_type96_test.dart
new file mode 100644
index 0000000..ec3c67d
--- /dev/null
+++ b/tests/language/function_type/function_type96_test.dart
@@ -0,0 +1,895 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int x, [core.List<core.int>]);
+typedef F1<T> = core.List<core.int> Function(int, [List<Function>]);
+typedef F2<T> = Function([Function]);
+typedef F3<T> = int Function<A>(List<T> x);
+typedef F4<T> = int Function({int x}) Function();
+typedef F5<T> = int Function(core.List<core.int> x) Function();
+typedef F6<T> = Function Function(int, [int x]) Function();
+typedef F7<T> = Function Function([List<Function>]) Function();
+typedef F8<T> = Function Function({List<T> x}) Function();
+typedef F9<T> = List<Function> Function(int y, {Function x}) Function();
+typedef F10<T> = List<Function> Function(int, [List<T> x]) Function();
+typedef F11<T> = core.List<core.int> Function(Function) Function();
+typedef F12<T> = core.List<core.int> Function(int x, [core.List<core.int>])
+    Function();
+typedef F13<T> = List<T> Function(int, {int x}) Function();
+typedef F14<T> = List<T> Function([core.List<core.int> x]) Function();
+typedef F15<T> = Function(int y, [int x]) Function();
+typedef F16<T> = Function(int, [List<Function>]) Function();
+typedef F17<T> = Function(int, {List<T> x}) Function();
+typedef F18<T> = void Function(List<Function> x) Function();
+typedef F19<T> = void Function(int y, [List<T> x]) Function();
+typedef F20<T> = List<Function> Function<A>(int x) Function();
+typedef F21<T> = Function<A>(Function x) Function();
+typedef F22<T> = void Function<A>(List<Function> x) Function();
+
+Function f0(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
+core.List<core.int> f1(int x0, [List<Function> x1 = const []]) =>
+    throw 'uncalled';
+f2([Function x0 = _voidFunction]) => throw 'uncalled';
+int f3<A>(List<int> x) => throw 'uncalled';
+int Function({int x}) f4() => throw 'uncalled';
+int Function(core.List<core.int> x) f5() => throw 'uncalled';
+Function Function(int, [int x]) f6() => throw 'uncalled';
+Function Function([List<Function>]) f7() => throw 'uncalled';
+Function Function({List<int> x}) f8() => throw 'uncalled';
+List<Function> Function(int y, {Function x}) f9() => throw 'uncalled';
+List<Function> Function(int, [List<int> x]) f10() => throw 'uncalled';
+core.List<core.int> Function(Function) f11() => throw 'uncalled';
+core.List<core.int> Function(int x, [core.List<core.int>]) f12() =>
+    throw 'uncalled';
+List<int> Function(int, {int x}) f13() => throw 'uncalled';
+List<int> Function([core.List<core.int> x]) f14() => throw 'uncalled';
+Function(int y, [int x]) f15() => throw 'uncalled';
+Function(int, [List<Function>]) f16() => throw 'uncalled';
+Function(int, {List<int> x}) f17() => throw 'uncalled';
+void Function(List<Function> x) f18() => throw 'uncalled';
+void Function(int y, [List<int> x]) f19() => throw 'uncalled';
+List<Function> Function<A>(int x) f20() => throw 'uncalled';
+Function<A>(Function x) f21() => throw 'uncalled';
+void Function<A>(List<Function> x) f22() => throw 'uncalled';
+
+class U96<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int x, [core.List<core.int>]) x0;
+  late core.List<core.int> Function(int, [List<Function>]) x1;
+  late Function([Function]) x2;
+  late int Function<A>(List<T> x) x3;
+  late int Function({int x}) Function() x4;
+  late int Function(core.List<core.int> x) Function() x5;
+  late Function Function(int, [int x]) Function() x6;
+  late Function Function([List<Function>]) Function() x7;
+  late Function Function({List<T> x}) Function() x8;
+  late List<Function> Function(int y, {Function x}) Function() x9;
+  late List<Function> Function(int, [List<T> x]) Function() x10;
+  late core.List<core.int> Function(Function) Function() x11;
+  late core.List<core.int> Function(int x, [core.List<core.int>]) Function()
+      x12;
+  late List<T> Function(int, {int x}) Function() x13;
+  late List<T> Function([core.List<core.int> x]) Function() x14;
+  late Function(int y, [int x]) Function() x15;
+  late Function(int, [List<Function>]) Function() x16;
+  late Function(int, {List<T> x}) Function() x17;
+  late void Function(List<Function> x) Function() x18;
+  late void Function(int y, [List<T> x]) Function() x19;
+  late List<Function> Function<A>(int x) Function() x20;
+  late Function<A>(Function x) Function() x21;
+  late void Function<A>(List<Function> x) Function() x22;
+
+  U96({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x, [core.List<core.int> x0 = const []]) => throw 'uncalled';
+  core.List<core.int> m1(int x0, [List<Function> x1 = const []]) =>
+      throw 'uncalled';
+  m2([Function x0 = _voidFunction]) => throw 'uncalled';
+  int m3<A>(List<T> x) => throw 'uncalled';
+  int Function({int x}) m4() => throw 'uncalled';
+  int Function(core.List<core.int> x) m5() => throw 'uncalled';
+  Function Function(int, [int x]) m6() => throw 'uncalled';
+  Function Function([List<Function>]) m7() => throw 'uncalled';
+  Function Function({List<T> x}) m8() => throw 'uncalled';
+  List<Function> Function(int y, {Function x}) m9() => throw 'uncalled';
+  List<Function> Function(int, [List<T> x]) m10() => throw 'uncalled';
+  core.List<core.int> Function(Function) m11() => throw 'uncalled';
+  core.List<core.int> Function(int x, [core.List<core.int>]) m12() =>
+      throw 'uncalled';
+  List<T> Function(int, {int x}) m13() => throw 'uncalled';
+  List<T> Function([core.List<core.int> x]) m14() => throw 'uncalled';
+  Function(int y, [int x]) m15() => throw 'uncalled';
+  Function(int, [List<Function>]) m16() => throw 'uncalled';
+  Function(int, {List<T> x}) m17() => throw 'uncalled';
+  void Function(List<Function> x) m18() => throw 'uncalled';
+  void Function(int y, [List<T> x]) m19() => throw 'uncalled';
+  List<Function> Function<A>(int x) m20() => throw 'uncalled';
+  Function<A>(Function x) m21() => throw 'uncalled';
+  void Function<A>(List<Function> x) m22() => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int x, [core.List<core.int>])
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int x, [core.List<core.int>]) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int x, [core.List<core.int>]));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int, [List<Function>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, [List<Function>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int, [List<Function>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function([Function])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function([Function]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function([Function]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// int Function<A>(List<T> x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<T> x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is int Function<A>(List<T> x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+    // The static function has its T always set to int.
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isFalse(f3 is F3<bool>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    Expect.isFalse(confuse(f3) is F3<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        x3 = confuse(f3);
+      });
+      Expect.throws(() {
+        l3 = (f3 as dynamic);
+      });
+      Expect.throws(() {
+        l3 = confuse(f3);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m3 is F3<int>);
+      Expect.equals(true, m3 is F3<bool>);
+      Expect.equals(true, confuse(m3) is F3<int>);
+      Expect.equals(true, confuse(m3) is F3<bool>);
+    }
+  }
+
+  /// int Function({int x}) Function()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function({int x}) Function() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function({int x}) Function());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(core.List<core.int> x) Function()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(core.List<core.int> x) Function() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(core.List<core.int> x) Function());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function(int, [int x]) Function()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [int x]) Function() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is Function Function(int, [int x]) Function());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([List<Function>]) Function()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<Function>]) Function() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([List<Function>]) Function());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({List<T> x}) Function()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({List<T> x}) Function() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function({List<T> x}) Function());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int y, {Function x}) Function()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {Function x}) Function() l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int y, {Function x}) Function());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<T> x]) Function()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<T> x]) Function() l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [List<T> x]) Function());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(Function) Function()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(Function) Function() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(Function) Function());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int x, [core.List<core.int>]) Function()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [core.List<core.int>]) Function() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int x,
+            [core.List<core.int>])
+        Function());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, {int x}) Function()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {int x}) Function() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int, {int x}) Function());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([core.List<core.int> x]) Function()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([core.List<core.int> x]) Function() l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([core.List<core.int> x]) Function());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int y, [int x]) Function()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [int x]) Function() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function(int y, [int x]) Function());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(int, [List<Function>]) Function()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<Function>]) Function() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [List<Function>]) Function());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {List<T> x}) Function()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {List<T> x}) Function() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, {List<T> x}) Function());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(List<Function> x) Function()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(List<Function> x) Function() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(List<Function> x) Function());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [List<T> x]) Function()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [List<T> x]) Function() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, [List<T> x]) Function());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(int x) Function()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(int x) Function() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is List<Function> Function<A>(int x) Function());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// Function<A>(Function x) Function()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    Function<A>(Function x) Function() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is Function<A>(Function x) Function());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// void Function<A>(List<Function> x) Function()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<Function> x) Function() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is void Function<A>(List<Function> x) Function());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U96().runTests();
+  new U96<int>(tIsInt: true).runTests();
+  new U96<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type97_test.dart b/tests/language/function_type/function_type97_test.dart
new file mode 100644
index 0000000..061794a
--- /dev/null
+++ b/tests/language/function_type/function_type97_test.dart
@@ -0,0 +1,874 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function({core.List<core.int> x});
+typedef F1<T> = core.List<core.int> Function(int x, [List<Function>]);
+typedef F2<T> = Function(int, [Function]);
+typedef F3<T> = int Function<A>();
+typedef F4<T> = int Function({int x}) Function(int x);
+typedef F5<T> = int Function(core.List<core.int> x) Function(int x);
+typedef F6<T> = Function Function(int, [int x]) Function(int x);
+typedef F7<T> = Function Function([List<Function>]) Function(int x);
+typedef F8<T> = Function Function({List<T> x}) Function(int x);
+typedef F9<T> = List<Function> Function(int y, {Function x}) Function(int x);
+typedef F10<T> = List<Function> Function(int, [List<T> x]) Function(int x);
+typedef F11<T> = core.List<core.int> Function(Function) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int x, [core.List<core.int>])
+    Function(int x);
+typedef F13<T> = List<T> Function(int, {int x}) Function(int x);
+typedef F14<T> = List<T> Function([core.List<core.int> x]) Function(int x);
+typedef F15<T> = Function(int y, [int x]) Function(int x);
+typedef F16<T> = Function(int, [List<Function>]) Function(int x);
+typedef F17<T> = Function(int, {List<T> x}) Function(int x);
+typedef F18<T> = void Function(List<Function> x) Function(int x);
+typedef F19<T> = void Function(int y, [List<T> x]) Function(int x);
+typedef F20<T> = List<Function> Function<A>(int x) Function(int x);
+typedef F21<T> = Function<A>(Function x) Function(int x);
+typedef F22<T> = void Function<A>(List<Function> x) Function(int x);
+
+Function f0({core.List<core.int> x = const []}) => throw 'uncalled';
+core.List<core.int> f1(int x, [List<Function> x0 = const []]) =>
+    throw 'uncalled';
+f2(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+int f3<A>() => throw 'uncalled';
+int Function({int x}) f4(int x) => throw 'uncalled';
+int Function(core.List<core.int> x) f5(int x) => throw 'uncalled';
+Function Function(int, [int x]) f6(int x) => throw 'uncalled';
+Function Function([List<Function>]) f7(int x) => throw 'uncalled';
+Function Function({List<int> x}) f8(int x) => throw 'uncalled';
+List<Function> Function(int y, {Function x}) f9(int x) => throw 'uncalled';
+List<Function> Function(int, [List<int> x]) f10(int x) => throw 'uncalled';
+core.List<core.int> Function(Function) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int x, [core.List<core.int>]) f12(int x) =>
+    throw 'uncalled';
+List<int> Function(int, {int x}) f13(int x) => throw 'uncalled';
+List<int> Function([core.List<core.int> x]) f14(int x) => throw 'uncalled';
+Function(int y, [int x]) f15(int x) => throw 'uncalled';
+Function(int, [List<Function>]) f16(int x) => throw 'uncalled';
+Function(int, {List<int> x}) f17(int x) => throw 'uncalled';
+void Function(List<Function> x) f18(int x) => throw 'uncalled';
+void Function(int y, [List<int> x]) f19(int x) => throw 'uncalled';
+List<Function> Function<A>(int x) f20(int x) => throw 'uncalled';
+Function<A>(Function x) f21(int x) => throw 'uncalled';
+void Function<A>(List<Function> x) f22(int x) => throw 'uncalled';
+
+class U97<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function({core.List<core.int> x}) x0;
+  late core.List<core.int> Function(int x, [List<Function>]) x1;
+  late Function(int, [Function]) x2;
+  late int Function<A>() x3;
+  late int Function({int x}) Function(int x) x4;
+  late int Function(core.List<core.int> x) Function(int x) x5;
+  late Function Function(int, [int x]) Function(int x) x6;
+  late Function Function([List<Function>]) Function(int x) x7;
+  late Function Function({List<T> x}) Function(int x) x8;
+  late List<Function> Function(int y, {Function x}) Function(int x) x9;
+  late List<Function> Function(int, [List<T> x]) Function(int x) x10;
+  late core.List<core.int> Function(Function) Function(int x) x11;
+  late core.List<core.int> Function(int x, [core.List<core.int>]) Function(
+      int x) x12;
+  late List<T> Function(int, {int x}) Function(int x) x13;
+  late List<T> Function([core.List<core.int> x]) Function(int x) x14;
+  late Function(int y, [int x]) Function(int x) x15;
+  late Function(int, [List<Function>]) Function(int x) x16;
+  late Function(int, {List<T> x}) Function(int x) x17;
+  late void Function(List<Function> x) Function(int x) x18;
+  late void Function(int y, [List<T> x]) Function(int x) x19;
+  late List<Function> Function<A>(int x) Function(int x) x20;
+  late Function<A>(Function x) Function(int x) x21;
+  late void Function<A>(List<Function> x) Function(int x) x22;
+
+  U97({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0({core.List<core.int> x = const []}) => throw 'uncalled';
+  core.List<core.int> m1(int x, [List<Function> x0 = const []]) =>
+      throw 'uncalled';
+  m2(int x0, [Function x1 = _voidFunction]) => throw 'uncalled';
+  int m3<A>() => throw 'uncalled';
+  int Function({int x}) m4(int x) => throw 'uncalled';
+  int Function(core.List<core.int> x) m5(int x) => throw 'uncalled';
+  Function Function(int, [int x]) m6(int x) => throw 'uncalled';
+  Function Function([List<Function>]) m7(int x) => throw 'uncalled';
+  Function Function({List<T> x}) m8(int x) => throw 'uncalled';
+  List<Function> Function(int y, {Function x}) m9(int x) => throw 'uncalled';
+  List<Function> Function(int, [List<T> x]) m10(int x) => throw 'uncalled';
+  core.List<core.int> Function(Function) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int x, [core.List<core.int>]) m12(int x) =>
+      throw 'uncalled';
+  List<T> Function(int, {int x}) m13(int x) => throw 'uncalled';
+  List<T> Function([core.List<core.int> x]) m14(int x) => throw 'uncalled';
+  Function(int y, [int x]) m15(int x) => throw 'uncalled';
+  Function(int, [List<Function>]) m16(int x) => throw 'uncalled';
+  Function(int, {List<T> x}) m17(int x) => throw 'uncalled';
+  void Function(List<Function> x) m18(int x) => throw 'uncalled';
+  void Function(int y, [List<T> x]) m19(int x) => throw 'uncalled';
+  List<Function> Function<A>(int x) m20(int x) => throw 'uncalled';
+  Function<A>(Function x) m21(int x) => throw 'uncalled';
+  void Function<A>(List<Function> x) m22(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function({core.List<core.int> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function({core.List<core.int> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function({core.List<core.int> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int x, [List<Function>])
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [List<Function>]) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int x, [List<Function>]));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int, [Function])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int, [Function]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int, [Function]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// int Function<A>()
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    int Function<A>() l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is int Function<A>());
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function({int x}) Function(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function({int x}) Function(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function({int x}) Function(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(core.List<core.int> x) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(core.List<core.int> x) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(core.List<core.int> x) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function(int, [int x]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [int x]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is Function Function(int, [int x]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([List<Function>]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<Function>]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({List<T> x}) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({List<T> x}) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function({List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int y, {Function x}) Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {Function x}) Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(
+        m9 is List<Function> Function(int y, {Function x}) Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<T> x]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<T> x]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(
+        m10 is List<Function> Function(int, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(Function) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(Function) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(
+        m11 is core.List<core.int> Function(Function) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int x, [core.List<core.int>]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [core.List<core.int>]) Function(int x)
+        l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int x,
+            [core.List<core.int>])
+        Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, {int x}) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {int x}) Function(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int, {int x}) Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([core.List<core.int> x]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([core.List<core.int> x]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(
+        m14 is List<T> Function([core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int y, [int x]) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [int x]) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is Function(int y, [int x]) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(int, [List<Function>]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<Function>]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [List<Function>]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {List<T> x}) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {List<T> x}) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, {List<T> x}) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(List<Function> x) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(List<Function> x) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [List<T> x]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [List<T> x]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, [List<T> x]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(int x) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(int x) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is List<Function> Function<A>(int x) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// Function<A>(Function x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    Function<A>(Function x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is Function<A>(Function x) Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// void Function<A>(List<Function> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<Function> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is void Function<A>(List<Function> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U97().runTests();
+  new U97<int>(tIsInt: true).runTests();
+  new U97<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type98_test.dart b/tests/language/function_type/function_type98_test.dart
new file mode 100644
index 0000000..1a7aded
--- /dev/null
+++ b/tests/language/function_type/function_type98_test.dart
@@ -0,0 +1,918 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int, {core.List<core.int> x});
+typedef F1<T> = core.List<core.int> Function({List<Function> x});
+typedef F2<T> = Function(int x, [Function]);
+typedef F3<T> = int Function<A>(A x);
+typedef F4<T> = int Function({int x}) Function<B extends core.int>();
+typedef F5<T> = int Function(core.List<core.int> x)
+    Function<B extends core.int>();
+typedef F6<T> = Function Function(int, [int x]) Function<B extends core.int>();
+typedef F7<T> = Function Function([List<Function>])
+    Function<B extends core.int>();
+typedef F8<T> = Function Function({List<T> x}) Function<B extends core.int>();
+typedef F9<T> = List<Function> Function(int y, {Function x})
+    Function<B extends core.int>();
+typedef F10<T> = List<Function> Function(int, [List<T> x])
+    Function<B extends core.int>();
+typedef F11<T> = core.List<core.int> Function(Function)
+    Function<B extends core.int>();
+typedef F12<T> = core.List<core.int> Function(int x, [core.List<core.int>])
+    Function<B extends core.int>();
+typedef F13<T> = List<T> Function(int, {int x}) Function<B extends core.int>();
+typedef F14<T> = List<T> Function([core.List<core.int> x])
+    Function<B extends core.int>();
+typedef F15<T> = Function(int y, [int x]) Function<B extends core.int>();
+typedef F16<T> = Function(int, [List<Function>]) Function<B extends core.int>();
+typedef F17<T> = Function(int, {List<T> x}) Function<B extends core.int>();
+typedef F18<T> = void Function(List<Function> x) Function<B extends core.int>();
+typedef F19<T> = void Function(int y, [List<T> x])
+    Function<B extends core.int>();
+typedef F20<T> = List<Function> Function<A>(int x)
+    Function<B extends core.int>();
+typedef F21<T> = Function<A>(Function x) Function<B extends core.int>();
+typedef F22<T> = void Function<A>(List<Function> x)
+    Function<B extends core.int>();
+
+Function f0(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
+core.List<core.int> f1({List<Function> x = const []}) => throw 'uncalled';
+f2(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+int f3<A>(A x) => throw 'uncalled';
+int Function({int x}) f4<B extends core.int>() => throw 'uncalled';
+int Function(core.List<core.int> x) f5<B extends core.int>() =>
+    throw 'uncalled';
+Function Function(int, [int x]) f6<B extends core.int>() => throw 'uncalled';
+Function Function([List<Function>]) f7<B extends core.int>() =>
+    throw 'uncalled';
+Function Function({List<int> x}) f8<B extends core.int>() => throw 'uncalled';
+List<Function> Function(int y, {Function x}) f9<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function(int, [List<int> x]) f10<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(Function) f11<B extends core.int>() =>
+    throw 'uncalled';
+core.List<core.int> Function(int x, [core.List<core.int>])
+    f12<B extends core.int>() => throw 'uncalled';
+List<int> Function(int, {int x}) f13<B extends core.int>() => throw 'uncalled';
+List<int> Function([core.List<core.int> x]) f14<B extends core.int>() =>
+    throw 'uncalled';
+Function(int y, [int x]) f15<B extends core.int>() => throw 'uncalled';
+Function(int, [List<Function>]) f16<B extends core.int>() => throw 'uncalled';
+Function(int, {List<int> x}) f17<B extends core.int>() => throw 'uncalled';
+void Function(List<Function> x) f18<B extends core.int>() => throw 'uncalled';
+void Function(int y, [List<int> x]) f19<B extends core.int>() =>
+    throw 'uncalled';
+List<Function> Function<A>(int x) f20<B extends core.int>() => throw 'uncalled';
+Function<A>(Function x) f21<B extends core.int>() => throw 'uncalled';
+void Function<A>(List<Function> x) f22<B extends core.int>() =>
+    throw 'uncalled';
+
+class U98<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int, {core.List<core.int> x}) x0;
+  late core.List<core.int> Function({List<Function> x}) x1;
+  late Function(int x, [Function]) x2;
+  late int Function<A>(A x) x3;
+  late int Function({int x}) Function<B extends core.int>() x4;
+  late int Function(core.List<core.int> x) Function<B extends core.int>() x5;
+  late Function Function(int, [int x]) Function<B extends core.int>() x6;
+  late Function Function([List<Function>]) Function<B extends core.int>() x7;
+  late Function Function({List<T> x}) Function<B extends core.int>() x8;
+  late List<Function> Function(int y, {Function x})
+      Function<B extends core.int>() x9;
+  late List<Function> Function(int, [List<T> x]) Function<B extends core.int>()
+      x10;
+  late core.List<core.int> Function(Function) Function<B extends core.int>()
+      x11;
+  late core.List<core.int> Function(int x, [core.List<core.int>])
+      Function<B extends core.int>() x12;
+  late List<T> Function(int, {int x}) Function<B extends core.int>() x13;
+  late List<T> Function([core.List<core.int> x]) Function<B extends core.int>()
+      x14;
+  late Function(int y, [int x]) Function<B extends core.int>() x15;
+  late Function(int, [List<Function>]) Function<B extends core.int>() x16;
+  late Function(int, {List<T> x}) Function<B extends core.int>() x17;
+  late void Function(List<Function> x) Function<B extends core.int>() x18;
+  late void Function(int y, [List<T> x]) Function<B extends core.int>() x19;
+  late List<Function> Function<A>(int x) Function<B extends core.int>() x20;
+  late Function<A>(Function x) Function<B extends core.int>() x21;
+  late void Function<A>(List<Function> x) Function<B extends core.int>() x22;
+
+  U98({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int x0, {core.List<core.int> x = const []}) => throw 'uncalled';
+  core.List<core.int> m1({List<Function> x = const []}) => throw 'uncalled';
+  m2(int x, [Function x0 = _voidFunction]) => throw 'uncalled';
+  int m3<A>(A x) => throw 'uncalled';
+  int Function({int x}) m4<B extends core.int>() => throw 'uncalled';
+  int Function(core.List<core.int> x) m5<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function(int, [int x]) m6<B extends core.int>() => throw 'uncalled';
+  Function Function([List<Function>]) m7<B extends core.int>() =>
+      throw 'uncalled';
+  Function Function({List<T> x}) m8<B extends core.int>() => throw 'uncalled';
+  List<Function> Function(int y, {Function x}) m9<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function(int, [List<T> x]) m10<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(Function) m11<B extends core.int>() =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x, [core.List<core.int>])
+      m12<B extends core.int>() => throw 'uncalled';
+  List<T> Function(int, {int x}) m13<B extends core.int>() => throw 'uncalled';
+  List<T> Function([core.List<core.int> x]) m14<B extends core.int>() =>
+      throw 'uncalled';
+  Function(int y, [int x]) m15<B extends core.int>() => throw 'uncalled';
+  Function(int, [List<Function>]) m16<B extends core.int>() => throw 'uncalled';
+  Function(int, {List<T> x}) m17<B extends core.int>() => throw 'uncalled';
+  void Function(List<Function> x) m18<B extends core.int>() => throw 'uncalled';
+  void Function(int y, [List<T> x]) m19<B extends core.int>() =>
+      throw 'uncalled';
+  List<Function> Function<A>(int x) m20<B extends core.int>() =>
+      throw 'uncalled';
+  Function<A>(Function x) m21<B extends core.int>() => throw 'uncalled';
+  void Function<A>(List<Function> x) m22<B extends core.int>() =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int, {core.List<core.int> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {core.List<core.int> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function({List<Function> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({List<Function> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function({List<Function> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function(int x, [Function])
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [Function]) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function(int x, [Function]));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// int Function<A>(A x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(A x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is int Function<A>(A x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function({int x}) Function<B extends core.int>()
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function({int x}) Function<B extends core.int>() l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is int Function({int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(core.List<core.int> x) Function<B extends core.int>()
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(core.List<core.int> x) Function<B extends core.int>() l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(core.List<core.int> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function(int, [int x]) Function<B extends core.int>()
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [int x]) Function<B extends core.int>() l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is Function Function(int, [int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([List<Function>]) Function<B extends core.int>()
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<Function>]) Function<B extends core.int>() l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([List<Function>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({List<T> x}) Function<B extends core.int>()
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({List<T> x}) Function<B extends core.int>() l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(
+        m8 is Function Function({List<T> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int y, {Function x}) Function<B extends core.int>()
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {Function x}) Function<B extends core.int>()
+        l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int y, {Function x})
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<T> x]) Function<B extends core.int>()
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<T> x]) Function<B extends core.int>()
+        l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(Function) Function<B extends core.int>()
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(Function) Function<B extends core.int>() l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(Function)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int x, [core.List<core.int>]) Function<B extends core.int>()
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [core.List<core.int>])
+        Function<B extends core.int>() l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int x,
+            [core.List<core.int>])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, {int x}) Function<B extends core.int>()
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {int x}) Function<B extends core.int>() l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(
+        m13 is List<T> Function(int, {int x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([core.List<core.int> x]) Function<B extends core.int>()
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([core.List<core.int> x]) Function<B extends core.int>()
+        l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([core.List<core.int> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int y, [int x]) Function<B extends core.int>()
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [int x]) Function<B extends core.int>() l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is Function(int y, [int x]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(int, [List<Function>]) Function<B extends core.int>()
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<Function>]) Function<B extends core.int>() l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(
+        m16 is Function(int, [List<Function>]) Function<B extends core.int>());
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {List<T> x}) Function<B extends core.int>()
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {List<T> x}) Function<B extends core.int>() l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int, {List<T> x}) Function<B extends core.int>());
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(List<Function> x) Function<B extends core.int>()
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(List<Function> x) Function<B extends core.int>() l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(
+        m18 is void Function(List<Function> x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [List<T> x]) Function<B extends core.int>()
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [List<T> x]) Function<B extends core.int>() l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, [List<T> x])
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(int x) Function<B extends core.int>()
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(int x) Function<B extends core.int>() l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is List<Function> Function<A>(int x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// Function<A>(Function x) Function<B extends core.int>()
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    Function<A>(Function x) Function<B extends core.int>() l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is Function<A>(Function x) Function<B extends core.int>());
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// void Function<A>(List<Function> x) Function<B extends core.int>()
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<Function> x) Function<B extends core.int>() l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is void Function<A>(List<Function> x)
+        Function<B extends core.int>());
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U98().runTests();
+  new U98<int>(tIsInt: true).runTests();
+  new U98<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type99_test.dart b/tests/language/function_type/function_type99_test.dart
new file mode 100644
index 0000000..59b8b8e
--- /dev/null
+++ b/tests/language/function_type/function_type99_test.dart
@@ -0,0 +1,943 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = Function Function(int y, {core.List<core.int> x});
+typedef F1<T> = core.List<core.int> Function(int, {List<Function> x});
+typedef F2<T> = Function({Function x});
+typedef F3<T> = int Function<A>(List<A> x);
+typedef F4<T> = int Function({int x}) Function<B extends core.int>(int x);
+typedef F5<T> = int Function(core.List<core.int> x)
+    Function<B extends core.int>(int x);
+typedef F6<T> = Function Function(int, [int x]) Function<B extends core.int>(
+    int x);
+typedef F7<T> = Function Function([List<Function>])
+    Function<B extends core.int>(int x);
+typedef F8<T> = Function Function({List<T> x}) Function<B extends core.int>(
+    int x);
+typedef F9<T> = List<Function> Function(int y, {Function x})
+    Function<B extends core.int>(int x);
+typedef F10<T> = List<Function> Function(int, [List<T> x])
+    Function<B extends core.int>(int x);
+typedef F11<T> = core.List<core.int> Function(Function)
+    Function<B extends core.int>(int x);
+typedef F12<T> = core.List<core.int> Function(int x, [core.List<core.int>])
+    Function<B extends core.int>(int x);
+typedef F13<T> = List<T> Function(int, {int x}) Function<B extends core.int>(
+    int x);
+typedef F14<T> = List<T> Function([core.List<core.int> x])
+    Function<B extends core.int>(int x);
+typedef F15<T> = Function(int y, [int x]) Function<B extends core.int>(int x);
+typedef F16<T> = Function(int, [List<Function>]) Function<B extends core.int>(
+    int x);
+typedef F17<T> = Function(int, {List<T> x}) Function<B extends core.int>(int x);
+typedef F18<T> = void Function(List<Function> x) Function<B extends core.int>(
+    int x);
+typedef F19<T> = void Function(int y, [List<T> x]) Function<B extends core.int>(
+    int x);
+typedef F20<T> = List<Function> Function<A>(int x) Function<B extends core.int>(
+    int x);
+typedef F21<T> = Function<A>(Function x) Function<B extends core.int>(int x);
+typedef F22<T> = void Function<A>(List<Function> x)
+    Function<B extends core.int>(int x);
+
+Function f0(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
+core.List<core.int> f1(int x0, {List<Function> x = const []}) =>
+    throw 'uncalled';
+f2({Function x = _voidFunction}) => throw 'uncalled';
+int f3<A>(List<A> x) => throw 'uncalled';
+int Function({int x}) f4<B extends core.int>(int x) => throw 'uncalled';
+int Function(core.List<core.int> x) f5<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function(int, [int x]) f6<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function([List<Function>]) f7<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function Function({List<int> x}) f8<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int y, {Function x}) f9<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function(int, [List<int> x]) f10<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(Function) f11<B extends core.int>(int x) =>
+    throw 'uncalled';
+core.List<core.int> Function(int x, [core.List<core.int>])
+    f12<B extends core.int>(int x) => throw 'uncalled';
+List<int> Function(int, {int x}) f13<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<int> Function([core.List<core.int> x]) f14<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int y, [int x]) f15<B extends core.int>(int x) => throw 'uncalled';
+Function(int, [List<Function>]) f16<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function(int, {List<int> x}) f17<B extends core.int>(int x) => throw 'uncalled';
+void Function(List<Function> x) f18<B extends core.int>(int x) =>
+    throw 'uncalled';
+void Function(int y, [List<int> x]) f19<B extends core.int>(int x) =>
+    throw 'uncalled';
+List<Function> Function<A>(int x) f20<B extends core.int>(int x) =>
+    throw 'uncalled';
+Function<A>(Function x) f21<B extends core.int>(int x) => throw 'uncalled';
+void Function<A>(List<Function> x) f22<B extends core.int>(int x) =>
+    throw 'uncalled';
+
+class U99<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late Function Function(int y, {core.List<core.int> x}) x0;
+  late core.List<core.int> Function(int, {List<Function> x}) x1;
+  late Function({Function x}) x2;
+  late int Function<A>(List<A> x) x3;
+  late int Function({int x}) Function<B extends core.int>(int x) x4;
+  late int Function(core.List<core.int> x) Function<B extends core.int>(int x)
+      x5;
+  late Function Function(int, [int x]) Function<B extends core.int>(int x) x6;
+  late Function Function([List<Function>]) Function<B extends core.int>(int x)
+      x7;
+  late Function Function({List<T> x}) Function<B extends core.int>(int x) x8;
+  late List<Function> Function(int y, {Function x})
+      Function<B extends core.int>(int x) x9;
+  late List<Function> Function(int, [List<T> x]) Function<B extends core.int>(
+      int x) x10;
+  late core.List<core.int> Function(Function) Function<B extends core.int>(
+      int x) x11;
+  late core.List<core.int> Function(int x, [core.List<core.int>])
+      Function<B extends core.int>(int x) x12;
+  late List<T> Function(int, {int x}) Function<B extends core.int>(int x) x13;
+  late List<T> Function([core.List<core.int> x]) Function<B extends core.int>(
+      int x) x14;
+  late Function(int y, [int x]) Function<B extends core.int>(int x) x15;
+  late Function(int, [List<Function>]) Function<B extends core.int>(int x) x16;
+  late Function(int, {List<T> x}) Function<B extends core.int>(int x) x17;
+  late void Function(List<Function> x) Function<B extends core.int>(int x) x18;
+  late void Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+      x19;
+  late List<Function> Function<A>(int x) Function<B extends core.int>(int x)
+      x20;
+  late Function<A>(Function x) Function<B extends core.int>(int x) x21;
+  late void Function<A>(List<Function> x) Function<B extends core.int>(int x)
+      x22;
+
+  U99({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  Function m0(int y, {core.List<core.int> x = const []}) => throw 'uncalled';
+  core.List<core.int> m1(int x0, {List<Function> x = const []}) =>
+      throw 'uncalled';
+  m2({Function x = _voidFunction}) => throw 'uncalled';
+  int m3<A>(List<A> x) => throw 'uncalled';
+  int Function({int x}) m4<B extends core.int>(int x) => throw 'uncalled';
+  int Function(core.List<core.int> x) m5<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function(int, [int x]) m6<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function([List<Function>]) m7<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function Function({List<T> x}) m8<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int y, {Function x}) m9<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function(int, [List<T> x]) m10<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(Function) m11<B extends core.int>(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int x, [core.List<core.int>])
+      m12<B extends core.int>(int x) => throw 'uncalled';
+  List<T> Function(int, {int x}) m13<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<T> Function([core.List<core.int> x]) m14<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int y, [int x]) m15<B extends core.int>(int x) => throw 'uncalled';
+  Function(int, [List<Function>]) m16<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function(int, {List<T> x}) m17<B extends core.int>(int x) => throw 'uncalled';
+  void Function(List<Function> x) m18<B extends core.int>(int x) =>
+      throw 'uncalled';
+  void Function(int y, [List<T> x]) m19<B extends core.int>(int x) =>
+      throw 'uncalled';
+  List<Function> Function<A>(int x) m20<B extends core.int>(int x) =>
+      throw 'uncalled';
+  Function<A>(Function x) m21<B extends core.int>(int x) => throw 'uncalled';
+  void Function<A>(List<Function> x) m22<B extends core.int>(int x) =>
+      throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+  }
+
+  /// Function Function(int y, {core.List<core.int> x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    Function Function(int y, {core.List<core.int> x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is Function Function(int y, {core.List<core.int> x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// core.List<core.int> Function(int, {List<Function> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int, {List<Function> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is core.List<core.int> Function(int, {List<Function> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+  }
+
+  /// Function({Function x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    Function({Function x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is Function({Function x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// int Function<A>(List<A> x)
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    int Function<A>(List<A> x) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is int Function<A>(List<A> x));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// int Function({int x}) Function<B extends core.int>(int x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    int Function({int x}) Function<B extends core.int>(int x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(
+        m4 is int Function({int x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(core.List<core.int> x) Function<B extends core.int>(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(core.List<core.int> x) Function<B extends core.int>(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(core.List<core.int> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// Function Function(int, [int x]) Function<B extends core.int>(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, [int x]) Function<B extends core.int>(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(m6 is Function Function(int, [int x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([List<Function>]) Function<B extends core.int>(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([List<Function>]) Function<B extends core.int>(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({List<T> x}) Function<B extends core.int>(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({List<T> x}) Function<B extends core.int>(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function({List<T> x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+    // The static function has its T always set to int.
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isFalse(f8 is F8<bool>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    Expect.isFalse(confuse(f8) is F8<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        x8 = confuse(f8);
+      });
+      Expect.throws(() {
+        l8 = (f8 as dynamic);
+      });
+      Expect.throws(() {
+        l8 = confuse(f8);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m8 is F8<int>);
+      Expect.equals(tIsBool, m8 is F8<bool>);
+      Expect.equals(tIsInt, confuse(m8) is F8<int>);
+      Expect.equals(tIsBool, confuse(m8) is F8<bool>);
+    }
+  }
+
+  /// List<Function> Function(int y, {Function x}) Function<B extends core.int>(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int y, {Function x}) Function<B extends core.int>(
+        int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is List<Function> Function(int y, {Function x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<T> x]) Function<B extends core.int>(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<T> x]) Function<B extends core.int>(
+        int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+    // The static function has its T always set to int.
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isFalse(f10 is F10<bool>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    Expect.isFalse(confuse(f10) is F10<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        x10 = confuse(f10);
+      });
+      Expect.throws(() {
+        l10 = (f10 as dynamic);
+      });
+      Expect.throws(() {
+        l10 = confuse(f10);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m10 is F10<int>);
+      Expect.equals(tIsBool, m10 is F10<bool>);
+      Expect.equals(tIsInt, confuse(m10) is F10<int>);
+      Expect.equals(tIsBool, confuse(m10) is F10<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(Function) Function<B extends core.int>(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(Function) Function<B extends core.int>(int x)
+        l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is core.List<core.int> Function(Function)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+  }
+
+  /// core.List<core.int> Function(int x, [core.List<core.int>]) Function<B extends core.int>(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [core.List<core.int>])
+        Function<B extends core.int>(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(m12 is core.List<core.int> Function(int x,
+            [core.List<core.int>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// List<T> Function(int, {int x}) Function<B extends core.int>(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(int, {int x}) Function<B extends core.int>(int x) l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is List<T> Function(int, {int x})
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+    // The static function has its T always set to int.
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isFalse(f13 is F13<bool>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    Expect.isFalse(confuse(f13) is F13<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        x13 = confuse(f13);
+      });
+      Expect.throws(() {
+        l13 = (f13 as dynamic);
+      });
+      Expect.throws(() {
+        l13 = confuse(f13);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m13 is F13<int>);
+      Expect.equals(tIsBool, m13 is F13<bool>);
+      Expect.equals(tIsInt, confuse(m13) is F13<int>);
+      Expect.equals(tIsBool, confuse(m13) is F13<bool>);
+    }
+  }
+
+  /// List<T> Function([core.List<core.int> x]) Function<B extends core.int>(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([core.List<core.int> x]) Function<B extends core.int>(
+        int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([core.List<core.int> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// Function(int y, [int x]) Function<B extends core.int>(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    Function(int y, [int x]) Function<B extends core.int>(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(
+        m15 is Function(int y, [int x]) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+  }
+
+  /// Function(int, [List<Function>]) Function<B extends core.int>(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [List<Function>]) Function<B extends core.int>(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [List<Function>])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {List<T> x}) Function<B extends core.int>(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {List<T> x}) Function<B extends core.int>(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(
+        m17 is Function(int, {List<T> x}) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+    // The static function has its T always set to int.
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isFalse(f17 is F17<bool>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    Expect.isFalse(confuse(f17) is F17<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        x17 = confuse(f17);
+      });
+      Expect.throws(() {
+        l17 = (f17 as dynamic);
+      });
+      Expect.throws(() {
+        l17 = confuse(f17);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m17 is F17<int>);
+      Expect.equals(tIsBool, m17 is F17<bool>);
+      Expect.equals(tIsInt, confuse(m17) is F17<int>);
+      Expect.equals(tIsBool, confuse(m17) is F17<bool>);
+    }
+  }
+
+  /// void Function(List<Function> x) Function<B extends core.int>(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(List<Function> x) Function<B extends core.int>(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [List<T> x]) Function<B extends core.int>(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [List<T> x]) Function<B extends core.int>(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(m19 is void Function(int y, [List<T> x])
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+    // The static function has its T always set to int.
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isFalse(f19 is F19<bool>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    Expect.isFalse(confuse(f19) is F19<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        x19 = confuse(f19);
+      });
+      Expect.throws(() {
+        l19 = (f19 as dynamic);
+      });
+      Expect.throws(() {
+        l19 = confuse(f19);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m19 is F19<int>);
+      Expect.equals(tIsBool, m19 is F19<bool>);
+      Expect.equals(tIsInt, confuse(m19) is F19<int>);
+      Expect.equals(tIsBool, confuse(m19) is F19<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(int x) Function<B extends core.int>(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(int x) Function<B extends core.int>(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is List<Function> Function<A>(int x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+  }
+
+  /// Function<A>(Function x) Function<B extends core.int>(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    Function<A>(Function x) Function<B extends core.int>(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(
+        m21 is Function<A>(Function x) Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// void Function<A>(List<Function> x) Function<B extends core.int>(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    void Function<A>(List<Function> x) Function<B extends core.int>(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is void Function<A>(List<Function> x)
+        Function<B extends core.int>(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+  }
+}
+
+void main() {
+  new U99().runTests();
+  new U99<int>(tIsInt: true).runTests();
+  new U99<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/function_type9_test.dart b/tests/language/function_type/function_type9_test.dart
new file mode 100644
index 0000000..f967587
--- /dev/null
+++ b/tests/language/function_type/function_type9_test.dart
@@ -0,0 +1,910 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+
+typedef F0<T> = int Function(int, {int x});
+typedef F1<T> = Function Function(int, {List<T> x});
+typedef F2<T> = core.List<core.int> Function({core.List<core.int> x});
+typedef F3<T> = Function(int x, [List<Function>]);
+typedef F4<T> = List<Function> Function<A>(Function x);
+typedef F5<T> = int Function(Function x) Function(int x);
+typedef F6<T> = int Function(int y, [core.List<core.int> x]) Function(int x);
+typedef F7<T> = Function Function([int]) Function(int x);
+typedef F8<T> = Function Function({List<Function> x}) Function(int x);
+typedef F9<T> = Function Function() Function(int x);
+typedef F10<T> = List<Function> Function(int, [List<Function> x]) Function(
+    int x);
+typedef F11<T> = List<Function> Function([List<T>]) Function(int x);
+typedef F12<T> = core.List<core.int> Function(int x, [Function]) Function(
+    int x);
+typedef F13<T> = core.List<core.int> Function(int y, {core.List<core.int> x})
+    Function(int x);
+typedef F14<T> = List<T> Function([Function x]) Function(int x);
+typedef F15<T> = List<T> Function(core.List<core.int>) Function(int x);
+typedef F16<T> = Function(int, [int]) Function(int x);
+typedef F17<T> = Function(int, {List<Function> x}) Function(int x);
+typedef F18<T> = void Function(int x) Function(int x);
+typedef F19<T> = void Function(int y, [List<Function> x]) Function(int x);
+typedef F20<T> = void Function(int, [List<T>]) Function(int x);
+typedef F21<T> = List<Function> Function<A>(core.List<core.int> x) Function(
+    int x);
+typedef F22<T> = Function<A>(List<T> x) Function(int x);
+typedef F23<T> = void Function<A>() Function(int x);
+
+int f0(int x0, {int x = -1}) => throw 'uncalled';
+Function f1(int x0, {List<int> x = const []}) => throw 'uncalled';
+core.List<core.int> f2({core.List<core.int> x = const []}) => throw 'uncalled';
+f3(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+List<Function> f4<A>(Function x) => throw 'uncalled';
+int Function(Function x) f5(int x) => throw 'uncalled';
+int Function(int y, [core.List<core.int> x]) f6(int x) => throw 'uncalled';
+Function Function([int]) f7(int x) => throw 'uncalled';
+Function Function({List<Function> x}) f8(int x) => throw 'uncalled';
+Function Function() f9(int x) => throw 'uncalled';
+List<Function> Function(int, [List<Function> x]) f10(int x) => throw 'uncalled';
+List<Function> Function([List<int>]) f11(int x) => throw 'uncalled';
+core.List<core.int> Function(int x, [Function]) f12(int x) => throw 'uncalled';
+core.List<core.int> Function(int y, {core.List<core.int> x}) f13(int x) =>
+    throw 'uncalled';
+List<int> Function([Function x]) f14(int x) => throw 'uncalled';
+List<int> Function(core.List<core.int>) f15(int x) => throw 'uncalled';
+Function(int, [int]) f16(int x) => throw 'uncalled';
+Function(int, {List<Function> x}) f17(int x) => throw 'uncalled';
+void Function(int x) f18(int x) => throw 'uncalled';
+void Function(int y, [List<Function> x]) f19(int x) => throw 'uncalled';
+void Function(int, [List<int>]) f20(int x) => throw 'uncalled';
+List<Function> Function<A>(core.List<core.int> x) f21(int x) =>
+    throw 'uncalled';
+Function<A>(List<int> x) f22(int x) => throw 'uncalled';
+void Function<A>() f23(int x) => throw 'uncalled';
+
+class U9<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+  late int Function(int, {int x}) x0;
+  late Function Function(int, {List<T> x}) x1;
+  late core.List<core.int> Function({core.List<core.int> x}) x2;
+  late Function(int x, [List<Function>]) x3;
+  late List<Function> Function<A>(Function x) x4;
+  late int Function(Function x) Function(int x) x5;
+  late int Function(int y, [core.List<core.int> x]) Function(int x) x6;
+  late Function Function([int]) Function(int x) x7;
+  late Function Function({List<Function> x}) Function(int x) x8;
+  late Function Function() Function(int x) x9;
+  late List<Function> Function(int, [List<Function> x]) Function(int x) x10;
+  late List<Function> Function([List<T>]) Function(int x) x11;
+  late core.List<core.int> Function(int x, [Function]) Function(int x) x12;
+  late core.List<core.int> Function(int y, {core.List<core.int> x}) Function(
+      int x) x13;
+  late List<T> Function([Function x]) Function(int x) x14;
+  late List<T> Function(core.List<core.int>) Function(int x) x15;
+  late Function(int, [int]) Function(int x) x16;
+  late Function(int, {List<Function> x}) Function(int x) x17;
+  late void Function(int x) Function(int x) x18;
+  late void Function(int y, [List<Function> x]) Function(int x) x19;
+  late void Function(int, [List<T>]) Function(int x) x20;
+  late List<Function> Function<A>(core.List<core.int> x) Function(int x) x21;
+  late Function<A>(List<T> x) Function(int x) x22;
+  late void Function<A>() Function(int x) x23;
+
+  U9({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+  int m0(int x0, {int x = -1}) => throw 'uncalled';
+  Function m1(int x0, {List<T> x = const []}) => throw 'uncalled';
+  core.List<core.int> m2({core.List<core.int> x = const []}) =>
+      throw 'uncalled';
+  m3(int x, [List<Function> x0 = const []]) => throw 'uncalled';
+  List<Function> m4<A>(Function x) => throw 'uncalled';
+  int Function(Function x) m5(int x) => throw 'uncalled';
+  int Function(int y, [core.List<core.int> x]) m6(int x) => throw 'uncalled';
+  Function Function([int]) m7(int x) => throw 'uncalled';
+  Function Function({List<Function> x}) m8(int x) => throw 'uncalled';
+  Function Function() m9(int x) => throw 'uncalled';
+  List<Function> Function(int, [List<Function> x]) m10(int x) =>
+      throw 'uncalled';
+  List<Function> Function([List<T>]) m11(int x) => throw 'uncalled';
+  core.List<core.int> Function(int x, [Function]) m12(int x) =>
+      throw 'uncalled';
+  core.List<core.int> Function(int y, {core.List<core.int> x}) m13(int x) =>
+      throw 'uncalled';
+  List<T> Function([Function x]) m14(int x) => throw 'uncalled';
+  List<T> Function(core.List<core.int>) m15(int x) => throw 'uncalled';
+  Function(int, [int]) m16(int x) => throw 'uncalled';
+  Function(int, {List<Function> x}) m17(int x) => throw 'uncalled';
+  void Function(int x) m18(int x) => throw 'uncalled';
+  void Function(int y, [List<Function> x]) m19(int x) => throw 'uncalled';
+  void Function(int, [List<T>]) m20(int x) => throw 'uncalled';
+  List<Function> Function<A>(core.List<core.int> x) m21(int x) =>
+      throw 'uncalled';
+  Function<A>(List<T> x) m22(int x) => throw 'uncalled';
+  void Function<A>() m23(int x) => throw 'uncalled';
+
+  runTests() {
+    testF0();
+    testF1();
+    testF2();
+    testF3();
+    testF4();
+    testF5();
+    testF6();
+    testF7();
+    testF8();
+    testF9();
+    testF10();
+    testF11();
+    testF12();
+    testF13();
+    testF14();
+    testF15();
+    testF16();
+    testF17();
+    testF18();
+    testF19();
+    testF20();
+    testF21();
+    testF22();
+    testF23();
+  }
+
+  /// int Function(int, {int x})
+  void testF0() {
+    Expect.isTrue(f0 is F0<int>);
+    Expect.isTrue(confuse(f0) is F0<int>);
+    // In checked mode, verifies the type.
+    int Function(int, {int x}) l0;
+    // The static function f0 sets `T` to `int`.
+    if (tIsInt) {
+      x0 = f0 as dynamic;
+      l0 = f0 as dynamic;
+      x0 = confuse(f0);
+      l0 = confuse(f0);
+    }
+
+    Expect.isTrue(m0 is F0<T>);
+    Expect.isTrue(m0 is int Function(int, {int x}));
+    Expect.isTrue(confuse(m0) is F0<T>);
+    // In checked mode, verifies the type.
+    x0 = m0;
+    l0 = m0;
+    x0 = confuse(m0);
+    l0 = confuse(m0);
+  }
+
+  /// Function Function(int, {List<T> x})
+  void testF1() {
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    // In checked mode, verifies the type.
+    Function Function(int, {List<T> x}) l1;
+    // The static function f1 sets `T` to `int`.
+    if (tIsInt) {
+      x1 = f1 as dynamic;
+      l1 = f1 as dynamic;
+      x1 = confuse(f1);
+      l1 = confuse(f1);
+    }
+
+    Expect.isTrue(m1 is F1<T>);
+    Expect.isTrue(m1 is Function Function(int, {List<T> x}));
+    Expect.isTrue(confuse(m1) is F1<T>);
+    // In checked mode, verifies the type.
+    x1 = m1;
+    l1 = m1;
+    x1 = confuse(m1);
+    l1 = confuse(m1);
+    // The static function has its T always set to int.
+    Expect.isTrue(f1 is F1<int>);
+    Expect.isFalse(f1 is F1<bool>);
+    Expect.isTrue(confuse(f1) is F1<int>);
+    Expect.isFalse(confuse(f1) is F1<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        x1 = confuse(f1);
+      });
+      Expect.throws(() {
+        l1 = (f1 as dynamic);
+      });
+      Expect.throws(() {
+        l1 = confuse(f1);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(true, m1 is F1<int>);
+      Expect.equals(true, m1 is F1<bool>);
+      Expect.equals(true, confuse(m1) is F1<int>);
+      Expect.equals(true, confuse(m1) is F1<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function({core.List<core.int> x})
+  void testF2() {
+    Expect.isTrue(f2 is F2<int>);
+    Expect.isTrue(confuse(f2) is F2<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function({core.List<core.int> x}) l2;
+    // The static function f2 sets `T` to `int`.
+    if (tIsInt) {
+      x2 = f2 as dynamic;
+      l2 = f2 as dynamic;
+      x2 = confuse(f2);
+      l2 = confuse(f2);
+    }
+
+    Expect.isTrue(m2 is F2<T>);
+    Expect.isTrue(m2 is core.List<core.int> Function({core.List<core.int> x}));
+    Expect.isTrue(confuse(m2) is F2<T>);
+    // In checked mode, verifies the type.
+    x2 = m2;
+    l2 = m2;
+    x2 = confuse(m2);
+    l2 = confuse(m2);
+  }
+
+  /// Function(int x, [List<Function>])
+  void testF3() {
+    Expect.isTrue(f3 is F3<int>);
+    Expect.isTrue(confuse(f3) is F3<int>);
+    // In checked mode, verifies the type.
+    Function(int x, [List<Function>]) l3;
+    // The static function f3 sets `T` to `int`.
+    if (tIsInt) {
+      x3 = f3 as dynamic;
+      l3 = f3 as dynamic;
+      x3 = confuse(f3);
+      l3 = confuse(f3);
+    }
+
+    Expect.isTrue(m3 is F3<T>);
+    Expect.isTrue(m3 is Function(int x, [List<Function>]));
+    Expect.isTrue(confuse(m3) is F3<T>);
+    // In checked mode, verifies the type.
+    x3 = m3;
+    l3 = m3;
+    x3 = confuse(m3);
+    l3 = confuse(m3);
+  }
+
+  /// List<Function> Function<A>(Function x)
+  void testF4() {
+    Expect.isTrue(f4 is F4<int>);
+    Expect.isTrue(confuse(f4) is F4<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(Function x) l4;
+    // The static function f4 sets `T` to `int`.
+    if (tIsInt) {
+      x4 = f4 as dynamic;
+      l4 = f4 as dynamic;
+      x4 = confuse(f4);
+      l4 = confuse(f4);
+    }
+
+    Expect.isTrue(m4 is F4<T>);
+    Expect.isTrue(m4 is List<Function> Function<A>(Function x));
+    Expect.isTrue(confuse(m4) is F4<T>);
+    // In checked mode, verifies the type.
+    x4 = m4;
+    l4 = m4;
+    x4 = confuse(m4);
+    l4 = confuse(m4);
+  }
+
+  /// int Function(Function x) Function(int x)
+  void testF5() {
+    Expect.isTrue(f5 is F5<int>);
+    Expect.isTrue(confuse(f5) is F5<int>);
+    // In checked mode, verifies the type.
+    int Function(Function x) Function(int x) l5;
+    // The static function f5 sets `T` to `int`.
+    if (tIsInt) {
+      x5 = f5 as dynamic;
+      l5 = f5 as dynamic;
+      x5 = confuse(f5);
+      l5 = confuse(f5);
+    }
+
+    Expect.isTrue(m5 is F5<T>);
+    Expect.isTrue(m5 is int Function(Function x) Function(int x));
+    Expect.isTrue(confuse(m5) is F5<T>);
+    // In checked mode, verifies the type.
+    x5 = m5;
+    l5 = m5;
+    x5 = confuse(m5);
+    l5 = confuse(m5);
+  }
+
+  /// int Function(int y, [core.List<core.int> x]) Function(int x)
+  void testF6() {
+    Expect.isTrue(f6 is F6<int>);
+    Expect.isTrue(confuse(f6) is F6<int>);
+    // In checked mode, verifies the type.
+    int Function(int y, [core.List<core.int> x]) Function(int x) l6;
+    // The static function f6 sets `T` to `int`.
+    if (tIsInt) {
+      x6 = f6 as dynamic;
+      l6 = f6 as dynamic;
+      x6 = confuse(f6);
+      l6 = confuse(f6);
+    }
+
+    Expect.isTrue(m6 is F6<T>);
+    Expect.isTrue(
+        m6 is int Function(int y, [core.List<core.int> x]) Function(int x));
+    Expect.isTrue(confuse(m6) is F6<T>);
+    // In checked mode, verifies the type.
+    x6 = m6;
+    l6 = m6;
+    x6 = confuse(m6);
+    l6 = confuse(m6);
+  }
+
+  /// Function Function([int]) Function(int x)
+  void testF7() {
+    Expect.isTrue(f7 is F7<int>);
+    Expect.isTrue(confuse(f7) is F7<int>);
+    // In checked mode, verifies the type.
+    Function Function([int]) Function(int x) l7;
+    // The static function f7 sets `T` to `int`.
+    if (tIsInt) {
+      x7 = f7 as dynamic;
+      l7 = f7 as dynamic;
+      x7 = confuse(f7);
+      l7 = confuse(f7);
+    }
+
+    Expect.isTrue(m7 is F7<T>);
+    Expect.isTrue(m7 is Function Function([int]) Function(int x));
+    Expect.isTrue(confuse(m7) is F7<T>);
+    // In checked mode, verifies the type.
+    x7 = m7;
+    l7 = m7;
+    x7 = confuse(m7);
+    l7 = confuse(m7);
+  }
+
+  /// Function Function({List<Function> x}) Function(int x)
+  void testF8() {
+    Expect.isTrue(f8 is F8<int>);
+    Expect.isTrue(confuse(f8) is F8<int>);
+    // In checked mode, verifies the type.
+    Function Function({List<Function> x}) Function(int x) l8;
+    // The static function f8 sets `T` to `int`.
+    if (tIsInt) {
+      x8 = f8 as dynamic;
+      l8 = f8 as dynamic;
+      x8 = confuse(f8);
+      l8 = confuse(f8);
+    }
+
+    Expect.isTrue(m8 is F8<T>);
+    Expect.isTrue(m8 is Function Function({List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m8) is F8<T>);
+    // In checked mode, verifies the type.
+    x8 = m8;
+    l8 = m8;
+    x8 = confuse(m8);
+    l8 = confuse(m8);
+  }
+
+  /// Function Function() Function(int x)
+  void testF9() {
+    Expect.isTrue(f9 is F9<int>);
+    Expect.isTrue(confuse(f9) is F9<int>);
+    // In checked mode, verifies the type.
+    Function Function() Function(int x) l9;
+    // The static function f9 sets `T` to `int`.
+    if (tIsInt) {
+      x9 = f9 as dynamic;
+      l9 = f9 as dynamic;
+      x9 = confuse(f9);
+      l9 = confuse(f9);
+    }
+
+    Expect.isTrue(m9 is F9<T>);
+    Expect.isTrue(m9 is Function Function() Function(int x));
+    Expect.isTrue(confuse(m9) is F9<T>);
+    // In checked mode, verifies the type.
+    x9 = m9;
+    l9 = m9;
+    x9 = confuse(m9);
+    l9 = confuse(m9);
+  }
+
+  /// List<Function> Function(int, [List<Function> x]) Function(int x)
+  void testF10() {
+    Expect.isTrue(f10 is F10<int>);
+    Expect.isTrue(confuse(f10) is F10<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function(int, [List<Function> x]) Function(int x) l10;
+    // The static function f10 sets `T` to `int`.
+    if (tIsInt) {
+      x10 = f10 as dynamic;
+      l10 = f10 as dynamic;
+      x10 = confuse(f10);
+      l10 = confuse(f10);
+    }
+
+    Expect.isTrue(m10 is F10<T>);
+    Expect.isTrue(m10 is List<Function> Function(int, [List<Function> x])
+        Function(int x));
+    Expect.isTrue(confuse(m10) is F10<T>);
+    // In checked mode, verifies the type.
+    x10 = m10;
+    l10 = m10;
+    x10 = confuse(m10);
+    l10 = confuse(m10);
+  }
+
+  /// List<Function> Function([List<T>]) Function(int x)
+  void testF11() {
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function([List<T>]) Function(int x) l11;
+    // The static function f11 sets `T` to `int`.
+    if (tIsInt) {
+      x11 = f11 as dynamic;
+      l11 = f11 as dynamic;
+      x11 = confuse(f11);
+      l11 = confuse(f11);
+    }
+
+    Expect.isTrue(m11 is F11<T>);
+    Expect.isTrue(m11 is List<Function> Function([List<T>]) Function(int x));
+    Expect.isTrue(confuse(m11) is F11<T>);
+    // In checked mode, verifies the type.
+    x11 = m11;
+    l11 = m11;
+    x11 = confuse(m11);
+    l11 = confuse(m11);
+    // The static function has its T always set to int.
+    Expect.isTrue(f11 is F11<int>);
+    Expect.isFalse(f11 is F11<bool>);
+    Expect.isTrue(confuse(f11) is F11<int>);
+    Expect.isFalse(confuse(f11) is F11<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        x11 = confuse(f11);
+      });
+      Expect.throws(() {
+        l11 = (f11 as dynamic);
+      });
+      Expect.throws(() {
+        l11 = confuse(f11);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m11 is F11<int>);
+      Expect.equals(tIsBool, m11 is F11<bool>);
+      Expect.equals(tIsInt, confuse(m11) is F11<int>);
+      Expect.equals(tIsBool, confuse(m11) is F11<bool>);
+    }
+  }
+
+  /// core.List<core.int> Function(int x, [Function]) Function(int x)
+  void testF12() {
+    Expect.isTrue(f12 is F12<int>);
+    Expect.isTrue(confuse(f12) is F12<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int x, [Function]) Function(int x) l12;
+    // The static function f12 sets `T` to `int`.
+    if (tIsInt) {
+      x12 = f12 as dynamic;
+      l12 = f12 as dynamic;
+      x12 = confuse(f12);
+      l12 = confuse(f12);
+    }
+
+    Expect.isTrue(m12 is F12<T>);
+    Expect.isTrue(
+        m12 is core.List<core.int> Function(int x, [Function]) Function(int x));
+    Expect.isTrue(confuse(m12) is F12<T>);
+    // In checked mode, verifies the type.
+    x12 = m12;
+    l12 = m12;
+    x12 = confuse(m12);
+    l12 = confuse(m12);
+  }
+
+  /// core.List<core.int> Function(int y, {core.List<core.int> x}) Function(int x)
+  void testF13() {
+    Expect.isTrue(f13 is F13<int>);
+    Expect.isTrue(confuse(f13) is F13<int>);
+    // In checked mode, verifies the type.
+    core.List<core.int> Function(int y, {core.List<core.int> x}) Function(int x)
+        l13;
+    // The static function f13 sets `T` to `int`.
+    if (tIsInt) {
+      x13 = f13 as dynamic;
+      l13 = f13 as dynamic;
+      x13 = confuse(f13);
+      l13 = confuse(f13);
+    }
+
+    Expect.isTrue(m13 is F13<T>);
+    Expect.isTrue(m13 is core.List<core.int> Function(int y,
+            {core.List<core.int> x})
+        Function(int x));
+    Expect.isTrue(confuse(m13) is F13<T>);
+    // In checked mode, verifies the type.
+    x13 = m13;
+    l13 = m13;
+    x13 = confuse(m13);
+    l13 = confuse(m13);
+  }
+
+  /// List<T> Function([Function x]) Function(int x)
+  void testF14() {
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    // In checked mode, verifies the type.
+    List<T> Function([Function x]) Function(int x) l14;
+    // The static function f14 sets `T` to `int`.
+    if (tIsInt) {
+      x14 = f14 as dynamic;
+      l14 = f14 as dynamic;
+      x14 = confuse(f14);
+      l14 = confuse(f14);
+    }
+
+    Expect.isTrue(m14 is F14<T>);
+    Expect.isTrue(m14 is List<T> Function([Function x]) Function(int x));
+    Expect.isTrue(confuse(m14) is F14<T>);
+    // In checked mode, verifies the type.
+    x14 = m14;
+    l14 = m14;
+    x14 = confuse(m14);
+    l14 = confuse(m14);
+    // The static function has its T always set to int.
+    Expect.isTrue(f14 is F14<int>);
+    Expect.isFalse(f14 is F14<bool>);
+    Expect.isTrue(confuse(f14) is F14<int>);
+    Expect.isFalse(confuse(f14) is F14<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        x14 = confuse(f14);
+      });
+      Expect.throws(() {
+        l14 = (f14 as dynamic);
+      });
+      Expect.throws(() {
+        l14 = confuse(f14);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m14 is F14<int>);
+      Expect.equals(tIsBool, m14 is F14<bool>);
+      Expect.equals(tIsInt, confuse(m14) is F14<int>);
+      Expect.equals(tIsBool, confuse(m14) is F14<bool>);
+    }
+  }
+
+  /// List<T> Function(core.List<core.int>) Function(int x)
+  void testF15() {
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    // In checked mode, verifies the type.
+    List<T> Function(core.List<core.int>) Function(int x) l15;
+    // The static function f15 sets `T` to `int`.
+    if (tIsInt) {
+      x15 = f15 as dynamic;
+      l15 = f15 as dynamic;
+      x15 = confuse(f15);
+      l15 = confuse(f15);
+    }
+
+    Expect.isTrue(m15 is F15<T>);
+    Expect.isTrue(m15 is List<T> Function(core.List<core.int>) Function(int x));
+    Expect.isTrue(confuse(m15) is F15<T>);
+    // In checked mode, verifies the type.
+    x15 = m15;
+    l15 = m15;
+    x15 = confuse(m15);
+    l15 = confuse(m15);
+    // The static function has its T always set to int.
+    Expect.isTrue(f15 is F15<int>);
+    Expect.isFalse(f15 is F15<bool>);
+    Expect.isTrue(confuse(f15) is F15<int>);
+    Expect.isFalse(confuse(f15) is F15<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        x15 = confuse(f15);
+      });
+      Expect.throws(() {
+        l15 = (f15 as dynamic);
+      });
+      Expect.throws(() {
+        l15 = confuse(f15);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m15 is F15<int>);
+      Expect.equals(tIsBool, m15 is F15<bool>);
+      Expect.equals(tIsInt, confuse(m15) is F15<int>);
+      Expect.equals(tIsBool, confuse(m15) is F15<bool>);
+    }
+  }
+
+  /// Function(int, [int]) Function(int x)
+  void testF16() {
+    Expect.isTrue(f16 is F16<int>);
+    Expect.isTrue(confuse(f16) is F16<int>);
+    // In checked mode, verifies the type.
+    Function(int, [int]) Function(int x) l16;
+    // The static function f16 sets `T` to `int`.
+    if (tIsInt) {
+      x16 = f16 as dynamic;
+      l16 = f16 as dynamic;
+      x16 = confuse(f16);
+      l16 = confuse(f16);
+    }
+
+    Expect.isTrue(m16 is F16<T>);
+    Expect.isTrue(m16 is Function(int, [int]) Function(int x));
+    Expect.isTrue(confuse(m16) is F16<T>);
+    // In checked mode, verifies the type.
+    x16 = m16;
+    l16 = m16;
+    x16 = confuse(m16);
+    l16 = confuse(m16);
+  }
+
+  /// Function(int, {List<Function> x}) Function(int x)
+  void testF17() {
+    Expect.isTrue(f17 is F17<int>);
+    Expect.isTrue(confuse(f17) is F17<int>);
+    // In checked mode, verifies the type.
+    Function(int, {List<Function> x}) Function(int x) l17;
+    // The static function f17 sets `T` to `int`.
+    if (tIsInt) {
+      x17 = f17 as dynamic;
+      l17 = f17 as dynamic;
+      x17 = confuse(f17);
+      l17 = confuse(f17);
+    }
+
+    Expect.isTrue(m17 is F17<T>);
+    Expect.isTrue(m17 is Function(int, {List<Function> x}) Function(int x));
+    Expect.isTrue(confuse(m17) is F17<T>);
+    // In checked mode, verifies the type.
+    x17 = m17;
+    l17 = m17;
+    x17 = confuse(m17);
+    l17 = confuse(m17);
+  }
+
+  /// void Function(int x) Function(int x)
+  void testF18() {
+    Expect.isTrue(f18 is F18<int>);
+    Expect.isTrue(confuse(f18) is F18<int>);
+    // In checked mode, verifies the type.
+    void Function(int x) Function(int x) l18;
+    // The static function f18 sets `T` to `int`.
+    if (tIsInt) {
+      x18 = f18 as dynamic;
+      l18 = f18 as dynamic;
+      x18 = confuse(f18);
+      l18 = confuse(f18);
+    }
+
+    Expect.isTrue(m18 is F18<T>);
+    Expect.isTrue(m18 is void Function(int x) Function(int x));
+    Expect.isTrue(confuse(m18) is F18<T>);
+    // In checked mode, verifies the type.
+    x18 = m18;
+    l18 = m18;
+    x18 = confuse(m18);
+    l18 = confuse(m18);
+  }
+
+  /// void Function(int y, [List<Function> x]) Function(int x)
+  void testF19() {
+    Expect.isTrue(f19 is F19<int>);
+    Expect.isTrue(confuse(f19) is F19<int>);
+    // In checked mode, verifies the type.
+    void Function(int y, [List<Function> x]) Function(int x) l19;
+    // The static function f19 sets `T` to `int`.
+    if (tIsInt) {
+      x19 = f19 as dynamic;
+      l19 = f19 as dynamic;
+      x19 = confuse(f19);
+      l19 = confuse(f19);
+    }
+
+    Expect.isTrue(m19 is F19<T>);
+    Expect.isTrue(
+        m19 is void Function(int y, [List<Function> x]) Function(int x));
+    Expect.isTrue(confuse(m19) is F19<T>);
+    // In checked mode, verifies the type.
+    x19 = m19;
+    l19 = m19;
+    x19 = confuse(m19);
+    l19 = confuse(m19);
+  }
+
+  /// void Function(int, [List<T>]) Function(int x)
+  void testF20() {
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    // In checked mode, verifies the type.
+    void Function(int, [List<T>]) Function(int x) l20;
+    // The static function f20 sets `T` to `int`.
+    if (tIsInt) {
+      x20 = f20 as dynamic;
+      l20 = f20 as dynamic;
+      x20 = confuse(f20);
+      l20 = confuse(f20);
+    }
+
+    Expect.isTrue(m20 is F20<T>);
+    Expect.isTrue(m20 is void Function(int, [List<T>]) Function(int x));
+    Expect.isTrue(confuse(m20) is F20<T>);
+    // In checked mode, verifies the type.
+    x20 = m20;
+    l20 = m20;
+    x20 = confuse(m20);
+    l20 = confuse(m20);
+    // The static function has its T always set to int.
+    Expect.isTrue(f20 is F20<int>);
+    Expect.isFalse(f20 is F20<bool>);
+    Expect.isTrue(confuse(f20) is F20<int>);
+    Expect.isFalse(confuse(f20) is F20<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        x20 = confuse(f20);
+      });
+      Expect.throws(() {
+        l20 = (f20 as dynamic);
+      });
+      Expect.throws(() {
+        l20 = confuse(f20);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m20 is F20<int>);
+      Expect.equals(tIsBool, m20 is F20<bool>);
+      Expect.equals(tIsInt, confuse(m20) is F20<int>);
+      Expect.equals(tIsBool, confuse(m20) is F20<bool>);
+    }
+  }
+
+  /// List<Function> Function<A>(core.List<core.int> x) Function(int x)
+  void testF21() {
+    Expect.isTrue(f21 is F21<int>);
+    Expect.isTrue(confuse(f21) is F21<int>);
+    // In checked mode, verifies the type.
+    List<Function> Function<A>(core.List<core.int> x) Function(int x) l21;
+    // The static function f21 sets `T` to `int`.
+    if (tIsInt) {
+      x21 = f21 as dynamic;
+      l21 = f21 as dynamic;
+      x21 = confuse(f21);
+      l21 = confuse(f21);
+    }
+
+    Expect.isTrue(m21 is F21<T>);
+    Expect.isTrue(m21 is List<Function> Function<A>(core.List<core.int> x)
+        Function(int x));
+    Expect.isTrue(confuse(m21) is F21<T>);
+    // In checked mode, verifies the type.
+    x21 = m21;
+    l21 = m21;
+    x21 = confuse(m21);
+    l21 = confuse(m21);
+  }
+
+  /// Function<A>(List<T> x) Function(int x)
+  void testF22() {
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    // In checked mode, verifies the type.
+    Function<A>(List<T> x) Function(int x) l22;
+    // The static function f22 sets `T` to `int`.
+    if (tIsInt) {
+      x22 = f22 as dynamic;
+      l22 = f22 as dynamic;
+      x22 = confuse(f22);
+      l22 = confuse(f22);
+    }
+
+    Expect.isTrue(m22 is F22<T>);
+    Expect.isTrue(m22 is Function<A>(List<T> x) Function(int x));
+    Expect.isTrue(confuse(m22) is F22<T>);
+    // In checked mode, verifies the type.
+    x22 = m22;
+    l22 = m22;
+    x22 = confuse(m22);
+    l22 = confuse(m22);
+    // The static function has its T always set to int.
+    Expect.isTrue(f22 is F22<int>);
+    Expect.isFalse(f22 is F22<bool>);
+    Expect.isTrue(confuse(f22) is F22<int>);
+    Expect.isFalse(confuse(f22) is F22<bool>);
+    if (tIsBool) {
+      Expect.throws(() {
+        x22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        x22 = confuse(f22);
+      });
+      Expect.throws(() {
+        l22 = (f22 as dynamic);
+      });
+      Expect.throws(() {
+        l22 = confuse(f22);
+      });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(tIsInt, m22 is F22<int>);
+      Expect.equals(tIsBool, m22 is F22<bool>);
+      Expect.equals(tIsInt, confuse(m22) is F22<int>);
+      Expect.equals(tIsBool, confuse(m22) is F22<bool>);
+    }
+  }
+
+  /// void Function<A>() Function(int x)
+  void testF23() {
+    Expect.isTrue(f23 is F23<int>);
+    Expect.isTrue(confuse(f23) is F23<int>);
+    // In checked mode, verifies the type.
+    void Function<A>() Function(int x) l23;
+    // The static function f23 sets `T` to `int`.
+    if (tIsInt) {
+      x23 = f23 as dynamic;
+      l23 = f23 as dynamic;
+      x23 = confuse(f23);
+      l23 = confuse(f23);
+    }
+
+    Expect.isTrue(m23 is F23<T>);
+    Expect.isTrue(m23 is void Function<A>() Function(int x));
+    Expect.isTrue(confuse(m23) is F23<T>);
+    // In checked mode, verifies the type.
+    x23 = m23;
+    l23 = m23;
+    x23 = confuse(m23);
+    l23 = confuse(m23);
+  }
+}
+
+void main() {
+  new U9().runTests();
+  new U9<int>(tIsInt: true).runTests();
+  new U9<bool>(tIsBool: true).runTests();
+}
diff --git a/tests/language/function_type/test_generator.dart b/tests/language/function_type/test_generator.dart
new file mode 100644
index 0000000..f02d099
--- /dev/null
+++ b/tests/language/function_type/test_generator.dart
@@ -0,0 +1,831 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+// By convention:
+//
+//   T: generic type of typedef.
+//   A: generic type of returned function.
+//   B: generic type of function.
+//
+// Example:
+//    typedef F<T>: Function<A> Function<B>();
+//
+// We only use: Function, List, int (and function types).
+// We import 'dart:core' directly and with prefix 'core'.
+
+abstract class Printable {
+  /// Builds a descriptive string that can be used as an identifier.
+  ///
+  /// The string is mainly used for disambiguation, and not for its readability.
+  void writeIdentifier(StringBuffer buffer);
+}
+
+abstract class TypeLike implements Printable {
+  /// Prints `this` as valid Dart code for a Type.
+  void writeType(StringBuffer buffer);
+
+  /// Whether this type uses T in some way.
+  bool get usesT;
+
+  /// Whether this type uses T in a return (covariant) position.
+  ///
+  /// For example: `T`, `List<T>`, `T Function()`, or `Function(Function(T))`.
+  bool get returnsT;
+
+  /// Whether this type uses T in a parameter (contravariant) position.
+  ///
+  /// For example, `Function(T)`, `Function(List<T>)`, or
+  /// `Function(T Function())`.
+  bool get takesT;
+}
+
+/// Provides a unique integer for every parameter in a function.
+int parameterNameCounter = 0;
+
+/// Whether `T` should be replaced with `int`.
+bool shouldReplaceTWithInt = false;
+
+class Parameter implements TypeLike {
+  final TypeLike type;
+  final String name;
+
+  Parameter(this.type, this.name);
+
+  // Type or name can be null.
+  @override
+  writeIdentifier(buffer) {
+    if (type == null) {
+      buffer.write("null");
+    } else {
+      type.writeIdentifier(buffer);
+    }
+    buffer.write("_");
+    buffer.write(name);
+  }
+
+  void writeType(StringBuffer buffer) {
+    assert(type != null || name != null);
+    if (name == null) {
+      type.writeType(buffer);
+    } else if (type == null) {
+      buffer.write(name);
+    } else {
+      type.writeType(buffer);
+      buffer.write(" ");
+      buffer.write(name);
+    }
+  }
+
+  void writeInFunction(StringBuffer buffer, {bool optional}) {
+    assert(type != null || name != null);
+    if (name == null) {
+      type.writeType(buffer);
+      buffer.write(" x");
+      buffer.write(parameterNameCounter++);
+    } else if (type == null) {
+      buffer.write(name);
+    } else {
+      type.writeType(buffer);
+      buffer.write(" ");
+      buffer.write(name);
+    }
+
+    // Write a default value for optional parameters to avoid nullability
+    // errors.
+    if (optional) {
+      buffer.write(" = ");
+
+      var nominalType = type as NominalType;
+      const baseTypes = {
+        "int": "-1",
+        "Function": "_voidFunction",
+        "List": "const []",
+      };
+
+      if (baseTypes.containsKey(nominalType.name)) {
+        buffer.write(baseTypes[nominalType.name]);
+      } else if (shouldReplaceTWithInt && nominalType.name == "T") {
+        buffer.write("-1");
+      } else {
+        throw UnsupportedError("No default value for $type");
+      }
+    }
+  }
+
+  bool operator ==(other) {
+    return other is Parameter && name == other.name && type == other.type;
+  }
+
+  int get hashCode {
+    return ((name.hashCode * 37) ^ type.hashCode) & 0xFFFFFFFF;
+  }
+
+  bool get usesT => type?.usesT ?? false;
+  bool get takesT => type?.takesT ?? false;
+  bool get returnsT => type?.returnsT ?? false;
+}
+
+class GenericParameter implements TypeLike {
+  final String name;
+  final TypeLike bound;
+
+  GenericParameter(this.name, [this.bound]);
+
+  // Bound may be null.
+  @override
+  writeIdentifier(buffer) {
+    buffer.write(name);
+    buffer.write("_");
+    if (bound == null) {
+      buffer.write("null");
+    } else {
+      bound.writeIdentifier(buffer);
+    }
+  }
+
+  @override
+  writeType(buffer) {
+    buffer.write(name);
+    if (bound != null) {
+      buffer.write(" extends ");
+      bound.writeType(buffer);
+    }
+  }
+
+  bool operator ==(other) {
+    return other is GenericParameter &&
+        name == other.name &&
+        bound == other.bound;
+  }
+
+  int get hashCode {
+    return ((name.hashCode * 23) ^ bound.hashCode) & 0xFFFFFFFF;
+  }
+
+  bool get usesT => bound?.usesT ?? false;
+  bool get takesT => bound?.takesT ?? false;
+  bool get returnsT => bound?.returnsT ?? false;
+}
+
+void _describeList(StringBuffer buffer, List<Printable> list) {
+  if (list == null) {
+    buffer.write("0");
+    return;
+  }
+  buffer.write(list.length.toString());
+  buffer.write("_");
+  for (int i = 0; i < list.length; i++) {
+    if (i != 0) buffer.write("_");
+    list[i].writeIdentifier(buffer);
+  }
+}
+
+void _writeTypes(StringBuffer buffer, List<TypeLike> list,
+    [String prefix = "", String postfix = ""]) {
+  if (list == null || list.isEmpty) return;
+  buffer.write(prefix);
+  for (int i = 0; i < list.length; i++) {
+    if (i != 0) buffer.write(", ");
+    list[i].writeType(buffer);
+  }
+  buffer.write(postfix);
+}
+
+/// Write the parameters in [list] to [buffer]. If [inFunction] is true then
+/// the output are the formal parameters of a function signature (where
+/// optionals will have default values), and if [inFunction] is false then the
+/// output are formal parameter types of a function type (where default values
+/// and names of positional parameters are omitted).
+void _writeParameters(
+    StringBuffer buffer, List<Parameter> list, bool inFunction,
+    [String prefix = "", String postfix = ""]) {
+  if (list == null || list.isEmpty) return;
+  buffer.write(prefix);
+  for (int i = 0; i < list.length; i++) {
+    if (i != 0) buffer.write(", ");
+    if (inFunction) {
+      list[i].writeInFunction(buffer, optional: prefix != "");
+    } else {
+      list[i].writeType(buffer);
+    }
+  }
+  buffer.write(postfix);
+}
+
+bool _listUsesT(List elements) {
+  if (elements == null) return false;
+  return elements.any((p) => p.usesT);
+}
+
+bool _listEquals(List list1, List list2) {
+  if (list1 == list2) return true; // Also covers both being null.
+  if (list1 == null || list2 == null) return false;
+  for (int i = 0; i < list1.length; i++) {
+    if (list1[i] != list2[i]) return false;
+  }
+  return true;
+}
+
+int _listHash(List list) {
+  if (list == null) return null.hashCode;
+  int result = 71;
+  for (int i = 0; i < list.length; i++) {
+    result = ((result * 11) ^ list[i].hashCode) & 0xFFFFFFFF;
+  }
+  return result;
+}
+
+class FunctionType implements TypeLike {
+  final TypeLike returnType;
+  final List<GenericParameter> generic;
+  final List<Parameter> required;
+  final List<Parameter> optional;
+  final List<Parameter> named;
+
+  FunctionType(this.returnType, this.generic, this.required,
+      [this.optional, this.named]);
+
+  @override
+  writeIdentifier(buffer) {
+    buffer.write("Fun_");
+    if (returnType == null) {
+      buffer.write("null");
+    } else {
+      returnType.writeIdentifier(buffer);
+    }
+    buffer.write("_");
+    _describeList(buffer, generic);
+    buffer.write("_");
+    _describeList(buffer, required);
+    buffer.write("_");
+    _describeList(buffer, optional);
+    buffer.write("_");
+    _describeList(buffer, named);
+  }
+
+  @override
+  writeType(buffer) {
+    if (returnType != null) {
+      returnType.writeType(buffer);
+      buffer.write(" ");
+    }
+    buffer.write("Function");
+    if (generic != null) _writeTypes(buffer, generic, "<", ">");
+    buffer.write("(");
+    bool inFunction = false;
+    _writeParameters(buffer, required, inFunction);
+    if ((optional != null || named != null) &&
+        required != null &&
+        required.isNotEmpty) {
+      buffer.write(", ");
+    }
+    _writeParameters(buffer, optional, inFunction, "[", "]");
+    _writeParameters(buffer, named, inFunction, "{", "}");
+    buffer.write(")");
+  }
+
+  /// Writes this type as if it was a function.
+  void writeFunction(StringBuffer buffer, String name, {bool replaceT: true}) {
+    shouldReplaceTWithInt = replaceT;
+    parameterNameCounter = 0;
+
+    if (returnType != null) {
+      returnType.writeType(buffer);
+      buffer.write(" ");
+    }
+
+    buffer.write(name);
+    if (generic != null) _writeTypes(buffer, generic, "<", ">");
+    buffer.write("(");
+    bool inFunction = true;
+    _writeParameters(buffer, required, inFunction);
+    if ((optional != null || named != null) &&
+        required != null &&
+        required.isNotEmpty) {
+      buffer.write(", ");
+    }
+    _writeParameters(buffer, optional, inFunction, "[", "]");
+    _writeParameters(buffer, named, inFunction, "{", "}");
+    buffer.write(") => throw 'uncalled';");
+
+    shouldReplaceTWithInt = false;
+  }
+
+  bool operator ==(other) {
+    return returnType == other.returnType &&
+        _listEquals(generic, other.generic) &&
+        _listEquals(required, other.required) &&
+        _listEquals(optional, other.optional) &&
+        _listEquals(named, other.named);
+  }
+
+  int get hashCode {
+    return ((returnType.hashCode * 13) ^
+            (_listHash(generic) * 17) ^
+            (_listHash(required) * 53) ^
+            (_listHash(optional) ^ 31) ^
+            (_listHash(named) * 87)) &
+        0xFFFFFFFF;
+  }
+
+  bool get usesT {
+    return (returnType?.usesT ?? false) ||
+        [generic, required, optional, named].any(_listUsesT);
+  }
+
+  bool get returnsT {
+    return (returnType?.returnsT ?? false) ||
+        [generic, required, optional, named]
+            .any((l) => l?.any((p) => p.takesT) ?? false);
+  }
+
+  bool get takesT {
+    return (returnType?.takesT ?? false) ||
+        [generic, required, optional, named]
+            .any((l) => l?.any((p) => p.returnsT) ?? false);
+  }
+
+  bool get reifiedTypeUsesT {
+    return returnType?.usesT ?? returnsT;
+  }
+}
+
+class NominalType implements TypeLike {
+  final String prefix;
+  final String name;
+  final List<TypeLike> generic;
+
+  NominalType(this.name, [this.prefix, this.generic]);
+
+  @override
+  writeIdentifier(buffer) {
+    buffer.write(prefix);
+    buffer.write("_");
+    buffer.write(name);
+    _describeList(buffer, generic);
+  }
+
+  @override
+  writeType(buffer) {
+    if (prefix != null && prefix != "") {
+      buffer.write(prefix);
+      buffer.write(".");
+    }
+    if (shouldReplaceTWithInt && name == "T") {
+      buffer.write("int");
+    } else {
+      buffer.write(name);
+    }
+    _writeTypes(buffer, generic, "<", ">");
+  }
+
+  bool operator ==(other) {
+    return other is NominalType && prefix == other.prefix && name == other.name;
+  }
+
+  int get hashCode {
+    return ((prefix.hashCode * 37) ^ name.hashCode) & 0xFFFFFFFF;
+  }
+
+  bool get usesT => name == "T" || _listUsesT(generic);
+
+  bool get returnsT => name == "T" || generic?.any((t) => t.returnsT) ?? false;
+
+  bool get takesT => generic?.any((t) => t.takesT) ?? false;
+}
+
+List<TypeLike> buildFunctionTypes() {
+  List<GenericParameter> as = [
+    new GenericParameter("A"),
+    // new GenericParameter("A", new NominalType("int")),
+    // new GenericParameter("A", new NominalType("int", "core")),
+  ];
+  List<GenericParameter> bs = [
+    // new GenericParameter("B"),
+    // new GenericParameter("B", new NominalType("int")),
+    new GenericParameter("B", new NominalType("int", "core")),
+  ];
+  List<TypeLike> basicTypes = [
+    new NominalType("int"),
+    // new NominalType("int", "core"),
+    // new NominalType("List"),
+    // new NominalType("List", "core"),
+    new NominalType("Function"),
+    new NominalType("List", "", [new NominalType("Function")]),
+    new NominalType("List", "core", [new NominalType("int", "core")]),
+    new NominalType("List", "", [new NominalType("T")]),
+    // new NominalType("List", "", [new NominalType("Function")]),
+  ];
+
+  List<TypeLike> basicsPlusNull = [
+    basicTypes,
+    <TypeLike>[null]
+  ].expand((x) => x).toList();
+
+  List<TypeLike> basicsPlusNullPlusVoid = [
+    basicsPlusNull,
+    [new NominalType("void")],
+  ].expand((x) => x).toList();
+
+  List<TypeLike> basicsPlusNullPlusB = [
+    basicsPlusNull,
+    [
+      new NominalType("B"),
+      new NominalType("List", "", [new NominalType("B")])
+    ]
+  ].expand((x) => x).toList();
+
+  List<TypeLike> basicsPlusNullPlusBPlusVoid = [
+    basicsPlusNullPlusB,
+    [new NominalType("void")],
+  ].expand((x) => x).toList();
+
+  List<TypeLike> basicsPlusNullPlusA = [
+    basicsPlusNull,
+    [
+      new NominalType("A"),
+      new NominalType("List", "", [new NominalType("A")])
+    ]
+  ].expand((x) => x).toList();
+
+  List<TypeLike> basicsPlusNullPlusAPlusVoid = [
+    basicsPlusNullPlusA,
+    [new NominalType("void")],
+  ].expand((x) => x).toList();
+
+  List<TypeLike> buildFunctionTypes(TypeLike returnType, TypeLike parameterType,
+      [List<GenericParameter> generics,
+      bool generateMoreCombinations = false]) {
+    List<TypeLike> result = [];
+
+    if (parameterType == null) {
+      // int Function().
+      result.add(new FunctionType(returnType, generics, null));
+      return result;
+    }
+
+    // int Function(int x).
+    result.add(new FunctionType(
+        returnType, generics, [new Parameter(parameterType, "x")]));
+
+    if (!generateMoreCombinations) return result;
+
+    // int Function([int x]).
+    result.add(new FunctionType(
+        returnType, generics, null, [new Parameter(parameterType, "x")]));
+    // int Function(int, [int x])
+    result.add(new FunctionType(
+        returnType,
+        generics,
+        [new Parameter(new NominalType("int"), null)],
+        [new Parameter(parameterType, "x")]));
+    // int Function(int x, [int x])
+    result.add(new FunctionType(
+        returnType,
+        generics,
+        [new Parameter(new NominalType("int"), "y")],
+        [new Parameter(parameterType, "x")]));
+    // int Function(int);
+    result.add(new FunctionType(
+        returnType, generics, [new Parameter(parameterType, null)]));
+    // int Function([int]);
+    result.add(new FunctionType(
+        returnType, generics, null, [new Parameter(parameterType, null)]));
+    // int Function(int, [int])
+    result.add(new FunctionType(
+        returnType,
+        generics,
+        [new Parameter(new NominalType("int"), null)],
+        [new Parameter(parameterType, null)]));
+    // int Function(int x, [int])
+    result.add(new FunctionType(
+        returnType,
+        generics,
+        [new Parameter(new NominalType("int"), "x")],
+        [new Parameter(parameterType, null)]));
+    // int Function({int x}).
+    result.add(new FunctionType(
+        returnType, generics, null, null, [new Parameter(parameterType, "x")]));
+    // int Function(int, {int x})
+    result.add(new FunctionType(
+        returnType,
+        generics,
+        [new Parameter(new NominalType("int"), null)],
+        null,
+        [new Parameter(parameterType, "x")]));
+    // int Function(int x, {int x})
+    result.add(new FunctionType(
+        returnType,
+        generics,
+        [new Parameter(new NominalType("int"), "y")],
+        null,
+        [new Parameter(parameterType, "x")]));
+    return result;
+  }
+
+  // The "smaller" function types. May also be used non-nested.
+  List<TypeLike> functionTypes = [];
+
+  for (TypeLike returnType in basicsPlusNullPlusVoid) {
+    for (TypeLike parameterType in basicsPlusNull) {
+      bool generateMoreCombinations = true;
+      functionTypes.addAll(buildFunctionTypes(
+          returnType, parameterType, null, generateMoreCombinations));
+    }
+  }
+
+  // These use `B` from the generic type of the enclosing function.
+  List<TypeLike> returnFunctionTypesB = [];
+  for (TypeLike returnType in basicsPlusNullPlusBPlusVoid) {
+    TypeLike parameterType = new NominalType("B");
+    returnFunctionTypesB.addAll(buildFunctionTypes(returnType, parameterType));
+  }
+  for (TypeLike parameterType in basicsPlusNull) {
+    TypeLike returnType = new NominalType("B");
+    returnFunctionTypesB.addAll(buildFunctionTypes(returnType, parameterType));
+  }
+
+  for (TypeLike returnType in basicsPlusNullPlusAPlusVoid) {
+    for (TypeLike parameterType in basicsPlusNullPlusA) {
+      for (GenericParameter a in as) {
+        functionTypes
+            .addAll(buildFunctionTypes(returnType, parameterType, [a]));
+      }
+    }
+  }
+
+  List<TypeLike> types = [];
+  types.addAll(functionTypes);
+
+  // Now add some higher-order function types.
+  for (TypeLike returnType in functionTypes) {
+    types.addAll(buildFunctionTypes(returnType, null));
+    types.addAll(buildFunctionTypes(returnType, new NominalType("int")));
+    for (var b in bs) {
+      types.addAll(buildFunctionTypes(returnType, null, [b]));
+      types.addAll(buildFunctionTypes(returnType, new NominalType("int"), [b]));
+    }
+  }
+  for (TypeLike returnType in returnFunctionTypesB) {
+    for (var b in bs) {
+      types.addAll(buildFunctionTypes(returnType, null, [b]));
+      types.addAll(buildFunctionTypes(returnType, new NominalType("int"), [b]));
+    }
+  }
+
+  return types;
+}
+
+final String HEADER = """
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+// GENERATED - DON'T EDIT.
+
+import 'dart:core';
+import 'dart:core' as core;
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(f) => f;
+
+void _voidFunction() {}
+""";
+
+class Unit {
+  int typeCounter = 0;
+  final String name;
+  final StringBuffer typedefs = new StringBuffer();
+  final StringBuffer globals = new StringBuffer();
+  final StringBuffer tests = new StringBuffer();
+  final StringBuffer fields = new StringBuffer();
+  final StringBuffer statics = new StringBuffer();
+  final StringBuffer testMethods = new StringBuffer();
+  final StringBuffer methods = new StringBuffer();
+
+  Unit(this.name);
+
+  void write(StringBuffer buffer) {
+    buffer.write("""
+$HEADER
+
+$typedefs
+
+$globals
+
+class $name<T> {
+  final bool tIsBool;
+  final bool tIsInt;
+  final bool tIsDynamic;
+
+$fields
+
+  $name({this.tIsBool: false, this.tIsInt: false})
+      : tIsDynamic = !tIsBool && !tIsInt;
+
+$methods
+
+  runTests() {\n$tests  }
+
+$testMethods
+}
+
+void main() {
+  new $name().runTests();
+  new $name<int>(tIsInt: true).runTests();
+  new $name<bool>(tIsBool: true).runTests();
+}
+    """);
+  }
+}
+
+final TEST_METHOD_HEADER = """
+  /// #typeCode
+  void #testName() {""";
+
+// Tests that apply for every type.
+final COMMON_TESTS_TEMPLATE = """
+    Expect.isTrue(#staticFunName is #typeName<int>);
+    Expect.isTrue(confuse(#staticFunName) is #typeName<int>);
+    // In checked mode, verifies the type.
+    #typeCode #localName;
+    // The static function #staticFunName sets `T` to `int`.
+    if (tIsInt) {
+      #fieldName = #staticFunName as dynamic;
+      #localName = #staticFunName as dynamic;
+      #fieldName = confuse(#staticFunName);
+      #localName = confuse(#staticFunName);
+    }
+
+    Expect.isTrue(#methodFunName is #typeName<T>);
+    Expect.isTrue(#methodFunName is #typeCode);
+    Expect.isTrue(confuse(#methodFunName) is #typeName<T>);
+    // In checked mode, verifies the type.
+    #fieldName = #methodFunName;
+    #localName = #methodFunName;
+    #fieldName = confuse(#methodFunName);
+    #localName = confuse(#methodFunName);""";
+
+// Tests that depend on the typedef "T" argument.
+//
+// These tests are executed when the surrounding class is instantiated with
+// its generic type set to `int`, `dynamic` or `bool`. In the latter case, the
+// class field `tIsBool` is set to true.
+
+// While the types themselves are not affected by the class` `T`, the methods
+// of the class may use `T`:
+//
+// For example:
+//   class A<T> {
+//      f(List<T> x) {}
+//   }
+final TYPEDEF_T_TESTS_TEMPLATE = """
+    // The static function has its T always set to int.
+    Expect.isTrue(#staticFunName is #typeName<int>);
+    Expect.isFalse(#staticFunName is #typeName<bool>);
+    Expect.isTrue(confuse(#staticFunName) is #typeName<int>);
+    Expect.isFalse(confuse(#staticFunName) is #typeName<bool>);
+    if (tIsBool) {
+      Expect.throws(() { #fieldName = (#staticFunName as dynamic); });
+      Expect.throws(() { #fieldName = confuse(#staticFunName); });
+      Expect.throws(() { #localName = (#staticFunName as dynamic); });
+      Expect.throws(() { #localName = confuse(#staticFunName); });
+    }
+    if (tIsInt || tIsBool) {
+      Expect.equals(#isIntValue, #methodFunName is #typeName<int>);
+      Expect.equals(#isBoolValue, #methodFunName is #typeName<bool>);
+      Expect.equals(#isIntValue, confuse(#methodFunName) is #typeName<int>);
+      Expect.equals(#isBoolValue, confuse(#methodFunName) is #typeName<bool>);
+    }
+""";
+
+final TEST_METHOD_FOOTER = "  }";
+
+String createTypeName(int id) => "F$id";
+String createStaticFunName(int id) => "f$id";
+String createMethodFunName(int id) => "m$id";
+String createFieldName(int id) => "x$id";
+String createLocalName(int id) => "l$id";
+String createTestName(int id) => "test${createTypeName(id)}";
+
+String createTypeCode(FunctionType type) {
+  StringBuffer typeBuffer = new StringBuffer();
+  type.writeType(typeBuffer);
+  return typeBuffer.toString();
+}
+
+String createStaticFunCode(FunctionType type, int id) {
+  StringBuffer staticFunBuffer = new StringBuffer();
+  type.writeFunction(staticFunBuffer, createStaticFunName(id));
+  return staticFunBuffer.toString();
+}
+
+String createMethodFunCode(FunctionType type, int id) {
+  StringBuffer methodFunBuffer = new StringBuffer();
+  type.writeFunction(methodFunBuffer, createMethodFunName(id), replaceT: false);
+  return methodFunBuffer.toString();
+}
+
+String createTestMethodFunCode(FunctionType type, String typeCode, int id) {
+  var tIsInt = type.reifiedTypeUsesT ? 'tIsInt' : 'true';
+  var tIsBool = type.reifiedTypeUsesT ? 'tIsBool' : 'true';
+
+  String fillTemplate(String template, int id) {
+    var result = template
+        .replaceAll("#typeName", createTypeName(id))
+        .replaceAll("#staticFunName", createStaticFunName(id))
+        .replaceAll("#methodFunName", createMethodFunName(id))
+        .replaceAll("#fieldName", createFieldName(id))
+        .replaceAll("#localName", createLocalName(id))
+        .replaceAll("#testName", createTestName(id))
+        .replaceAll("#typeCode", typeCode)
+        .replaceAll("#isIntValue", tIsInt)
+        .replaceAll("#isBoolValue", tIsBool);
+    assert(!result.contains("#"));
+    return result;
+  }
+
+  String commonTests = fillTemplate(COMMON_TESTS_TEMPLATE, id);
+  String genericTTests = "";
+  if (type.usesT) {
+    genericTTests = fillTemplate(TYPEDEF_T_TESTS_TEMPLATE, id);
+  }
+  return """
+${fillTemplate(TEST_METHOD_HEADER, id)}
+$commonTests
+$genericTTests
+$TEST_METHOD_FOOTER
+""";
+}
+
+void generateTests() {
+  // Keep methods and classes smaller by distributing over several different
+  // classes.
+  List<Unit> units = [];
+  for (int i = 0; i < 100; i++) {
+    units.add(new Unit("U$i"));
+  }
+
+  var types = buildFunctionTypes();
+
+  int unitCounter = 0;
+  for (var type in types) {
+    Unit unit = units[unitCounter % units.length];
+    unitCounter++;
+    int typeCounter = unit.typeCounter++;
+
+    String typeName = createTypeName(typeCounter);
+    String fieldName = createFieldName(typeCounter);
+    String testName = createTestName(typeCounter);
+
+    String typeCode = createTypeCode(type);
+    String staticFunCode = createStaticFunCode(type, typeCounter);
+    String methodFunCode = createMethodFunCode(type, typeCounter);
+    String testMethodCode =
+        createTestMethodFunCode(type, typeCode, typeCounter);
+
+    unit.typedefs.writeln("typedef $typeName<T> = $typeCode;");
+    unit.globals.writeln(staticFunCode);
+    // Mark all fields 'late' to avoid uninitialized field errors.
+    unit.fields.writeln("  late $typeCode $fieldName;");
+    unit.methods.writeln("  $methodFunCode");
+    unit.testMethods.writeln("$testMethodCode");
+    unit.tests.writeln("    $testName();");
+  }
+
+  for (int i = 0; i < units.length; i++) {
+    var unit = units[i];
+    var buffer = new StringBuffer();
+    unit.write(buffer);
+    var path = Platform.script.resolve("function_type${i}_test.dart").path;
+    new File(path).writeAsStringSync(buffer.toString());
+  }
+}
+
+void printUsage() {
+  print("""
+Generates function type tests.
+
+All tests are generated in the same directory as this script.
+""");
+}
+
+void main(List<String> arguments) {
+  if (arguments.length != 0) {
+    printUsage();
+    return;
+  }
+  generateTests();
+}
diff --git a/tests/language/nnbd/required_named_parameters/required_named_args_legacy_test.dart b/tests/language/nnbd/required_named_parameters/required_named_args_legacy_test.dart
index 8dee572..bffc4f9 100644
--- a/tests/language/nnbd/required_named_parameters/required_named_args_legacy_test.dart
+++ b/tests/language/nnbd/required_named_parameters/required_named_args_legacy_test.dart
@@ -15,13 +15,17 @@
 
   // Valid: Invocation with all arguments provided.
   f("", p1: 100, p2: "", p3: true);
+  Function.apply(f, [""], {#p1: 100, #p2: "", #p3: true});
 
   // Valid: Invocation that omits non-required named arguments.
   f("", p1: 100, p2: "");
+  Function.apply(f, [""], {#p1: 100, #p2: ""});
 
   // Valid: Invocation may pass null as a required named argument.
   f("", p1: null, p2: null);
+  Function.apply(f, [""], {#p1: null, #p2: null});
 
   // Valid: Invocation may omit a required named argument.
   f("", p1: 100);
+  Function.apply(f, [""], {#p1: 100});
 }
diff --git a/tests/language/nnbd/required_named_parameters/required_named_args_strong_test.dart b/tests/language/nnbd/required_named_parameters/required_named_args_strong_test.dart
index c066411..7139036 100644
--- a/tests/language/nnbd/required_named_parameters/required_named_args_strong_test.dart
+++ b/tests/language/nnbd/required_named_parameters/required_named_args_strong_test.dart
@@ -32,9 +32,15 @@
   Expect.throws(() {
     f("", p1: null, p2: null);
   });
+  Expect.throws(() {
+    Function.apply(f, [""], {#p1: null, #p2: null});
+  });
 
   // Invalid: Invocation that omits a required named argument.
   Expect.throws(() {
     f("", p1: 100);
   });
+  Expect.throws(() {
+    Function.apply(f, [""], {#p1: 100});
+  });
 }
diff --git a/tests/language/nnbd/required_named_parameters/required_named_args_test.dart b/tests/language/nnbd/required_named_parameters/required_named_args_test.dart
index c6c6f68..d19b0eb 100644
--- a/tests/language/nnbd/required_named_parameters/required_named_args_test.dart
+++ b/tests/language/nnbd/required_named_parameters/required_named_args_test.dart
@@ -19,7 +19,9 @@
 
   // Valid: Invocation with all arguments provided.
   f("", p1: 100, p2: "", p3: true);
+  Function.apply(f, [""], {#p1: 100, #p2: "", #p3: true});
 
   // Valid: Invocation that omits non-required named arguments.
   f("", p1: 100, p2: "");
+  Function.apply(f, [""], {#p1: 100, #p2: ""});
 }
diff --git a/tests/language/nnbd/required_named_parameters/required_named_args_weak_test.dart b/tests/language/nnbd/required_named_parameters/required_named_args_weak_test.dart
index 5468b69..7d161e9 100644
--- a/tests/language/nnbd/required_named_parameters/required_named_args_weak_test.dart
+++ b/tests/language/nnbd/required_named_parameters/required_named_args_weak_test.dart
@@ -26,7 +26,9 @@
 
   // Valid: Invocation may pass null as a required named argument in weak mode.
   f("", p1: null, p2: null);
+  Function.apply(f, [""], {#p1: null, #p2: null});
 
   // Valid: Invocation may omit a required named argument in weak mode.
   f("", p1: 100);
+  Function.apply(f, [""], {#p1: 100});
 }
diff --git a/tests/lib/async/future_test.dart b/tests/lib/async/future_test.dart
index e65d28a..b084c86 100644
--- a/tests/lib/async/future_test.dart
+++ b/tests/lib/async/future_test.dart
@@ -904,7 +904,7 @@
         new Iterable.generate(5, (i) {
           if (i != 3) return new Future.delayed(cms * (i + 1), () => i);
           throw "throwing synchronously in iterable";
-        }), cleanUp: (index) {
+        }), cleanUp: (dynamic index) {
       Expect.isFalse(cleanups[index]);
       cleanups[index] = true;
       if (cleanups.every((x) => x)) asyncEnd();
diff --git a/tests/lib/async/futures_test.dart b/tests/lib/async/futures_test.dart
index 1cf5e0e..9d8597f 100644
--- a/tests/lib/async/futures_test.dart
+++ b/tests/lib/async/futures_test.dart
@@ -193,7 +193,7 @@
 
 Future testForEach() {
   final seen = <int>[];
-  return Future.forEach([1, 2, 3, 4, 5], (n) {
+  return Future.forEach([1, 2, 3, 4, 5], (dynamic n) {
     seen.add(n);
     return new Future.value();
   }).then((_) => Expect.listEquals([1, 2, 3, 4, 5], seen));
@@ -207,7 +207,7 @@
 
 Future testForEachWithException() {
   final seen = <int>[];
-  return Future.forEach([1, 2, 3, 4, 5], (n) {
+  return Future.forEach([1, 2, 3, 4, 5], (dynamic n) {
     if (n == 4) throw 'correct exception';
     seen.add(n);
     return new Future.value();
diff --git a/tests/lib/async/stream_controller_async_test.dart b/tests/lib/async/stream_controller_async_test.dart
index dc83af6..b77d0df 100644
--- a/tests/lib/async/stream_controller_async_test.dart
+++ b/tests/lib/async/stream_controller_async_test.dart
@@ -22,7 +22,7 @@
   test("StreamController.fold", () {
     StreamController c = new StreamController();
     Stream stream = c.stream.asBroadcastStream(onCancel: cancelSub);
-    stream.fold(0, (a, b) => a + b).then(expectAsync((int v) {
+    stream.fold<dynamic>(0, (a, b) => a + b).then(expectAsync((int v) {
       Expect.equals(42, v);
     }));
     c.add(10);
@@ -46,7 +46,7 @@
   test("Single-subscription StreamController.fold", () {
     StreamController c = new StreamController();
     Stream stream = c.stream;
-    stream.fold(0, (a, b) => a + b).then(expectAsync((int v) {
+    stream.fold<dynamic>(0, (a, b) => a + b).then(expectAsync((int v) {
       Expect.equals(42, v);
     }));
     c.add(10);
diff --git a/tests/lib/async/zone_run_unary_test.dart b/tests/lib/async/zone_run_unary_test.dart
index b505bc5d..0f7fd74 100644
--- a/tests/lib/async/zone_run_unary_test.dart
+++ b/tests/lib/async/zone_run_unary_test.dart
@@ -25,7 +25,7 @@
 
   events.add("zone forked");
   Zone expectedZone = forked;
-  var result = forked.runUnary((arg) {
+  var result = forked.runUnary((dynamic arg) {
     Expect.identical(expectedZone, Zone.current);
     events.add("run closure");
     return arg + 3;
@@ -43,7 +43,7 @@
 
   asyncStart();
   shouldForward = true;
-  result = forked.runUnary((arg) {
+  result = forked.runUnary((dynamic arg) {
     Expect.identical(forked, Zone.current);
     events.add("run closure 2");
     scheduleMicrotask(() {
diff --git a/tests/lib/convert/chunked_conversion_utf82_test.dart b/tests/lib/convert/chunked_conversion_utf82_test.dart
index bc0b200..2e07f87 100644
--- a/tests/lib/convert/chunked_conversion_utf82_test.dart
+++ b/tests/lib/convert/chunked_conversion_utf82_test.dart
@@ -46,11 +46,14 @@
   return buffer.toString();
 }
 
-final TESTS = [
+final TESTS0 = [
   // Unfinished UTF-8 sequences.
   [0xc3],
   [0xE2, 0x82],
-  [0xF0, 0xA4, 0xAD],
+  [0xF0, 0xA4, 0xAD]
+];
+
+final TESTS1 = [
   // Overlong encoding of euro-sign.
   [0xF0, 0x82, 0x82, 0xAC],
   // Other overlong/unfinished sequences.
@@ -77,11 +80,11 @@
   // Test that 0xC0|1, 0x80 does not eat the next character.
   [
     [0xC0, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   [
     [0xC1, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   // 0xF5 .. 0xFF never appear in valid UTF-8 sequences.
   [
@@ -220,44 +223,49 @@
 ];
 
 main() {
-  var allTests = TESTS.expand((test) {
+  var allTests = [...TESTS0, ...TESTS1].expand((test) {
     // Pairs of test and expected string output when malformed strings are
-    // allowed. Replacement character: U+FFFD
+    // allowed. Replacement character: U+FFFD, one per unfinished sequence or
+    // undecodable byte.
+    String replacement =
+        TESTS0.contains(test) ? "\u{FFFD}" : "\u{FFFD}" * test.length;
     return [
-      [test, "\u{FFFD}"],
+      [test, "${replacement}"],
       [
-        new List<int>.from([0x61])..addAll(test),
-        "a\u{FFFD}"
+        [0x61, ...test],
+        "a${replacement}"
       ],
       [
-        new List<int>.from([0x61])
-          ..addAll(test)
-          ..add(0x61),
-        "a\u{FFFD}a"
-      ],
-      [new List<int>.from(test)..add(0x61), "\u{FFFD}a"],
-      [new List<int>.from(test)..addAll(test), "\u{FFFD}\u{FFFD}"],
-      [
-        new List<int>.from(test)
-          ..add(0x61)
-          ..addAll(test),
-        "\u{FFFD}a\u{FFFD}"
+        [0x61, ...test, 0x61],
+        "a${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test),
-        "å\u{FFFD}"
+        [...test, 0x61],
+        "${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test)..addAll([0xc3, 0xa5]),
-        "å\u{FFFD}å"
+        [...test, ...test],
+        "${replacement}${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5]),
-        "\u{FFFD}å"
+        [...test, 0x61, ...test],
+        "${replacement}a${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5])..addAll(test),
-        "\u{FFFD}å\u{FFFD}"
+        [0xc3, 0xa5, ...test],
+        "å${replacement}"
+      ],
+      [
+        [0xc3, 0xa5, ...test, 0xc3, 0xa5],
+        "å${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5],
+        "${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5, ...test],
+        "${replacement}å${replacement}"
       ]
     ];
   });
diff --git a/tests/lib/convert/chunked_conversion_utf86_test.dart b/tests/lib/convert/chunked_conversion_utf86_test.dart
index a42e752..8c9a08c 100644
--- a/tests/lib/convert/chunked_conversion_utf86_test.dart
+++ b/tests/lib/convert/chunked_conversion_utf86_test.dart
@@ -28,11 +28,14 @@
   return buffer.toString();
 }
 
-final TESTS = [
+final TESTS0 = [
   // Unfinished UTF-8 sequences.
   [0xc3],
   [0xE2, 0x82],
-  [0xF0, 0xA4, 0xAD],
+  [0xF0, 0xA4, 0xAD]
+];
+
+final TESTS1 = [
   // Overlong encoding of euro-sign.
   [0xF0, 0x82, 0x82, 0xAC],
   // Other overlong/unfinished sequences.
@@ -59,11 +62,11 @@
   // Test that 0xC0|1, 0x80 does not eat the next character.
   [
     [0xC0, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   [
     [0xC1, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   // 0xF5 .. 0xFF never appear in valid UTF-8 sequences.
   [
@@ -202,44 +205,49 @@
 ];
 
 main() {
-  var allTests = TESTS.expand((test) {
+  var allTests = [...TESTS0, ...TESTS1].expand((test) {
     // Pairs of test and expected string output when malformed strings are
-    // allowed. Replacement character: U+FFFD
+    // allowed. Replacement character: U+FFFD, one per unfinished sequence or
+    // undecodable byte.
+    String replacement =
+        TESTS0.contains(test) ? "\u{FFFD}" : "\u{FFFD}" * test.length;
     return [
-      [test, "\u{FFFD}"],
+      [test, "${replacement}"],
       [
-        new List<int>.from([0x61])..addAll(test),
-        "a\u{FFFD}"
+        [0x61, ...test],
+        "a${replacement}"
       ],
       [
-        new List<int>.from([0x61])
-          ..addAll(test)
-          ..add(0x61),
-        "a\u{FFFD}a"
-      ],
-      [new List<int>.from(test)..add(0x61), "\u{FFFD}a"],
-      [new List<int>.from(test)..addAll(test), "\u{FFFD}\u{FFFD}"],
-      [
-        new List<int>.from(test)
-          ..add(0x61)
-          ..addAll(test),
-        "\u{FFFD}a\u{FFFD}"
+        [0x61, ...test, 0x61],
+        "a${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test),
-        "å\u{FFFD}"
+        [...test, 0x61],
+        "${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test)..addAll([0xc3, 0xa5]),
-        "å\u{FFFD}å"
+        [...test, ...test],
+        "${replacement}${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5]),
-        "\u{FFFD}å"
+        [...test, 0x61, ...test],
+        "${replacement}a${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5])..addAll(test),
-        "\u{FFFD}å\u{FFFD}"
+        [0xc3, 0xa5, ...test],
+        "å${replacement}"
+      ],
+      [
+        [0xc3, 0xa5, ...test, 0xc3, 0xa5],
+        "å${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5],
+        "${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5, ...test],
+        "${replacement}å${replacement}"
       ]
     ];
   });
diff --git a/tests/lib/convert/chunked_conversion_utf87_test.dart b/tests/lib/convert/chunked_conversion_utf87_test.dart
index ab42ee2..5434f1f 100644
--- a/tests/lib/convert/chunked_conversion_utf87_test.dart
+++ b/tests/lib/convert/chunked_conversion_utf87_test.dart
@@ -49,11 +49,14 @@
   return utf8.decode(bytes);
 }
 
-final TESTS = [
+final TESTS0 = [
   // Unfinished UTF-8 sequences.
   [0xc3],
   [0xE2, 0x82],
-  [0xF0, 0xA4, 0xAD],
+  [0xF0, 0xA4, 0xAD]
+];
+
+final TESTS1 = [
   // Overlong encoding of euro-sign.
   [0xF0, 0x82, 0x82, 0xAC],
   // Other overlong/unfinished sequences.
@@ -80,11 +83,11 @@
   // Test that 0xC0|1, 0x80 does not eat the next character.
   [
     [0xC0, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   [
     [0xC1, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   // 0xF5 .. 0xFF never appear in valid UTF-8 sequences.
   [
@@ -223,44 +226,49 @@
 ];
 
 main() {
-  var allTests = TESTS.expand((test) {
+  var allTests = [...TESTS0, ...TESTS1].expand((test) {
     // Pairs of test and expected string output when malformed strings are
-    // allowed. Replacement character: U+FFFD
+    // allowed. Replacement character: U+FFFD, one per unfinished sequence or
+    // undecodable byte.
+    String replacement =
+        TESTS0.contains(test) ? "\u{FFFD}" : "\u{FFFD}" * test.length;
     return [
-      [test, "\u{FFFD}"],
+      [test, "${replacement}"],
       [
-        new List<int>.from([0x61])..addAll(test),
-        "a\u{FFFD}"
+        [0x61, ...test],
+        "a${replacement}"
       ],
       [
-        new List<int>.from([0x61])
-          ..addAll(test)
-          ..add(0x61),
-        "a\u{FFFD}a"
-      ],
-      [new List<int>.from(test)..add(0x61), "\u{FFFD}a"],
-      [new List<int>.from(test)..addAll(test), "\u{FFFD}\u{FFFD}"],
-      [
-        new List<int>.from(test)
-          ..add(0x61)
-          ..addAll(test),
-        "\u{FFFD}a\u{FFFD}"
+        [0x61, ...test, 0x61],
+        "a${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test),
-        "å\u{FFFD}"
+        [...test, 0x61],
+        "${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test)..addAll([0xc3, 0xa5]),
-        "å\u{FFFD}å"
+        [...test, ...test],
+        "${replacement}${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5]),
-        "\u{FFFD}å"
+        [...test, 0x61, ...test],
+        "${replacement}a${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5])..addAll(test),
-        "\u{FFFD}å\u{FFFD}"
+        [0xc3, 0xa5, ...test],
+        "å${replacement}"
+      ],
+      [
+        [0xc3, 0xa5, ...test, 0xc3, 0xa5],
+        "å${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5],
+        "${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5, ...test],
+        "${replacement}å${replacement}"
       ]
     ];
   });
diff --git a/tests/lib/convert/chunked_conversion_utf88_test.dart b/tests/lib/convert/chunked_conversion_utf88_test.dart
index c0a63d7..93cab53b 100644
--- a/tests/lib/convert/chunked_conversion_utf88_test.dart
+++ b/tests/lib/convert/chunked_conversion_utf88_test.dart
@@ -112,8 +112,7 @@
   const LEADING_SURROGATE = 0xd801;
   const TRAILING_SURROGATE = 0xdc12;
   const UTF8_ENCODING = const [0xf0, 0x90, 0x90, 0x92];
-  const UTF8_LEADING = const [0xed, 0xa0, 0x81];
-  const UTF8_TRAILING = const [0xed, 0xb0, 0x92];
+  const UTF8_REPLACEMENT = const [0xef, 0xbf, 0xbd];
   const CHAR_A = 0x61;
 
   // Test surrogates at all kinds of locations.
@@ -129,17 +128,17 @@
     codeUnits[i] = LEADING_SURROGATE;
     var str = new String.fromCharCodes(codeUnits);
     var bytes = new List.filled(i + 3, CHAR_A);
-    bytes[i] = UTF8_LEADING[0];
-    bytes[i + 1] = UTF8_LEADING[1];
-    bytes[i + 2] = UTF8_LEADING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits[i] = TRAILING_SURROGATE;
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 3, CHAR_A);
-    bytes[i] = UTF8_TRAILING[0];
-    bytes[i + 1] = UTF8_TRAILING[1];
-    bytes[i + 2] = UTF8_TRAILING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits.add(CHAR_A);
@@ -158,36 +157,36 @@
     codeUnits[i + 1] = TRAILING_SURROGATE;
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 6, CHAR_A);
-    bytes[i] = UTF8_TRAILING[0];
-    bytes[i + 1] = UTF8_TRAILING[1];
-    bytes[i + 2] = UTF8_TRAILING[2];
-    bytes[i + 3] = UTF8_TRAILING[0];
-    bytes[i + 4] = UTF8_TRAILING[1];
-    bytes[i + 5] = UTF8_TRAILING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits[i] = LEADING_SURROGATE;
     codeUnits[i + 1] = LEADING_SURROGATE;
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 6, CHAR_A);
-    bytes[i] = UTF8_LEADING[0];
-    bytes[i + 1] = UTF8_LEADING[1];
-    bytes[i + 2] = UTF8_LEADING[2];
-    bytes[i + 3] = UTF8_LEADING[0];
-    bytes[i + 4] = UTF8_LEADING[1];
-    bytes[i + 5] = UTF8_LEADING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits[i] = TRAILING_SURROGATE;
     codeUnits[i + 1] = LEADING_SURROGATE;
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 6, CHAR_A);
-    bytes[i] = UTF8_TRAILING[0];
-    bytes[i + 1] = UTF8_TRAILING[1];
-    bytes[i + 2] = UTF8_TRAILING[2];
-    bytes[i + 3] = UTF8_LEADING[0];
-    bytes[i + 4] = UTF8_LEADING[1];
-    bytes[i + 5] = UTF8_LEADING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits.add(CHAR_A);
@@ -210,12 +209,12 @@
     codeUnits[i + 2] = CHAR_A; // Add trailing 'a'.
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 7, CHAR_A);
-    bytes[i] = UTF8_TRAILING[0];
-    bytes[i + 1] = UTF8_TRAILING[1];
-    bytes[i + 2] = UTF8_TRAILING[2];
-    bytes[i + 3] = UTF8_TRAILING[0];
-    bytes[i + 4] = UTF8_TRAILING[1];
-    bytes[i + 5] = UTF8_TRAILING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits[i] = LEADING_SURROGATE;
@@ -223,12 +222,12 @@
     codeUnits[i + 2] = CHAR_A; // Add trailing 'a'.
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 7, CHAR_A);
-    bytes[i] = UTF8_LEADING[0];
-    bytes[i + 1] = UTF8_LEADING[1];
-    bytes[i + 2] = UTF8_LEADING[2];
-    bytes[i + 3] = UTF8_LEADING[0];
-    bytes[i + 4] = UTF8_LEADING[1];
-    bytes[i + 5] = UTF8_LEADING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits[i] = TRAILING_SURROGATE;
@@ -236,12 +235,12 @@
     codeUnits[i + 2] = CHAR_A; // Add trailing 'a'.
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 7, CHAR_A);
-    bytes[i] = UTF8_TRAILING[0];
-    bytes[i + 1] = UTF8_TRAILING[1];
-    bytes[i + 2] = UTF8_TRAILING[2];
-    bytes[i + 3] = UTF8_LEADING[0];
-    bytes[i + 4] = UTF8_LEADING[1];
-    bytes[i + 5] = UTF8_LEADING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     // Make sure the invariant is correct.
diff --git a/tests/lib/convert/json_utf8_chunk_test.dart b/tests/lib/convert/json_utf8_chunk_test.dart
index c18f330..e75019d 100644
--- a/tests/lib/convert/json_utf8_chunk_test.dart
+++ b/tests/lib/convert/json_utf8_chunk_test.dart
@@ -284,69 +284,69 @@
 void testMalformed() {
   // Overlong encodings.
   jsonMalformedTest(
-      "overlong-0-2", "@\uFFFD@", [0x22, 0x40, 0xc0, 0x80, 0x40, 0x22]);
-  jsonMalformedTest(
-      "overlong-0-3", "@\uFFFD@", [0x22, 0x40, 0xe0, 0x80, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("overlong-0-4", "@\uFFFD@",
+      "overlong-0-2", "@\uFFFD\uFFFD@", [0x22, 0x40, 0xc0, 0x80, 0x40, 0x22]);
+  jsonMalformedTest("overlong-0-3", "@\uFFFD\uFFFD\uFFFD@",
+      [0x22, 0x40, 0xe0, 0x80, 0x80, 0x40, 0x22]);
+  jsonMalformedTest("overlong-0-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0x80, 0x80, 0x40, 0x22]);
 
   jsonMalformedTest(
-      "overlong-7f-2", "@\uFFFD@", [0x22, 0x40, 0xc1, 0xbf, 0x40, 0x22]);
-  jsonMalformedTest(
-      "overlong-7f-3", "@\uFFFD@", [0x22, 0x40, 0xe0, 0x81, 0xbf, 0x40, 0x22]);
-  jsonMalformedTest("overlong-7f-4", "@\uFFFD@",
+      "overlong-7f-2", "@\uFFFD\uFFFD@", [0x22, 0x40, 0xc1, 0xbf, 0x40, 0x22]);
+  jsonMalformedTest("overlong-7f-3", "@\uFFFD\uFFFD\uFFFD@",
+      [0x22, 0x40, 0xe0, 0x81, 0xbf, 0x40, 0x22]);
+  jsonMalformedTest("overlong-7f-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0x81, 0xbf, 0x40, 0x22]);
 
-  jsonMalformedTest(
-      "overlong-80-3", "@\uFFFD@", [0x22, 0x40, 0xe0, 0x82, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("overlong-80-4", "@\uFFFD@",
+  jsonMalformedTest("overlong-80-3", "@\uFFFD\uFFFD\uFFFD@",
+      [0x22, 0x40, 0xe0, 0x82, 0x80, 0x40, 0x22]);
+  jsonMalformedTest("overlong-80-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0x82, 0x80, 0x40, 0x22]);
 
-  jsonMalformedTest(
-      "overlong-7ff-3", "@\uFFFD@", [0x22, 0x40, 0xe0, 0x9f, 0xbf, 0x40, 0x22]);
-  jsonMalformedTest("overlong-7ff-4", "@\uFFFD@",
+  jsonMalformedTest("overlong-7ff-3", "@\uFFFD\uFFFD\uFFFD@",
+      [0x22, 0x40, 0xe0, 0x9f, 0xbf, 0x40, 0x22]);
+  jsonMalformedTest("overlong-7ff-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0x9f, 0xbf, 0x40, 0x22]);
 
-  jsonMalformedTest("overlong-800-4", "@\uFFFD@",
+  jsonMalformedTest("overlong-800-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0xa0, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("overlong-ffff-4", "@\uFFFD@",
+  jsonMalformedTest("overlong-ffff-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x8f, 0xbf, 0xbf, 0x40, 0x22]);
 
   // Unterminated multibyte sequences.
   jsonMalformedTest(
       "unterminated-2-normal", "@\uFFFD@", [0x22, 0x40, 0xc0, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-3-normal", "@\uFFFD@",
+  jsonMalformedTest("unterminated-3-normal", "@\uFFFD\uFFFD@",
       [0x22, 0x40, 0xe0, 0x80, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-4-normal", "@\uFFFD@",
+  jsonMalformedTest("unterminated-4-normal", "@\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0x80, 0x40, 0x22]);
 
   jsonMalformedTest("unterminated-2-multi", "@\uFFFD\x80@",
       [0x22, 0x40, 0xc0, 0xc2, 0x80, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-3-multi", "@\uFFFD\x80@",
+  jsonMalformedTest("unterminated-3-multi", "@\uFFFD\uFFFD\x80@",
       [0x22, 0x40, 0xe0, 0x80, 0xc2, 0x80, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-4-multi", "@\uFFFD\x80@",
+  jsonMalformedTest("unterminated-4-multi", "@\uFFFD\uFFFD\uFFFD\x80@",
       [0x22, 0x40, 0xf0, 0x80, 0x80, 0xc2, 0x80, 0x40, 0x22]);
 
   jsonMalformedTest("unterminated-2-escape", "@\uFFFD\n@",
       [0x22, 0x40, 0xc0, 0x5c, 0x6e, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-3-escape", "@\uFFFD\n@",
+  jsonMalformedTest("unterminated-3-escape", "@\uFFFD\uFFFD\n@",
       [0x22, 0x40, 0xe0, 0x80, 0x5c, 0x6e, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-4-escape", "@\uFFFD\n@",
+  jsonMalformedTest("unterminated-4-escape", "@\uFFFD\uFFFD\uFFFD\n@",
       [0x22, 0x40, 0xf0, 0x80, 0x80, 0x5c, 0x6e, 0x40, 0x22]);
 
   jsonMalformedTest("unterminated-2-end", "@\uFFFD", [0x22, 0x40, 0xc0, 0x22]);
 
   jsonMalformedTest(
-      "unterminated-3-end", "@\uFFFD", [0x22, 0x40, 0xe0, 0x80, 0x22]);
+      "unterminated-3-end", "@\uFFFD\uFFFD", [0x22, 0x40, 0xe0, 0x80, 0x22]);
 
-  jsonMalformedTest(
-      "unterminated-4-end", "@\uFFFD", [0x22, 0x40, 0xf0, 0x80, 0x80, 0x22]);
+  jsonMalformedTest("unterminated-4-end", "@\uFFFD\uFFFD\uFFFD",
+      [0x22, 0x40, 0xf0, 0x80, 0x80, 0x22]);
 
   // Unexpected continuation byte
   // - after a normal character.
@@ -372,13 +372,13 @@
       "leading-2", "@\uFFFD\x80@", [0x22, 0x40, 0xc0, 0xc2, 0x80, 0x40, 0x22]);
   jsonMalformedTest("leading-3-1", "@\uFFFD\x80@",
       [0x22, 0x40, 0xe0, 0xc2, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("leading-3-2", "@\uFFFD\x80@",
+  jsonMalformedTest("leading-3-2", "@\uFFFD\uFFFD\x80@",
       [0x22, 0x40, 0xe0, 0x80, 0xc2, 0x80, 0x40, 0x22]);
   jsonMalformedTest("leading-4-1", "@\uFFFD\x80@",
       [0x22, 0x40, 0xf0, 0xc2, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("leading-4-2", "@\uFFFD\x80@",
+  jsonMalformedTest("leading-4-2", "@\uFFFD\uFFFD\x80@",
       [0x22, 0x40, 0xf0, 0x80, 0xc2, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("leading-4-3", "@\uFFFD\x80@",
+  jsonMalformedTest("leading-4-3", "@\uFFFD\uFFFD\uFFFD\x80@",
       [0x22, 0x40, 0xf0, 0x80, 0x80, 0xc2, 0x80, 0x40, 0x22]);
 
   // Overlong encodings of ASCII outside of strings always fail.
diff --git a/tests/lib/convert/line_splitter_test.dart b/tests/lib/convert/line_splitter_test.dart
index 81b4bf3..4196bf0 100644
--- a/tests/lib/convert/line_splitter_test.dart
+++ b/tests/lib/convert/line_splitter_test.dart
@@ -26,7 +26,7 @@
 
   var inputs = const ['line1', 'line2', 'long line 3', ' line 4 ', 'l5'];
 
-  var buffer = inputs.fold(new StringBuffer(), (buff, e) {
+  var buffer = inputs.fold(new StringBuffer(), (dynamic buff, dynamic e) {
     buff.write(e);
     buff.write(lineTerminators[breakIndex]);
 
diff --git a/tests/lib/convert/utf82_test.dart b/tests/lib/convert/utf82_test.dart
index df08103..cf0c2b0 100644
--- a/tests/lib/convert/utf82_test.dart
+++ b/tests/lib/convert/utf82_test.dart
@@ -28,11 +28,14 @@
   return new Utf8Codec(allowMalformed: true).decoder.convert(bytes);
 }
 
-final TESTS = [
+final TESTS0 = [
   // Unfinished UTF-8 sequences.
   [0xc3],
   [0xE2, 0x82],
-  [0xF0, 0xA4, 0xAD],
+  [0xF0, 0xA4, 0xAD]
+];
+
+final TESTS1 = [
   // Overlong encoding of euro-sign.
   [0xF0, 0x82, 0x82, 0xAC],
   // Other overlong/unfinished sequences.
@@ -64,11 +67,11 @@
   // Test that 0xC0|1, 0x80 does not eat the next character.
   [
     [0xC0, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   [
     [0xC1, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   // 0xF5 .. 0xFF never appear in valid UTF-8 sequences.
   [
@@ -207,44 +210,49 @@
 ];
 
 main() {
-  var allTests = TESTS.expand((test) {
+  var allTests = [...TESTS0, ...TESTS1].expand((test) {
     // Pairs of test and expected string output when malformed strings are
-    // allowed. Replacement character: U+FFFD
+    // allowed. Replacement character: U+FFFD, one per unfinished sequence or
+    // undecodable byte.
+    String replacement =
+        TESTS0.contains(test) ? "\u{FFFD}" : "\u{FFFD}" * test.length;
     return [
-      [test, "\u{FFFD}"],
+      [test, "${replacement}"],
       [
-        new List<int>.from([0x61])..addAll(test),
-        "a\u{FFFD}"
+        [0x61, ...test],
+        "a${replacement}"
       ],
       [
-        new List<int>.from([0x61])
-          ..addAll(test)
-          ..add(0x61),
-        "a\u{FFFD}a"
-      ],
-      [new List<int>.from(test)..add(0x61), "\u{FFFD}a"],
-      [new List<int>.from(test)..addAll(test), "\u{FFFD}\u{FFFD}"],
-      [
-        new List<int>.from(test)
-          ..add(0x61)
-          ..addAll(test),
-        "\u{FFFD}a\u{FFFD}"
+        [0x61, ...test, 0x61],
+        "a${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test),
-        "å\u{FFFD}"
+        [...test, 0x61],
+        "${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test)..addAll([0xc3, 0xa5]),
-        "å\u{FFFD}å"
+        [...test, ...test],
+        "${replacement}${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5]),
-        "\u{FFFD}å"
+        [...test, 0x61, ...test],
+        "${replacement}a${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5])..addAll(test),
-        "\u{FFFD}å\u{FFFD}"
+        [0xc3, 0xa5, ...test],
+        "å${replacement}"
+      ],
+      [
+        [0xc3, 0xa5, ...test, 0xc3, 0xa5],
+        "å${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5],
+        "${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5, ...test],
+        "${replacement}å${replacement}"
       ]
     ];
   });
diff --git a/tests/lib/convert/utf84_test.dart b/tests/lib/convert/utf84_test.dart
index bc1db59..566b1fa 100755
--- a/tests/lib/convert/utf84_test.dart
+++ b/tests/lib/convert/utf84_test.dart
@@ -727,10 +727,14 @@
   Expect.listEquals([0xe000], utf8ToRunes([0xee, 0x80, 0x80]), "e000");
   Expect.listEquals([unicodeReplacementCharacterRune],
       utf8ToRunes([0xef, 0xbf, 0xbd]), "fffd");
-  Expect
-      .listEquals([0x10ffff], utf8ToRunes([0xf4, 0x8f, 0xbf, 0xbf]), "10ffff");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xf4, 0x90, 0x80, 0x80]), "110000");
+  Expect.listEquals(
+      [0x10ffff], utf8ToRunes([0xf4, 0x8f, 0xbf, 0xbf]), "10ffff");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xf4, 0x90, 0x80, 0x80]), "110000");
 
   // unexpected continuation bytes
   Expect.listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0x80]),
@@ -795,12 +799,15 @@
   // Sequences with last continuation byte missing
   Expect.listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xc2]),
       "2-byte sequence with last byte missing");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xe0, 0x80]), "3-byte sequence with last byte missing");
   Expect.listEquals(
-      [unicodeReplacementCharacterRune],
-      utf8ToRunes([0xf0, 0x80, 0x80]),
-      "4-byte sequence with last byte missing");
+      [unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
+      utf8ToRunes([0xe0, 0x80]),
+      "3-byte sequence with last byte missing");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xf0, 0x80, 0x80]), "4-byte sequence with last byte missing");
   Expect.listEquals([
     unicodeReplacementCharacterRune,
     unicodeReplacementCharacterRune,
@@ -871,6 +878,9 @@
         unicodeReplacementCharacterRune,
         unicodeReplacementCharacterRune,
         unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
         unicodeReplacementCharacterRune
       ],
       utf8ToRunes([
@@ -890,8 +900,8 @@
         0x80,
         0x80,
         0xdf,
-        0xef,
-        0xbf,
+        0xef, // These two bytes form one incomplete sequence.
+        0xbf, // All others form one per byte.
         0xf7,
         0xbf,
         0xbf,
@@ -908,10 +918,10 @@
       "Concatenation of incomplete sequences");
 
   // Impossible bytes
-  Expect
-      .listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xfe]), "fe");
-  Expect
-      .listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xff]), "ff");
+  Expect.listEquals(
+      [unicodeReplacementCharacterRune], utf8ToRunes([0xfe]), "fe");
+  Expect.listEquals(
+      [unicodeReplacementCharacterRune], utf8ToRunes([0xff]), "ff");
   Expect.listEquals([
     unicodeReplacementCharacterRune,
     unicodeReplacementCharacterRune,
@@ -921,11 +931,20 @@
 
   // Overlong sequences
   Expect.listEquals(
-      [unicodeReplacementCharacterRune], utf8ToRunes([0xc0, 0xaf]), "c0 af");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xe0, 0x80, 0xaf]), "e0 80 af");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xf0, 0x80, 0x80, 0xaf]), "f0 80 80 af");
+      [unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
+      utf8ToRunes([0xc0, 0xaf]),
+      "c0 af");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xe0, 0x80, 0xaf]), "e0 80 af");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xf0, 0x80, 0x80, 0xaf]), "f0 80 80 af");
   Expect.listEquals([
     unicodeReplacementCharacterRune,
     unicodeReplacementCharacterRune,
@@ -943,11 +962,20 @@
   ], utf8ToRunes([0xfc, 0x80, 0x80, 0x80, 0x80, 0xaf]), "fc 80 80 80 80 af");
 
   Expect.listEquals(
-      [unicodeReplacementCharacterRune], utf8ToRunes([0xc1, 0xbf]), "c1 bf");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xe0, 0x9f, 0xbf]), "e0 9f bf");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xf0, 0x8f, 0xbf, 0xbf]), "f0 8f bf bf");
+      [unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
+      utf8ToRunes([0xc1, 0xbf]),
+      "c1 bf");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xe0, 0x9f, 0xbf]), "e0 9f bf");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xf0, 0x8f, 0xbf, 0xbf]), "f0 8f bf bf");
   Expect.listEquals([
     unicodeReplacementCharacterRune,
     unicodeReplacementCharacterRune,
@@ -965,11 +993,20 @@
   ], utf8ToRunes([0xfc, 0x83, 0xbf, 0xbf, 0xbf, 0xbf]), "fc 83 bf bf bf bf");
 
   Expect.listEquals(
-      [unicodeReplacementCharacterRune], utf8ToRunes([0xc0, 0x80]), "c0 80");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xe0, 0x80, 0x80]), "e0 80 80");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xf0, 0x80, 0x80, 0x80]), "f0 80 80 80");
+      [unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
+      utf8ToRunes([0xc0, 0x80]),
+      "c0 80");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xe0, 0x80, 0x80]), "e0 80 80");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xf0, 0x80, 0x80, 0x80]), "f0 80 80 80");
   Expect.listEquals([
     unicodeReplacementCharacterRune,
     unicodeReplacementCharacterRune,
diff --git a/tests/lib/convert/utf85_test.dart b/tests/lib/convert/utf85_test.dart
index 3f287e9..a380991 100644
--- a/tests/lib/convert/utf85_test.dart
+++ b/tests/lib/convert/utf85_test.dart
@@ -9,7 +9,7 @@
 
 main() {
   for (int i = 0; i <= 0x10FFFF; i++) {
-    if (i == unicodeBomCharacterRune) continue;
+    if (i == unicodeBomCharacterRune || (i & 0x1FF800) == 0xD800) continue;
     Expect.equals(
         i, utf8.decode(utf8.encode(new String.fromCharCode(i))).runes.first);
   }
diff --git a/tests/lib/convert/utf8_encode_test.dart b/tests/lib/convert/utf8_encode_test.dart
index 1e611bb..0a43e14 100644
--- a/tests/lib/convert/utf8_encode_test.dart
+++ b/tests/lib/convert/utf8_encode_test.dart
@@ -25,8 +25,8 @@
   String ascii = "ABCDE";
   Expect.listEquals([0x41, 0x42, 0x43, 0x44, 0x45], encoder.convert(ascii));
   Expect.listEquals([0x41, 0x42, 0x43, 0x44, 0x45], encoder.convert(ascii, 0));
-  Expect
-      .listEquals([0x41, 0x42, 0x43, 0x44, 0x45], encoder.convert(ascii, 0, 5));
+  Expect.listEquals(
+      [0x41, 0x42, 0x43, 0x44, 0x45], encoder.convert(ascii, 0, 5));
   Expect.listEquals([0x42, 0x43, 0x44, 0x45], encoder.convert(ascii, 1));
   Expect.listEquals([0x41, 0x42, 0x43, 0x44], encoder.convert(ascii, 0, 4));
   Expect.listEquals([0x42, 0x43, 0x44], encoder.convert(ascii, 1, 4));
@@ -50,6 +50,6 @@
   Expect.listEquals(
       [0xc2, 0x82, 0xe1, 0x81, 0x81], encoder.convert(unicode, 1, 3));
   // Split in the middle of a surrogate pair.
-  Expect.listEquals([0xc2, 0x82, 0xe1, 0x81, 0x81, 0xed, 0xa0, 0x80],
+  Expect.listEquals([0xc2, 0x82, 0xe1, 0x81, 0x81, 0xef, 0xbf, 0xbd],
       encoder.convert(unicode, 1, 4));
 }
diff --git a/tests/lib/convert/utf8_test.dart b/tests/lib/convert/utf8_test.dart
index 858c982..6f97fd0 100644
--- a/tests/lib/convert/utf8_test.dart
+++ b/tests/lib/convert/utf8_test.dart
@@ -73,28 +73,29 @@
 
   // Bad encoding, points to first bad byte.
   testExn([0x80, 0x00], 0);
-  testExn([0xC0, 0x00], 1);
-  testExn([0xE0, 0x00], 1);
-  testExn([0xE0, 0x80, 0x00], 2);
-  testExn([0xF0, 0x00], 1);
-  testExn([0xF0, 0x80, 0x00], 2);
-  testExn([0xF0, 0x80, 0x80, 0x00], 3);
+  testExn([0xC2, 0x00], 1);
+  testExn([0xE2, 0x00], 1);
+  testExn([0xE2, 0x80, 0x00], 2);
+  testExn([0xF2, 0x00], 1);
+  testExn([0xF2, 0x80, 0x00], 2);
+  testExn([0xF2, 0x80, 0x80, 0x00], 3);
   testExn([0xF8, 0x00], 0);
   // Short encoding, points to end.
-  testExn([0xC0], 1);
-  testExn([0xE0], 1);
-  testExn([0xE0, 0x80], 2);
-  testExn([0xF0], 1);
-  testExn([0xF0, 0x80], 2);
-  testExn([0xF0, 0x80, 0x80], 3);
-  // Overlong encoding, points to start of encoding.
+  testExn([0xC2], 1);
+  testExn([0xE2], 1);
+  testExn([0xE2, 0x80], 2);
+  testExn([0xF2], 1);
+  testExn([0xF2, 0x80], 2);
+  testExn([0xF2, 0x80, 0x80], 3);
+  // Overlong encoding, points to byte that gave enough information to conclude
+  // that it was overlong.
   testExn([0xC0, 0x80], 0);
   testExn([0xC1, 0xBF], 0);
-  testExn([0xE0, 0x80, 0x80], 0);
-  testExn([0xE0, 0x9F, 0xBF], 0);
-  testExn([0xF0, 0x80, 0x80, 0x80], 0);
-  testExn([0xF0, 0x8F, 0xBF, 0xBF], 0);
+  testExn([0xE0, 0x80, 0x80], 1);
+  testExn([0xE0, 0x9F, 0xBF], 1);
+  testExn([0xF0, 0x80, 0x80, 0x80], 1);
+  testExn([0xF0, 0x8F, 0xBF, 0xBF], 1);
   // Invalid character (value too large, over 0x10FFFF).
-  testExn([0xF4, 0x90, 0x80, 0x80], 0);
+  testExn([0xF4, 0x90, 0x80, 0x80], 1);
   testExn([0xF7, 0xBF, 0xBF, 0xBF], 0);
 }
diff --git a/tests/lib/isolate/no_package_test.dart b/tests/lib/isolate/no_package_test.dart
new file mode 100644
index 0000000..833e56b
--- /dev/null
+++ b/tests/lib/isolate/no_package_test.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io";
+import "package:async_helper/async_minitest.dart";
+
+void testNoPackages(String filePath, String uri, String expected) {
+  File mainIsolate = new File(filePath);
+  mainIsolate.writeAsStringSync('''
+    library spawn_tests;
+
+    import \'dart:isolate\';
+
+    void main() async {
+      const String debugName = \'spawnedIsolate\';
+      final exitPort = ReceivePort();
+      final port = new ReceivePort();
+      port.listen((msg) {
+          print(msg);
+          port.close();
+      });
+
+      final isolate = await Isolate.spawnUri(
+        Uri.parse(\'$uri\'),
+          [\'$expected\'],
+          port.sendPort,
+          paused: false,
+          debugName: debugName,
+          onExit: exitPort.sendPort);
+
+      // Explicitly await spawned isolate exit to enforce main isolate not
+      // completing (and the stand-alone runtime exiting) before the spawned
+      // isolate is done.
+      await exitPort.first;
+    }
+    ''');
+  var exec = Platform.resolvedExecutable;
+  var args = <String>[];
+  args.add(mainIsolate.path);
+  var result = Process.runSync(exec, args);
+  expect(result.stdout.contains('$expected'), true);
+}
+
+void main() {
+  // Create temporary directory.
+  var tmpDir = Directory.systemTemp.createTempSync();
+  var tmpDirPath = tmpDir.path;
+
+  // Generate code for an isolate to run without any package specification.
+  File noPackageIsolate = new File("$tmpDirPath/no_package.dart");
+  noPackageIsolate.writeAsStringSync('''
+    library SpawnUriIsolate;
+    main(List<String> args, replyTo) {
+      var data = args[0];
+      replyTo.send(data);
+    }
+    ''');
+
+  try {
+    // Isolate Spawning another Isolate without any package specification.
+    testNoPackages("$tmpDirPath/no_package_isolate.dart", noPackageIsolate.path,
+        're: no package');
+  } finally {
+    tmpDir.deleteSync(recursive: true);
+  }
+}
diff --git a/tests/lib/isolate/package_config_getter_test.dart b/tests/lib/isolate/package_config_getter_test.dart
new file mode 100644
index 0000000..0b7d506
--- /dev/null
+++ b/tests/lib/isolate/package_config_getter_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:path/path.dart' as path;
+
+import 'spawn_uri__package_uri__test.dart';
+
+final executable = Platform.executable;
+
+main() async {
+  // Make a folder structure that has both ".dart_tool/package_config.json" and
+  // ".packages" and ensure VM prefers to use ".packages".
+  await withTempDir((String tempDir) async {
+    // Setup ".packages" with "foo -> ..." mapping.
+    final dotPackagesPath = path.join(tempDir, '.packages');
+    final dotPackagesFile = File(dotPackagesPath);
+    await dotPackagesFile.writeAsString(buildDotPackages('foo'));
+
+    // Setup bogus ".dart_tool/package_config.json" with "invalid -> ..."
+    // mapping.
+    final dotDartToolDir = path.join(tempDir, '.dart_tool');
+    await Directory(dotDartToolDir).create();
+    final packageConfigJsonPath =
+        path.join(dotDartToolDir, 'package_config.json');
+    final packageConfigJsonFile = File(packageConfigJsonPath);
+    await packageConfigJsonFile
+        .writeAsString(buildPackageConfig('invalid', true));
+
+    final mainFile = path.join(tempDir, 'main.dart');
+    await File(mainFile).writeAsString('''
+import 'dart:io' as io;
+import 'dart:isolate';
+
+main() async {
+  final uri = await Isolate.packageConfig;
+  final expectedUri = Uri.parse('${dotPackagesFile.uri}');
+  if (uri != expectedUri) {
+    throw 'VM should use .packages file (but used \$uri).';
+  }
+}
+''');
+
+    await run(executable, [mainFile]);
+  });
+}
diff --git a/tests/lib/isolate/package_config_test.dart b/tests/lib/isolate/package_config_test.dart
index cc345ee..c9b4f02 100644
--- a/tests/lib/isolate/package_config_test.dart
+++ b/tests/lib/isolate/package_config_test.dart
@@ -8,33 +8,26 @@
 import 'dart:io';
 import 'dart:isolate';
 
-final SPAWN_PACKAGE_CONFIG = "foobar:///no/such/file/";
+const String packageConfig = "foobar:///no/such/file/";
+const String errorString = "IsolateSpawnException: Unable to spawn isolate:";
+const String errorString2 = "Error when reading '$packageConfig'";
 
-main([args, port]) async {
-  if (port != null) {
-    testPackageConfig(port);
-    return;
+main([args, msg]) async {
+  if (msg != null) {
+    throw 'unreachable';
   }
-  var p = new RawReceivePort();
-  Isolate.spawnUri(Platform.script, [], p.sendPort,
-      packageConfig: Uri.parse(SPAWN_PACKAGE_CONFIG));
-  p.handler = (msg) {
-    p.close();
-    if (msg[0] != SPAWN_PACKAGE_CONFIG) {
-      throw "Bad package config in child isolate: ${msg[0]}";
-    }
-    if (msg[1] != null) {
-      throw "Non-null loaded package config in isolate: ${msg[1]}";
-    }
-    print("SUCCESS");
-  };
-  print("Spawning isolate's package config: ${await Isolate.packageConfig}");
-}
-
-testPackageConfig(port) async {
-  var packageConfigStr = Platform.packageConfig;
-  var packageConfig = await Isolate.packageConfig;
-  print("Spawned isolate's package config flag: $packageConfigStr");
-  print("Spawned isolate's loaded package config: $packageConfig");
-  port.send([packageConfigStr, packageConfig.toString()]);
+  dynamic error;
+  try {
+    await Isolate.spawnUri(Platform.script, [], 'msg',
+        packageConfig: Uri.parse('foobar:///no/such/file/'));
+  } catch (e) {
+    error = e;
+  }
+  if (error == null) throw 'Expected a Spawning error.';
+  if (!'$error'.contains(errorString)) {
+    throw 'Epected: $errorString to contain "$errorString"';
+  }
+  if (!'$error'.contains(errorString2)) {
+    throw 'Epected: $errorString to contain "$errorString2"';
+  }
 }
diff --git a/tests/lib/isolate/package_resolve_test.dart b/tests/lib/isolate/package_resolve_test.dart
index 241732e..50686a3 100644
--- a/tests/lib/isolate/package_resolve_test.dart
+++ b/tests/lib/isolate/package_resolve_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
@@ -8,44 +8,67 @@
 import 'dart:io';
 import 'dart:isolate';
 
-final SPAWN_PACKAGE_ROOT = "file:///no/such/package/root/";
-final PACKAGE_URI = "package:foo/bar.dart";
-final PACKAGE_PATH = "file:///no/such/package/root/foo/bar.dart";
+final packageUriToResolve = "package:foo/bar.dart";
+final packageResolvedUri = "file:///no/such/directory/lib/bar.dart";
+
+final dotPackages = """
+# This is the content of a .packages file.
+foo:file:///no/such/directory/lib/
+""";
+
+final packageConfigJson = """
+{
+  "configVersion": 2,
+  "packages": [
+    {
+      "name": "foo",
+      "rootUri": "file:///no/such/directory",
+      "packageUri": "lib/",
+      "languageVersion": "2.7"
+    }
+  ]
+}
+""";
 
 main([args, port]) async {
   if (port != null) {
     testPackageResolution(port);
     return;
   }
-  var p = new RawReceivePort();
-  Isolate.spawnUri(Platform.script, [], p.sendPort,
-      packageRoot: Uri.parse(SPAWN_PACKAGE_ROOT));
-  p.handler = (msg) {
-    p.close();
-    if (msg is! List) {
-      print(msg.runtimeType);
-      throw "Failure return from spawned isolate:\n\n$msg";
-    }
-    if (msg[0] != null) {
-      throw "Bad package root in child isolate: ${msg[0]}";
-    }
-    if (msg[1] != null) {
-      throw "Package path not matching: ${msg[1]}";
-    }
-    print("SUCCESS");
-  };
-  print("Spawning isolate's package root: ${await Isolate.packageRoot}");
+  await runTest(dotPackages);
+  await runTest(packageConfigJson);
+}
+
+Future runTest(String packageConfig) async {
+  final data = Uri.dataFromString(packageConfig);
+  final port = ReceivePort();
+  await Isolate.spawnUri(Platform.script, [], port.sendPort,
+      packageConfig: data);
+  final msg = await port.first;
+  if (msg is! List) {
+    print(msg.runtimeType);
+    throw "Failure return from spawned isolate:\n\n$msg";
+  }
+  if (msg[0] != data.toString()) {
+    throw "Bad package config in child isolate: ${msg[0]}\n"
+        "Expected: $data";
+  }
+  if (msg[1] != packageResolvedUri) {
+    throw "Package path not matching: ${msg[1]}";
+  }
+  print("SUCCESS");
 }
 
 testPackageResolution(port) async {
   try {
-    var packageRootStr = Platform.packageRoot;
-    var packageRoot = await Isolate.packageRoot;
-    var resolvedPkg = await Isolate.resolvePackageUri(Uri.parse(PACKAGE_URI));
-    print("Spawned isolate's package root flag: $packageRootStr");
-    print("Spawned isolate's loaded package root: $packageRoot");
+    var packageConfigStr = Platform.packageConfig;
+    var packageConfig = await Isolate.packageConfig;
+    var resolvedPkg =
+        await Isolate.resolvePackageUri(Uri.parse(packageUriToResolve));
+    print("Spawned isolate's package config flag: $packageConfigStr");
+    print("Spawned isolate's loaded package config: $packageConfig");
     print("Spawned isolate's resolved package path: $resolvedPkg");
-    port.send([packageRoot.toString(), resolvedPkg.toString()]);
+    port.send([packageConfig?.toString(), resolvedPkg?.toString()]);
   } catch (e, s) {
     port.send("$e\n$s\n");
   }
diff --git a/tests/lib/isolate/spawn_uri__package_uri__test.dart b/tests/lib/isolate/spawn_uri__package_uri__test.dart
new file mode 100644
index 0000000..d5efa2c
--- /dev/null
+++ b/tests/lib/isolate/spawn_uri__package_uri__test.dart
@@ -0,0 +1,181 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+
+final executable = Platform.executable;
+
+main() async {
+  // Run the Dart VM with or without:
+  //     --packages=<packages|package_config>
+  for (final runWithPackagesArg in const [true, false]) {
+    // Run the isolate with or without
+    //    Isolate.spawnUri(..., packageConfig: <packages|package_config>)
+    print('TEST runWithPackagesArg = $runWithPackagesArg ');
+    for (final spawnWithPackageConfig in const [true, false]) {
+      print('TEST spawnWithPackageConfig = $spawnWithPackageConfig ');
+      final bool checkForResolveUri =
+          runWithPackagesArg || !spawnWithPackageConfig;
+      await runDotPackagesTest(
+          runWithPackagesArg, spawnWithPackageConfig, checkForResolveUri);
+      for (final optionalPackageUri in const [true, false]) {
+        print('TEST optionalPackageUri = $optionalPackageUri');
+        await runPackageConfigTest(runWithPackagesArg, spawnWithPackageConfig,
+            optionalPackageUri, checkForResolveUri);
+      }
+    }
+  }
+}
+
+Future runPackageConfigTest(bool withPackagesArg, bool spawnWithArg,
+    bool optionalPackageUri, bool checkForResolveUri) async {
+  await withApplicationDirAndDotDartToolPackageConfig(
+      (String tempDir, String packageJson, String mainFile) async {
+    final args = [if (withPackagesArg) '--packages=$packageJson', mainFile];
+    await run(executable, args);
+  }, spawnWithArg, optionalPackageUri, checkForResolveUri);
+}
+
+Future runDotPackagesTest(
+    bool withPackagesArg, bool spawnWithArg, bool checkForResolveUri) async {
+  await withApplicationDirAndDotPackages(
+      (String tempDir, String dotPackagesFile, String mainFile) async {
+    final args = [
+      if (withPackagesArg) '--packages=$dotPackagesFile',
+      mainFile,
+    ];
+    await run(executable, args);
+  }, spawnWithArg, checkForResolveUri);
+}
+
+Future withApplicationDirAndDotPackages(
+    Future fn(String tempDir, String packagesDir, String mainFile),
+    bool spawnWithArg,
+    bool checkForResolveUri) async {
+  await withTempDir((String tempDir) async {
+    // Setup ".packages"
+    final dotPackagesFile =
+        path.join(tempDir, spawnWithArg ? 'baz.packages' : '.packages');
+    await File(dotPackagesFile).writeAsString(buildDotPackages('foo'));
+
+    final mainFile = path.join(tempDir, 'main.dart');
+    final childIsolateFile = path.join(tempDir, 'child_isolate.dart');
+    final importUri = 'package:foo/child_isolate.dart';
+    await File(childIsolateFile).writeAsString(buildChildIsolate());
+    await File(mainFile).writeAsString(buildMainIsolate(
+        importUri,
+        spawnWithArg ? dotPackagesFile : null,
+        checkForResolveUri ? childIsolateFile : null));
+
+    await fn(tempDir, dotPackagesFile, mainFile);
+  });
+}
+
+Future withApplicationDirAndDotDartToolPackageConfig(
+    Future fn(String tempDir, String packageJson, String mainFile),
+    bool spawnWithArg,
+    bool optionalPackageUri,
+    bool checkForResolveUri) async {
+  await withTempDir((String tempDir) async {
+    // Setup ".dart_tool/package_config.json"
+    final dotDartToolDir = path.join(tempDir, '.dart_tool');
+    await Directory(dotDartToolDir).create();
+    final packageConfigJsonFile = path.join(
+        dotDartToolDir, spawnWithArg ? 'baz.packages' : 'package_config.json');
+    await File(packageConfigJsonFile)
+        .writeAsString(buildPackageConfig('foo', optionalPackageUri));
+
+    // Setup actual application
+    final mainFile = path.join(tempDir, 'main.dart');
+    final childIsolateFile = path.join(tempDir, 'child_isolate.dart');
+    final importUri = 'package:foo/child_isolate.dart';
+    await File(childIsolateFile).writeAsString(buildChildIsolate());
+    await File(mainFile).writeAsString(buildMainIsolate(
+        importUri,
+        spawnWithArg ? packageConfigJsonFile : null,
+        checkForResolveUri ? childIsolateFile : null));
+
+    await fn(tempDir, packageConfigJsonFile, mainFile);
+  });
+}
+
+Future withTempDir(Future fn(String dir)) async {
+  final dir = await Directory.systemTemp.createTemp('spawn_uri');
+  try {
+    await fn(dir.absolute.path);
+  } finally {
+    await dir.delete(recursive: true);
+  }
+}
+
+Future<ProcessResult> run(String executable, List<String> args,
+    {String? cwd}) async {
+  print('Running $executable ${args.join(' ')}');
+  final String workingDirectory = cwd ?? Directory.current.absolute.path;
+  final result = await Process.run(executable, ['--trace-loading', ...args],
+      workingDirectory: workingDirectory);
+  print('exitCode:\n${result.exitCode}');
+  print('stdout:\n${result.stdout}');
+  print('stdout:\n${result.stderr}');
+  Expect.equals(0, result.exitCode);
+  return result;
+}
+
+String buildDotPackages(String packageName) => '$packageName:.';
+
+String buildPackageConfig(String packageName, bool optionalPackageUri) => '''
+{
+  "configVersion": 2,
+  "packages": [
+    {
+      "name": "$packageName",
+      "rootUri": "../"
+      ${optionalPackageUri ? ', "packageUri": "./"' : ''}
+    }
+  ]
+}
+''';
+
+String buildChildIsolate() => '''
+  import 'dart:isolate';
+
+  main(List<String> args, SendPort message) {
+    message.send('child isolate is done');
+  }
+''';
+
+String buildMainIsolate(
+        String spawnUri, String? packageConfigUri, String? childIsolatePath) =>
+    '''
+  import 'dart:isolate';
+  import 'dart:io' as io;
+
+  main(List<String> args) async {
+    io.exitCode = 1;
+
+    final uri = Uri.parse('$spawnUri');
+    final resolvedUri = await Isolate.resolvePackageUri(uri);
+    if ("""\${resolvedUri?.toFilePath()}""" != r"""$childIsolatePath""") {
+      throw 'Could not Isolate.resolvePackageUri(uri).';
+    }
+
+    final rp = ReceivePort();
+    final isolateArgs = <String>['a'];
+    await Isolate.spawnUri(
+        uri,
+        isolateArgs,
+        rp.sendPort,
+        packageConfig: ${packageConfigUri != null ? 'Uri.file(r"$packageConfigUri")' : 'null'});
+    final childIsolateMessage = await rp.first;
+    if (childIsolateMessage != 'child isolate is done') {
+      throw 'Did not receive correct message from child isolate.';
+    }
+
+    // Test was successful.
+    io.exitCode = 0;
+  }
+''';
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index f3cd0bd..cd733a9 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -11,6 +11,9 @@
 developer/timeline_test: Skip # Not supported
 isolate/issue_24243_parent_isolate_test: Skip # Requires checked mode
 
+[ $runtime == dart_precompiled ]
+isolate/package_config_getter_test: SkipByDesign # AOT mode doesn't preserve package structure.
+
 [ $runtime == ff ]
 convert/streamed_conversion_utf8_decode_test: Slow, Pass # Issue 12029
 mirrors/mirrors_reader_test: Slow, Pass # Issue 16589
@@ -24,6 +27,9 @@
 html/indexeddb_3_test: Skip # Times out 1 out of 10.
 html/worker_api_test: Skip # Issue 13221
 
+[ $runtime != vm ]
+isolate/spawn_uri__package_uri__test: SkipByDesign # This test uses Isolate.spawnUri and only works in JIT mode.
+
 [ $system == windows ]
 html/xhr_test/xhr: Skip # Times out.  Issue 21527
 
@@ -49,13 +55,6 @@
 [ $arch != x64 || $compiler == dartkb || $runtime != vm ]
 isolate/int32_length_overflow_test: SkipSlow
 
-[ $compiler != none || $runtime != vm ]
-isolate/package_config_test: SkipByDesign # Uses Isolate.packageConfig
-isolate/package_resolve_test: SkipByDesign # Uses Isolate.resolvePackageUri
-isolate/package_root_test: SkipByDesign # Uses Isolate.packageRoot
-isolate/scenarios/*: SkipByDesign # Use automatic package resolution, spawnFunction and .dart URIs.
-isolate/spawn_uri_fail_test: SkipByDesign # Uses dart:io.
-
 [ $mode == product || $runtime != vm ]
 isolate/checked_test: Skip # Unsupported.
 
@@ -93,8 +92,13 @@
 isolate/nested_spawn_test: Skip # Isolate.spawnUri
 isolate/nnbd_spawn_autodetect_test: Skip # Auto detect not for precompiled.
 isolate/nnbd_spawnuri_autodetect_test: Skip # Auto detect not for precompiled.
+isolate/no_package_test: Skip # Isolate.spawnUri
+isolate/package_config_test: Skip # Isolate.spawnUri
 isolate/raw_port_test: Skip # Isolate.spawnUri
 isolate/request_reply_test: Skip # Isolate.spawnUri
+isolate/scenarios/automatic_resolution_spec/package_resolve_test: Skip # Isolate.spawnUri
+isolate/scenarios/package_relative_spec/package_relative_spec_test: Skip # Isolate.spawnUri
+isolate/scenarios/short_package/short_package_test: Skip # Isolate.spawnUri
 isolate/spawn_function_custom_class_test: Skip # Isolate.spawnUri
 isolate/spawn_function_test: Skip # Isolate.spawnUri
 isolate/spawn_uri_exported_main_test: Skip # Isolate.spawnUri
@@ -108,6 +112,13 @@
 isolate/static_function_test: Skip # Isolate.spawnUri
 isolate/unresolved_ports_test: Skip # Isolate.spawnUri
 
+[ $runtime != vm || $compiler != dartk && $compiler != none ]
+isolate/package_config_test: SkipByDesign # Uses Isolate.packageConfig
+isolate/package_resolve_test: SkipByDesign # Uses Isolate.resolvePackageUri
+isolate/package_root_test: SkipByDesign # Uses Isolate.packageRoot
+isolate/scenarios/*: SkipByDesign # Use automatic package resolution, spawnFunction and .dart URIs.
+isolate/spawn_uri_fail_test: SkipByDesign # Uses dart:io.
+
 [ $hot_reload || $hot_reload_rollback ]
 convert/chunked_conversion_utf88_test: SkipSlow
 convert/utf85_test: SkipSlow
diff --git a/tests/lib/lib_vm.status b/tests/lib/lib_vm.status
index 92cc427..ae42a72 100644
--- a/tests/lib/lib_vm.status
+++ b/tests/lib/lib_vm.status
@@ -139,6 +139,9 @@
 isolate/non_fatal_exception_in_timer_callback_test/sleep: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/object_leak_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/ondone_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/package_config_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/package_resolve_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/package_root_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/pause_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/ping_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/port_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
@@ -147,12 +150,15 @@
 isolate/regress_flutter_22796_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/request_reply_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/resolve_package_uri_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/scenarios/package_data_uri_spec/package_resolve_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/send_private_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/simple_message_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_function_custom_class_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_function_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_generic_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/spawn_uri__package_uri__test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_uri_exported_main_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/spawn_uri_fail_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_uri_missing_from_isolate_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_uri_missing_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_uri_multi_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
diff --git a/tests/lib/mirrors/instance_members_easier_test.dart b/tests/lib/mirrors/instance_members_easier_test.dart
index e71fb13..ccd1b4f 100644
--- a/tests/lib/mirrors/instance_members_easier_test.dart
+++ b/tests/lib/mirrors/instance_members_easier_test.dart
@@ -54,15 +54,18 @@
     #==,
     #noSuchMethod,
     #toString
-  ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate));
+  ], selectKeys(cm.instanceMembers, (dynamic dm) => !dm.isPrivate));
   // Filter out private to avoid implementation-specific members of Object.
 
-  Expect.setEquals([
-    #instanceVariable,
-    const Symbol('instanceVariable='),
-    #inheritedInstanceVariable,
-    const Symbol('inheritedInstanceVariable=')
-  ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate && dm.isSynthetic));
+  Expect.setEquals(
+      [
+        #instanceVariable,
+        const Symbol('instanceVariable='),
+        #inheritedInstanceVariable,
+        const Symbol('inheritedInstanceVariable=')
+      ],
+      selectKeys(
+          cm.instanceMembers, (dynamic dm) => !dm.isPrivate && dm.isSynthetic));
 
   cm = reflectClass(Derived);
   Expect.setEquals([
@@ -75,7 +78,7 @@
     #==,
     #noSuchMethod,
     #toString
-  ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate));
+  ], selectKeys(cm.instanceMembers, (dynamic dm) => !dm.isPrivate));
 
   cm = reflectClass(EasierMixinApplication);
   Expect.setEquals([
@@ -87,5 +90,5 @@
     #==,
     #noSuchMethod,
     #toString
-  ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate));
+  ], selectKeys(cm.instanceMembers, (dynamic dm) => !dm.isPrivate));
 }
diff --git a/tests/lib/mirrors/instance_members_test.dart b/tests/lib/mirrors/instance_members_test.dart
index c71b5fa5..1eeb39a 100644
--- a/tests/lib/mirrors/instance_members_test.dart
+++ b/tests/lib/mirrors/instance_members_test.dart
@@ -40,15 +40,18 @@
     #==,
     #noSuchMethod,
     #toString
-  ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate));
+  ], selectKeys(cm.instanceMembers, (dynamic dm) => !dm.isPrivate));
   // Filter out private to avoid implementation-specific members of Object.
 
-  Expect.setEquals([
-    #instanceVariable,
-    const Symbol('instanceVariable='),
-    #inheritedInstanceVariable,
-    const Symbol('inheritedInstanceVariable='),
-    #mixinInstanceVariable,
-    const Symbol('mixinInstanceVariable=')
-  ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate && dm.isSynthetic));
+  Expect.setEquals(
+      [
+        #instanceVariable,
+        const Symbol('instanceVariable='),
+        #inheritedInstanceVariable,
+        const Symbol('inheritedInstanceVariable='),
+        #mixinInstanceVariable,
+        const Symbol('mixinInstanceVariable=')
+      ],
+      selectKeys(
+          cm.instanceMembers, (dynamic dm) => !dm.isPrivate && dm.isSynthetic));
 }
diff --git a/tests/lib/mirrors/instance_members_with_override_test.dart b/tests/lib/mirrors/instance_members_with_override_test.dart
index f1065c5..7325248 100644
--- a/tests/lib/mirrors/instance_members_with_override_test.dart
+++ b/tests/lib/mirrors/instance_members_with_override_test.dart
@@ -49,7 +49,7 @@
     #==,
     #noSuchMethod,
     #toString
-  ], selectKeys(sMirror.instanceMembers, (dm) => !dm.isPrivate));
+  ], selectKeys(sMirror.instanceMembers, (dynamic dm) => !dm.isPrivate));
   // Filter out private to avoid implementation-specific members of Object.
 
   Expect.equals(sMirror, sMirror.instanceMembers[#field]!.owner);
@@ -74,7 +74,7 @@
     #==,
     #noSuchMethod,
     #toString
-  ], selectKeys(cMirror.instanceMembers, (dm) => !dm.isPrivate));
+  ], selectKeys(cMirror.instanceMembers, (dynamic dm) => !dm.isPrivate));
   // Filter out private to avoid implementation-specific members of Object.
 
   Expect.equals(cMirror, cMirror.instanceMembers[#field]!.owner);
diff --git a/tests/lib/mirrors/static_members_easier_test.dart b/tests/lib/mirrors/static_members_easier_test.dart
index 43b02b9..105a1c6 100644
--- a/tests/lib/mirrors/static_members_easier_test.dart
+++ b/tests/lib/mirrors/static_members_easier_test.dart
@@ -27,5 +27,5 @@
   ], selectKeys(cm.staticMembers, (dm) => true));
 
   Expect.setEquals([#staticVariable, const Symbol('staticVariable=')],
-      selectKeys(cm.staticMembers, (dm) => dm.isSynthetic));
+      selectKeys(cm.staticMembers, (dynamic dm) => dm.isSynthetic));
 }
diff --git a/tests/lib/mirrors/static_members_test.dart b/tests/lib/mirrors/static_members_test.dart
index beeed6d..74cbb42 100644
--- a/tests/lib/mirrors/static_members_test.dart
+++ b/tests/lib/mirrors/static_members_test.dart
@@ -36,5 +36,5 @@
     const Symbol('staticVariable='),
     MirrorSystem.getSymbol('_staticVariable', lm),
     MirrorSystem.getSymbol('_staticVariable=', lm)
-  ], selectKeys(cm.staticMembers, (dm) => dm.isSynthetic));
+  ], selectKeys(cm.staticMembers, (dynamic dm) => dm.isSynthetic));
 }
diff --git a/tests/lib_2/convert/chunked_conversion_utf82_test.dart b/tests/lib_2/convert/chunked_conversion_utf82_test.dart
index bc0b200..2e07f87 100644
--- a/tests/lib_2/convert/chunked_conversion_utf82_test.dart
+++ b/tests/lib_2/convert/chunked_conversion_utf82_test.dart
@@ -46,11 +46,14 @@
   return buffer.toString();
 }
 
-final TESTS = [
+final TESTS0 = [
   // Unfinished UTF-8 sequences.
   [0xc3],
   [0xE2, 0x82],
-  [0xF0, 0xA4, 0xAD],
+  [0xF0, 0xA4, 0xAD]
+];
+
+final TESTS1 = [
   // Overlong encoding of euro-sign.
   [0xF0, 0x82, 0x82, 0xAC],
   // Other overlong/unfinished sequences.
@@ -77,11 +80,11 @@
   // Test that 0xC0|1, 0x80 does not eat the next character.
   [
     [0xC0, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   [
     [0xC1, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   // 0xF5 .. 0xFF never appear in valid UTF-8 sequences.
   [
@@ -220,44 +223,49 @@
 ];
 
 main() {
-  var allTests = TESTS.expand((test) {
+  var allTests = [...TESTS0, ...TESTS1].expand((test) {
     // Pairs of test and expected string output when malformed strings are
-    // allowed. Replacement character: U+FFFD
+    // allowed. Replacement character: U+FFFD, one per unfinished sequence or
+    // undecodable byte.
+    String replacement =
+        TESTS0.contains(test) ? "\u{FFFD}" : "\u{FFFD}" * test.length;
     return [
-      [test, "\u{FFFD}"],
+      [test, "${replacement}"],
       [
-        new List<int>.from([0x61])..addAll(test),
-        "a\u{FFFD}"
+        [0x61, ...test],
+        "a${replacement}"
       ],
       [
-        new List<int>.from([0x61])
-          ..addAll(test)
-          ..add(0x61),
-        "a\u{FFFD}a"
-      ],
-      [new List<int>.from(test)..add(0x61), "\u{FFFD}a"],
-      [new List<int>.from(test)..addAll(test), "\u{FFFD}\u{FFFD}"],
-      [
-        new List<int>.from(test)
-          ..add(0x61)
-          ..addAll(test),
-        "\u{FFFD}a\u{FFFD}"
+        [0x61, ...test, 0x61],
+        "a${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test),
-        "å\u{FFFD}"
+        [...test, 0x61],
+        "${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test)..addAll([0xc3, 0xa5]),
-        "å\u{FFFD}å"
+        [...test, ...test],
+        "${replacement}${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5]),
-        "\u{FFFD}å"
+        [...test, 0x61, ...test],
+        "${replacement}a${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5])..addAll(test),
-        "\u{FFFD}å\u{FFFD}"
+        [0xc3, 0xa5, ...test],
+        "å${replacement}"
+      ],
+      [
+        [0xc3, 0xa5, ...test, 0xc3, 0xa5],
+        "å${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5],
+        "${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5, ...test],
+        "${replacement}å${replacement}"
       ]
     ];
   });
diff --git a/tests/lib_2/convert/chunked_conversion_utf86_test.dart b/tests/lib_2/convert/chunked_conversion_utf86_test.dart
index a42e752..8c9a08c 100644
--- a/tests/lib_2/convert/chunked_conversion_utf86_test.dart
+++ b/tests/lib_2/convert/chunked_conversion_utf86_test.dart
@@ -28,11 +28,14 @@
   return buffer.toString();
 }
 
-final TESTS = [
+final TESTS0 = [
   // Unfinished UTF-8 sequences.
   [0xc3],
   [0xE2, 0x82],
-  [0xF0, 0xA4, 0xAD],
+  [0xF0, 0xA4, 0xAD]
+];
+
+final TESTS1 = [
   // Overlong encoding of euro-sign.
   [0xF0, 0x82, 0x82, 0xAC],
   // Other overlong/unfinished sequences.
@@ -59,11 +62,11 @@
   // Test that 0xC0|1, 0x80 does not eat the next character.
   [
     [0xC0, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   [
     [0xC1, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   // 0xF5 .. 0xFF never appear in valid UTF-8 sequences.
   [
@@ -202,44 +205,49 @@
 ];
 
 main() {
-  var allTests = TESTS.expand((test) {
+  var allTests = [...TESTS0, ...TESTS1].expand((test) {
     // Pairs of test and expected string output when malformed strings are
-    // allowed. Replacement character: U+FFFD
+    // allowed. Replacement character: U+FFFD, one per unfinished sequence or
+    // undecodable byte.
+    String replacement =
+        TESTS0.contains(test) ? "\u{FFFD}" : "\u{FFFD}" * test.length;
     return [
-      [test, "\u{FFFD}"],
+      [test, "${replacement}"],
       [
-        new List<int>.from([0x61])..addAll(test),
-        "a\u{FFFD}"
+        [0x61, ...test],
+        "a${replacement}"
       ],
       [
-        new List<int>.from([0x61])
-          ..addAll(test)
-          ..add(0x61),
-        "a\u{FFFD}a"
-      ],
-      [new List<int>.from(test)..add(0x61), "\u{FFFD}a"],
-      [new List<int>.from(test)..addAll(test), "\u{FFFD}\u{FFFD}"],
-      [
-        new List<int>.from(test)
-          ..add(0x61)
-          ..addAll(test),
-        "\u{FFFD}a\u{FFFD}"
+        [0x61, ...test, 0x61],
+        "a${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test),
-        "å\u{FFFD}"
+        [...test, 0x61],
+        "${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test)..addAll([0xc3, 0xa5]),
-        "å\u{FFFD}å"
+        [...test, ...test],
+        "${replacement}${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5]),
-        "\u{FFFD}å"
+        [...test, 0x61, ...test],
+        "${replacement}a${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5])..addAll(test),
-        "\u{FFFD}å\u{FFFD}"
+        [0xc3, 0xa5, ...test],
+        "å${replacement}"
+      ],
+      [
+        [0xc3, 0xa5, ...test, 0xc3, 0xa5],
+        "å${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5],
+        "${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5, ...test],
+        "${replacement}å${replacement}"
       ]
     ];
   });
diff --git a/tests/lib_2/convert/chunked_conversion_utf87_test.dart b/tests/lib_2/convert/chunked_conversion_utf87_test.dart
index 9794690..67929af 100644
--- a/tests/lib_2/convert/chunked_conversion_utf87_test.dart
+++ b/tests/lib_2/convert/chunked_conversion_utf87_test.dart
@@ -49,11 +49,14 @@
   return utf8.decode(bytes);
 }
 
-final TESTS = [
+final TESTS0 = [
   // Unfinished UTF-8 sequences.
   [0xc3],
   [0xE2, 0x82],
-  [0xF0, 0xA4, 0xAD],
+  [0xF0, 0xA4, 0xAD]
+];
+
+final TESTS1 = [
   // Overlong encoding of euro-sign.
   [0xF0, 0x82, 0x82, 0xAC],
   // Other overlong/unfinished sequences.
@@ -80,11 +83,11 @@
   // Test that 0xC0|1, 0x80 does not eat the next character.
   [
     [0xC0, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   [
     [0xC1, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   // 0xF5 .. 0xFF never appear in valid UTF-8 sequences.
   [
@@ -223,44 +226,49 @@
 ];
 
 main() {
-  var allTests = TESTS.expand((test) {
+  var allTests = [...TESTS0, ...TESTS1].expand((test) {
     // Pairs of test and expected string output when malformed strings are
-    // allowed. Replacement character: U+FFFD
+    // allowed. Replacement character: U+FFFD, one per unfinished sequence or
+    // undecodable byte.
+    String replacement =
+        TESTS0.contains(test) ? "\u{FFFD}" : "\u{FFFD}" * test.length;
     return [
-      [test, "\u{FFFD}"],
+      [test, "${replacement}"],
       [
-        new List<int>.from([0x61])..addAll(test),
-        "a\u{FFFD}"
+        [0x61, ...test],
+        "a${replacement}"
       ],
       [
-        new List<int>.from([0x61])
-          ..addAll(test)
-          ..add(0x61),
-        "a\u{FFFD}a"
-      ],
-      [new List<int>.from(test)..add(0x61), "\u{FFFD}a"],
-      [new List<int>.from(test)..addAll(test), "\u{FFFD}\u{FFFD}"],
-      [
-        new List<int>.from(test)
-          ..add(0x61)
-          ..addAll(test),
-        "\u{FFFD}a\u{FFFD}"
+        [0x61, ...test, 0x61],
+        "a${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test),
-        "å\u{FFFD}"
+        [...test, 0x61],
+        "${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test)..addAll([0xc3, 0xa5]),
-        "å\u{FFFD}å"
+        [...test, ...test],
+        "${replacement}${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5]),
-        "\u{FFFD}å"
+        [...test, 0x61, ...test],
+        "${replacement}a${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5])..addAll(test),
-        "\u{FFFD}å\u{FFFD}"
+        [0xc3, 0xa5, ...test],
+        "å${replacement}"
+      ],
+      [
+        [0xc3, 0xa5, ...test, 0xc3, 0xa5],
+        "å${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5],
+        "${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5, ...test],
+        "${replacement}å${replacement}"
       ]
     ];
   });
diff --git a/tests/lib_2/convert/chunked_conversion_utf88_test.dart b/tests/lib_2/convert/chunked_conversion_utf88_test.dart
index 58cecaa..8b19b2a 100644
--- a/tests/lib_2/convert/chunked_conversion_utf88_test.dart
+++ b/tests/lib_2/convert/chunked_conversion_utf88_test.dart
@@ -112,8 +112,7 @@
   const LEADING_SURROGATE = 0xd801;
   const TRAILING_SURROGATE = 0xdc12;
   const UTF8_ENCODING = const [0xf0, 0x90, 0x90, 0x92];
-  const UTF8_LEADING = const [0xed, 0xa0, 0x81];
-  const UTF8_TRAILING = const [0xed, 0xb0, 0x92];
+  const UTF8_REPLACEMENT = const [0xef, 0xbf, 0xbd];
   const CHAR_A = 0x61;
 
   // Test surrogates at all kinds of locations.
@@ -129,17 +128,17 @@
     codeUnits[i] = LEADING_SURROGATE;
     var str = new String.fromCharCodes(codeUnits);
     var bytes = new List.filled(i + 3, CHAR_A);
-    bytes[i] = UTF8_LEADING[0];
-    bytes[i + 1] = UTF8_LEADING[1];
-    bytes[i + 2] = UTF8_LEADING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits[i] = TRAILING_SURROGATE;
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 3, CHAR_A);
-    bytes[i] = UTF8_TRAILING[0];
-    bytes[i + 1] = UTF8_TRAILING[1];
-    bytes[i + 2] = UTF8_TRAILING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits.length = i + 2;
@@ -157,36 +156,36 @@
     codeUnits[i + 1] = TRAILING_SURROGATE;
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 6, CHAR_A);
-    bytes[i] = UTF8_TRAILING[0];
-    bytes[i + 1] = UTF8_TRAILING[1];
-    bytes[i + 2] = UTF8_TRAILING[2];
-    bytes[i + 3] = UTF8_TRAILING[0];
-    bytes[i + 4] = UTF8_TRAILING[1];
-    bytes[i + 5] = UTF8_TRAILING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits[i] = LEADING_SURROGATE;
     codeUnits[i + 1] = LEADING_SURROGATE;
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 6, CHAR_A);
-    bytes[i] = UTF8_LEADING[0];
-    bytes[i + 1] = UTF8_LEADING[1];
-    bytes[i + 2] = UTF8_LEADING[2];
-    bytes[i + 3] = UTF8_LEADING[0];
-    bytes[i + 4] = UTF8_LEADING[1];
-    bytes[i + 5] = UTF8_LEADING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits[i] = TRAILING_SURROGATE;
     codeUnits[i + 1] = LEADING_SURROGATE;
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 6, CHAR_A);
-    bytes[i] = UTF8_TRAILING[0];
-    bytes[i + 1] = UTF8_TRAILING[1];
-    bytes[i + 2] = UTF8_TRAILING[2];
-    bytes[i + 3] = UTF8_LEADING[0];
-    bytes[i + 4] = UTF8_LEADING[1];
-    bytes[i + 5] = UTF8_LEADING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits.length = i + 3;
@@ -208,12 +207,12 @@
     codeUnits[i + 2] = CHAR_A; // Add trailing 'a'.
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 7, CHAR_A);
-    bytes[i] = UTF8_TRAILING[0];
-    bytes[i + 1] = UTF8_TRAILING[1];
-    bytes[i + 2] = UTF8_TRAILING[2];
-    bytes[i + 3] = UTF8_TRAILING[0];
-    bytes[i + 4] = UTF8_TRAILING[1];
-    bytes[i + 5] = UTF8_TRAILING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits[i] = LEADING_SURROGATE;
@@ -221,12 +220,12 @@
     codeUnits[i + 2] = CHAR_A; // Add trailing 'a'.
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 7, CHAR_A);
-    bytes[i] = UTF8_LEADING[0];
-    bytes[i + 1] = UTF8_LEADING[1];
-    bytes[i + 2] = UTF8_LEADING[2];
-    bytes[i + 3] = UTF8_LEADING[0];
-    bytes[i + 4] = UTF8_LEADING[1];
-    bytes[i + 5] = UTF8_LEADING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     codeUnits[i] = TRAILING_SURROGATE;
@@ -234,12 +233,12 @@
     codeUnits[i + 2] = CHAR_A; // Add trailing 'a'.
     str = new String.fromCharCodes(codeUnits);
     bytes = new List.filled(i + 7, CHAR_A);
-    bytes[i] = UTF8_TRAILING[0];
-    bytes[i + 1] = UTF8_TRAILING[1];
-    bytes[i + 2] = UTF8_TRAILING[2];
-    bytes[i + 3] = UTF8_LEADING[0];
-    bytes[i + 4] = UTF8_LEADING[1];
-    bytes[i + 5] = UTF8_LEADING[2];
+    bytes[i] = UTF8_REPLACEMENT[0];
+    bytes[i + 1] = UTF8_REPLACEMENT[1];
+    bytes[i + 2] = UTF8_REPLACEMENT[2];
+    bytes[i + 3] = UTF8_REPLACEMENT[0];
+    bytes[i + 4] = UTF8_REPLACEMENT[1];
+    bytes[i + 5] = UTF8_REPLACEMENT[2];
     runTest([bytes, str]);
 
     // Make sure the invariant is correct.
diff --git a/tests/lib_2/convert/json_utf8_chunk_test.dart b/tests/lib_2/convert/json_utf8_chunk_test.dart
index ec47339..cf5064e 100644
--- a/tests/lib_2/convert/json_utf8_chunk_test.dart
+++ b/tests/lib_2/convert/json_utf8_chunk_test.dart
@@ -284,69 +284,69 @@
 void testMalformed() {
   // Overlong encodings.
   jsonMalformedTest(
-      "overlong-0-2", "@\uFFFD@", [0x22, 0x40, 0xc0, 0x80, 0x40, 0x22]);
-  jsonMalformedTest(
-      "overlong-0-3", "@\uFFFD@", [0x22, 0x40, 0xe0, 0x80, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("overlong-0-4", "@\uFFFD@",
+      "overlong-0-2", "@\uFFFD\uFFFD@", [0x22, 0x40, 0xc0, 0x80, 0x40, 0x22]);
+  jsonMalformedTest("overlong-0-3", "@\uFFFD\uFFFD\uFFFD@",
+      [0x22, 0x40, 0xe0, 0x80, 0x80, 0x40, 0x22]);
+  jsonMalformedTest("overlong-0-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0x80, 0x80, 0x40, 0x22]);
 
   jsonMalformedTest(
-      "overlong-7f-2", "@\uFFFD@", [0x22, 0x40, 0xc1, 0xbf, 0x40, 0x22]);
-  jsonMalformedTest(
-      "overlong-7f-3", "@\uFFFD@", [0x22, 0x40, 0xe0, 0x81, 0xbf, 0x40, 0x22]);
-  jsonMalformedTest("overlong-7f-4", "@\uFFFD@",
+      "overlong-7f-2", "@\uFFFD\uFFFD@", [0x22, 0x40, 0xc1, 0xbf, 0x40, 0x22]);
+  jsonMalformedTest("overlong-7f-3", "@\uFFFD\uFFFD\uFFFD@",
+      [0x22, 0x40, 0xe0, 0x81, 0xbf, 0x40, 0x22]);
+  jsonMalformedTest("overlong-7f-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0x81, 0xbf, 0x40, 0x22]);
 
-  jsonMalformedTest(
-      "overlong-80-3", "@\uFFFD@", [0x22, 0x40, 0xe0, 0x82, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("overlong-80-4", "@\uFFFD@",
+  jsonMalformedTest("overlong-80-3", "@\uFFFD\uFFFD\uFFFD@",
+      [0x22, 0x40, 0xe0, 0x82, 0x80, 0x40, 0x22]);
+  jsonMalformedTest("overlong-80-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0x82, 0x80, 0x40, 0x22]);
 
-  jsonMalformedTest(
-      "overlong-7ff-3", "@\uFFFD@", [0x22, 0x40, 0xe0, 0x9f, 0xbf, 0x40, 0x22]);
-  jsonMalformedTest("overlong-7ff-4", "@\uFFFD@",
+  jsonMalformedTest("overlong-7ff-3", "@\uFFFD\uFFFD\uFFFD@",
+      [0x22, 0x40, 0xe0, 0x9f, 0xbf, 0x40, 0x22]);
+  jsonMalformedTest("overlong-7ff-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0x9f, 0xbf, 0x40, 0x22]);
 
-  jsonMalformedTest("overlong-800-4", "@\uFFFD@",
+  jsonMalformedTest("overlong-800-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0xa0, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("overlong-ffff-4", "@\uFFFD@",
+  jsonMalformedTest("overlong-ffff-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x8f, 0xbf, 0xbf, 0x40, 0x22]);
 
   // Unterminated multibyte sequences.
   jsonMalformedTest(
       "unterminated-2-normal", "@\uFFFD@", [0x22, 0x40, 0xc0, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-3-normal", "@\uFFFD@",
+  jsonMalformedTest("unterminated-3-normal", "@\uFFFD\uFFFD@",
       [0x22, 0x40, 0xe0, 0x80, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-4-normal", "@\uFFFD@",
+  jsonMalformedTest("unterminated-4-normal", "@\uFFFD\uFFFD\uFFFD@",
       [0x22, 0x40, 0xf0, 0x80, 0x80, 0x40, 0x22]);
 
   jsonMalformedTest("unterminated-2-multi", "@\uFFFD\x80@",
       [0x22, 0x40, 0xc0, 0xc2, 0x80, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-3-multi", "@\uFFFD\x80@",
+  jsonMalformedTest("unterminated-3-multi", "@\uFFFD\uFFFD\x80@",
       [0x22, 0x40, 0xe0, 0x80, 0xc2, 0x80, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-4-multi", "@\uFFFD\x80@",
+  jsonMalformedTest("unterminated-4-multi", "@\uFFFD\uFFFD\uFFFD\x80@",
       [0x22, 0x40, 0xf0, 0x80, 0x80, 0xc2, 0x80, 0x40, 0x22]);
 
   jsonMalformedTest("unterminated-2-escape", "@\uFFFD\n@",
       [0x22, 0x40, 0xc0, 0x5c, 0x6e, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-3-escape", "@\uFFFD\n@",
+  jsonMalformedTest("unterminated-3-escape", "@\uFFFD\uFFFD\n@",
       [0x22, 0x40, 0xe0, 0x80, 0x5c, 0x6e, 0x40, 0x22]);
 
-  jsonMalformedTest("unterminated-4-escape", "@\uFFFD\n@",
+  jsonMalformedTest("unterminated-4-escape", "@\uFFFD\uFFFD\uFFFD\n@",
       [0x22, 0x40, 0xf0, 0x80, 0x80, 0x5c, 0x6e, 0x40, 0x22]);
 
   jsonMalformedTest("unterminated-2-end", "@\uFFFD", [0x22, 0x40, 0xc0, 0x22]);
 
   jsonMalformedTest(
-      "unterminated-3-end", "@\uFFFD", [0x22, 0x40, 0xe0, 0x80, 0x22]);
+      "unterminated-3-end", "@\uFFFD\uFFFD", [0x22, 0x40, 0xe0, 0x80, 0x22]);
 
-  jsonMalformedTest(
-      "unterminated-4-end", "@\uFFFD", [0x22, 0x40, 0xf0, 0x80, 0x80, 0x22]);
+  jsonMalformedTest("unterminated-4-end", "@\uFFFD\uFFFD\uFFFD",
+      [0x22, 0x40, 0xf0, 0x80, 0x80, 0x22]);
 
   // Unexpected continuation byte
   // - after a normal character.
@@ -372,13 +372,13 @@
       "leading-2", "@\uFFFD\x80@", [0x22, 0x40, 0xc0, 0xc2, 0x80, 0x40, 0x22]);
   jsonMalformedTest("leading-3-1", "@\uFFFD\x80@",
       [0x22, 0x40, 0xe0, 0xc2, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("leading-3-2", "@\uFFFD\x80@",
+  jsonMalformedTest("leading-3-2", "@\uFFFD\uFFFD\x80@",
       [0x22, 0x40, 0xe0, 0x80, 0xc2, 0x80, 0x40, 0x22]);
   jsonMalformedTest("leading-4-1", "@\uFFFD\x80@",
       [0x22, 0x40, 0xf0, 0xc2, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("leading-4-2", "@\uFFFD\x80@",
+  jsonMalformedTest("leading-4-2", "@\uFFFD\uFFFD\x80@",
       [0x22, 0x40, 0xf0, 0x80, 0xc2, 0x80, 0x40, 0x22]);
-  jsonMalformedTest("leading-4-3", "@\uFFFD\x80@",
+  jsonMalformedTest("leading-4-3", "@\uFFFD\uFFFD\uFFFD\x80@",
       [0x22, 0x40, 0xf0, 0x80, 0x80, 0xc2, 0x80, 0x40, 0x22]);
 
   // Overlong encodings of ASCII outside of strings always fail.
diff --git a/tests/lib_2/convert/utf82_test.dart b/tests/lib_2/convert/utf82_test.dart
index df08103..cf0c2b0 100644
--- a/tests/lib_2/convert/utf82_test.dart
+++ b/tests/lib_2/convert/utf82_test.dart
@@ -28,11 +28,14 @@
   return new Utf8Codec(allowMalformed: true).decoder.convert(bytes);
 }
 
-final TESTS = [
+final TESTS0 = [
   // Unfinished UTF-8 sequences.
   [0xc3],
   [0xE2, 0x82],
-  [0xF0, 0xA4, 0xAD],
+  [0xF0, 0xA4, 0xAD]
+];
+
+final TESTS1 = [
   // Overlong encoding of euro-sign.
   [0xF0, 0x82, 0x82, 0xAC],
   // Other overlong/unfinished sequences.
@@ -64,11 +67,11 @@
   // Test that 0xC0|1, 0x80 does not eat the next character.
   [
     [0xC0, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   [
     [0xC1, 0x80, 0x61],
-    "Xa"
+    "XXa"
   ],
   // 0xF5 .. 0xFF never appear in valid UTF-8 sequences.
   [
@@ -207,44 +210,49 @@
 ];
 
 main() {
-  var allTests = TESTS.expand((test) {
+  var allTests = [...TESTS0, ...TESTS1].expand((test) {
     // Pairs of test and expected string output when malformed strings are
-    // allowed. Replacement character: U+FFFD
+    // allowed. Replacement character: U+FFFD, one per unfinished sequence or
+    // undecodable byte.
+    String replacement =
+        TESTS0.contains(test) ? "\u{FFFD}" : "\u{FFFD}" * test.length;
     return [
-      [test, "\u{FFFD}"],
+      [test, "${replacement}"],
       [
-        new List<int>.from([0x61])..addAll(test),
-        "a\u{FFFD}"
+        [0x61, ...test],
+        "a${replacement}"
       ],
       [
-        new List<int>.from([0x61])
-          ..addAll(test)
-          ..add(0x61),
-        "a\u{FFFD}a"
-      ],
-      [new List<int>.from(test)..add(0x61), "\u{FFFD}a"],
-      [new List<int>.from(test)..addAll(test), "\u{FFFD}\u{FFFD}"],
-      [
-        new List<int>.from(test)
-          ..add(0x61)
-          ..addAll(test),
-        "\u{FFFD}a\u{FFFD}"
+        [0x61, ...test, 0x61],
+        "a${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test),
-        "å\u{FFFD}"
+        [...test, 0x61],
+        "${replacement}a"
       ],
       [
-        new List<int>.from([0xc3, 0xa5])..addAll(test)..addAll([0xc3, 0xa5]),
-        "å\u{FFFD}å"
+        [...test, ...test],
+        "${replacement}${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5]),
-        "\u{FFFD}å"
+        [...test, 0x61, ...test],
+        "${replacement}a${replacement}"
       ],
       [
-        new List<int>.from(test)..addAll([0xc3, 0xa5])..addAll(test),
-        "\u{FFFD}å\u{FFFD}"
+        [0xc3, 0xa5, ...test],
+        "å${replacement}"
+      ],
+      [
+        [0xc3, 0xa5, ...test, 0xc3, 0xa5],
+        "å${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5],
+        "${replacement}å"
+      ],
+      [
+        [...test, 0xc3, 0xa5, ...test],
+        "${replacement}å${replacement}"
       ]
     ];
   });
diff --git a/tests/lib_2/convert/utf84_test.dart b/tests/lib_2/convert/utf84_test.dart
index bc1db59..566b1fa 100755
--- a/tests/lib_2/convert/utf84_test.dart
+++ b/tests/lib_2/convert/utf84_test.dart
@@ -727,10 +727,14 @@
   Expect.listEquals([0xe000], utf8ToRunes([0xee, 0x80, 0x80]), "e000");
   Expect.listEquals([unicodeReplacementCharacterRune],
       utf8ToRunes([0xef, 0xbf, 0xbd]), "fffd");
-  Expect
-      .listEquals([0x10ffff], utf8ToRunes([0xf4, 0x8f, 0xbf, 0xbf]), "10ffff");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xf4, 0x90, 0x80, 0x80]), "110000");
+  Expect.listEquals(
+      [0x10ffff], utf8ToRunes([0xf4, 0x8f, 0xbf, 0xbf]), "10ffff");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xf4, 0x90, 0x80, 0x80]), "110000");
 
   // unexpected continuation bytes
   Expect.listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0x80]),
@@ -795,12 +799,15 @@
   // Sequences with last continuation byte missing
   Expect.listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xc2]),
       "2-byte sequence with last byte missing");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xe0, 0x80]), "3-byte sequence with last byte missing");
   Expect.listEquals(
-      [unicodeReplacementCharacterRune],
-      utf8ToRunes([0xf0, 0x80, 0x80]),
-      "4-byte sequence with last byte missing");
+      [unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
+      utf8ToRunes([0xe0, 0x80]),
+      "3-byte sequence with last byte missing");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xf0, 0x80, 0x80]), "4-byte sequence with last byte missing");
   Expect.listEquals([
     unicodeReplacementCharacterRune,
     unicodeReplacementCharacterRune,
@@ -871,6 +878,9 @@
         unicodeReplacementCharacterRune,
         unicodeReplacementCharacterRune,
         unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
+        unicodeReplacementCharacterRune,
         unicodeReplacementCharacterRune
       ],
       utf8ToRunes([
@@ -890,8 +900,8 @@
         0x80,
         0x80,
         0xdf,
-        0xef,
-        0xbf,
+        0xef, // These two bytes form one incomplete sequence.
+        0xbf, // All others form one per byte.
         0xf7,
         0xbf,
         0xbf,
@@ -908,10 +918,10 @@
       "Concatenation of incomplete sequences");
 
   // Impossible bytes
-  Expect
-      .listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xfe]), "fe");
-  Expect
-      .listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xff]), "ff");
+  Expect.listEquals(
+      [unicodeReplacementCharacterRune], utf8ToRunes([0xfe]), "fe");
+  Expect.listEquals(
+      [unicodeReplacementCharacterRune], utf8ToRunes([0xff]), "ff");
   Expect.listEquals([
     unicodeReplacementCharacterRune,
     unicodeReplacementCharacterRune,
@@ -921,11 +931,20 @@
 
   // Overlong sequences
   Expect.listEquals(
-      [unicodeReplacementCharacterRune], utf8ToRunes([0xc0, 0xaf]), "c0 af");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xe0, 0x80, 0xaf]), "e0 80 af");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xf0, 0x80, 0x80, 0xaf]), "f0 80 80 af");
+      [unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
+      utf8ToRunes([0xc0, 0xaf]),
+      "c0 af");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xe0, 0x80, 0xaf]), "e0 80 af");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xf0, 0x80, 0x80, 0xaf]), "f0 80 80 af");
   Expect.listEquals([
     unicodeReplacementCharacterRune,
     unicodeReplacementCharacterRune,
@@ -943,11 +962,20 @@
   ], utf8ToRunes([0xfc, 0x80, 0x80, 0x80, 0x80, 0xaf]), "fc 80 80 80 80 af");
 
   Expect.listEquals(
-      [unicodeReplacementCharacterRune], utf8ToRunes([0xc1, 0xbf]), "c1 bf");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xe0, 0x9f, 0xbf]), "e0 9f bf");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xf0, 0x8f, 0xbf, 0xbf]), "f0 8f bf bf");
+      [unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
+      utf8ToRunes([0xc1, 0xbf]),
+      "c1 bf");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xe0, 0x9f, 0xbf]), "e0 9f bf");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xf0, 0x8f, 0xbf, 0xbf]), "f0 8f bf bf");
   Expect.listEquals([
     unicodeReplacementCharacterRune,
     unicodeReplacementCharacterRune,
@@ -965,11 +993,20 @@
   ], utf8ToRunes([0xfc, 0x83, 0xbf, 0xbf, 0xbf, 0xbf]), "fc 83 bf bf bf bf");
 
   Expect.listEquals(
-      [unicodeReplacementCharacterRune], utf8ToRunes([0xc0, 0x80]), "c0 80");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xe0, 0x80, 0x80]), "e0 80 80");
-  Expect.listEquals([unicodeReplacementCharacterRune],
-      utf8ToRunes([0xf0, 0x80, 0x80, 0x80]), "f0 80 80 80");
+      [unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
+      utf8ToRunes([0xc0, 0x80]),
+      "c0 80");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xe0, 0x80, 0x80]), "e0 80 80");
+  Expect.listEquals([
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune,
+    unicodeReplacementCharacterRune
+  ], utf8ToRunes([0xf0, 0x80, 0x80, 0x80]), "f0 80 80 80");
   Expect.listEquals([
     unicodeReplacementCharacterRune,
     unicodeReplacementCharacterRune,
diff --git a/tests/lib_2/convert/utf85_test.dart b/tests/lib_2/convert/utf85_test.dart
index 3f287e9..a380991 100644
--- a/tests/lib_2/convert/utf85_test.dart
+++ b/tests/lib_2/convert/utf85_test.dart
@@ -9,7 +9,7 @@
 
 main() {
   for (int i = 0; i <= 0x10FFFF; i++) {
-    if (i == unicodeBomCharacterRune) continue;
+    if (i == unicodeBomCharacterRune || (i & 0x1FF800) == 0xD800) continue;
     Expect.equals(
         i, utf8.decode(utf8.encode(new String.fromCharCode(i))).runes.first);
   }
diff --git a/tests/lib_2/convert/utf8_encode_test.dart b/tests/lib_2/convert/utf8_encode_test.dart
index 1e611bb..0a43e14 100644
--- a/tests/lib_2/convert/utf8_encode_test.dart
+++ b/tests/lib_2/convert/utf8_encode_test.dart
@@ -25,8 +25,8 @@
   String ascii = "ABCDE";
   Expect.listEquals([0x41, 0x42, 0x43, 0x44, 0x45], encoder.convert(ascii));
   Expect.listEquals([0x41, 0x42, 0x43, 0x44, 0x45], encoder.convert(ascii, 0));
-  Expect
-      .listEquals([0x41, 0x42, 0x43, 0x44, 0x45], encoder.convert(ascii, 0, 5));
+  Expect.listEquals(
+      [0x41, 0x42, 0x43, 0x44, 0x45], encoder.convert(ascii, 0, 5));
   Expect.listEquals([0x42, 0x43, 0x44, 0x45], encoder.convert(ascii, 1));
   Expect.listEquals([0x41, 0x42, 0x43, 0x44], encoder.convert(ascii, 0, 4));
   Expect.listEquals([0x42, 0x43, 0x44], encoder.convert(ascii, 1, 4));
@@ -50,6 +50,6 @@
   Expect.listEquals(
       [0xc2, 0x82, 0xe1, 0x81, 0x81], encoder.convert(unicode, 1, 3));
   // Split in the middle of a surrogate pair.
-  Expect.listEquals([0xc2, 0x82, 0xe1, 0x81, 0x81, 0xed, 0xa0, 0x80],
+  Expect.listEquals([0xc2, 0x82, 0xe1, 0x81, 0x81, 0xef, 0xbf, 0xbd],
       encoder.convert(unicode, 1, 4));
 }
diff --git a/tests/lib_2/convert/utf8_test.dart b/tests/lib_2/convert/utf8_test.dart
index 858c982..6f97fd0 100644
--- a/tests/lib_2/convert/utf8_test.dart
+++ b/tests/lib_2/convert/utf8_test.dart
@@ -73,28 +73,29 @@
 
   // Bad encoding, points to first bad byte.
   testExn([0x80, 0x00], 0);
-  testExn([0xC0, 0x00], 1);
-  testExn([0xE0, 0x00], 1);
-  testExn([0xE0, 0x80, 0x00], 2);
-  testExn([0xF0, 0x00], 1);
-  testExn([0xF0, 0x80, 0x00], 2);
-  testExn([0xF0, 0x80, 0x80, 0x00], 3);
+  testExn([0xC2, 0x00], 1);
+  testExn([0xE2, 0x00], 1);
+  testExn([0xE2, 0x80, 0x00], 2);
+  testExn([0xF2, 0x00], 1);
+  testExn([0xF2, 0x80, 0x00], 2);
+  testExn([0xF2, 0x80, 0x80, 0x00], 3);
   testExn([0xF8, 0x00], 0);
   // Short encoding, points to end.
-  testExn([0xC0], 1);
-  testExn([0xE0], 1);
-  testExn([0xE0, 0x80], 2);
-  testExn([0xF0], 1);
-  testExn([0xF0, 0x80], 2);
-  testExn([0xF0, 0x80, 0x80], 3);
-  // Overlong encoding, points to start of encoding.
+  testExn([0xC2], 1);
+  testExn([0xE2], 1);
+  testExn([0xE2, 0x80], 2);
+  testExn([0xF2], 1);
+  testExn([0xF2, 0x80], 2);
+  testExn([0xF2, 0x80, 0x80], 3);
+  // Overlong encoding, points to byte that gave enough information to conclude
+  // that it was overlong.
   testExn([0xC0, 0x80], 0);
   testExn([0xC1, 0xBF], 0);
-  testExn([0xE0, 0x80, 0x80], 0);
-  testExn([0xE0, 0x9F, 0xBF], 0);
-  testExn([0xF0, 0x80, 0x80, 0x80], 0);
-  testExn([0xF0, 0x8F, 0xBF, 0xBF], 0);
+  testExn([0xE0, 0x80, 0x80], 1);
+  testExn([0xE0, 0x9F, 0xBF], 1);
+  testExn([0xF0, 0x80, 0x80, 0x80], 1);
+  testExn([0xF0, 0x8F, 0xBF, 0xBF], 1);
   // Invalid character (value too large, over 0x10FFFF).
-  testExn([0xF4, 0x90, 0x80, 0x80], 0);
+  testExn([0xF4, 0x90, 0x80, 0x80], 1);
   testExn([0xF7, 0xBF, 0xBF, 0xBF], 0);
 }
diff --git a/tests/lib_2/isolate/package_config_getter_test.dart b/tests/lib_2/isolate/package_config_getter_test.dart
new file mode 100644
index 0000000..0b7d506
--- /dev/null
+++ b/tests/lib_2/isolate/package_config_getter_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:path/path.dart' as path;
+
+import 'spawn_uri__package_uri__test.dart';
+
+final executable = Platform.executable;
+
+main() async {
+  // Make a folder structure that has both ".dart_tool/package_config.json" and
+  // ".packages" and ensure VM prefers to use ".packages".
+  await withTempDir((String tempDir) async {
+    // Setup ".packages" with "foo -> ..." mapping.
+    final dotPackagesPath = path.join(tempDir, '.packages');
+    final dotPackagesFile = File(dotPackagesPath);
+    await dotPackagesFile.writeAsString(buildDotPackages('foo'));
+
+    // Setup bogus ".dart_tool/package_config.json" with "invalid -> ..."
+    // mapping.
+    final dotDartToolDir = path.join(tempDir, '.dart_tool');
+    await Directory(dotDartToolDir).create();
+    final packageConfigJsonPath =
+        path.join(dotDartToolDir, 'package_config.json');
+    final packageConfigJsonFile = File(packageConfigJsonPath);
+    await packageConfigJsonFile
+        .writeAsString(buildPackageConfig('invalid', true));
+
+    final mainFile = path.join(tempDir, 'main.dart');
+    await File(mainFile).writeAsString('''
+import 'dart:io' as io;
+import 'dart:isolate';
+
+main() async {
+  final uri = await Isolate.packageConfig;
+  final expectedUri = Uri.parse('${dotPackagesFile.uri}');
+  if (uri != expectedUri) {
+    throw 'VM should use .packages file (but used \$uri).';
+  }
+}
+''');
+
+    await run(executable, [mainFile]);
+  });
+}
diff --git a/tests/lib_2/isolate/package_config_test.dart b/tests/lib_2/isolate/package_config_test.dart
index 3039f3e..c9b4f02 100644
--- a/tests/lib_2/isolate/package_config_test.dart
+++ b/tests/lib_2/isolate/package_config_test.dart
@@ -8,33 +8,26 @@
 import 'dart:io';
 import 'dart:isolate';
 
-final SPAWN_PACKAGE_CONFIG = "foobar:///no/such/file/";
+const String packageConfig = "foobar:///no/such/file/";
+const String errorString = "IsolateSpawnException: Unable to spawn isolate:";
+const String errorString2 = "Error when reading '$packageConfig'";
 
-main([args, port]) async {
-  if (port != null) {
-    testPackageConfig(port);
-    return;
+main([args, msg]) async {
+  if (msg != null) {
+    throw 'unreachable';
   }
-  var p = new RawReceivePort();
-  Isolate.spawnUri(Platform.script, [], p.sendPort,
-      packageConfig: Uri.parse(SPAWN_PACKAGE_CONFIG));
-  p.handler = (msg) {
-    p.close();
-    if (msg[0] != SPAWN_PACKAGE_CONFIG) {
-      throw "Bad package config in child isolate: ${msg[0]}";
-    }
-    if (msg[1] != null) {
-      throw "Non-null loaded package config in isolate: ${msg[1]}";
-    }
-    print("SUCCESS");
-  };
-  print("Spawning isolate's package config: ${await Isolate.packageConfig}");
-}
-
-testPackageConfig(port) async {
-  var packageConfigStr = Platform.packageConfig;
-  var packageConfig = await Isolate.packageConfig;
-  print("Spawned isolate's package config flag: $packageConfigStr");
-  print("Spawned isolate's loaded package config: $packageConfig");
-  port.send([packageConfigStr, packageConfig?.toString()]);
+  dynamic error;
+  try {
+    await Isolate.spawnUri(Platform.script, [], 'msg',
+        packageConfig: Uri.parse('foobar:///no/such/file/'));
+  } catch (e) {
+    error = e;
+  }
+  if (error == null) throw 'Expected a Spawning error.';
+  if (!'$error'.contains(errorString)) {
+    throw 'Epected: $errorString to contain "$errorString"';
+  }
+  if (!'$error'.contains(errorString2)) {
+    throw 'Epected: $errorString to contain "$errorString2"';
+  }
 }
diff --git a/tests/lib_2/isolate/package_resolve_test.dart b/tests/lib_2/isolate/package_resolve_test.dart
index 4379b4c..50686a3 100644
--- a/tests/lib_2/isolate/package_resolve_test.dart
+++ b/tests/lib_2/isolate/package_resolve_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
@@ -8,44 +8,67 @@
 import 'dart:io';
 import 'dart:isolate';
 
-final SPAWN_PACKAGE_ROOT = "file:///no/such/package/root/";
-final PACKAGE_URI = "package:foo/bar.dart";
-final PACKAGE_PATH = "file:///no/such/package/root/foo/bar.dart";
+final packageUriToResolve = "package:foo/bar.dart";
+final packageResolvedUri = "file:///no/such/directory/lib/bar.dart";
+
+final dotPackages = """
+# This is the content of a .packages file.
+foo:file:///no/such/directory/lib/
+""";
+
+final packageConfigJson = """
+{
+  "configVersion": 2,
+  "packages": [
+    {
+      "name": "foo",
+      "rootUri": "file:///no/such/directory",
+      "packageUri": "lib/",
+      "languageVersion": "2.7"
+    }
+  ]
+}
+""";
 
 main([args, port]) async {
   if (port != null) {
     testPackageResolution(port);
     return;
   }
-  var p = new RawReceivePort();
-  Isolate.spawnUri(Platform.script, [], p.sendPort,
-      packageRoot: Uri.parse(SPAWN_PACKAGE_ROOT));
-  p.handler = (msg) {
-    p.close();
-    if (msg is! List) {
-      print(msg.runtimeType);
-      throw "Failure return from spawned isolate:\n\n$msg";
-    }
-    if (msg[0] != null) {
-      throw "Bad package root in child isolate: ${msg[0]}";
-    }
-    if (msg[1] != null) {
-      throw "Package path not matching: ${msg[1]}";
-    }
-    print("SUCCESS");
-  };
-  print("Spawning isolate's package root: ${await Isolate.packageRoot}");
+  await runTest(dotPackages);
+  await runTest(packageConfigJson);
+}
+
+Future runTest(String packageConfig) async {
+  final data = Uri.dataFromString(packageConfig);
+  final port = ReceivePort();
+  await Isolate.spawnUri(Platform.script, [], port.sendPort,
+      packageConfig: data);
+  final msg = await port.first;
+  if (msg is! List) {
+    print(msg.runtimeType);
+    throw "Failure return from spawned isolate:\n\n$msg";
+  }
+  if (msg[0] != data.toString()) {
+    throw "Bad package config in child isolate: ${msg[0]}\n"
+        "Expected: $data";
+  }
+  if (msg[1] != packageResolvedUri) {
+    throw "Package path not matching: ${msg[1]}";
+  }
+  print("SUCCESS");
 }
 
 testPackageResolution(port) async {
   try {
-    var packageRootStr = Platform.packageRoot;
-    var packageRoot = await Isolate.packageRoot;
-    var resolvedPkg = await Isolate.resolvePackageUri(Uri.parse(PACKAGE_URI));
-    print("Spawned isolate's package root flag: $packageRootStr");
-    print("Spawned isolate's loaded package root: $packageRoot");
+    var packageConfigStr = Platform.packageConfig;
+    var packageConfig = await Isolate.packageConfig;
+    var resolvedPkg =
+        await Isolate.resolvePackageUri(Uri.parse(packageUriToResolve));
+    print("Spawned isolate's package config flag: $packageConfigStr");
+    print("Spawned isolate's loaded package config: $packageConfig");
     print("Spawned isolate's resolved package path: $resolvedPkg");
-    port.send([packageRoot?.toString(), resolvedPkg?.toString()]);
+    port.send([packageConfig?.toString(), resolvedPkg?.toString()]);
   } catch (e, s) {
     port.send("$e\n$s\n");
   }
diff --git a/tests/lib_2/isolate/scenarios/package_data_uri_spec/package_resolve_test.dart b/tests/lib_2/isolate/scenarios/package_data_uri_spec/package_resolve_test.dart
index ddb77c4..50686a3 100644
--- a/tests/lib_2/isolate/scenarios/package_data_uri_spec/package_resolve_test.dart
+++ b/tests/lib_2/isolate/scenarios/package_data_uri_spec/package_resolve_test.dart
@@ -2,15 +2,32 @@
 // 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.
 
+// VMOptions=--enable-isolate-groups
+// VMOptions=--no-enable-isolate-groups
+
 import 'dart:io';
 import 'dart:isolate';
 
-final PACKAGE_URI = "package:foo/bar.dart";
-final PACKAGE_PATH = "file:///no/such/directory/bar.dart";
+final packageUriToResolve = "package:foo/bar.dart";
+final packageResolvedUri = "file:///no/such/directory/lib/bar.dart";
 
-final PACKAGE_SPEC = """
+final dotPackages = """
 # This is the content of a .packages file.
-foo:file:///no/such/directory/
+foo:file:///no/such/directory/lib/
+""";
+
+final packageConfigJson = """
+{
+  "configVersion": 2,
+  "packages": [
+    {
+      "name": "foo",
+      "rootUri": "file:///no/such/directory",
+      "packageUri": "lib/",
+      "languageVersion": "2.7"
+    }
+  ]
+}
 """;
 
 main([args, port]) async {
@@ -18,34 +35,36 @@
     testPackageResolution(port);
     return;
   }
-  var data = new Uri.dataFromString(PACKAGE_SPEC);
-  var p = new RawReceivePort();
-  Isolate.spawnUri(Platform.script, [], p.sendPort, packageConfig: data);
-  p.handler = (msg) {
-    p.close();
-    if (msg is! List) {
-      print(msg.runtimeType);
-      throw "Failure return from spawned isolate:\n\n$msg";
-    }
-    if (msg[0] != data.toString()) {
-      throw "Bad package config in child isolate: ${msg[0]}\n"
-          "Expected: $data";
-    }
-    if (msg[1] != PACKAGE_PATH) {
-      throw "Package path not matching: ${msg[1]}";
-    }
-    print("SUCCESS");
-  };
-  print("Spawning isolate's package root: ${await Isolate.packageRoot}");
+  await runTest(dotPackages);
+  await runTest(packageConfigJson);
+}
+
+Future runTest(String packageConfig) async {
+  final data = Uri.dataFromString(packageConfig);
+  final port = ReceivePort();
+  await Isolate.spawnUri(Platform.script, [], port.sendPort,
+      packageConfig: data);
+  final msg = await port.first;
+  if (msg is! List) {
+    print(msg.runtimeType);
+    throw "Failure return from spawned isolate:\n\n$msg";
+  }
+  if (msg[0] != data.toString()) {
+    throw "Bad package config in child isolate: ${msg[0]}\n"
+        "Expected: $data";
+  }
+  if (msg[1] != packageResolvedUri) {
+    throw "Package path not matching: ${msg[1]}";
+  }
+  print("SUCCESS");
 }
 
 testPackageResolution(port) async {
   try {
-    var packageRootStr = Platform.packageRoot;
     var packageConfigStr = Platform.packageConfig;
     var packageConfig = await Isolate.packageConfig;
-    var resolvedPkg = await Isolate.resolvePackageUri(Uri.parse(PACKAGE_URI));
-    print("Spawned isolate's package root flag: $packageRootStr");
+    var resolvedPkg =
+        await Isolate.resolvePackageUri(Uri.parse(packageUriToResolve));
     print("Spawned isolate's package config flag: $packageConfigStr");
     print("Spawned isolate's loaded package config: $packageConfig");
     print("Spawned isolate's resolved package path: $resolvedPkg");
diff --git a/tests/lib_2/isolate/spawn_uri__package_uri__test.dart b/tests/lib_2/isolate/spawn_uri__package_uri__test.dart
new file mode 100644
index 0000000..61837fc
--- /dev/null
+++ b/tests/lib_2/isolate/spawn_uri__package_uri__test.dart
@@ -0,0 +1,181 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+
+final executable = Platform.executable;
+
+main() async {
+  // Run the Dart VM with or without:
+  //     --packages=<packages|package_config>
+  for (final runWithPackagesArg in const [true, false]) {
+    // Run the isolate with or without
+    //    Isolate.spawnUri(..., packageConfig: <packages|package_config>)
+    print('TEST runWithPackagesArg = $runWithPackagesArg ');
+    for (final spawnWithPackageConfig in const [true, false]) {
+      print('TEST spawnWithPackageConfig = $spawnWithPackageConfig ');
+      final bool checkForResolveUri =
+          runWithPackagesArg || !spawnWithPackageConfig;
+      await runDotPackagesTest(
+          runWithPackagesArg, spawnWithPackageConfig, checkForResolveUri);
+      for (final optionalPackageUri in const [true, false]) {
+        print('TEST optionalPackageUri = $optionalPackageUri');
+        await runPackageConfigTest(runWithPackagesArg, spawnWithPackageConfig,
+            optionalPackageUri, checkForResolveUri);
+      }
+    }
+  }
+}
+
+Future runPackageConfigTest(bool withPackagesArg, bool spawnWithArg,
+    bool optionalPackageUri, bool checkForResolveUri) async {
+  await withApplicationDirAndDotDartToolPackageConfig(
+      (String tempDir, String packageJson, String mainFile) async {
+    final args = [if (withPackagesArg) '--packages=$packageJson', mainFile];
+    await run(executable, args);
+  }, spawnWithArg, optionalPackageUri, checkForResolveUri);
+}
+
+Future runDotPackagesTest(
+    bool withPackagesArg, bool spawnWithArg, bool checkForResolveUri) async {
+  await withApplicationDirAndDotPackages(
+      (String tempDir, String dotPackagesFile, String mainFile) async {
+    final args = [
+      if (withPackagesArg) '--packages=$dotPackagesFile',
+      mainFile,
+    ];
+    await run(executable, args);
+  }, spawnWithArg, checkForResolveUri);
+}
+
+Future withApplicationDirAndDotPackages(
+    Future fn(String tempDir, String packagesDir, String mainFile),
+    bool spawnWithArg,
+    bool checkForResolveUri) async {
+  await withTempDir((String tempDir) async {
+    // Setup ".packages"
+    final dotPackagesFile =
+        path.join(tempDir, spawnWithArg ? 'baz.packages' : '.packages');
+    await File(dotPackagesFile).writeAsString(buildDotPackages('foo'));
+
+    final mainFile = path.join(tempDir, 'main.dart');
+    final childIsolateFile = path.join(tempDir, 'child_isolate.dart');
+    final importUri = 'package:foo/child_isolate.dart';
+    await File(childIsolateFile).writeAsString(buildChildIsolate());
+    await File(mainFile).writeAsString(buildMainIsolate(
+        importUri,
+        spawnWithArg ? dotPackagesFile : null,
+        checkForResolveUri ? childIsolateFile : null));
+
+    await fn(tempDir, dotPackagesFile, mainFile);
+  });
+}
+
+Future withApplicationDirAndDotDartToolPackageConfig(
+    Future fn(String tempDir, String packageJson, String mainFile),
+    bool spawnWithArg,
+    bool optionalPackageUri,
+    bool checkForResolveUri) async {
+  await withTempDir((String tempDir) async {
+    // Setup ".dart_tool/package_config.json"
+    final dotDartToolDir = path.join(tempDir, '.dart_tool');
+    await Directory(dotDartToolDir).create();
+    final packageConfigJsonFile = path.join(
+        dotDartToolDir, spawnWithArg ? 'baz.packages' : 'package_config.json');
+    await File(packageConfigJsonFile)
+        .writeAsString(buildPackageConfig('foo', optionalPackageUri));
+
+    // Setup actual application
+    final mainFile = path.join(tempDir, 'main.dart');
+    final childIsolateFile = path.join(tempDir, 'child_isolate.dart');
+    final importUri = 'package:foo/child_isolate.dart';
+    await File(childIsolateFile).writeAsString(buildChildIsolate());
+    await File(mainFile).writeAsString(buildMainIsolate(
+        importUri,
+        spawnWithArg ? packageConfigJsonFile : null,
+        checkForResolveUri ? childIsolateFile : null));
+
+    await fn(tempDir, packageConfigJsonFile, mainFile);
+  });
+}
+
+Future withTempDir(Future fn(String dir)) async {
+  final dir = await Directory.systemTemp.createTemp('spawn_uri');
+  try {
+    await fn(dir.absolute.path);
+  } finally {
+    await dir.delete(recursive: true);
+  }
+}
+
+Future<ProcessResult> run(String executable, List<String> args,
+    {String cwd}) async {
+  print('Running $executable ${args.join(' ')}');
+  final String workingDirectory = cwd ?? Directory.current.absolute.path;
+  final result = await Process.run(executable, ['--trace-loading', ...args],
+      workingDirectory: workingDirectory);
+  print('exitCode:\n${result.exitCode}');
+  print('stdout:\n${result.stdout}');
+  print('stdout:\n${result.stderr}');
+  Expect.equals(0, result.exitCode);
+  return result;
+}
+
+String buildDotPackages(String packageName) => '$packageName:.';
+
+String buildPackageConfig(String packageName, bool optionalPackageUri) => '''
+{
+  "configVersion": 2,
+  "packages": [
+    {
+      "name": "$packageName",
+      "rootUri": "../"
+      ${optionalPackageUri ? ', "packageUri": "./"' : ''}
+    }
+  ]
+}
+''';
+
+String buildChildIsolate() => '''
+  import 'dart:isolate';
+
+  main(List<String> args, SendPort message) {
+    message.send('child isolate is done');
+  }
+''';
+
+String buildMainIsolate(
+        String spawnUri, String packageConfigUri, String childIsolatePath) =>
+    '''
+  import 'dart:isolate';
+  import 'dart:io' as io;
+
+  main(List<String> args) async {
+    io.exitCode = 1;
+
+    final uri = Uri.parse('$spawnUri');
+    final resolvedUri = await Isolate.resolvePackageUri(uri);
+    if ("""\${resolvedUri?.toFilePath()}""" != r"""$childIsolatePath""") {
+      throw 'Could not Isolate.resolvePackageUri(uri).';
+    }
+
+    final rp = ReceivePort();
+    final isolateArgs = <String>['a'];
+    await Isolate.spawnUri(
+        uri,
+        isolateArgs,
+        rp.sendPort,
+        packageConfig: ${packageConfigUri != null ? 'Uri.file(r"$packageConfigUri")' : 'null'});
+    final childIsolateMessage = await rp.first;
+    if (childIsolateMessage != 'child isolate is done') {
+      throw 'Did not receive correct message from child isolate.';
+    }
+
+    // Test was successful.
+    io.exitCode = 0;
+  }
+''';
diff --git a/tests/lib_2/lib_2.status b/tests/lib_2/lib_2.status
index 432516a..3365351 100644
--- a/tests/lib_2/lib_2.status
+++ b/tests/lib_2/lib_2.status
@@ -11,6 +11,9 @@
 developer/timeline_test: Skip # Not supported
 isolate/issue_24243_parent_isolate_test: Skip # Requires checked mode
 
+[ $runtime == dart_precompiled ]
+isolate/package_config_getter_test: SkipByDesign # AOT mode doesn't preserve package structure.
+
 [ $runtime == ff ]
 convert/streamed_conversion_utf8_decode_test: Slow, Pass # Issue 12029
 mirrors/mirrors_reader_test: Slow, Pass # Issue 16589
@@ -24,6 +27,9 @@
 html/indexeddb_3_test: Skip # Times out 1 out of 10.
 html/worker_api_test: Skip # Issue 13221
 
+[ $runtime != vm ]
+isolate/spawn_uri__package_uri__test: SkipByDesign # This test uses Isolate.spawnUri and only works in JIT mode.
+
 [ $system == windows ]
 html/xhr_test/xhr: Skip # Times out.  Issue 21527
 
@@ -49,13 +55,6 @@
 [ $arch != x64 || $compiler == dartkb || $runtime != vm ]
 isolate/int32_length_overflow_test: SkipSlow
 
-[ $compiler != none || $runtime != vm ]
-isolate/package_config_test: SkipByDesign # Uses Isolate.packageConfig
-isolate/package_resolve_test: SkipByDesign # Uses Isolate.resolvePackageUri
-isolate/package_root_test: SkipByDesign # Uses Isolate.packageRoot
-isolate/scenarios/*: SkipByDesign # Use automatic package resolution, spawnFunction and .dart URIs.
-isolate/spawn_uri_fail_test: SkipByDesign # Uses dart:io.
-
 [ $mode == product || $runtime != vm ]
 isolate/checked_test: Skip # Unsupported.
 
@@ -91,8 +90,12 @@
 isolate/mint_maker_test: Skip # Isolate.spawnUri
 isolate/nested_spawn2_test: Skip # Isolate.spawnUri
 isolate/nested_spawn_test: Skip # Isolate.spawnUri
+isolate/package_config_test: Skip # Isolate.spawnUri
 isolate/raw_port_test: Skip # Isolate.spawnUri
 isolate/request_reply_test: Skip # Isolate.spawnUri
+isolate/scenarios/automatic_resolution_spec/package_resolve_test: Skip # Isolate.spawnUri
+isolate/scenarios/package_relative_spec/package_relative_spec_test: Skip # Isolate.spawnUri
+isolate/scenarios/short_package/short_package_test: Skip # Isolate.spawnUri
 isolate/spawn_function_custom_class_test: Skip # Isolate.spawnUri
 isolate/spawn_function_test: Skip # Isolate.spawnUri
 isolate/spawn_uri_exported_main_test: Skip # Isolate.spawnUri
@@ -106,6 +109,13 @@
 isolate/static_function_test: Skip # Isolate.spawnUri
 isolate/unresolved_ports_test: Skip # Isolate.spawnUri
 
+[ $runtime != vm || $compiler != dartk && $compiler != none ]
+isolate/package_config_test: SkipByDesign # Uses Isolate.packageConfig
+isolate/package_resolve_test: SkipByDesign # Uses Isolate.resolvePackageUri
+isolate/package_root_test: SkipByDesign # Uses Isolate.packageRoot
+isolate/scenarios/*: SkipByDesign # Use automatic package resolution, spawnFunction and .dart URIs.
+isolate/spawn_uri_fail_test: SkipByDesign # Uses dart:io.
+
 [ $hot_reload || $hot_reload_rollback ]
 convert/chunked_conversion_utf88_test: SkipSlow
 convert/utf85_test: SkipSlow
diff --git a/tests/lib_2/lib_2_vm.status b/tests/lib_2/lib_2_vm.status
index 78b9986..65cb43c 100644
--- a/tests/lib_2/lib_2_vm.status
+++ b/tests/lib_2/lib_2_vm.status
@@ -124,6 +124,9 @@
 isolate/non_fatal_exception_in_timer_callback_test/sleep: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/object_leak_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/ondone_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/package_config_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/package_resolve_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/package_root_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/pause_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/ping_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/port_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
@@ -132,12 +135,15 @@
 isolate/regress_flutter_22796_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/request_reply_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/resolve_package_uri_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/scenarios/package_data_uri_spec/package_resolve_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/send_private_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/simple_message_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_function_custom_class_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_function_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_generic_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/spawn_uri__package_uri__test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_uri_exported_main_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/spawn_uri_fail_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_uri_missing_from_isolate_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_uri_missing_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
 isolate/spawn_uri_multi_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
diff --git a/tools/VERSION b/tools/VERSION
index 14923ef..b30807e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -33,7 +33,7 @@
 MAJOR 2
 MINOR 9
 PATCH 0
-PRERELEASE 7
+PRERELEASE 8
 PRERELEASE_PATCH 0
 ABI_VERSION 32
 OLDEST_SUPPORTED_ABI_VERSION 32
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 7536b70..9dc2f2f 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -770,7 +770,7 @@
       }
     },
     "dartk-android-(debug|product|release)-(arm|arm64)": {},
-    "dartkp-(linux|win|mac)-(debug|product|release)-(simarm|simarm64)": {
+    "dartkp-(linux|win|mac)-(debug|product|release)-(arm64|simarm|simarm64)": {
       "options": {
         "use-elf": true
       }
@@ -1957,6 +1957,33 @@
     },
     {
       "builders": [
+        "cross-vm-precomp-linux-release-arm64"
+      ],
+      "meta": {
+        "description": "This configuration is for the cross arm AOT builders."
+      },
+      "steps": [
+        {
+          "name": "build dart",
+          "script": "tools/build.py",
+          "arguments": [
+            "dart_precompiled_runtime",
+            "gen_snapshot",
+            "runtime_kernel"
+          ]
+        },
+        {
+          "name": "vm tests",
+          "arguments": [
+            "-ndartkp-${system}-${mode}-${arch}"
+          ],
+          "fileset": "vm-kernel",
+          "shards": 1
+        }
+      ]
+    },
+    {
+      "builders": [
         "app-kernel-linux-debug-x64",
         "app-kernel-linux-product-x64",
         "app-kernel-linux-release-x64"
diff --git a/tools/migration/bin/progress.dart b/tools/migration/bin/progress.dart
index 270caa8..d14b838 100644
--- a/tools/migration/bin/progress.dart
+++ b/tools/migration/bin/progress.dart
@@ -30,6 +30,8 @@
   var totalMigratedFiles = 0;
   var totalMigratedLines = 0;
 
+  var skipCompleteSubfolders = arguments.contains("--incomplete");
+
   for (var rootDir in legacyRootDirs) {
     var subdirs = Directory(p.join(testRoot, rootDir))
         .listSync()
@@ -59,6 +61,7 @@
       }
 
       if (files == 0) continue;
+      if (skipCompleteSubfolders && lines == migratedLines) continue;
 
       _show(dir, migratedFiles, files, migratedLines, lines);
       totalFiles += files;