+
+ // Hack for robustness if sort order is broken
+ if (mid - 2 >= start &&
+ compareIdx(token, sortCollator, mid - 1) < 0 &&
+ compareIdx(token, sortCollator, mid - 2) < 0) {
+ end = mid + 1;
+ } else {
+ start = mid + 1;
+ }
+ }
+ }
+
+ // if the word before is the better match, move
+ // our result to it
+ if (start > 0 && start < sortedIndexEntries.size()) {
+ String prev = sortedIndexEntries.get(start - 1).normalizedToken();
+ String next = sortedIndexEntries.get(start).normalizedToken();
+ if (findMatchLen(sortCollator, token, prev) >= findMatchLen(sortCollator, token, next))
+ start--;
+ }
+
+ // If the search term was normalized, try to find an exact match first
+ if (!orig_token.equalsIgnoreCase(token)) {
+ int matchLen = findMatchLen(sortCollator, token, sortedIndexEntries.get(start).normalizedToken());
+ int scan = start;
+ while (scan >= 0 && scan < sortedIndexEntries.size()) {
+ IndexEntry e = sortedIndexEntries.get(scan);
+ if (e.token.equalsIgnoreCase(orig_token))
+ {
+ return scan;
+ }
+ if (matchLen > findMatchLen(sortCollator, token, e.normalizedToken()))
+ break;
+ if (interrupted.get()) return start;
+ scan++;