anchor.diff:      return null;
     }
   
  +  List<ir.Parameter> createJoinParameters(IrBuilder leftBuilder,
  +                                          List<ir.Primitive> leftArguments,
  +                                          IrBuilder rightBuilder,
  +                                          List<ir.Primitive> rightArguments) {
  +    // The sets of free and assigned variables for a delimited builder is
  +    // initially the length of the assigned variables of the parent.  The free
  +    // variables cannot grow because there cannot be free occurrences of
  +    // variables that were not declared before the entrance to the delimited
  +    // subgraph.  The assigned variables can grow when new variables are
  +    // declared in the delimited graph, but we only inspect the prefix
  +    // corresponding to the parent's declared variables.
  +    assert(assignedVars.length == leftBuilder.freeVars.length);
  +    assert(assignedVars.length == rightBuilder.freeVars.length);
  +    assert(assignedVars.length <= leftBuilder.assignedVars.length);
  +    assert(assignedVars.length <= rightBuilder.assignedVars.length);
  +
  +    List<ir.Parameter> parameters = <ir.Parameter>[];
  +    // If a variable was assigned on either the left or the right (and control
  +    // flow reaches the end of the corresponding subterm) then the variable has
  +    // different values reaching the join point and needs to be passed as an
  +    // argument to the join point continuation.
  +    for (int i = 0; i < assignedVars.length; ++i) {
  +      // The last assignments if any reaching the end of the two subterms.
  +      ir.Definition leftAssignment =
  +          leftBuilder.isOpen ? leftBuilder.assignedVars[i] : null;
  +      ir.Definition rightAssignment =
  +          rightBuilder.isOpen ? rightBuilder.assignedVars[i] : null;
  +
  +      if (leftAssignment != null || rightAssignment != null) {
  +        // The corresponsing argument is the reaching definition if any, or a
  +        // free occurrence.  In the case that control does not reach both the
  +        // left and right subterms we will still have a join continuation with
  +        // possibly arguments passed to it.  Such singly-used continuations
  +        // are eliminated by the shrinking conversions.
  +        ir.Parameter parameter = new ir.Parameter(null);
  +        parameters.add(parameter);
  +        leftArguments.add(leftAssignment == null
  +                              ? leftBuilder.freeVars[i]
  +                              : leftAssignment);
  +        rightArguments.add(rightAssignment == null
  +                              ? rightBuilder.freeVars[i]
  +                              : rightAssignment);
  +      }
  +    }
  +    return parameters;
  +  }
  +
  +  void captureFreeVariables(IrBuilder leftBuilder,
  +                            IrBuilder rightBuilder,
  +                            List<ir.Parameter> parameters) {
  +    int parameterIndex = 0;
  +    for (int i = 0; i < assignedVars.length; ++i) {
  +      // This is the definition that reaches the left and right subterms.  All
  +      // free uses in either term are uses of this definition.
  +      ir.Definition reachingDefinition =
  +          assignedVars[i] == null ? freeVars[i] : assignedVars[i];
  +      reachingDefinition
  +          ..substituteFor(leftBuilder.freeVars[i])
  +          ..substituteFor(rightBuilder.freeVars[i]);
  +
  +      // Also add join continuation parameters as assignments for the join
  +      // body.  This is done last because the assigned variables are updated
  +      // in place.
  +      if ((leftBuilder.isOpen && leftBuilder.assignedVars[i] != null) ||
  +          (rightBuilder.isOpen && rightBuilder.assignedVars[i] != null)) {
  +        assignedVars[i] = parameters[parameterIndex++];
  +      }
  +    }
  +  }
  +
     ir.Primitive visitIf(ast.If node) {
       assert(isOpen);
       ir.Primitive condition = visit(node.condition);
  
positive.code:     ir.Primitive thenValue = thenBuilder.visit(node.thenExpression);
      ir.Primitive elseValue = elseBuilder.visit(node.elseExpression);
  
      // Construct a join in the same way as for if statements, see visitIf.
      // There is always control flow out of expressions so thenBuilder.isOpen
      // and elseBuilder.isOpen.  There is an extra join-point continuation
      // parameter for the expression value.
      assert(assignedVars.length == thenBuilder.freeVars.length);
      assert(assignedVars.length == elseBuilder.freeVars.length);
      assert(assignedVars.length <= thenBuilder.assignedVars.length);
      assert(assignedVars.length <= elseBuilder.assignedVars.length);
      List<ir.Parameter> parameters = <ir.Parameter>[];
      List<ir.Primitive> thenArguments = <ir.Primitive>[];
      List<ir.Primitive> elseArguments = <ir.Primitive>[];
      for (int i = 0; i < assignedVars.length; ++i) {
        ir.Definition thenAssignment = thenBuilder.assignedVars[i];
        ir.Definition elseAssignment = elseBuilder.assignedVars[i];
        if (thenAssignment != null || elseAssignment != null) {
          ir.Parameter parameter = new ir.Parameter(null);
          parameters.add(parameter);
          thenArguments.add(thenAssignment == null
                                ? thenBuilder.freeVars[i]
                                : thenAssignment);
          elseArguments.add(elseAssignment == null
                                ? elseBuilder.freeVars[i]
                                : elseAssignment);
        }
      }
      // Add a continuation parameter for the result of the expression.
      ir.Parameter resultParameter = new ir.Parameter(null);
      parameters.add(resultParameter);
  
negative.code:     // assigned variables in the then and else parts are arguments to the join
      // point continuation if any.
  
      List<ir.Primitive> thenArguments = <ir.Primitive>[];
      List<ir.Primitive> elseArguments = <ir.Primitive>[];
      List<ir.Parameter> parameters =
          createJoinParameters(thenBuilder, thenArguments,
                               elseBuilder, elseArguments);
  
      // Create a then and else continuations and a join continuation if
      // necessary.  Jump to the join continuation from the exits of the then
  