anchor.diff:      thenContinuation.body = thenBuilder.root;
       elseContinuation.body = elseBuilder.root;
   
  -    // Capture free occurrences in the then and else bodies.  This is done
  -    // after creating invocations of the join continuation so free join
  +    // Capture free occurrences in the then and else bodies and add join
  +    // continuation parameters as assignments reaching the join body.  This is
  +    // done after creating invocations of the join continuation so free join
       // continuation arguments are properly captured.
  -    //
  -    // Also add join continuation parameters as assignments for the join body.
  -    // This is done last because the assigned variables are updated in place.
  -    int parameterIndex = 0;
  -    for (int i = 0; i < assignedVars.length; ++i) {
  -      // This is the definition that reaches the then and else continuations.
  -      // All free uses in either continuation are uses of this definition.
  -      ir.Definition reachingDefinition =
  -          assignedVars[i] == null ? freeVars[i] : assignedVars[i];
  -      reachingDefinition
  -          ..substituteFor(thenBuilder.freeVars[i])
  -          ..substituteFor(elseBuilder.freeVars[i]);
  -
  -      if ((thenBuilder.isOpen && thenBuilder.assignedVars[i] != null) ||
  -          (elseBuilder.isOpen && elseBuilder.assignedVars[i] != null)) {
  -        assignedVars[i] = parameters[parameterIndex++];
  -      }
  -    }
  +    captureFreeVariables(thenBuilder, elseBuilder, parameters);
   
       ir.Expression branch =
           new ir.LetCont(thenContinuation,
  
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:     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);
  