private void processGroupValue() {
    char nextChar;
    if (myCursor == myTemplate.length()) throw new IllegalArgumentException("Illegal group reference: group index is missing");
    nextChar = myTemplate.charAt(myCursor++);
    String group;
    if (nextChar == '{') {
      StringBuilder gsb = new StringBuilder();
      while (myCursor < myTemplate.length()) {
        nextChar = myTemplate.charAt(myCursor);
        if (isLatinLetter(nextChar) || isDigit(nextChar)) {
          gsb.append(nextChar);
          myCursor++;
        } else {
          break;
        }
      }
      if (gsb.length() == 0) throw new IllegalArgumentException("named capturing group has 0 length name");
      if (nextChar != '}') throw new IllegalArgumentException("named capturing group is missing trailing '}'");
      String gname = gsb.toString();
      if (isDigit(gname.charAt(0))) {
        throw new IllegalArgumentException("capturing group name {" + gname + "} starts with digit character");
      }
      myCursor++;
      group = myMatcher.group(gname);
    } else {
      // The first number is always a group
      int refNum = (int)nextChar - '0';
      if (refNum < 0 || refNum > 9) throw new IllegalArgumentException("Illegal group reference");
      // Capture the largest legal group string
      while (true) {
        if (myCursor >= myTemplate.length()) break;
        int nextDigit = myTemplate.charAt(myCursor) - '0';
        if (nextDigit < 0 || nextDigit > 9) break;
        int newRefNum = (refNum * 10) + nextDigit;
        if (myMatcher.groupCount() < newRefNum) break;
        refNum = newRefNum;
        myCursor++;
      }
      group = myMatcher.group(refNum);
    }
    if (group != null) {
      myReplacement.append(group);
    }
  }
private void processGroupValue()