docs: protected void makeAnswerArraysAndTagIndex(Collection<List<IN>> ob) {
  
      HashSet<String>[] featureIndices = new HashSet[windowSize];
      for (int i = 0; i < windowSize; i++) {
        featureIndices[i] = new HashSet<String>();
      }
  
      labelIndices = new HashIndex[windowSize];
      for (int i = 0; i < labelIndices.length; i++) {
        labelIndices[i] = new HashIndex<CRFLabel>();
      }
  
      Index<CRFLabel> labelIndex = labelIndices[windowSize - 1];
  
      classIndex = new HashIndex<String>();
      // classIndex.add("O");
      classIndex.add(flags.backgroundSymbol);
  
      HashSet[] seenBackgroundFeatures = new HashSet[2];
      seenBackgroundFeatures[0] = new HashSet();
      seenBackgroundFeatures[1] = new HashSet();
  
  
      int wordCount = 0;
  
      for (List<IN> doc : ob) {
  
        if (flags.useReverse) {
          Collections.reverse(doc);
        }
  
        int docSize = doc.size();
        // create the full set of labels in classIndex
        // note: update to use addAll later
        for (int j = 0; j < docSize; j++) {
          wordCount++;
          String ans = doc.get(j).get(AnswerAnnotation.class);
          if (ans == null || ans.equals("")) {
            throw new IllegalArgumentException("Word " + wordCount + " (\"" + doc.get(j).get(TextAnnotation.class) + "\") has a blank answer");
          }
          classIndex.add(ans);
        }
  
        for (int j = 0; j < docSize; j++) {
  
          CRFDatum<List<String>, CRFLabel> d = makeDatum(doc, j, featureFactory);
          labelIndex.add(d.label());
  
          List<List<String>> features = d.asFeatures();
          for (int k = 0, fsize = features.size(); k < fsize; k++) {
            Collection<String> cliqueFeatures = features.get(k);
            if (k < 2 && flags.removeBackgroundSingletonFeatures) {
              String ans = doc.get(j).get(AnswerAnnotation.class);
              boolean background = ans.equals(flags.backgroundSymbol);
              if (k == 1 && j > 0 && background) {
                ans = doc.get(j - 1).get(AnswerAnnotation.class);
                background = ans.equals(flags.backgroundSymbol);
              }
              if (background) {
                for (String f : cliqueFeatures) {
                  if (!featureIndices[k].contains(f)) {
                    if (seenBackgroundFeatures[k].contains(f)) {
                      seenBackgroundFeatures[k].remove(f);
                      featureIndices[k].add(f);
                    } else {
                      seenBackgroundFeatures[k].add(f);
                    }
                  }
                }
              } else {
                seenBackgroundFeatures[k].removeAll(cliqueFeatures);
                featureIndices[k].addAll(cliqueFeatures);
              }
            } else {
              featureIndices[k].addAll(cliqueFeatures);
            }
          }
        }
  
        if (flags.useReverse) {
          Collections.reverse(doc);
        }
      }
  
      // String[] fs = new String[featureIndices[0].size()];
      // for (Iterator iter = featureIndices[0].iterator(); iter.hasNext(); ) {
      // System.err.println(iter.next());
      // }
  
      int numFeatures = 0;
      for (int i = 0; i < windowSize; i++) {
        numFeatures += featureIndices[i].size();
      }
  
      featureIndex = new HashIndex<String>();
      map = new int[numFeatures];
      for (int i = 0; i < windowSize; i++) {
        featureIndex.addAll(featureIndices[i]);
        for (String str : featureIndices[i]) {
          map[featureIndex.indexOf(str)] = i;
        }
      }
  
      if (flags.useObservedSequencesOnly) {
        for (int i = 0, liSize = labelIndex.size(); i < liSize; i++) {
          CRFLabel label = labelIndex.get(i);
          for (int j = windowSize - 2; j >= 0; j--) {
            label = label.getOneSmallerLabel();
            labelIndices[j].add(label);
          }
        }
      } else {
        for (int i = 0; i < labelIndices.length; i++) {
          labelIndices[i] = allLabels(i + 1, classIndex);
        }
      }
  
      if (VERBOSE) {
        for (int i = 0, fiSize = featureIndex.size(); i < fiSize; i++) {
          System.out.println(i + ": " + featureIndex.get(i));
        }
      }
    }