code: public static byte[][] toHttp2Headers(Metadata headers) {
      byte[][] serializedHeaders = InternalMetadata.serialize(headers);
      // TODO(carl-mastrangelo): eventually remove this once all callers are updated.
      if (serializedHeaders == null) {
        return new byte[][]{};
      }
      int k = 0;
      for (int i = 0; i < serializedHeaders.length; i += 2) {
        byte[] key = serializedHeaders[i];
        byte[] value = serializedHeaders[i + 1];
        if (endsWith(key, binaryHeaderSuffixBytes)) {
          // Binary header.
          serializedHeaders[k] = key;
          serializedHeaders[k + 1]
              = InternalMetadata.BASE64_ENCODING_OMIT_PADDING.encode(value).getBytes(US_ASCII);
          k += 2;
        } else {
          // Non-binary header.
          // Filter out headers that contain non-spec-compliant ASCII characters.
          // TODO(zhangkun83): only do such check in development mode since it's expensive
          if (isSpecCompliantAscii(value)) {
            serializedHeaders[k] = key;
            serializedHeaders[k + 1] = value;
            k += 2;
          } else {
            String keyString = new String(key, US_ASCII);
            logger.warning("Metadata key=" + keyString + ", value=" + Arrays.toString(value)
                + " contains invalid ASCII characters");
          }
        }
      }
      // Fast path, everything worked out fine.
      if (k == serializedHeaders.length) {
        return serializedHeaders;
      }
      return Arrays.copyOfRange(serializedHeaders, 0, k);
    }
docs: Transform the given headers to a format where only spec-compliant ASCII characters are allowed.
  Binary header values are encoded by Base64 in the result.  It is safe to modify the returned
  array, but not to modify any of the underlying byte arrays.
  
  @return the interleaved keys and values.