docs: @Override
      public List<Writable> next() {
          if(numFeatures < 0 && numLabels < 0){
              throw new IllegalStateException("Cannot get record: setConf(Configuration) has not been called. A setConf " +
                      "call is rquired to specify the number of features and/or labels in the source dataset");
          }
  
  
          Writable w = getNextRecord();
          if (w == null)
              throw new NoSuchElementException("No next element found!");
          String line = w.toString();
          List<Writable> record = new ArrayList<>(Collections.nCopies(numFeatures, ZERO));
  
          // Remove trailing comments
          String commentRegex = ALLOWED_DELIMITERS + "*" + COMMENT_CHAR + ".*$";
          String[] tokens = line.replaceFirst(commentRegex, "").split(ALLOWED_DELIMITERS);
  
          // Iterate over feature tokens
          for (int i = 1; i < tokens.length; i++) {
              String token = tokens[i];
              // Split into feature index and value
              String[] featureTokens = token.split(FEATURE_DELIMITER);
              if (featureTokens[0].startsWith(QID_PREFIX)) {
                  // Ignore QID entry for now
              } else {
                  // Parse feature index -- enforce that it's a positive integer
                  int index = -1;
                  try {
                      index = Integer.parseInt(featureTokens[0]);
                      if (index < 0)
                          throw new NumberFormatException("");
                  } catch (NumberFormatException e) {
                      String msg = String.format("Feature index must be positive integer (found %s)", featureTokens[i].toString());
                      throw new NumberFormatException(msg);
                  }
  
                  // If not using zero-based indexing, shift all indeces to left by one
                  if (!zeroBasedIndexing) {
                      if (index == 0)
                          throw new IndexOutOfBoundsException("Found feature with index " + index + " but not using zero-based indexing");
                      index--;
                  }
  
                  // Check whether feature index exceeds number of features
                  if (numFeatures >= 0 && index >= numFeatures)
                      throw new IndexOutOfBoundsException("Found " + (index+1) + " features in record, expected " + numFeatures);
  
                  // Add feature
                  record.set(index, new DoubleWritable(Double.parseDouble(featureTokens[1])));
              }
          }
  
          // If labels should be appended
          if (appendLabel) {
              List<Writable> labels = new ArrayList<>();
  
              // Treat labels as indeces for multilabel binary classification
              if (multilabel) {
                  labels = new ArrayList<>(Collections.nCopies(numLabels, LABEL_ZERO));
                  if (!tokens[0].equals("")) {
                      String[] labelTokens = tokens[0].split(LABEL_DELIMITER);
                      for (int i = 0; i < labelTokens.length; i++) {
                          // Parse label index -- enforce that it's a positive integer
                          int index = -1;
                          try {
                              index = Integer.parseInt(labelTokens[i]);
                              if (index < 0)
                                  throw new NumberFormatException("");
                          } catch (NumberFormatException e) {
                              String msg = String.format("Multilabel index must be positive integer (found %s)", labelTokens[i].toString());
                              throw new NumberFormatException(msg);
                          }
  
                          // If not using zero-based indexing for labels, shift all indeces to left by one
                          if (!zeroBasedLabelIndexing) {
                              if (index == 0)
                                  throw new IndexOutOfBoundsException("Found label with index " + index + " but not using zero-based indexing");
                              index--;
                          }
  
                          // Check whether label index exceeds number of labels
                          if (numLabels >= 0 && index >= numLabels)
                              throw new IndexOutOfBoundsException("Found " + (index + 1) + " labels in record, expected " + numLabels);
  
                          // Add label
                          labels.set(index, LABEL_ONE);
                      }
                  }
              } else {
                  String[] labelTokens = tokens[0].split(LABEL_DELIMITER);
                  int numLabelsFound = labelTokens[0].equals("") ? 0 : labelTokens.length;
                  if (numLabels < 0)
                      numLabels = numLabelsFound;
                  if (numLabelsFound != numLabels)
                      throw new IndexOutOfBoundsException("Found " + labelTokens.length + " labels in record, expected " + numLabels);
                  for (int i = 0; i < numLabelsFound; i++) {
                      try { // Encode label as integer, if possible
                          labels.add(new IntWritable(Integer.parseInt(labelTokens[i])));
                      } catch (NumberFormatException e) {
                          labels.add(new DoubleWritable(Double.parseDouble(labelTokens[i])));
                      }
                  }
              }
  
              // Append labels to record
              record.addAll(labels);
          }
  
          return record;
      }