docs: public static ArrayList<Cell> extractDataPoints(final ArrayList<KeyValue> row,
        final int estimated_nvalues) {
      final ArrayList<Cell> cells = new ArrayList<Cell>(estimated_nvalues);
      for (final KeyValue kv : row) {
        final byte[] qual = kv.qualifier();
        final int len = qual.length;
        final byte[] val = kv.value();
        
        if (len % 2 != 0) {
          // skip a non data point column
          continue;
        } else if (len == 2) {  // Single-value cell.
          // Maybe we need to fix the flags in the qualifier.
          final byte[] actual_val = fixFloatingPointValue(qual[1], val);
          final byte q = fixQualifierFlags(qual[1], actual_val.length);
          final byte[] actual_qual;
          
          if (q != qual[1]) {  // We need to fix the qualifier.
            actual_qual = new byte[] { qual[0], q };  // So make a copy.
          } else {
            actual_qual = qual;  // Otherwise use the one we already have.
          }
          
          final Cell cell = new Cell(actual_qual, actual_val);
          cells.add(cell);
          continue;
        } else if (len == 4 && inMilliseconds(qual[0])) {
          // since ms support is new, there's nothing to fix
          final Cell cell = new Cell(qual, val);
          cells.add(cell);
          continue;
        }
        
        // Now break it down into Cells.
        int val_idx = 0;
        try {
          for (int i = 0; i < len; i += 2) {
            final byte[] q = extractQualifier(qual, i);
            final int vlen = getValueLengthFromQualifier(qual, i);
            if (inMilliseconds(qual[i])) {
              i += 2;
            }
            
            final byte[] v = new byte[vlen];
            System.arraycopy(val, val_idx, v, 0, vlen);
            val_idx += vlen;
            final Cell cell = new Cell(q, v);
            cells.add(cell);
          }
        } catch (ArrayIndexOutOfBoundsException e) {
          throw new IllegalDataException("Corrupted value: couldn't break down"
              + " into individual values (consumed " + val_idx + " bytes, but was"
              + " expecting to consume " + (val.length - 1) + "): " + kv
              + ", cells so far: " + cells);
        }
        
        // Check we consumed all the bytes of the value.  Remember the last byte
        // is metadata, so it's normal that we didn't consume it.
        if (val_idx != val.length - 1) {
          throw new IllegalDataException("Corrupted value: couldn't break down"
            + " into individual values (consumed " + val_idx + " bytes, but was"
            + " expecting to consume " + (val.length - 1) + "): " + kv
            + ", cells so far: " + cells);
        }
      }
      
      Collections.sort(cells);
      return cells;
    }