sclass WordIndex { S regexp = "\\w+"; MultiSetMap index = ciMultiSetMap(); // sets are better for lookups void add(A a, S text) { Set words = extractWords(text); for (S word : words) index.add(word, a); } Set extractWords(S text) { ret asCISet(extractWords_list(text)); } LS extractWords_list(S text) { ret regexpExtractAll(regexp, text); } L wordRanges(S text) { ret regexpFindRanges(regexp, text); } Set get(S word) { ret index.get(word); } void remove(A a, S text) { Set words = extractWords(text); for (S word : words) index.remove(word, a); } NavigableSet words() { ret (NavigableSet) keys(index); } int numWords() { ret l(index.index); } // These methods only work when A = S void add(S s) { add((A) s, s); } void remove(S s) { remove((A) s, s); } }