sclass AdaptiveIdentifierCompression { new SS shortenings; new MultiSet tokenCount; new SS expansions; S escapeWord = "xx"; S codeAlphabet = lowerCaseAlphabet(); ItIt newCodeMaker; int conflicts; settable int minCountToCompress = 2; void init { newCodeMaker if null = allWordsOfAlphabet(codeAlphabet); } S encode(S token) { if (!isIdentifier(token)) ret token; init(); tokenCount.add(token); S code = shortenings.get(token); if (code != null) ret code; int count = tokenCount.get(token); if (count < minCountToCompress) ret token; S conflict = expansions.get(code); if (conflict != null) { warn("conflict: " + token); ++conflicts; // TODO } code = newCode(); if (code != null) { shortenings.put(token, code); expansions.put(code, token); } ret token; } S newCode() { S code; do { if (!newCodeMaker.hasNext()) null; code = newCodeMaker.next(); } while (shortenings.containsKey(code)); ret code; } }