private void ProcessRegEx_eNFA(String regEx, State leftState, State rightState){
		//regEx = RemoveUnnecessaryBrackets(regEx);
		// first we separate the regEx by '|' operator into separate regular expressions
		List<String> choices = new ArrayList<String>();
		int bracketsNum = 0;
		int lastSubstringEndIndex = 0;
		for (int i = 0; i < regEx.length(); ++i){
			if (regEx.charAt(i) == '(' && IsOperator(regEx, i)) ++bracketsNum;
			else if (regEx.charAt(i) == ')' && IsOperator(regEx, i)) --bracketsNum;
			else if (bracketsNum == 0 && regEx.charAt(i) == '|' && IsOperator(regEx, i)){
				String s = regEx.substring(lastSubstringEndIndex, i);
				lastSubstringEndIndex = i+1;
				choices.add(s);
			}
		}
		// add the last choice (this could also be the only one)
		String s = regEx.substring(lastSubstringEndIndex, regEx.length());
		choices.add(s);
		
		if (choices.size() >= 2){ // at least one choice operator ('|') 
			// has been found outside of the brackets
			for (int i = 0; i < choices.size(); ++i){
				// add epsilon transitions
				State tempLeftState = AddState();
				State tempRightState = AddState();
				AddEpsilonTransition(leftState, tempLeftState);
				AddEpsilonTransition(tempRightState, rightState);
				ProcessRegEx_eNFA(choices.get(i), tempLeftState, tempRightState);
				}
		}
		else{ // no choice operators outside of the brackets.
			// This also mean that choices.get(0) == regEx
			// concatenation
			Boolean prefixFlag = false;
			State lastState = leftState;
			for (int i = 0; i < regEx.length(); ++i){
				State a, b;
				if (prefixFlag){ // 1
					prefixFlag = false;
					char inputC;
					// jos dodati za * $ | \ <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
					if (regEx.charAt(i) == '*') inputC = '*';
					if (regEx.charAt(i) == '$') inputC = '$';
					if (regEx.charAt(i) == '|') inputC = '|';
					if (regEx.charAt(i) == '\\') inputC = '\\';
					
					if (regEx.charAt(i) == 't') inputC = '\t';
					else if (regEx.charAt(i) == 'n') inputC = '\n';
					else if (regEx.charAt(i) == '_') inputC = ' ';
					else inputC = regEx.charAt(i);
					
					a = AddState();
					b = AddState();
					AddTransition(a, b, inputC);
					if (!mInputCharacters.contains(inputC)) mInputCharacters.add(inputC);
				}
				else{ // 2
					if (regEx.charAt(i) == '\\'){
						prefixFlag = true;
						continue;
					}
					if (regEx.charAt(i) != '('){ // 2a
						
						a = AddState();
						b = AddState();
						if (regEx.charAt(i) == '$') AddEpsilonTransition(a, b);
						else{
							AddTransition(a, b, regEx.charAt(i));
							if (!mInputCharacters.contains(regEx.charAt(i))) mInputCharacters.add(regEx.charAt(i));
						}
					}
					else{ // 2b
						// first find the appropriate closed bracket character index
						int j = -1;
						int bracketsCount = 0;
						for (int k = i + 1; k < regEx.length(); ++k){
							if (bracketsCount == 0 && regEx.charAt(k) == ')' && IsOperator(regEx, k)){
								j = k;
								break;
							}
							else if (regEx.charAt(k) == '(' && IsOperator(regEx, k)) ++bracketsCount;
							else if (regEx.charAt(k) == ')' && IsOperator(regEx, k)) --bracketsCount;
						}
						a = AddState();
						b = AddState();
						ProcessRegEx_eNFA(regEx.substring(i+1, j), a, b);
						i = j;						
					}
				}
				
				// Check for Kleen operator
				if ((i+1) < regEx.length() && regEx.charAt(i+1) == '*'){
					State x = a;
					State y = b;
					a = AddState();
					b = AddState();
					
					AddEpsilonTransition(a, x);
					AddEpsilonTransition(y, b);
					AddEpsilonTransition(a, b);
					AddEpsilonTransition(y, x);
					i = i+1;
				}
				
				// connecting this part with the rest of the NFA
				AddEpsilonTransition(lastState, a);
				lastState = b;
			}
			//dodaj_epsilon_prijelaz(automat, lastStateId, desno_stanje)	
			AddEpsilonTransition(lastState, rightState);
		}		
	}