_XimReCreateIC(ic)
    Xic			 ic;
{
    Xim			 im = (Xim)ic->core.im;
    Xic			 save_ic;
    XIMResourceList	 res;
    unsigned int         num;
    XIMStyle		 input_style = ic->core.input_style;
    XimDefICValues	 ic_values;
    INT16		 len;
    CARD16		*buf_s;
    char		*tmp;
    CARD32		 tmp_buf32[BUFSIZE/4];
    char		*tmp_buf = (char *)tmp_buf32;
    char		*buf;
    int			 buf_size;
    char		*data;
    int			 data_len;
    int			 ret_len;
    int			 total;
    int			 idx;
    CARD32		 reply32[BUFSIZE/4];
    char		*reply = (char *)reply32;
    XPointer		 preply;
    int			 ret_code;

    if (!(save_ic = Xmalloc(sizeof(XicRec))))
	return False;
    memcpy((char *)save_ic, (char *)ic, sizeof(XicRec));

    ic->core.filter_events = im->private.proto.forward_event_mask;
    ic->private.proto.forward_event_mask =
				im->private.proto.forward_event_mask;
    ic->private.proto.synchronous_event_mask =
				im->private.proto.synchronous_event_mask;

    num = im->core.ic_num_resources;
    buf_size = sizeof(XIMResource) * num;
    if (!(res = Xmalloc(buf_size)))
	goto ErrorOnReCreateIC;
    (void)memcpy((char *)res, (char *)im->core.ic_resources, buf_size);
    ic->private.proto.ic_resources     = res;
    ic->private.proto.ic_num_resources = num;

    num = im->private.proto.ic_num_inner_resources;
    buf_size = sizeof(XIMResource) * num;
    if (!(res = Xmalloc(buf_size)))
	goto ErrorOnReCreateIC;
    (void)memcpy((char *)res,
			(char *)im->private.proto.ic_inner_resources, buf_size);
    ic->private.proto.ic_inner_resources     = res;
    ic->private.proto.ic_num_inner_resources = num;

    _XimSetICMode(ic->private.proto.ic_resources,
			ic->private.proto.ic_num_resources, input_style);

    _XimSetICMode(ic->private.proto.ic_inner_resources,
			ic->private.proto.ic_num_inner_resources, input_style);

    _XimGetCurrentICValues(ic, &ic_values);
    buf = tmp_buf;
    buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16);
    data_len = BUFSIZE - buf_size;
    total = 0;
    idx = 0;
    for (;;) {
	data = &buf[buf_size];
	if (!_XimEncodeSavedICATTRIBUTE(ic, ic->private.proto.ic_resources,
		ic->private.proto.ic_num_resources, &idx, data, data_len,
		&ret_len, (XPointer)&ic_values, XIM_CREATEIC)) {
	    if (buf != tmp_buf)
		Xfree(buf);
	    goto ErrorOnReCreateIC;
	}

	total += ret_len;
	if (idx == -1) {
	    break;
	}

	buf_size += ret_len;
	if (buf == tmp_buf) {
	    if (!(tmp = Xmalloc(buf_size + data_len))) {
		goto ErrorOnReCreateIC;
	    }
	    memcpy(tmp, buf, buf_size);
	    buf = tmp;
	} else {
	    if (!(tmp = Xrealloc(buf, (buf_size + data_len)))) {
		Xfree(buf);
		goto ErrorOnReCreateIC;
	    }
	    buf = tmp;
	}
    }

    buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
    buf_s[0] = im->private.proto.imid;
    buf_s[1] = (INT16)total;

    len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total);
    _XimSetHeader((XPointer)buf, XIM_CREATE_IC, 0, &len);
    if (!(_XimWrite(im, len, (XPointer)buf))) {
	if (buf != tmp_buf)
	    Xfree(buf);
	goto ErrorOnReCreateIC;
    }
    _XimFlush(im);
    if (buf != tmp_buf)
	Xfree(buf);
    ic->private.proto.waitCallback = True;
    buf_size = BUFSIZE;
    ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
						 _XimCreateICCheck, 0);
    if (ret_code == XIM_TRUE) {
	preply = reply;
    } else if (ret_code == XIM_OVERFLOW) {
	if (len <= 0) {
	    preply = reply;
	} else {
	    buf_size = (int)len;
	    preply = Xmalloc(buf_size);
	    ret_code = _XimRead(im, &len, preply, buf_size,
						 _XimCreateICCheck, 0);
	    if (ret_code != XIM_TRUE) {
		Xfree(preply);
		ic->private.proto.waitCallback = False;
		goto ErrorOnReCreateIC;
	    }
	}
    } else {
	ic->private.proto.waitCallback = False;
	goto ErrorOnReCreateIC;
    }
    ic->private.proto.waitCallback = False;
    buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
    if (*((CARD8 *)preply) == XIM_ERROR) {
	_XimProcError(im, 0, (XPointer)&buf_s[3]);
	if (reply != preply)
	    Xfree(preply);
	goto ErrorOnReCreateIC;
    }

    ic->private.proto.icid = buf_s[1];		/* icid */
    if (reply != preply)
	Xfree(preply);

    _XimRegisterFilter(ic);
    MARK_IC_CONNECTED(ic);

    Xfree(save_ic->private.proto.ic_resources);
    Xfree(save_ic->private.proto.ic_inner_resources);
    Xfree(save_ic);
    return True;

ErrorOnReCreateIC:
    memcpy((char *)ic, (char *)save_ic, sizeof(XicRec));
    Xfree(save_ic);
    return False;
}