tcmd_t *final_actions(ctx_t &ctx, const clos_t &fin)
{
    dfa_t &dfa = ctx.dfa;
    const Rule &rule = dfa.rules[fin.state->rule];
    const tagver_t *vers = ctx.dc_tagvertbl[fin.tvers];
    const hidx_t look = fin.thist;
    const typename ctx_t::history_t &thist = ctx.history;
    tcpool_t &tcpool = dfa.tcpool;
    tcmd_t *copy = NULL, *save = NULL, **p;

    for (size_t t = rule.ltag; t < rule.htag; ++t) {

        const Tag &tag = dfa.tags[t];
        if (fixed(tag)) continue;

        const tagver_t v = abs(vers[t]), l = last(thist, look, t);
        tagver_t &f = dfa.finvers[t];
        if (l == TAGVER_ZERO) {
            copy = tcpool.make_copy(copy, f, v);
        } else if (history(tag)) {
            save = tcpool.make_add(save, f, v, thist, look, t);
        } else {
            save = tcpool.make_set(save, f, l);
        }
    }

    // join 'copy' and 'save' commands
    for (p = &copy; *p; p = &(*p)->next);
    *p = save;

    return copy;
}
tcmd_t *final_actions(ctx_t &ctx, const clos_t &fin)
{
    dfa_t &dfa = ctx.dfa;
    const Rule &rule = dfa.rules[fin.state->rule];
    const tagver_t *vers = ctx.dc_tagvertbl[fin.tvers];
    const hidx_t look = fin.thist;
    const typename ctx_t::history_t &thist = ctx.history;
    tcpool_t &tcpool = dfa.tcpool;
    tcmd_t *copy = NULL, *save = NULL, **p;

    for (size_t t = rule.ltag; t < rule.htag; ++t) {

        const Tag &tag = dfa.tags[t];
        if (fixed(tag)) continue;

        const tagver_t v = abs(vers[t]), l = last(thist, look, t);
        tagver_t &f = dfa.finvers[t];
        if (l == TAGVER_ZERO) {
            copy = tcpool.make_copy(copy, f, v);
        } else if (history(tag)) {
            save = tcpool.make_add(save, f, v, thist, look, t);
        } else {
            save = tcpool.make_set(save, f, l);
        }
    }

     
    for (p = &copy; *p; p = &(*p)->next);
    *p = save;

    return copy;
}