code: public Pair<int[][][][], int[][]> documentsToDataAndLabels(Collection<List<IN>> documents) {
  
      // first index is the number of the document
      // second index is position in the document also the index of the
      // clique/factor table
      // third index is the number of elements in the clique/window these features
      // are for (starting with last element)
      // fourth index is position of the feature in the array that holds them
      // element in data[i][j][k][m] is the index of the mth feature occurring in
      // position k of the jth clique of the ith document
      // int[][][][] data = new int[documentsSize][][][];
      List<int[][][]> data = new ArrayList<int[][][]>();
  
      // first index is the number of the document
      // second index is the position in the document
      // element in labels[i][j] is the index of the correct label (if it exists)
      // at position j in document i
      // int[][] labels = new int[documentsSize][];
      List<int[]> labels = new ArrayList<int[]>();
  
      int numDatums = 0;
  
      for (List<IN> doc : documents) {
        Pair<int[][][], int[]> docPair = documentToDataAndLabels(doc);
        data.add(docPair.first());
        labels.add(docPair.second());
        numDatums += doc.size();
      }
  
      System.err.println("numClasses: " + classIndex.size() + ' ' + classIndex);
      System.err.println("numDocuments: " + data.size());
      System.err.println("numDatums: " + numDatums);
      System.err.println("numFeatures: " + featureIndex.size());
      printFeatures();
  
      int[][][][] dataA = new int[0][][][];
      int[][] labelsA = new int[0][];
  
      return new Pair<int[][][][], int[][]>(data.toArray(dataA), labels.toArray(labelsA));
    }
docs: Convert an ObjectBank to arrays of data features and labels.
  
  @return A Pair, where the first element is an int[][][][] representing the
  data and the second element is an int[][] representing the labels.