let continue (r: running)
  : state * output_event list =
    let current t = win_valid t.task_win r.running_state in
    begin match r.running_task_queue with
    | [] ->
        (Waiting({ waiting_state = r.running_state}), [])
    | t :: ts when not (current t) ->
        let r' = { r with running_task_queue = ts } in
        (Running(r'), [])
    | { task_expr = X(R(Error(msg))) } :: ts ->
        let r' = { r with running_task_queue = ts } in
        (Running(r'), [ UI_error(msg) ])
    | { task_expr = X(R(_)) } :: ts ->
        let r' = { r with running_task_queue = ts } in
        (Running(r'), [])
    | t :: ts -> (* the task is current and not finished *)
        let b = r.running_state in
        let w = win_assoc_valid t.task_win b in
        let p = page_assoc_valid w.win_page b in
        let ctx = {
          context_win = t.task_win;
          context_act = p.page_environment;
        } in
        let (b', e', oes, ts') = step_expr ctx b t.task_expr in
        let r' = {
          running_state = b';
          running_task_queue = { t with task_expr = e' } :: ts @ ts';
        } in
        (Running(r'), oes)
    end