private void ProcessState(StateNFA state){
		// This is basically implementation of 4.b) and 4.c)
		// It uses recursion
		
		// first 4.b)
		if (state.mItem.mRightSymbolsIndices.size() != state.mItem.mItemDotPosition){ // Does this state represent a complete item.
			// create state, create transition, recursive call
			StateNFA newState = CreateState(state.mItem.mLeftNonTerminalSymbolIndex, state.mItem.mRightSymbolsIndices,
					false, state.mItem.mItemDotPosition + 1, state.mItem.mBEGINS_Set, state.mItem.mProductionIndex);
			int newStateIndex;
			if ((newStateIndex = GetIndexOf(newState)) == -1){ // does this state already exist?
				mStates.add(newState); // if not: add it
				ProcessState(newState);
			}
			else newState = mStates.get(newStateIndex); // if yes: get it
			
			// Now create the transition
			if (!mTransitions.containsKey(state)) mTransitions.put(state, new ArrayList<Transition>());
			Transition tempT = new Transition();
			tempT.mInput = state.mItem.mRightSymbolsIndices.get(state.mItem.mItemDotPosition);
			tempT.mNextState = newState;
			mTransitions.get(state).add(tempT);
		}
		// now 4.c)
		if (state.mItem.mRightSymbolsIndices.size() != state.mItem.mItemDotPosition &&
				mParser.GetSymbols().get(state.mItem.mRightSymbolsIndices.get(state.mItem.mItemDotPosition)).mIsTerminal == false){
			int symbolIndex = state.mItem.mRightSymbolsIndices.get(state.mItem.mItemDotPosition);
			// create state, create transition, recursive call
			for (int i = 0; i < mParser.GetProductions().size(); ++i){
				if (mParser.GetProductions().get(i).mLeftNonTerminalSymbolIndex == symbolIndex){
					// This is beta from the book.
					List<Integer> beta = new ArrayList<Integer>();
					for (int j = state.mItem.mItemDotPosition + 1; j < state.mItem.mRightSymbolsIndices.size(); ++j) 
						beta.add(state.mItem.mRightSymbolsIndices.get(j)); // fill beta with everything right of the dot
					List<Integer> b_set = mB_Sets.Get_BEGINS(beta);
					// check for rule ii)
					if (mB_Sets.AreEmpty(beta)){
						for (int j = 0; j < state.mItem.mBEGINS_Set.size(); ++j)
							if (!b_set.contains(state.mItem.mBEGINS_Set.get(j))) b_set.add(state.mItem.mBEGINS_Set.get(j));
					}
					StateNFA newState = CreateState(symbolIndex, mParser.GetProductions().get(i).mRightSymbolsIndices,
							(symbolIndex == mParser.GetInitialNonTerminalSymbol()), 0, b_set, i);
					int newStateIndex;
					if ((newStateIndex = GetIndexOf(newState)) == -1){ // does this state already exist?
						mStates.add(newState); // if not: add it
						ProcessState(newState);
					}
					else newState = mStates.get(newStateIndex); // if yes: get it
					
					// Now create the epsilon transition
					if (!mEpsilonTransitions.containsKey(state)) mEpsilonTransitions.put(state, new ArrayList<EpsilonTransition>());
					EpsilonTransition tempT = new EpsilonTransition();
					tempT.mNextState = newState;
					mEpsilonTransitions.get(state).add(tempT);
				}
			}
		}
		
	}