### Question:
TokenReplacer { public String process(String raw) throws TokenReplacerOverflowException { if (raw == null) { return null; } String input = raw; long depth; long maxDepth = getMaxDepth(); boolean modified = true; for(depth = 0; depth < maxDepth && modified; depth++) { modified = false; for (Region region : regions) { int next = raw.indexOf(region.start); if (next >= 0) { int end = raw.indexOf(region.end, next + region.end.length()); if (end > 0) { String replace = replace(region, raw.substring(next + region.start.length(), end)); if (replace == null) { replace = ""; } raw = raw.replace(raw.substring(next, end + region.end.length()), replace); modified = true; } } } } if (depth == maxDepth) { throw new TokenReplacerOverflowException(input, maxDepth); } return raw; } TokenReplacer(String begin, String end);  TokenReplacer(Region region);  TokenReplacer(Region regions[]); abstract String replace(Region region, String src); abstract long getMaxDepth(); String process(String raw);  }### Answer:
@Test public void testReplacer() { TokenReplacer finite = new TokenReplacer("%{", "}%") { @Override public String replace(Region region, String src) { return "a"; } @Override public long getMaxDepth() { return 10; } }; try { assertEquals("a", finite.process("%{foobar}%")); } catch (TokenReplacerOverflowException ex) { fail(); } }
@Test public void testMaxDepth() { TokenReplacer infinite = new TokenReplacer("%{", "}%") { @Override public String replace(Region region, String src) { return "%{" + "a" + src + "}%"; } @Override public long getMaxDepth() { return 10; } }; boolean fail = false; try { infinite.process("%{}%"); } catch (TokenReplacerOverflowException ex) { assertEquals("Depth 10 exceeded trying to expand \"%{}%\"", ex.getMessage()); fail = true; } assertTrue(fail); }