StateMachine implements MatchProcessor { @Override public MatchProcessorResult process(StringBuilder characterBuffer, int firstModifiableCharacterInBuffer, MatchResult matchResult) { MatchProcessorResult result = transitions.process(characterBuffer, firstModifiableCharacterInBuffer, matchResult); State newState = transitions.pollNewState(); if (newState != currentState) { changeStateTo(newState); } return result; } StateMachine(State initialState, DelegatingMatcher delegatingMatcher); State getCurrentState(); @Override MatchProcessorResult process(StringBuilder characterBuffer, int firstModifiableCharacterInBuffer,
            MatchResult matchResult);  }
@Test public void testProcess() throws Exception { List<String> foundTokens = new ArrayList<String>(); TokenCollector tokenCollector = new TokenCollector(foundTokens); State state0 = new State("Start"); State state1 = new State("SectionStart", "<section class='abc'>"); State state2 = new State("SectionTitle", "(<h1>)([^<>]*)(</h1>)", "$1TITLE_FOUND$3"); State state3 = new State("ListItem", "(<li>)([^<>]*)(</li>)", "$1LIST_ITEM_FOUND$3"); State state4 = new State("SectionEnd", "</section>"); state0.setTransitions(asList(state1), tokenCollector); state1.setTransitions(asList(state2, state3, state4), tokenCollector); state2.setTransitions(asList(state3, state4), tokenCollector); state3.setTransitions(asList(state3, state4), tokenCollector); state4.setTransitions(asList(state1), tokenCollector); DelegatingMatcher delegatingMatcher = new DelegatingMatcher(); StateMachine stateMachine = new StateMachine(state0, delegatingMatcher); Modifier modifier = new RegexModifier(delegatingMatcher, stateMachine, 1, 2048); String input = ""; input += "text <section class='abc'>"; input += "text <h1>my title</h1>"; input += "text <ul>"; input += "text <li>my first list item</li>"; input += "text <li>my second list item</li>"; input += "text </ul>"; input += "text </section>"; input += "text <h1>title outside section</h1>"; input += "text <li>list item outside section</li>"; Reader reader = new ModifyingReader(new StringReader(input), modifier); String foundOutput = IOUtils.toString(reader); assertEquals(5, foundTokens.size()); assertEquals("SectionStart:<section class='abc'>", foundTokens.get(0)); assertEquals("SectionTitle:<h1>my title</h1>", foundTokens.get(1)); assertEquals("ListItem:<li>my first list item</li>", foundTokens.get(2)); assertEquals("ListItem:<li>my second list item</li>", foundTokens.get(3)); assertEquals("SectionEnd:</section>", foundTokens.get(4)); String output = ""; output += "text <section class='abc'>"; output += "text <h1>TITLE_FOUND</h1>"; output += "text <ul>"; output += "text <li>LIST_ITEM_FOUND</li>"; output += "text <li>LIST_ITEM_FOUND</li>"; output += "text </ul>"; output += "text </section>"; output += "text <h1>title outside section</h1>"; output += "text <li>list item outside section</li>"; assertEquals(output, foundOutput); }