xmlRelaxNGValidateDefinition(xmlRelaxNGValidCtxtPtr ctxt,
                             xmlRelaxNGDefinePtr define)
{
    xmlRelaxNGStatesPtr states, res;
    int i, j, k, ret, oldflags;

    /*
     * We should NOT have both ctxt->state and ctxt->states
     */
    if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
        TODO xmlRelaxNGFreeValidState(ctxt, ctxt->state);
        ctxt->state = NULL;
    }

    if ((ctxt->states == NULL) || (ctxt->states->nbState == 1)) {
        if (ctxt->states != NULL) {
            ctxt->state = ctxt->states->tabState[0];
            xmlRelaxNGFreeStates(ctxt, ctxt->states);
            ctxt->states = NULL;
        }
        ret = xmlRelaxNGValidateState(ctxt, define);
        if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
            TODO xmlRelaxNGFreeValidState(ctxt, ctxt->state);
            ctxt->state = NULL;
        }
        if ((ctxt->states != NULL) && (ctxt->states->nbState == 1)) {
            ctxt->state = ctxt->states->tabState[0];
            xmlRelaxNGFreeStates(ctxt, ctxt->states);
            ctxt->states = NULL;
        }
        return (ret);
    }

    states = ctxt->states;
    ctxt->states = NULL;
    res = NULL;
    j = 0;
    oldflags = ctxt->flags;
    ctxt->flags |= FLAGS_IGNORABLE;
    for (i = 0; i < states->nbState; i++) {
        ctxt->state = states->tabState[i];
        ctxt->states = NULL;
        ret = xmlRelaxNGValidateState(ctxt, define);
        /*
         * We should NOT have both ctxt->state and ctxt->states
         */
        if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
            TODO xmlRelaxNGFreeValidState(ctxt, ctxt->state);
            ctxt->state = NULL;
        }
        if (ret == 0) {
            if (ctxt->states == NULL) {
                if (res != NULL) {
                    /* add the state to the container */
                    xmlRelaxNGAddStates(ctxt, res, ctxt->state);
                    ctxt->state = NULL;
                } else {
                    /* add the state directly in states */
                    states->tabState[j++] = ctxt->state;
                    ctxt->state = NULL;
                }
            } else {
                if (res == NULL) {
                    /* make it the new container and copy other results */
                    res = ctxt->states;
                    ctxt->states = NULL;
                    for (k = 0; k < j; k++)
                        xmlRelaxNGAddStates(ctxt, res,
                                            states->tabState[k]);
                } else {
                    /* add all the new results to res and reff the container */
                    for (k = 0; k < ctxt->states->nbState; k++)
                        xmlRelaxNGAddStates(ctxt, res,
                                            ctxt->states->tabState[k]);
                    xmlRelaxNGFreeStates(ctxt, ctxt->states);
                    ctxt->states = NULL;
                }
            }
        } else {
            if (ctxt->state != NULL) {
                xmlRelaxNGFreeValidState(ctxt, ctxt->state);
                ctxt->state = NULL;
            } else if (ctxt->states != NULL) {
                for (k = 0; k < ctxt->states->nbState; k++)
                    xmlRelaxNGFreeValidState(ctxt,
                                             ctxt->states->tabState[k]);
                xmlRelaxNGFreeStates(ctxt, ctxt->states);
                ctxt->states = NULL;
            }
        }
    }
    ctxt->flags = oldflags;
    if (res != NULL) {
        xmlRelaxNGFreeStates(ctxt, states);
        ctxt->states = res;
        ret = 0;
    } else if (j > 1) {
        states->nbState = j;
        ctxt->states = states;
        ret = 0;
    } else if (j == 1) {
        ctxt->state = states->tabState[0];
        xmlRelaxNGFreeStates(ctxt, states);
        ret = 0;
    } else {
        ret = -1;
        xmlRelaxNGFreeStates(ctxt, states);
        if (ctxt->states != NULL) {
            xmlRelaxNGFreeStates(ctxt, ctxt->states);
            ctxt->states = NULL;
        }
    }
    if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
        TODO xmlRelaxNGFreeValidState(ctxt, ctxt->state);
        ctxt->state = NULL;
    }
    return (ret);
}