private void computeLookaheadClosure(LRLookaheadSets lookaheadSets,int state,BitSet seedItems)
	{
		LR0ItemSet stateI = dfa.getItemSet(state);
		
		BitSet fringe1 = new BitSet(),fringe2 = new BitSet();
		BitSet combinedFirst = new BitSet();
		
		fringe1.or(seedItems);
		
		boolean setsChanged = true;
		while(setsChanged)
		{
			setsChanged = false;
			for(int item = fringe1.nextSetBit(0);item >= 0;item = fringe1.nextSetBit(item+1))
			{
				if(stateI.getPosition(item) >= spec.pr.getRHSLength(stateI.getProduction(item))) continue;
				combinedFirst.clear();
				boolean useLookahead = computeCombinedFirst(stateI.getProduction(item),stateI.getPosition(item),combinedFirst);
				// BOTTLENECK -- could speed this up by having a map of productions
				// e.g. A -> b (*) C d  -->   C -> e
				for(int i = 0;i < stateI.size();i++)
				{
					if(spec.pr.getLHS(stateI.getProduction(i)) == spec.pr.getRHSSym(stateI.getProduction(item),stateI.getPosition(item)) &&
					   stateI.getPosition(i) == 0)
					{
						boolean setChanged;
						setChanged = ParserSpec.union(lookaheadSets.getLookahead(state,i),combinedFirst);
						if(useLookahead) setChanged |= ParserSpec.union(lookaheadSets.getLookahead(state,i),lookaheadSets.getLookahead(state,item));
						if(setChanged)
						{
							setsChanged = true;
							fringe2.set(i);
						}
					}
				}
			}
			seedItems.or(fringe2);
			fringe1.clear();
			fringe1.or(fringe2);
		}
	}