void __comps_objrtree_set(COMPS_ObjRTree *rt, char *key, size_t len,
                          COMPS_Object *ndata) {

    COMPS_HSListItem *it, *lesser;
    COMPS_HSList *subnodes;
    COMPS_ObjRTreeData *rtd;
    static COMPS_ObjRTreeData *rtdata;

    size_t _len, offset=0;
    unsigned x, found = 0;
    char ended;

    //len = strlen(key);

    if (rt->subnodes == NULL)
        return;

    subnodes = rt->subnodes;
    while (offset != len)
    {
        found = 0;
        lesser = NULL;
        for (it = subnodes->first; it != NULL; it=it->next) {
            if (((COMPS_ObjRTreeData*)it->data)->key[0] == key[offset]) {
                found = 1;
                break;
            } else if (((COMPS_ObjRTreeData*)it->data)->key[0] < key[offset]) {
                lesser = it;
            }
        }
        if (!found) { // not found in subnodes; create new subnode
            rtd = comps_objrtree_data_create_n(key+offset, len-offset, ndata);
            if (!lesser) {
                comps_hslist_prepend(subnodes, rtd, 0);
            } else {
                comps_hslist_insert_after(subnodes, lesser, rtd, 0);
            }
            rt->len++;
            return;
        } else {
            rtdata = (COMPS_ObjRTreeData*)it->data;
            ended = 0;
            for (x=1; ;x++) {
                if (rtdata->key[x] == 0) ended += 1;
                if (x == len - offset) ended += 2;
                if (ended != 0) break;
                if (key[offset+x] != rtdata->key[x]) break;
            }
            if (ended == 3) { //keys equals; data replacement
                comps_object_destroy(rtdata->data);
                rtdata->data = ndata;
                return;
            } else if (ended == 2) { //global key ends first; make global leaf
                //printf("ended2\n");
                comps_hslist_remove(subnodes, it);
                it->next = NULL;
                rtd = comps_objrtree_data_create_n(key+offset, len-offset, ndata);
                comps_hslist_append(subnodes, rtd, 0);
                ((COMPS_ObjRTreeData*)subnodes->last->data)->subnodes->last = it;
                ((COMPS_ObjRTreeData*)subnodes->last->data)->subnodes->first = it;
                _len = len - offset;

                memmove(rtdata->key,rtdata->key+_len,
                        strlen(rtdata->key) - _len);
                rtdata->key[strlen(rtdata->key) - _len] = 0;
                rtdata->key = realloc(rtdata->key,
                                      sizeof(char)* (strlen(rtdata->key)+1));
                rt->len++;
                return;
            } else if (ended == 1) { //local key ends first; go deeper
                subnodes = rtdata->subnodes;
                offset += x;
            } else {
                COMPS_Object *tmpdata = rtdata->data;
                COMPS_HSList *tmphslist = rtdata->subnodes;
                //tmpch = rtdata->key[x];             // split mutual key
                rtdata->subnodes = comps_hslist_create();
                comps_hslist_init(rtdata->subnodes, NULL, NULL,
                                  &comps_objrtree_data_destroy_v);
                int cmpret = strcmp(key+offset+x, rtdata->key+x);
                rtdata->data = NULL;

                if (cmpret > 0) {
                    rtd = comps_objrtree_data_create(rtdata->key+x, tmpdata);
                    comps_hslist_destroy(&rtd->subnodes);
                    rtd->subnodes = tmphslist;

                    comps_hslist_append(rtdata->subnodes,rtd, 0);
                    rtd = comps_objrtree_data_create(key+offset+x, ndata);
                    comps_hslist_append(rtdata->subnodes, rtd, 0);

                } else {
                    rtd = comps_objrtree_data_create(key+offset+x, ndata);
                    comps_hslist_append(rtdata->subnodes, rtd, 0);
                    rtd = comps_objrtree_data_create(rtdata->key+x, tmpdata);
                    comps_hslist_destroy(&rtd->subnodes);
                    rtd->subnodes = tmphslist;
                    comps_hslist_append(rtdata->subnodes, rtd, 0);
                }
                rtdata->key = realloc(rtdata->key, sizeof(char)*(x+1));
                rtdata->key[x] = 0;
                rt->len++;
                return;
            }
        }
    }
}