// A = type of value in nodes. // All nodes can have values, not only leaves // Can be case-sensitive or case-insensitive sclass StringTrie { A value; TreeMap> children; *() {} *(A *value) {} void makeCaseInsensitive() { children = asCIMap(children); } bool isCaseInsensitive() { ret isCIMap(children); } void add(S string, A value) { if (empty(string)) ret with this.value = value; S existingPrefix = isCaseInsensitive() ? longestPrefixInCISet(string, children) : longestPrefixInTreeSet(string, children); if (nempty(existingPrefix)) ret with children.get(existingPrefix).add(substring(string, l(existingPrefix)), value); if (children == null) children = new TreeMap; children.put(string, value); } }