public boolean detectAmbiguities(DetectionMethod method) {		
		IPairGraph pg = createPairGraph(method);			
		pg.init(nfa, monitor);
		if (!pg.detectAmbiguities()) {
			return false;
		}

		if (!pg.potentiallyAmbiguous()) {
			if (config.findHarmlessProductions) {
				harmlessProductions = nfa.grammar.productions;
				harmfulProductions = new ShareableHashSet<Production>();
				harmlessPatterns = new Relation<Pair<Production,Integer>, Production>();
			}
		} else {
			if (config.findHarmlessProductions) {
				Set<Production> usedProductions = pg.getUsedProductions();
				monitor.println("Used productions: " + usedProductions.size() + " / " + nfa.grammar.nrReachableProductions);
				
				harmlessProductions = new ShareableHashSet<Production>();
				for (Production p : nfa.grammar.productions) {
					if (p.reachable && !p.reconstructed && !usedProductions.contains(p)) {
						if (!p.lhs.s.startsWith("[")) { // don't include character classes TODO hack
							harmlessProductions.add(p);
						}
					}
				}
				harmfulProductions = new ShareableHashSet<Production>();
				harmfulProductions.addAll(nfa.grammar.productions);
				harmfulProductions.removeAll(harmlessProductions);
				
				// includes only reachable productions (b/c of Grammar.getItemDerives())
				harmlessPatterns = pg.getHarmlessPatterns(usedProductions);
			}
		}
		return true;
	}