public static Metadata copyFromHeaders(HttpHeaders headers) {
        if (headers.isEmpty()) {
            return new Metadata();
        }

        int numHeaders = 0;
        for (Entry<AsciiString, String> entry : headers) {
            final AsciiString name = entry.getKey();
            final String value = entry.getValue();
            if (STRIPPED_HEADERS.contains(name)) {
                continue;
            }

            if (isBinary(name)) {
                numHeaders += COMMA_MATCHER.countIn(value) + 1;
            } else {
                numHeaders += 1;
            }
        }

        final byte[][] metadata = new byte[numHeaders * 2][];

        int i = 0;
        for (Entry<AsciiString, String> entry : headers) {
            final AsciiString name = entry.getKey();
            final String value = entry.getValue();
            if (STRIPPED_HEADERS.contains(name)) {
                continue;
            }

            final byte[] nameBytes = name.isEntireArrayUsed() ? name.array() : name.toByteArray();
            if (isBinary(name)) {
                int commaIndex = COMMA_MATCHER.indexIn(value);
                if (commaIndex == -1) {
                    metadata[i++] = nameBytes;
                    metadata[i++] = Base64.getDecoder().decode(value);
                } else {
                    int substringStartIndex = 0;
                    while (commaIndex != -1) {
                        final String substring = value.substring(substringStartIndex, commaIndex);
                        metadata[i++] = nameBytes;
                        metadata[i++] = Base64.getDecoder().decode(substring);

                        substringStartIndex = commaIndex + 1;
                        commaIndex = COMMA_MATCHER.indexIn(value, commaIndex + 1);
                    }
                    final String substring = value.substring(substringStartIndex);
                    metadata[i++] = nameBytes;
                    metadata[i++] = Base64.getDecoder().decode(substring);
                }
            } else {
                metadata[i++] = nameBytes;
                metadata[i++] = value.getBytes(StandardCharsets.UTF_8);
            }
        }

        return InternalMetadata.newMetadata(metadata);
    }
Copies the headers in the Armeria {@link HttpHeaders} into a gRPC {@link Metadata}.
grpc/src/main/java/com/linecorp/armeria/internal/common/grpc/MetadataUtil.java