static void command_resume(char * token, Channel * c) {
    char id[256];
    long mode;
    long count;
    Context * ctx;
    int err = 0;

    json_read_string(&c->inp, id, sizeof(id));
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    mode = json_read_long(&c->inp);
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    count = json_read_long(&c->inp);
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (peek_stream(&c->inp) != MARKER_EOM) {
        json_read_struct(&c->inp, resume_params_callback, &err);
        if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    }
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);
    if (err == 0) {
        ctx = id2ctx(id);
        assert(safe_event_list == NULL);

        if (ctx == NULL) {
            err = ERR_INV_CONTEXT;
        }
        else if (ctx->exited) {
            err = ERR_ALREADY_EXITED;
        }
        else if (!ctx->intercepted) {
            err = ERR_ALREADY_RUNNING;
        }
        else if (ctx->regs_error) {
            err = ctx->regs_error;
        }
        else if (count != 1) {
            err = EINVAL;
        }
        else if (mode == RM_RESUME || mode == RM_STEP_INTO) {
            send_event_context_resumed(&c->bcg->out, ctx);
            if (mode == RM_STEP_INTO) {
                if (context_single_step(ctx) < 0) {
                    err = errno;
                }
                else {
                    ctx->pending_intercept = 1;
                }
            }
            else if (context_continue(ctx) < 0) {
                err = errno;
            }
        }
        else {
            err = EINVAL;
        }
    }
    send_simple_result(c, token, err);
}
static void read_stream_done(Channel *c, void *client_data, int error) {
    PortConnection * conn = ((PortReadInfo *) client_data)->conn;
    int idx = ((PortReadInfo *) client_data)->idx;

    size_t read_size = 0;

    conn->pending_read_request &= ~(1 << idx);
    if (error) {
        trace(LOG_ALWAYS, "Reply error %d: %s\n", error, errno_to_str(error));
        read_packet_callback(conn, error, idx, 0);
    }
    else {
        int end;
        InputStream *inp = &conn->server->channel->inp;
        int ch = peek_stream(inp);
        if (ch == 'n') {
            (void) read_stream(inp);
            if (read_stream(inp) != 'u') goto err_json_syntax;
            if (read_stream(inp) != 'l') goto err_json_syntax;
            if (read_stream(inp) != 'l') goto err_json_syntax;
        }
        else {
            JsonReadBinaryState state;

            json_read_binary_start(&state, inp);

            for (;;) {
                size_t rd = json_read_binary_data(&state,
                        conn->read_buffer[idx] + read_size,
                        sizeof conn->read_buffer[idx]);
                if (rd == 0) break;
                read_size += rd;
            }

            assert(state.size_start <= 0 || read_size == state.size_start);

            json_read_binary_end(&state);
        }
        json_test_char(&c->inp, MARKER_EOA);
        error = read_errno(inp);
        (void)json_read_long(inp);
        if (read_stream(inp) != 0) goto err_json_syntax;
        end = json_read_boolean(inp);
        json_test_char(&c->inp, MARKER_EOA);
        json_test_char(&c->inp, MARKER_EOM);

#if 0
        if (read_stream(inp) != 0 || read_stream(inp) != MARKER_EOM) goto err_json_syntax;
#endif
        if (end) read_packet_callback(conn, 0, idx, 0);
        else read_packet_callback(conn, 0, idx, read_size);
    }
    return;
    err_json_syntax: return;
}