// TODO: Pass "DicTraverseSession *traverseSession" when the source code structure settles down.
static void initSessionInstance(void *traverseSession, const Dictionary *const dictionary,
        const int *prevWord, const int prevWordLength) {
    if (traverseSession) {
        DicTraverseSession *tSession = static_cast<DicTraverseSession *>(traverseSession);
        tSession->init(dictionary, prevWord, prevWordLength);
    }
}
/**
 * Returns a set of suggestions for the given input touch points. The commitPoint argument indicates
 * whether to prematurely commit the suggested words up to the given point for sentence-level
 * suggestion.
 *
 * Note: Currently does not support concurrent calls across threads. Continuous suggestion is
 * automatically activated for sequential calls that share the same starting input.
 * TODO: Stop detecting continuous suggestion. Start using traverseSession instead.
 */
void Suggest::getSuggestions(ProximityInfo *pInfo, void *traverseSession,
        int *inputXs, int *inputYs, int *times, int *pointerIds, int *inputCodePoints,
        int inputSize, const float weightOfLangModelVsSpatialModel,
        SuggestionResults *const outSuggestionResults) const {
    PROF_INIT;
    PROF_TIMER_START(0);
    const float maxSpatialDistance = TRAVERSAL->getMaxSpatialDistance();
    DicTraverseSession *tSession = static_cast<DicTraverseSession *>(traverseSession);
    tSession->setupForGetSuggestions(pInfo, inputCodePoints, inputSize, inputXs, inputYs, times,
            pointerIds, maxSpatialDistance, TRAVERSAL->getMaxPointerCount());
    // TODO: Add the way to evaluate cache

    initializeSearch(tSession);
    PROF_TIMER_END(0);
    PROF_TIMER_START(1);

    // keep expanding search dicNodes until all have terminated.
    while (tSession->getDicTraverseCache()->activeSize() > 0) {
        expandCurrentDicNodes(tSession);
        tSession->getDicTraverseCache()->advanceActiveDicNodes();
        tSession->getDicTraverseCache()->advanceInputIndex(inputSize);
    }
    PROF_TIMER_END(1);
    PROF_TIMER_START(2);
    SuggestionsOutputUtils::outputSuggestions(
            SCORING, tSession, weightOfLangModelVsSpatialModel, outSuggestionResults);
    PROF_TIMER_END(2);
}
static void latinime_initDicTraverseSession(JNIEnv *env, jclass clazz, jlong traverseSession,
        jlong dictionary, jintArray previousWord, jint previousWordLength) {
    DicTraverseSession *ts = reinterpret_cast<DicTraverseSession *>(traverseSession);
    if (!ts) {
        return;
    }
    Dictionary *dict = reinterpret_cast<Dictionary *>(dictionary);
    if (!previousWord) {
        PrevWordsInfo prevWordsInfo;
        ts->init(dict, &prevWordsInfo, 0 /* suggestOptions */);
        return;
    }
    int prevWord[previousWordLength];
    env->GetIntArrayRegion(previousWord, 0, previousWordLength, prevWord);
    PrevWordsInfo prevWordsInfo(prevWord, previousWordLength, false /* isStartOfSentence */);
    ts->init(dict, &prevWordsInfo, 0 /* suggestOptions */);
}