private GeneralizedDFA buildScannerDFA()
	{
		// Collect the sub-NFAs for all regexes.
		HashSet<SetOfCharsSyntax> allCharRanges = new HashSet<SetOfCharsSyntax>();
		for(int t = spec.terminals.nextSetBit(0);t >= 0;t = spec.terminals.nextSetBit(t+1))
		{
			if(t == spec.getEOFTerminal()) continue;
			allCharRanges.addAll(spec.t.getRegex(t).acceptVisitor(transitionLabelCalculator));
		}
		nfa = new GeneralizedNFA(spec.terminals.cardinality(),allCharRanges.size());
		BitSet allStartStates = new BitSet();
		// Add accept symbols and gather start states for individual regexes.
		for(int t = spec.terminals.nextSetBit(0);t >= 0;t = spec.terminals.nextSetBit(t+1))
		{
			if(t == spec.getEOFTerminal()) continue;
			Pair<Integer,BitSet> states = spec.t.getRegex(t).acceptVisitor(automatonGenerator);
			allStartStates.set(states.first());
			for(int j = states.second().nextSetBit(0);j >= 0;j = states.second().nextSetBit(j+1))
			{
				nfa.addAcceptSymbol(j,t);
			}
		}
		// Create a scanner-wide start state and add epsilon transitions
		// into the start states for all the individual regexes.
		int newStartState = nfa.addState();
		nfa.addEpsilonTransitions(newStartState,allStartStates);

		// DEBUG-X-BEGIN
		//System.err.println("\n====== NFA ======\n");
		//System.err.println("Start state: " + newStartState);
		//System.err.println(nfa.toString());
		// DEBUG-X-END		
		
		// Convert the NFA to a DFA.
		GeneralizedDFA dfa = nfa.determinize(newStartState);
		
		return dfa;
	}