anchor.diff:  import 'update_statement_visitor.dart' show bindingToUpdateStatement;
   import 'view_compiler_utils.dart' show unwrapDirective, unwrapDirectiveInstance;
   import 'view_name_resolver.dart';
  -
  -o.ReadClassMemberExpr _createBindFieldExpr(num exprIndex) =>
  -    o.ReadClassMemberExpr('_expr_$exprIndex');
  -
  -o.ReadVarExpr _createCurrValueExpr(num exprIndex) =>
  -    o.variable('currVal_$exprIndex');
  -
  -/// Generates code to bind template expression.
  -///
  -/// If [checkExpression] is immutable, code is added to [literalMethod] to be
  -/// executed once when the component is created. Otherwise statements are added
  -/// to [method] to be executed on each change detection cycle.
  -void _bind(
  -  ViewStorage storage,
  -  o.ReadVarExpr currValExpr,
  -  o.ReadClassMemberExpr fieldExpr,
  -  o.Expression checkExpression,
  -  bool isImmutable,
  -  bool isNullable,
  -  List<o.Statement> actions,
  -  CompileMethod method,
  -  CompileMethod literalMethod, {
  -  o.OutputType fieldType,
  -  bool isHostComponent = false,
  -  o.Expression fieldExprInitializer,
  -}) {
  -  if (isImmutable) {
  -    // If the expression is immutable, it will never change, so we can run it
  -    // once on the first change detection.
  -    if (!isHostComponent) {
  -      _bindLiteral(checkExpression, actions, currValExpr.name, fieldExpr.name,
  -          literalMethod, isNullable);
  -    }
  -    return;
  -  }
  -  if (checkExpression == null) {
  -    // e.g. an empty expression was given
  -    return;
  -  }
  -  bool isPrimitive = _isPrimitiveFieldType(fieldType);
  -  ViewStorageItem previousValueField = storage.allocate(fieldExpr.name,
  -      modifiers: const [o.StmtModifier.Private],
  -      initializer: fieldExprInitializer,
  -      outputType: isPrimitive ? fieldType : null);
  -  method.addStmt(currValExpr
  -      .set(checkExpression)
  -      .toDeclStmt(null, [o.StmtModifier.Final]));
  -  method.addStmt(o.IfStmt(
  -      o.importExpr(Identifiers.checkBinding).callFn([fieldExpr, currValExpr]),
  -      List.from(actions)
  -        ..addAll([
  -          storage.buildWriteExpr(previousValueField, currValExpr).toStmt()
  -        ])));
  -}
  -
  -void _directBinding(
  -  ir.Binding binding,
  -  BoundValueConverter converter,
  -  CompileMethod method,
  -  o.Expression appViewInstance,
  -  NodeReference renderNode,
  -  bool isHtmlElement,
  -) {
  -  var expression =
  -      converter.convertSourceToExpression(binding.source, binding.target.type);
  -  var updateStatement = bindingToUpdateStatement(
  -    binding,
  -    appViewInstance,
  -    renderNode,
  -    isHtmlElement,
  -    expression,
  -  );
  -  method.addStmt(updateStatement);
  -}
  -
  -/// The same as [_bind], but we know that [checkExpression] is a literal.
  -///
  -/// This means we don't need to create a change detection field or check if it
  -/// has changed. We know for sure that there will only be one transition from
  -/// [null] to whatever the value of [checkExpression] is. So we can just output
  -/// the [actions] and run them once on the first change detection run.
  -// TODO(alorenzen): Replace usages with _directBinding().
  -void _bindLiteral(
  -    o.Expression checkExpression,
  -    List<o.Statement> actions,
  -    String currValName,
  -    String fieldName,
  -    CompileMethod method,
  -    bool isNullable) {
  -  if (checkExpression == o.NULL_EXPR ||
  -      (checkExpression is o.LiteralExpr && checkExpression.value == null)) {
  -    // In this case, there is no transition, since change detection variables
  -    // are initialized to null.
  -    return;
  -  }
  -
  -  var mappedActions = actions
  -      // Replace all 'currVal_X' with the actual expression
  -      .map(
  -          (stmt) => o.replaceVarInStatement(currValName, checkExpression, stmt))
  -      // Replace all 'expr_X' with 'null'
  -      .map((stmt) => o.replaceVarInStatement(fieldName, o.NULL_EXPR, stmt));
  -  if (isNullable) {
  -    method.addStmt(o.IfStmt(
  -        checkExpression.notIdentical(o.NULL_EXPR), mappedActions.toList()));
  -  } else {
  -    method.addStmts(mappedActions.toList());
  -  }
  -}
  -
  -void bindRenderText(
  -    ir.Binding binding, CompileNode compileNode, CompileView view) {
  -  if (binding.source.isImmutable) {
  -    // We already set the value to the text node at creation
  -    return;
  -  }
  -  _directBinding(
  -    binding,
  -    BoundValueConverter.forView(view, DetectChangesVars.cachedCtx),
  -    view.detectChangesRenderPropertiesMethod,
  -    o.THIS_EXPR,
  -    compileNode.renderNode,
  -    false,
  -  );
  -}
   
   /// For each binding, creates code to update the binding.
   ///
  
positive.code:       .addStmt(callDetectHostPropertiesExpr.toStmt());
  }
  
  void bindDirectiveInputs(
      List<ir.Binding> inputs,
      CompileDirectiveMetadata directive,
      o.Expression directiveInstance,
      CompileElement compileElement,
      {bool isHostComponent = false}) {
    if (directive.inputs.isEmpty) {
      return;
    }
  
    var view = compileElement.view;
    var detectChangesInInputsMethod = view.detectChangesInInputsMethod;
    var lifecycleHooks = directive.lifecycleHooks;
    bool calcChangesMap = lifecycleHooks.contains(LifecycleHooks.onChanges);
    bool afterChanges = lifecycleHooks.contains(LifecycleHooks.afterChanges);
    var isOnPushComp = directive.isComponent &&
        directive.changeDetection == ChangeDetectionStrategy.OnPush;
    var calcChanged = isOnPushComp || afterChanges;
  
    if (calcChangesMap) {
      // We need to reinitialize changes, otherwise a second change
      // detection cycle would cause extra ngOnChanges call.
      view.requiresOnChangesCall = true;
      detectChangesInInputsMethod
          .addStmt(DetectChangesVars.changes.set(o.NULL_EXPR).toStmt());
    }
    if (afterChanges) {
      view.requiresAfterChangesCall = true;
    }
  
    // We want to call AfterChanges lifecycle only if we detect a change,
    // unlike OnChanges, we don't need to collect a map of SimpleChange(s)
    // therefore we keep track of changes using bool changed variable.
    // At the beginning of change detecting inputs we reset this flag to false,
    // and then set it to true if any of it's inputs change.
    if (calcChanged && !isHostComponent) {
      detectChangesInInputsMethod
          .addStmt(DetectChangesVars.changed.set(o.literal(false)).toStmt());
    }
    bindAndWriteToRenderer(
      inputs,
      BoundValueConverter.forView(view, DetectChangesVars.cachedCtx),
      directiveInstance,
      null,
      false,
      view.nameResolver,
      view.storage,
      detectChangesInInputsMethod,
      isHostComponent: isHostComponent,
      calcChanged: calcChanged,
      calcChangesMap: calcChangesMap,
    );
    if (isOnPushComp) {
      detectChangesInInputsMethod.addStmt(o.IfStmt(DetectChangesVars.changed, [
        compileElement.componentView.callMethod('markAsCheckOnce', []).toStmt()
      ]));
    }
  }
  
  List<o.Statement> _changesMap(String inputName, o.ReadClassMemberExpr fieldExpr,
          o.ReadVarExpr currValExpr) =>
      [
  
negative.code:   );
  }
  
  o.ReadClassMemberExpr _createBindFieldExpr(num exprIndex) =>
      o.ReadClassMemberExpr('_expr_$exprIndex');
  
  o.ReadVarExpr _createCurrValueExpr(num exprIndex) =>
      o.variable('currVal_$exprIndex');
  
  /// Generates code to bind template expression.
  ///
  /// If [checkExpression] is immutable, code is added to [literalMethod] to be
  /// executed once when the component is created. Otherwise statements are added
  /// to [method] to be executed on each change detection cycle.
  void _bind(
    ViewStorage storage,
    o.ReadVarExpr currValExpr,
    o.ReadClassMemberExpr fieldExpr,
    o.Expression checkExpression,
    bool isImmutable,
    bool isNullable,
    List<o.Statement> actions,
    CompileMethod method,
    CompileMethod literalMethod, {
    o.OutputType fieldType,
    bool isHostComponent = false,
    o.Expression fieldExprInitializer,
  }) {
    if (isImmutable) {
      // If the expression is immutable, it will never change, so we can run it
      // once on the first change detection.
      if (!isHostComponent) {
        _bindLiteral(checkExpression, actions, currValExpr.name, fieldExpr.name,
            literalMethod, isNullable);
      }
      return;
    }
    if (checkExpression == null) {
      // e.g. an empty expression was given
      return;
    }
    bool isPrimitive = _isPrimitiveFieldType(fieldType);
    ViewStorageItem previousValueField = storage.allocate(fieldExpr.name,
        modifiers: const [o.StmtModifier.Private],
        initializer: fieldExprInitializer,
        outputType: isPrimitive ? fieldType : null);
    method.addStmt(currValExpr
        .set(checkExpression)
        .toDeclStmt(null, [o.StmtModifier.Final]));
    method.addStmt(o.IfStmt(
        o.importExpr(Identifiers.checkBinding).callFn([fieldExpr, currValExpr]),
        List.from(actions)
          ..addAll([
            storage.buildWriteExpr(previousValueField, currValExpr).toStmt()
          ])));
  }
  
  /// The same as [_bind], but we know that [checkExpression] is a literal.
  ///
  /// This means we don't need to create a change detection field or check if it
  /// has changed. We know for sure that there will only be one transition from
  /// [null] to whatever the value of [checkExpression] is. So we can just output
  /// the [actions] and run them once on the first change detection run.
  // TODO(alorenzen): Replace usages with _directBinding().
  void _bindLiteral(
      o.Expression checkExpression,
      List<o.Statement> actions,
      String currValName,
      String fieldName,
      CompileMethod method,
      bool isNullable) {
    if (checkExpression == o.NULL_EXPR ||
        (checkExpression is o.LiteralExpr && checkExpression.value == null)) {
      // In this case, there is no transition, since change detection variables
      // are initialized to null.
      return;
    }
  
    var mappedActions = actions
        // Replace all 'currVal_X' with the actual expression
        .map(
            (stmt) => o.replaceVarInStatement(currValName, checkExpression, stmt))
        // Replace all 'expr_X' with 'null'
        .map((stmt) => o.replaceVarInStatement(fieldName, o.NULL_EXPR, stmt));
    if (isNullable) {
      method.addStmt(o.IfStmt(
          checkExpression.notIdentical(o.NULL_EXPR), mappedActions.toList()));
    } else {
      method.addStmts(mappedActions.toList());
    }
  }
  
  // Component or directive level host properties are change detected inside
  