anchor.diff:        columnCount--;
         offset += 18;
       }
  -    fn(ff);
  +    queryResults.fields = ff;
       return offset;
  +  }
  +
  +  static final STRING_DATATYPE = 19;
  +
  +  parseDataRows(list, offset, queryResults) {
  +    var rows = [], fields = queryResults.fields;
  +    //var columnCount = getUint16(list, offset + 5);
  +    var columnCount = fields.length; // Take a shortcut.
  +    var ncol, dt, v, valueLen, row, len = list.length;
  +    do {
  +      row = [];
  +      for (ncol = 0; ncol < columnCount; ncol++) {
  +        dt = fields[ncol].dataTypeObjectId;
  +        valueLen = getInt32(list, offset + 7);
  +        offset += 11;
  +        if (dt == STRING_DATATYPE) {
  +          v = new String.fromCharCodes(list, offset, offset + valueLen);
  +        } else {
  +          throw "Unsupported data type (${dt}) for now.";
  +        }
  +        row.add(v);
  +        offset += valueLen;
  +      }
  +      rows.add(row);
  +    } while (offset < len && list[offset] == 68); // D for another DataRow.
  +    queryResults.rows = rows;
     }
   
     parseQueryResponse(list) {
  
positive.code:     var c = list[0];
      if (c == 84) { // T for RowDescription.
        var qr = new QueryResults(), offset;
        offset = parseRowDescription(list, (fields) {
          qr.fields = fields;
        });
        p(["qr", qr]);
      } else if (c == 69) { // E for ErrorResponse.
        throw "ErrorResponse: ${inspect(parseFields(list))}";
  
negative.code:   parseReadyForQuery(list, offset) {
      if (offset + 5 < list.length) {
        _backEndStatus = list[offset + 5];
      } else {
        throw "The BackendKeyData response was too short.";
      }
  