code: public void processDocument(BufferedReader document, Wordsi wordsi) {
          Queue<String> prevWords = new ArrayDeque<String>();
          Queue<String> nextWords = new ArrayDeque<String>();
          Queue<String> nextRealWord = new ArrayDeque<String>();
  
          Iterator<String> it = IteratorFactory.tokenizeOrdered(document);
  
          // Fill up the words after the context so that when the real processing
          // starts, the context is fully prepared.
          for (int i = 0 ; i < windowSize && it.hasNext(); ++i)
              addNextToken(it.next(), nextWords, nextRealWord);
  
          // Iterate through each of the words in the context, generating context
          // vectors for each acceptable word.
          String focusWord = null;
          String replacementWord = null;
          while (!nextWords.isEmpty()) {
              focusWord = nextWords.remove();
              replacementWord = nextRealWord.remove();
  
              // Advance the sliding window to the right.
              if (it.hasNext())
                  addNextToken(it.next(), nextWords, nextRealWord);
  
              // Represent the word if wordsi is willing to process it.
              if (!replacementWord.equals(EMPTY)) {
                  SparseDoubleVector contextVector = generator.generateContext(
                          prevWords, nextWords);
                  wordsi.handleContextVector(
                          focusWord, replacementWord, contextVector);
              }
  
              // Advance the sliding window to the right.
              prevWords.offer(focusWord);
              if (prevWords.size() > windowSize)
                  prevWords.remove();
          }
      }
docs: {@inheritDoc}