anchor.diff:  % end index of the block, and FSM state.
   % Returns next ID, FSM with either a new state and a transition to it, or a transition
   %  to the end state added.
  -evaluate_comm_transition(CommAST, PrevID, FSMState) ->
  +
  +evaluate_transition(X, [{continue, RecName}|_], PrevID, _EndIndex,
  +                    RecMap, FSMState, MonitorState) ->
  +  FSMState1 = evaluate_rec_transition(X, PrevID, RecName, RecMap, FSMState),
  +  {FSMState1, MonitorState};
  +evaluate_transition(X, [{par, ParallelBlocks}|XS], PrevID, EndIndex, RecMap, FSMState,
  +                    MonitorState) ->
     RunningID = get_running_id(FSMState),
  -  FSMState1 = add_state(standard_state(), FSMState),
  +
  +  {MonitorState1, NestedFSMIDs} = evaluate_parallel_blocks(ParallelBlocks,
  +                                                           MonitorState, RecMap),
  +  io:format("In Eval transition, X: ~p, PrevID: ~p, EndIndex: ~p, ~n XS: ~p~n",
  +            [X, PrevID, EndIndex, XS]),
  +  FSMState1 = evaluate_comm_transition(X, PrevID, par_state(NestedFSMIDs), FSMState),
  +  evaluate_block(XS, RunningID, EndIndex, RecMap, FSMState1, MonitorState1);
  +evaluate_transition(X, XS, PrevID, EndIndex, RecMap, FSMState, MonitorState) ->
  +  RunningID = get_running_id(FSMState),
  +  FSMState1 = evaluate_comm_transition(X, PrevID, standard_state(), FSMState),
  +  evaluate_block(XS, RunningID, EndIndex, RecMap, FSMState1, MonitorState).
  +
  +
  +evaluate_comm_transition(CommAST, PrevID, StateToAdd, FSMState) ->
  +  RunningID = get_running_id(FSMState),
  +  FSMState1 = add_state(StateToAdd, FSMState),
     add_comm_transition(CommAST, PrevID, RunningID, FSMState1).
   
  -
  +evaluate_rec_transition(CommAST, PrevID, RecName, RecMap, FSMState) ->
  +  IDRes = orddict:find(RecName, RecMap),
  +  case IDRes of
  +    {ok, ID} ->
  +      add_comm_transition(CommAST, PrevID, ID, FSMState);
  +    _ -> error(rec_name_unbound)
  +  end.
   
   % Takes the ID of the previously-created node, end index, FSM state, monitor state.
   % On each step?
  
positive.code: % evaluate_block([X|XS], PrevIndex, EndIndex, FSMState, MonitorState) ->
  
    ScopeEndIndex = block_size(Block) + 1,
    EvalRes = evaluate_block(Block, 0, ScopeEndIndex, FSMState1, MonitorState2),
    case EvalRes of
      {FSMState2, MonitorState3} ->
        FSMState3 = add_state(end_state(), FSMState2),
  
negative.code: % to new, predicated on the comm action, then recursively evaluate.
  % Return FSMState and MonitorState.
  %
  evaluate_block([], _PrevIndex, _EndIndex, _RecMap, FSMState, MonitorState) ->
    {FSMState, MonitorState};
  % Par is (unfortunately) a bit of a special case, and we need to take some care with it.
  % Essentially, it should never be evaluated in this block.
  evaluate_block([{par, _}|_], _, _, _, _, _) -> error(eval_par);
  evaluate_block([X], PrevIndex, EndIndex, RecMap, FSMState, MonitorState) ->
    IsCommAction = is_comm_action(X),
    if IsCommAction ->
         % Add transition to the end node of the scope
         FSMState1 = add_comm_transition(X, PrevIndex, EndIndex, FSMState),
         {FSMState1, MonitorState};
       not IsCommAction ->
         evaluate_scope(X, PrevIndex, EndIndex, RecMap, FSMState, MonitorState)
    end;
  evaluate_block([X|XS], PrevIndex, EndIndex, RecMap, FSMState, MonitorState) ->
    IsCommAction = is_comm_action(X),
    RunningID = get_running_id(FSMState),
    if IsCommAction ->
         % Make a transition to PrevIndex, make a new state
         evaluate_transition(X, XS, PrevIndex, EndIndex, RecMap, FSMState, MonitorState);
       not IsCommAction ->
         ScopeEndIndex = RunningID + instruction_size(X),
         {FSMState1, MonitorState1} =
           evaluate_scope(X, PrevIndex, ScopeEndIndex, RecMap, FSMState, MonitorState),
         FSMState2 = add_state(standard_state(), FSMState1),
         % PrevIndex here: end index of the scope.
         evaluate_block(XS, ScopeEndIndex, EndIndex, RecMap,
                        FSMState2, MonitorState1)
    end.
  
  
  % Evaluates parallel blocks.
  % Evaluates each block, stores in monitor state.
  % Returns {MonitorState, Block ID List}.
  evaluate_parallel_blocks(Blocks, MonitorState, RecMap) ->
    evaluate_parallel_blocks_inner(Blocks, MonitorState, [], RecMap).
  
  evaluate_parallel_blocks_inner([], MonitorState, BlockIDs, _RecMap) ->
    {MonitorState, BlockIDs};
  evaluate_parallel_blocks_inner([Block|ParallelBlocks], MonitorState, BlockIDs, RecMap) ->
    FSMID = MonitorState#outer_monitor_gen_state.running_nested_fsm_id,
    EvalRes = evaluate_nested_fsm(Block, FSMID, MonitorState),
    case EvalRes of
      {ok, NewMonitorState} ->
        evaluate_parallel_blocks_inner(ParallelBlocks, NewMonitorState, [FSMID|BlockIDs], RecMap);
      Other -> Other
    end.
  
  % Evaluates a list of blocks.
  % Returns an FSMState and MonitorState, and a list of top IDs.
  evaluate_blocks([], _PrevIndex, _EndIndex, _RecMap, FSMState, MonitorState) ->
    {FSMState, MonitorState};
  evaluate_blocks([Block|Blocks], PrevIndex, EndIndex, RecMap, FSMState, MonitorState) ->
    {FSMState1, MonitorState1} = evaluate_block(Block, PrevIndex, EndIndex, RecMap, FSMState, MonitorState),
    evaluate_blocks(Blocks, PrevIndex, EndIndex, RecMap, FSMState1, MonitorState1).
  
  % Takes top-level scope AST, FSM state and monitor state.
  % Returns ID of top node, new FSM state, new monitor state.
  evaluate_scope({local_protocol, _, _, _, _, Block}, _PrevIndex, _EndIndex, RecMap,
                 FSMState, MonitorState) ->
    ScopeEndIndex = instruction_size(Block),
    {FSMState1, MonitorState1} = evaluate_block(Block, 0, ScopeEndIndex, RecMap, FSMState, MonitorState),
    FSMState2 = add_state(standard_state(), FSMState1),
    {FSMState2, MonitorState1};
  evaluate_scope({rec, RecName, Interactions}, PrevIndex, EndIndex, RecMap, FSMState,
                 MonitorState) ->
    NewRecMap = orddict:store(RecName, PrevIndex, RecMap),
    evaluate_block(Interactions, PrevIndex, EndIndex, NewRecMap, FSMState, MonitorState);
  evaluate_scope({choice, _, ChoiceBlocks}, PrevIndex, EndIndex,
                 RecMap, FSMState, MonitorState) ->
    % We have a choice block.
    % We need to evaluate each block in turn.
    % Each block needs to converge on the end index.
    evaluate_blocks(ChoiceBlocks, PrevIndex, EndIndex, RecMap, FSMState, MonitorState).
  
  
  
  