// 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/dataStructures/Stack.java
// public class Stack<T> {
// 
//     StackItem<T> top;
// 
//     public Stack() {
//         top = null;
//     }
// 
//     public T push(T data) {
//         StackItem<T> newStackItem = new StackItem<T>(data);
// 
//         if (this.isEmpty()) {
//             top = newStackItem;
//         } else {
//             newStackItem.setNext(top);
//             top = newStackItem;
//         }
//         return newStackItem.data;
//     }
// 
//     public boolean isEmpty() {
//         return (top == null);
//     }
// 
//     public T pop() {
//         StackItem<T> newStackItem;
// 
//         if (this.isEmpty()) // stack is empty so top will be null
//             return null;
//         
//         newStackItem = top;
//         top = top.getNext();
// 
//         return newStackItem.data;
//     }
// 
//     public T peek() {
//         if(isEmpty())
//             return null;
//         return top.data;
//     }
// 
//      class StackItem<T> {
// 
//         private StackItem<T> next;
//         T data;
// 
//         StackItem(T item) {
//             data = item;
//             next = null;
//         }
// 
//         StackItem<T> getNext() {
//             return next;
//         }
// 
//         StackItem<T> setNext(T item) {
//             next = new StackItem<T>(item);
//             return next;
//         }
// 
//         StackItem<T> setNext(StackItem<T> item) {
//             next = item;
//             return item;
//         }
//     }
// 
// }
// 
// Path: karthik/regex/dataStructures/Tree.java
// public class Tree<T> {
// 
//     protected TreeNode<T> root;
// 
//     public Tree() {
//         root = null;
//     }
// 
//     public Tree(T data, Tree<T> leftSubTree, Tree<T> rightSubTree) {
//         root = null;
//         addItem(data, leftSubTree, rightSubTree);
//     }
// 
//     public Tree<T> addItem(T data, Tree<T> leftSubTree, Tree<T> rightSubTree) // always creates new tree with added item at root
//     {
//         TreeNode<T> node;
// 
//         node = new TreeNode<T>(data);
//         if (root == null)
//             root = node;
// 
//         root.setLeft((leftSubTree == null) ? null : leftSubTree.root);
//         root.setRight((rightSubTree == null) ? null : rightSubTree.root);
// 
//         return this;
//     }
// 
//     public void traverse() {
//         if (root == null)
//             return;
// 
//         recTraverse(root);
//     }
// 
//     protected void recTraverse(TreeNode<T> current) {
//         if (current == null)
//             return;
// 
//         recTraverse(current.getLeft());
//         current.display();
//         recTraverse(current.getRight());
// 
//         return;
//     }
// 
//     public boolean isEmpty() {
//         return (root == null);
//     }
// 
//     public boolean isLeaf(TreeNode<T> current) {
//         if ((current.getLeft() == null) && (current.getRight() == null))
//             return true;
//         else
//             return false;
//     }
// 
//     class TreeNode<T> {
// 
//         protected T data;
//         protected TreeNode<T> left, right;
// 
//         TreeNode(T i) {
//             data = i;
//             left = right = null;
//         }
// 
//         T getData() {
//             return data;
//         }
// 
//         void display() {
//             System.out.print(data.toString() + " ");
//         }
// 
//         TreeNode<T> getLeft() {
//             return left;
//         }
// 
//         TreeNode<T> getRight() {
//             return right;
//         }
// 
//         void setLeft(TreeNode<T> newnode) {
//             left = newnode;
//         }
// 
//         void setRight(TreeNode<T> newnode) {
//             right = newnode;
//         }
//     }
// }


import karthik.regex.RegexTokenNames;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import karthik.regex.dataStructures.Stack;
import karthik.regex.dataStructures.Tree;
            current.addGroupIDList(groupIDList);
            group_transition_matrix = ((GroupRegexToken) current).
                createTransitionMatrix();
            if (group_transition_matrix == null)  // regex in group was invalid
                return false;

            matcherStack.push(group_transition_matrix);
            getNextToken();

            if (debug_create_tree) {
                Tree<RegexToken> groupTree = ((GroupRegexToken) current).
                    debug_create_tree();
                debug_tree_stack.push(new Tree<>(new RegexToken(currentType,
                    current.getFlags()), groupTree, null));
            }

            return true;
        }

        if (lookaround())
            return true;

        return false;
    }

    private boolean lookaround() throws ParserException {
        RegexTokenNames currentType;

        RegexToken current = getCurrentToken();
        currentType = current.getType();
// 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/dataStructures/Stack.java
// public class Stack<T> {
// 
//     StackItem<T> top;
// 
//     public Stack() {
//         top = null;
//     }
// 
//     public T push(T data) {
//         StackItem<T> newStackItem = new StackItem<T>(data);
// 
//         if (this.isEmpty()) {
//             top = newStackItem;
//         } else {
//             newStackItem.setNext(top);
//             top = newStackItem;
//         }
//         return newStackItem.data;
//     }
// 
//     public boolean isEmpty() {
//         return (top == null);
//     }
// 
//     public T pop() {
//         StackItem<T> newStackItem;
// 
//         if (this.isEmpty()) // stack is empty so top will be null
//             return null;
//         
//         newStackItem = top;
//         top = top.getNext();
// 
//         return newStackItem.data;
//     }
// 
//     public T peek() {
//         if(isEmpty())
//             return null;
//         return top.data;
//     }
// 
//      class StackItem<T> {
// 
//         private StackItem<T> next;
//         T data;
// 
//         StackItem(T item) {
//             data = item;
//             next = null;
//         }
// 
//         StackItem<T> getNext() {
//             return next;
//         }
// 
//         StackItem<T> setNext(T item) {
//             next = new StackItem<T>(item);
//             return next;
//         }
// 
//         StackItem<T> setNext(StackItem<T> item) {
//             next = item;
//             return item;
//         }
//     }
// 
// }
// 
// Path: karthik/regex/dataStructures/Tree.java
// public class Tree<T> {
// 
//     protected TreeNode<T> root;
// 
//     public Tree() {
//         root = null;
//     }
// 
//     public Tree(T data, Tree<T> leftSubTree, Tree<T> rightSubTree) {
//         root = null;
//         addItem(data, leftSubTree, rightSubTree);
//     }
// 
//     public Tree<T> addItem(T data, Tree<T> leftSubTree, Tree<T> rightSubTree) // always creates new tree with added item at root
//     {
//         TreeNode<T> node;
// 
//         node = new TreeNode<T>(data);
//         if (root == null)
//             root = node;
// 
//         root.setLeft((leftSubTree == null) ? null : leftSubTree.root);
//         root.setRight((rightSubTree == null) ? null : rightSubTree.root);
// 
//         return this;
//     }
// 
//     public void traverse() {
//         if (root == null)
//             return;
// 
//         recTraverse(root);
//     }
// 
//     protected void recTraverse(TreeNode<T> current) {
//         if (current == null)
//             return;
// 
//         recTraverse(current.getLeft());
//         current.display();
//         recTraverse(current.getRight());
// 
//         return;
//     }
// 
//     public boolean isEmpty() {
//         return (root == null);
//     }
// 
//     public boolean isLeaf(TreeNode<T> current) {
//         if ((current.getLeft() == null) && (current.getRight() == null))
//             return true;
//         else
//             return false;
//     }
// 
//     class TreeNode<T> {
// 
//         protected T data;
//         protected TreeNode<T> left, right;
// 
//         TreeNode(T i) {
//             data = i;
//             left = right = null;
//         }
// 
//         T getData() {
//             return data;
//         }
// 
//         void display() {
//             System.out.print(data.toString() + " ");
//         }
// 
//         TreeNode<T> getLeft() {
//             return left;
//         }
// 
//         TreeNode<T> getRight() {
//             return right;
//         }
// 
//         void setLeft(TreeNode<T> newnode) {
//             left = newnode;
//         }
// 
//         void setRight(TreeNode<T> newnode) {
//             right = newnode;
//         }
//     }
// }


// Path: karthik/regex/Pattern.java
import karthik.regex.RegexTokenNames;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import karthik.regex.dataStructures.Stack;
import karthik.regex.dataStructures.Tree;

            current.addGroupIDList(groupIDList);
            group_transition_matrix = ((GroupRegexToken) current).
                createTransitionMatrix();
            if (group_transition_matrix == null)  // regex in group was invalid
                return false;

            matcherStack.push(group_transition_matrix);
            getNextToken();

            if (debug_create_tree) {
                Tree<RegexToken> groupTree = ((GroupRegexToken) current).
                    debug_create_tree();
                debug_tree_stack.push(new Tree<>(new RegexToken(currentType,
                    current.getFlags()), groupTree, null));
            }

            return true;
        }

        if (lookaround())
            return true;

        return false;
    }

    private boolean lookaround() throws ParserException {
        RegexTokenNames currentType;

        RegexToken current = getCurrentToken();
        currentType = current.getType();
        if (currentType == RegexTokenNames.LOOKAHEAD) {