// Path: karthik/regex/RegexTokenNames.java
// enum RegexTokenNames {
// 
//     CHAR, CHAR_CLASS, WHITESPACE, DOT, DIGIT, WORD,
//     NONDIGIT, NONWORD, NONWHITESPACE,
//     TAB, NEWLINE, FORMFEED, CARR_RETURN,
//     BRACE, STAR, PLUS, QUESTION,
//     LAZY_BRACE, LAZY_STAR, LAZY_PLUS, LAZY_QUESTION,
//     OR, AND, EPSILON,
//     GROUP, LOOKAHEAD, LOOKBEHIND,
//     WORD_BOUNDARY, NON_WORD_BOUNDARY,
//     STRING_START, STRING_END, LINE_START, LINE_END, JAVA_Z_STRING_END,
//     BACKREFERENCE, ENDBACKREFERENCE, BACKREF_STRING
// }


import karthik.regex.RegexTokenNames;
import java.util.ArrayList;
        // inGroup is true if the parser is inside a group enclosed by parentheses
        char currentChar;

        try {
            while (indexPos < len) {
                currentChar = inputString.charAt(indexPos++);
                switch (currentChar) {
                    case '\\':
                        currentChar = inputString.charAt(indexPos++);
                        handleEscapeChars(tokens, currentChar);
                        break;

                    case '[':
                        indexPos--;
                        tokens.add(parseCharClass());
                        break;

                    case '(':
                        if (inputString.charAt(indexPos) == '?') {
                            RegexToken lookaround_tok = handleLookaround_and_flags();
                            if (lookaround_tok != null)
                                tokens.add(lookaround_tok);
                            // null token means it was a flag so nothing to do
                        } else
                            tokens.add(parseGroup());
                        break;
                    case ')':
                        if (inGroup)
                            return;
                        // ) treated like ordinary character when not preceded by matching left parentheses
// Path: karthik/regex/RegexTokenNames.java
// enum RegexTokenNames {
// 
//     CHAR, CHAR_CLASS, WHITESPACE, DOT, DIGIT, WORD,
//     NONDIGIT, NONWORD, NONWHITESPACE,
//     TAB, NEWLINE, FORMFEED, CARR_RETURN,
//     BRACE, STAR, PLUS, QUESTION,
//     LAZY_BRACE, LAZY_STAR, LAZY_PLUS, LAZY_QUESTION,
//     OR, AND, EPSILON,
//     GROUP, LOOKAHEAD, LOOKBEHIND,
//     WORD_BOUNDARY, NON_WORD_BOUNDARY,
//     STRING_START, STRING_END, LINE_START, LINE_END, JAVA_Z_STRING_END,
//     BACKREFERENCE, ENDBACKREFERENCE, BACKREF_STRING
// }


// Path: karthik/regex/Tokenizer.java
import karthik.regex.RegexTokenNames;
import java.util.ArrayList;

        // inGroup is true if the parser is inside a group enclosed by parentheses
        char currentChar;

        try {
            while (indexPos < len) {
                currentChar = inputString.charAt(indexPos++);
                switch (currentChar) {
                    case '\\':
                        currentChar = inputString.charAt(indexPos++);
                        handleEscapeChars(tokens, currentChar);
                        break;

                    case '[':
                        indexPos--;
                        tokens.add(parseCharClass());
                        break;

                    case '(':
                        if (inputString.charAt(indexPos) == '?') {
                            RegexToken lookaround_tok = handleLookaround_and_flags();
                            if (lookaround_tok != null)
                                tokens.add(lookaround_tok);
                            // null token means it was a flag so nothing to do
                        } else
                            tokens.add(parseGroup());
                        break;
                    case ')':
                        if (inGroup)
                            return;
                        // ) treated like ordinary character when not preceded by matching left parentheses
                        tokens.add(new RegexToken(RegexTokenNames.CHAR,