public MultiThreadSequenceProcessing(Iterator<I> inputIterator, int nrOfThreads) {
   this.inputIterator = inputIterator;
   threads = new ArrayList<ProcessingThread>(nrOfThreads);
   for (int i = 0; i < nrOfThreads; i++) {
     if (inputIterator.hasNext()) {
       ProcessingThread thread = new ProcessingThread();
       thread.input = inputIterator.next();
       threads.add(thread);
       thread.proceed();
     }
   }
   threadCursor = 0;
   noMoreInputs = false;
   outputIterator = getNextOutputIterator();
   if (outputIterator != null && outputIterator.hasNext()) buffer = outputIterator.next();
 }
  private Iterator<O> getNextOutputIterator() {
    while (!noMoreInputs) {
      ProcessingThread thread = threads.get(threadCursor);
      if (thread == null) noMoreInputs = true;
      else {
        thread.waitUntilFinished();
        List<O> output = thread.output;
        thread.output = null;
        if (inputIterator.hasNext()) {
          thread.input = inputIterator.next();
          thread.proceed();
        } else {
          thread.terminate();
          threads.set(threadCursor, null);
        }

        threadCursor++;
        if (threadCursor == threads.size()) threadCursor = 0;
        if (output == null) System.err.println("asdf");
        if (output != null && output.size() != 0) return output.iterator();
      }
    }
    return null;
  }
  private OtpMbox getMbox() {

    ProcessingThread thread = (ProcessingThread) Thread.currentThread();
    return thread.getMbox();
  }