protected void detect() {
		monitor.println("\nDerivation length: " + length);
		
		AbstractWorker workerPool[] = new AbstractWorker[workers];
	
		startTime = System.currentTimeMillis();
		Job j = new Job(length, newStackFrame(dfa.startState));
		// have one worker hand out a predefined number of jobs
		AbstractWorker dealer = newWorker("dealer");
		dealer.setDealer(true);
		dealer.go(j, true);
	
		monitor.println("Jobs: " + jobs.size());
	
		long sentences = 0;
		if (jobs.size() > 0 && !monitor.canceling()) {
			for (int i = 0; i < workers; i++) {
				workerPool[i] = newWorker(("" + i));
				workerPool[i].start();
			}
			for (int i = 0; i < workers; i++) {
				while (workerPool[i].isAlive() && !monitor.canceling()) {
					try {
						workerPool[i].join();
					} catch (InterruptedException e) {
						return;
					}
				}
				sentences += workerPool[i].sentences;
			}
		}
		
		if (monitor.canceling()) {
			monitor.println("Aborted");
		} else {
			monitor.println("Done");
		}
		
		monitor.println("Sentences: " + sentences);
		int parsed = 0;
		for (Relation<Symbol, SymbolString> r : possibleAmbiguities) {
			parsed += r.size();
		}
		monitor.println("Parsed: " + parsed);
		monitor.println("Ambiguities found: " + ambiguities.size());
		monitor.println("Ambiguous nonterminals: " + ambiguities.m.size());
		monitor.println("Time: " + (System.currentTimeMillis() - startTime));
	}