// 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;
//         }
//     }
// 
// }


import java.util.HashMap;
import java.util.Map;
import karthik.regex.dataStructures.Stack;
/*
 * Copyright (C) 2014 karthik
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package karthik.regex;


/**
 *
 * @author karthik
 */
class ECloseCache {

    private Map<Integer, Integer[]> eclose_cache;

    private ECloseCache(Map<Integer, Integer[]> cache) {
        eclose_cache = cache;
    }

    Integer[] get_eps_transitions(Integer source_state) {
        Integer[] return_array = eclose_cache.get(source_state);

        return (return_array == null) ? new Integer[0] : return_array;
    }

    static ECloseCache create_eclose_cache(TransitionTable transition_table) {
        // e-closes every state in the transition matrix 

        Integer[] eclose_array_for_one_state;
        Map<Integer, Integer[]> return_map = new HashMap<>();

        Integer numStates = transition_table.getNumStates();
        for (Integer source_state = 0; source_state < numStates; source_state++) {
            eclose_array_for_one_state = calc_eclose_states(transition_table,
                source_state);
            return_map.put(source_state, eclose_array_for_one_state);
        }

        return new ECloseCache(return_map);
    }

    private static Integer[] calc_eclose_states(TransitionTable transition_table,
        Integer current_state) {

        Map<Integer, Integer> eclose_map = new HashMap<>();
// 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/ECloseCache.java
import java.util.HashMap;
import java.util.Map;
import karthik.regex.dataStructures.Stack;

/*
 * Copyright (C) 2014 karthik
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package karthik.regex;


/**
 *
 * @author karthik
 */
class ECloseCache {

    private Map<Integer, Integer[]> eclose_cache;

    private ECloseCache(Map<Integer, Integer[]> cache) {
        eclose_cache = cache;
    }

    Integer[] get_eps_transitions(Integer source_state) {
        Integer[] return_array = eclose_cache.get(source_state);

        return (return_array == null) ? new Integer[0] : return_array;
    }

    static ECloseCache create_eclose_cache(TransitionTable transition_table) {
        // e-closes every state in the transition matrix 

        Integer[] eclose_array_for_one_state;
        Map<Integer, Integer[]> return_map = new HashMap<>();

        Integer numStates = transition_table.getNumStates();
        for (Integer source_state = 0; source_state < numStates; source_state++) {
            eclose_array_for_one_state = calc_eclose_states(transition_table,
                source_state);
            return_map.put(source_state, eclose_array_for_one_state);
        }

        return new ECloseCache(return_map);
    }

    private static Integer[] calc_eclose_states(TransitionTable transition_table,
        Integer current_state) {

        Map<Integer, Integer> eclose_map = new HashMap<>();
        Stack<Integer> tempStack = new Stack<>();