protected <T> boolean match(
     int bid,
     SequenceMatcher.MatchedStates<T> matchedStates,
     SequenceMatcher.MatchedGroup matchedGroup,
     int matchedNodes) {
   T node = matchedStates.get();
   if (matcher.matches(
       node, matchedStates.elements().get(matchedGroup.matchBegin + matchedNodes))) {
     matchedNodes++;
     matchedStates
         .getBranchStates()
         .setMatchStateInfo(
             bid,
             this,
             new Pair<SequenceMatcher.MatchedGroup, Integer>(matchedGroup, matchedNodes));
     int len = matchedGroup.matchEnd - matchedGroup.matchBegin;
     if (len == matchedNodes) {
       matchedStates.addStates(bid, next);
     } else {
       matchedStates.addState(bid, this);
     }
     return true;
   }
   return false;
 }
 protected <T> boolean match(
     int bid, SequenceMatcher.MatchedStates<T> matchedStates, boolean consume) {
   if (consume) {
     // Get element and return if it matched or not
     T node = matchedStates.get();
     // TODO: Fix type checking
     if (pattern.match(node)) {
       // If matched, need to add next states to the queue of states to be processed
       matchedStates.addStates(bid, next);
       return true;
     } else {
       return false;
     }
   } else {
     // Not consuming element - add this state back to queue of states to be processed
     // This state was not successfully matched
     matchedStates.addState(bid, this);
     return false;
   }
 }