docs: @Override
    public void addRow(final KeyValue row) {
      if (this.key == null) {
        throw new IllegalStateException("setRow was never called on " + this);
      }
  
      final byte[] key = row.key();
      if (Bytes.memcmp(this.key, key, Const.SALT_WIDTH(), 
          key.length - Const.SALT_WIDTH()) != 0) {
        throw new IllegalDataException("Attempt to add a different row="
            + row + ", this=" + this);
      }
  
      final byte[] remote_qual = row.qualifier();
      final byte[] remote_val = row.value();
      final byte[] merged_qualifiers = new byte[qualifiers.length + remote_qual.length];
      final byte[] merged_values = new byte[values.length + remote_val.length]; 
  
      int remote_q_index = 0;
      int local_q_index = 0;
      int merged_q_index = 0;
      
      int remote_v_index = 0;
      int local_v_index = 0;
      int merged_v_index = 0;
      short v_length;
      short q_length;
      while (remote_q_index < remote_qual.length || 
          local_q_index < qualifiers.length) {
        // if the remote q has finished, we just need to handle left over locals
        if (remote_q_index >= remote_qual.length) {
          v_length = Internal.getValueLengthFromQualifier(qualifiers, 
              local_q_index);
          System.arraycopy(values, local_v_index, merged_values, 
              merged_v_index, v_length);
          local_v_index += v_length;
          merged_v_index += v_length;
          
          q_length = Internal.getQualifierLength(qualifiers, 
              local_q_index);
          System.arraycopy(qualifiers, local_q_index, merged_qualifiers, 
              merged_q_index, q_length);
          local_q_index += q_length;
          merged_q_index += q_length;
          
          continue;
        }
        
        // if the local q has finished, we need to handle the left over remotes
        if (local_q_index >= qualifiers.length) {
          v_length = Internal.getValueLengthFromQualifier(remote_qual, 
              remote_q_index);
          System.arraycopy(remote_val, remote_v_index, merged_values, 
              merged_v_index, v_length);
          remote_v_index += v_length;
          merged_v_index += v_length;
          
          q_length = Internal.getQualifierLength(remote_qual, 
              remote_q_index);
          System.arraycopy(remote_qual, remote_q_index, merged_qualifiers, 
              merged_q_index, q_length);
          remote_q_index += q_length;
          merged_q_index += q_length;
          
          continue;
        }
        
        // for dupes, we just need to skip and continue
        final int sort = Internal.compareQualifiers(remote_qual, remote_q_index, 
            qualifiers, local_q_index);
        if (sort == 0) {
          //LOG.debug("Discarding duplicate timestamp: " + 
          //    Internal.getOffsetFromQualifier(remote_qual, remote_q_index));
          v_length = Internal.getValueLengthFromQualifier(remote_qual, 
              remote_q_index);
          remote_v_index += v_length;
          q_length = Internal.getQualifierLength(remote_qual, 
              remote_q_index);
          remote_q_index += q_length;
          continue;
        }
        
        if (sort < 0) {
          v_length = Internal.getValueLengthFromQualifier(remote_qual, 
              remote_q_index);
          System.arraycopy(remote_val, remote_v_index, merged_values, 
              merged_v_index, v_length);
          remote_v_index += v_length;
          merged_v_index += v_length;
          
          q_length = Internal.getQualifierLength(remote_qual, 
              remote_q_index);
          System.arraycopy(remote_qual, remote_q_index, merged_qualifiers, 
              merged_q_index, q_length);
          remote_q_index += q_length;
          merged_q_index += q_length;
        } else {
          v_length = Internal.getValueLengthFromQualifier(qualifiers, 
              local_q_index);
          System.arraycopy(values, local_v_index, merged_values, 
              merged_v_index, v_length);
          local_v_index += v_length;
          merged_v_index += v_length;
          
          q_length = Internal.getQualifierLength(qualifiers, 
              local_q_index);
          System.arraycopy(qualifiers, local_q_index, merged_qualifiers, 
              merged_q_index, q_length);
          local_q_index += q_length;
          merged_q_index += q_length;
        }
      }
      
      // we may have skipped some columns if we were given duplicates. Since we
      // had allocated enough bytes to hold the incoming row, we need to shrink
      // the final results
      if (merged_q_index == merged_qualifiers.length) {
        qualifiers = merged_qualifiers;
      } else {
        qualifiers = Arrays.copyOfRange(merged_qualifiers, 0, merged_q_index);
      }
      
      // set the meta bit based on the local and remote metas
      byte meta = 0;
      if ((values[values.length - 1] & Const.MS_MIXED_COMPACT) == 
                                       Const.MS_MIXED_COMPACT || 
          (remote_val[remote_val.length - 1] & Const.MS_MIXED_COMPACT) == 
                                               Const.MS_MIXED_COMPACT) {
        meta = Const.MS_MIXED_COMPACT;
      }
      values = Arrays.copyOfRange(merged_values, 0, merged_v_index + 1);
      values[values.length - 1] = meta;
    }