Merge remote-tracking branch 'upstream/master' into fix-stream-compression-config-interface
diff --git a/BUILD b/BUILD
index 8ccc748..728bab1 100644
--- a/BUILD
+++ b/BUILD
@@ -574,6 +574,7 @@
         "src/core/lib/channel/handshaker_factory.cc",
         "src/core/lib/channel/handshaker_registry.cc",
         "src/core/lib/compression/compression.cc",
+        "src/core/lib/compression/compression_internal.cc",
         "src/core/lib/compression/message_compress.cc",
         "src/core/lib/compression/stream_compression.cc",
         "src/core/lib/compression/stream_compression_gzip.cc",
@@ -707,6 +708,7 @@
         "src/core/lib/channel/handshaker_factory.h",
         "src/core/lib/channel/handshaker_registry.h",
         "src/core/lib/compression/algorithm_metadata.h",
+        "src/core/lib/compression/compression_internal.h",
         "src/core/lib/compression/message_compress.h",
         "src/core/lib/compression/stream_compression.h",
         "src/core/lib/compression/stream_compression_gzip.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 139d1bd..f9649ec 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -963,6 +963,7 @@
   src/core/lib/channel/handshaker_factory.cc
   src/core/lib/channel/handshaker_registry.cc
   src/core/lib/compression/compression.cc
+  src/core/lib/compression/compression_internal.cc
   src/core/lib/compression/message_compress.cc
   src/core/lib/compression/stream_compression.cc
   src/core/lib/compression/stream_compression_gzip.cc
@@ -1315,6 +1316,7 @@
   src/core/lib/channel/handshaker_factory.cc
   src/core/lib/channel/handshaker_registry.cc
   src/core/lib/compression/compression.cc
+  src/core/lib/compression/compression_internal.cc
   src/core/lib/compression/message_compress.cc
   src/core/lib/compression/stream_compression.cc
   src/core/lib/compression/stream_compression_gzip.cc
@@ -1635,6 +1637,7 @@
   src/core/lib/channel/handshaker_factory.cc
   src/core/lib/channel/handshaker_registry.cc
   src/core/lib/compression/compression.cc
+  src/core/lib/compression/compression_internal.cc
   src/core/lib/compression/message_compress.cc
   src/core/lib/compression/stream_compression.cc
   src/core/lib/compression/stream_compression_gzip.cc
@@ -1899,6 +1902,7 @@
   src/core/lib/channel/handshaker_factory.cc
   src/core/lib/channel/handshaker_registry.cc
   src/core/lib/compression/compression.cc
+  src/core/lib/compression/compression_internal.cc
   src/core/lib/compression/message_compress.cc
   src/core/lib/compression/stream_compression.cc
   src/core/lib/compression/stream_compression_gzip.cc
@@ -2149,6 +2153,7 @@
   src/core/lib/channel/handshaker_factory.cc
   src/core/lib/channel/handshaker_registry.cc
   src/core/lib/compression/compression.cc
+  src/core/lib/compression/compression_internal.cc
   src/core/lib/compression/message_compress.cc
   src/core/lib/compression/stream_compression.cc
   src/core/lib/compression/stream_compression_gzip.cc
@@ -2907,6 +2912,7 @@
   src/core/lib/channel/handshaker_factory.cc
   src/core/lib/channel/handshaker_registry.cc
   src/core/lib/compression/compression.cc
+  src/core/lib/compression/compression_internal.cc
   src/core/lib/compression/message_compress.cc
   src/core/lib/compression/stream_compression.cc
   src/core/lib/compression/stream_compression_gzip.cc
diff --git a/Makefile b/Makefile
index 382956d..ffd0818 100644
--- a/Makefile
+++ b/Makefile
@@ -2954,6 +2954,7 @@
     src/core/lib/channel/handshaker_factory.cc \
     src/core/lib/channel/handshaker_registry.cc \
     src/core/lib/compression/compression.cc \
+    src/core/lib/compression/compression_internal.cc \
     src/core/lib/compression/message_compress.cc \
     src/core/lib/compression/stream_compression.cc \
     src/core/lib/compression/stream_compression_gzip.cc \
@@ -3306,6 +3307,7 @@
     src/core/lib/channel/handshaker_factory.cc \
     src/core/lib/channel/handshaker_registry.cc \
     src/core/lib/compression/compression.cc \
+    src/core/lib/compression/compression_internal.cc \
     src/core/lib/compression/message_compress.cc \
     src/core/lib/compression/stream_compression.cc \
     src/core/lib/compression/stream_compression_gzip.cc \
@@ -3625,6 +3627,7 @@
     src/core/lib/channel/handshaker_factory.cc \
     src/core/lib/channel/handshaker_registry.cc \
     src/core/lib/compression/compression.cc \
+    src/core/lib/compression/compression_internal.cc \
     src/core/lib/compression/message_compress.cc \
     src/core/lib/compression/stream_compression.cc \
     src/core/lib/compression/stream_compression_gzip.cc \
@@ -3880,6 +3883,7 @@
     src/core/lib/channel/handshaker_factory.cc \
     src/core/lib/channel/handshaker_registry.cc \
     src/core/lib/compression/compression.cc \
+    src/core/lib/compression/compression_internal.cc \
     src/core/lib/compression/message_compress.cc \
     src/core/lib/compression/stream_compression.cc \
     src/core/lib/compression/stream_compression_gzip.cc \
@@ -4108,6 +4112,7 @@
     src/core/lib/channel/handshaker_factory.cc \
     src/core/lib/channel/handshaker_registry.cc \
     src/core/lib/compression/compression.cc \
+    src/core/lib/compression/compression_internal.cc \
     src/core/lib/compression/message_compress.cc \
     src/core/lib/compression/stream_compression.cc \
     src/core/lib/compression/stream_compression_gzip.cc \
@@ -4849,6 +4854,7 @@
     src/core/lib/channel/handshaker_factory.cc \
     src/core/lib/channel/handshaker_registry.cc \
     src/core/lib/compression/compression.cc \
+    src/core/lib/compression/compression_internal.cc \
     src/core/lib/compression/message_compress.cc \
     src/core/lib/compression/stream_compression.cc \
     src/core/lib/compression/stream_compression_gzip.cc \
diff --git a/binding.gyp b/binding.gyp
index 91919c3..03daaf0 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -666,6 +666,7 @@
         'src/core/lib/channel/handshaker_factory.cc',
         'src/core/lib/channel/handshaker_registry.cc',
         'src/core/lib/compression/compression.cc',
+        'src/core/lib/compression/compression_internal.cc',
         'src/core/lib/compression/message_compress.cc',
         'src/core/lib/compression/stream_compression.cc',
         'src/core/lib/compression/stream_compression_gzip.cc',
diff --git a/build.yaml b/build.yaml
index d23716a..8b0aaa6 100644
--- a/build.yaml
+++ b/build.yaml
@@ -191,6 +191,7 @@
   - src/core/lib/channel/handshaker_factory.cc
   - src/core/lib/channel/handshaker_registry.cc
   - src/core/lib/compression/compression.cc
+  - src/core/lib/compression/compression_internal.cc
   - src/core/lib/compression/message_compress.cc
   - src/core/lib/compression/stream_compression.cc
   - src/core/lib/compression/stream_compression_gzip.cc
@@ -345,6 +346,7 @@
   - src/core/lib/channel/handshaker_factory.h
   - src/core/lib/channel/handshaker_registry.h
   - src/core/lib/compression/algorithm_metadata.h
+  - src/core/lib/compression/compression_internal.h
   - src/core/lib/compression/message_compress.h
   - src/core/lib/compression/stream_compression.h
   - src/core/lib/compression/stream_compression_gzip.h
diff --git a/config.m4 b/config.m4
index 5d92a2a..69f8e94 100644
--- a/config.m4
+++ b/config.m4
@@ -94,6 +94,7 @@
     src/core/lib/channel/handshaker_factory.cc \
     src/core/lib/channel/handshaker_registry.cc \
     src/core/lib/compression/compression.cc \
+    src/core/lib/compression/compression_internal.cc \
     src/core/lib/compression/message_compress.cc \
     src/core/lib/compression/stream_compression.cc \
     src/core/lib/compression/stream_compression_gzip.cc \
diff --git a/config.w32 b/config.w32
index 67b5e2f..ba05db8 100644
--- a/config.w32
+++ b/config.w32
@@ -71,6 +71,7 @@
     "src\\core\\lib\\channel\\handshaker_factory.cc " +
     "src\\core\\lib\\channel\\handshaker_registry.cc " +
     "src\\core\\lib\\compression\\compression.cc " +
+    "src\\core\\lib\\compression\\compression_internal.cc " +
     "src\\core\\lib\\compression\\message_compress.cc " +
     "src\\core\\lib\\compression\\stream_compression.cc " +
     "src\\core\\lib\\compression\\stream_compression_gzip.cc " +
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 08ef738..0165d10 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -316,6 +316,7 @@
                       'src/core/lib/channel/handshaker_factory.h',
                       'src/core/lib/channel/handshaker_registry.h',
                       'src/core/lib/compression/algorithm_metadata.h',
+                      'src/core/lib/compression/compression_internal.h',
                       'src/core/lib/compression/message_compress.h',
                       'src/core/lib/compression/stream_compression.h',
                       'src/core/lib/compression/stream_compression_gzip.h',
@@ -469,6 +470,7 @@
                       'src/core/lib/channel/handshaker_factory.cc',
                       'src/core/lib/channel/handshaker_registry.cc',
                       'src/core/lib/compression/compression.cc',
+                      'src/core/lib/compression/compression_internal.cc',
                       'src/core/lib/compression/message_compress.cc',
                       'src/core/lib/compression/stream_compression.cc',
                       'src/core/lib/compression/stream_compression_gzip.cc',
@@ -816,6 +818,7 @@
                               'src/core/lib/channel/handshaker_factory.h',
                               'src/core/lib/channel/handshaker_registry.h',
                               'src/core/lib/compression/algorithm_metadata.h',
+                              'src/core/lib/compression/compression_internal.h',
                               'src/core/lib/compression/message_compress.h',
                               'src/core/lib/compression/stream_compression.h',
                               'src/core/lib/compression/stream_compression_gzip.h',
diff --git a/grpc.def b/grpc.def
index 558be60..2a8d802 100644
--- a/grpc.def
+++ b/grpc.def
@@ -27,16 +27,15 @@
     census_delete_resource
     census_resource_id
     census_record_values
+    grpc_compression_algorithm_is_message
+    grpc_compression_algorithm_is_stream
     grpc_compression_algorithm_parse
     grpc_compression_algorithm_name
-    grpc_stream_compression_algorithm_name
     grpc_compression_algorithm_for_level
-    grpc_stream_compression_algorithm_for_level
     grpc_compression_options_init
     grpc_compression_options_enable_algorithm
     grpc_compression_options_disable_algorithm
     grpc_compression_options_is_algorithm_enabled
-    grpc_compression_options_is_stream_compression_algorithm_enabled
     grpc_metadata_array_init
     grpc_metadata_array_destroy
     grpc_call_details_init
diff --git a/grpc.gemspec b/grpc.gemspec
index ce23e6f..6afb09d 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -259,6 +259,7 @@
   s.files += %w( src/core/lib/channel/handshaker_factory.h )
   s.files += %w( src/core/lib/channel/handshaker_registry.h )
   s.files += %w( src/core/lib/compression/algorithm_metadata.h )
+  s.files += %w( src/core/lib/compression/compression_internal.h )
   s.files += %w( src/core/lib/compression/message_compress.h )
   s.files += %w( src/core/lib/compression/stream_compression.h )
   s.files += %w( src/core/lib/compression/stream_compression_gzip.h )
@@ -416,6 +417,7 @@
   s.files += %w( src/core/lib/channel/handshaker_factory.cc )
   s.files += %w( src/core/lib/channel/handshaker_registry.cc )
   s.files += %w( src/core/lib/compression/compression.cc )
+  s.files += %w( src/core/lib/compression/compression_internal.cc )
   s.files += %w( src/core/lib/compression/message_compress.cc )
   s.files += %w( src/core/lib/compression/stream_compression.cc )
   s.files += %w( src/core/lib/compression/stream_compression_gzip.cc )
diff --git a/grpc.gyp b/grpc.gyp
index 53e3885..14eecdd 100644
--- a/grpc.gyp
+++ b/grpc.gyp
@@ -232,6 +232,7 @@
         'src/core/lib/channel/handshaker_factory.cc',
         'src/core/lib/channel/handshaker_registry.cc',
         'src/core/lib/compression/compression.cc',
+        'src/core/lib/compression/compression_internal.cc',
         'src/core/lib/compression/message_compress.cc',
         'src/core/lib/compression/stream_compression.cc',
         'src/core/lib/compression/stream_compression_gzip.cc',
@@ -534,6 +535,7 @@
         'src/core/lib/channel/handshaker_factory.cc',
         'src/core/lib/channel/handshaker_registry.cc',
         'src/core/lib/compression/compression.cc',
+        'src/core/lib/compression/compression_internal.cc',
         'src/core/lib/compression/message_compress.cc',
         'src/core/lib/compression/stream_compression.cc',
         'src/core/lib/compression/stream_compression_gzip.cc',
@@ -741,6 +743,7 @@
         'src/core/lib/channel/handshaker_factory.cc',
         'src/core/lib/channel/handshaker_registry.cc',
         'src/core/lib/compression/compression.cc',
+        'src/core/lib/compression/compression_internal.cc',
         'src/core/lib/compression/message_compress.cc',
         'src/core/lib/compression/stream_compression.cc',
         'src/core/lib/compression/stream_compression_gzip.cc',
@@ -933,6 +936,7 @@
         'src/core/lib/channel/handshaker_factory.cc',
         'src/core/lib/channel/handshaker_registry.cc',
         'src/core/lib/compression/compression.cc',
+        'src/core/lib/compression/compression_internal.cc',
         'src/core/lib/compression/message_compress.cc',
         'src/core/lib/compression/stream_compression.cc',
         'src/core/lib/compression/stream_compression_gzip.cc',
diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h
index d9988e5..0e7ad0b 100644
--- a/include/grpc++/impl/codegen/call.h
+++ b/include/grpc++/impl/codegen/call.h
@@ -212,14 +212,12 @@
  public:
   CallOpSendInitialMetadata() : send_(false) {
     maybe_compression_level_.is_set = false;
-    maybe_stream_compression_level_.is_set = false;
   }
 
   void SendInitialMetadata(
       const std::multimap<grpc::string, grpc::string>& metadata,
       uint32_t flags) {
     maybe_compression_level_.is_set = false;
-    maybe_stream_compression_level_.is_set = false;
     send_ = true;
     flags_ = flags;
     initial_metadata_ =
@@ -231,11 +229,6 @@
     maybe_compression_level_.level = level;
   }
 
-  void set_stream_compression_level(grpc_stream_compression_level level) {
-    maybe_stream_compression_level_.is_set = true;
-    maybe_stream_compression_level_.level = level;
-  }
-
  protected:
   void AddOp(grpc_op* ops, size_t* nops) {
     if (!send_) return;
@@ -251,12 +244,6 @@
       op->data.send_initial_metadata.maybe_compression_level.level =
           maybe_compression_level_.level;
     }
-    op->data.send_initial_metadata.maybe_stream_compression_level.is_set =
-        maybe_stream_compression_level_.is_set;
-    if (maybe_stream_compression_level_.is_set) {
-      op->data.send_initial_metadata.maybe_stream_compression_level.level =
-          maybe_stream_compression_level_.level;
-    }
   }
   void FinishOp(bool* status) {
     if (!send_) return;
@@ -272,10 +259,6 @@
     bool is_set;
     grpc_compression_level level;
   } maybe_compression_level_;
-  struct {
-    bool is_set;
-    grpc_stream_compression_level level;
-  } maybe_stream_compression_level_;
 };
 
 class CallOpSendMessage {
diff --git a/include/grpc/compression.h b/include/grpc/compression.h
index 13a8dd6..8cc7778 100644
--- a/include/grpc/compression.h
+++ b/include/grpc/compression.h
@@ -30,28 +30,25 @@
 extern "C" {
 #endif
 
+/** Return if an algorithm is message compression algorithm. */
+GRPCAPI int grpc_compression_algorithm_is_message(
+    grpc_compression_algorithm algorithm);
+
+/** Return if an algorithm is stream compression algorithm. */
+GRPCAPI int grpc_compression_algorithm_is_stream(
+    grpc_compression_algorithm algorithm);
+
 /** Parses the \a slice as a grpc_compression_algorithm instance and updating \a
  * algorithm. Returns 1 upon success, 0 otherwise. */
 GRPCAPI int grpc_compression_algorithm_parse(
     grpc_slice value, grpc_compression_algorithm *algorithm);
 
-/** Parses the \a slice as a grpc_stream_compression_algorithm instance and
- * updating \a algorithm. Returns 1 upon success, 0 otherwise. */
-int grpc_stream_compression_algorithm_parse(
-    grpc_slice name, grpc_stream_compression_algorithm *algorithm);
-
 /** Updates \a name with the encoding name corresponding to a valid \a
  * algorithm. Note that \a name is statically allocated and must *not* be freed.
  * Returns 1 upon success, 0 otherwise. */
 GRPCAPI int grpc_compression_algorithm_name(
     grpc_compression_algorithm algorithm, const char **name);
 
-/** Updates \a name with the encoding name corresponding to a valid \a
- * algorithm. Note that \a name is statically allocated and must *not* be freed.
- * Returns 1 upon success, 0 otherwise. */
-GRPCAPI int grpc_stream_compression_algorithm_name(
-    grpc_stream_compression_algorithm algorithm, const char **name);
-
 /** Returns the compression algorithm corresponding to \a level for the
  * compression algorithms encoded in the \a accepted_encodings bitset.
  *
@@ -59,13 +56,6 @@
 GRPCAPI grpc_compression_algorithm grpc_compression_algorithm_for_level(
     grpc_compression_level level, uint32_t accepted_encodings);
 
-/** Returns the stream compression algorithm corresponding to \a level for the
- * compression algorithms encoded in the \a accepted_stream_encodings bitset.
- * It abort()s for unknown levels. */
-GRPCAPI grpc_stream_compression_algorithm
-grpc_stream_compression_algorithm_for_level(grpc_stream_compression_level level,
-                                            uint32_t accepted_stream_encodings);
-
 GRPCAPI void grpc_compression_options_init(grpc_compression_options *opts);
 
 /** Mark \a algorithm as enabled in \a opts. */
@@ -80,11 +70,6 @@
 GRPCAPI int grpc_compression_options_is_algorithm_enabled(
     const grpc_compression_options *opts, grpc_compression_algorithm algorithm);
 
-/** Returns true if \a algorithm is marked as enabled in \a opts. */
-GRPCAPI int grpc_compression_options_is_stream_compression_algorithm_enabled(
-    const grpc_compression_options *opts,
-    grpc_stream_compression_algorithm algorithm);
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/grpc/impl/codegen/compression_types.h b/include/grpc/impl/codegen/compression_types.h
index 4419e2a..dec37fa 100644
--- a/include/grpc/impl/codegen/compression_types.h
+++ b/include/grpc/impl/codegen/compression_types.h
@@ -29,11 +29,6 @@
  * algorithm */
 #define GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY \
   "grpc-internal-encoding-request"
-/** To be used as initial metadata key for the request of a concrete stream
- * compression
- * algorithm */
-#define GRPC_STREAM_COMPRESSION_REQUEST_ALGORITHM_MD_KEY \
-  "grpc-internal-stream-encoding-request"
 
 /** To be used in channel arguments.
  *
@@ -43,17 +38,9 @@
  * Its value is an int from the \a grpc_compression_algorithm enum. */
 #define GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM \
   "grpc.default_compression_algorithm"
-/** Default stream compression algorithm for the channel.
- * Its value is an int from the \a grpc_stream_compression_algorithm enum. */
-#define GRPC_STREAM_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM \
-  "grpc.default_stream_compression_algorithm"
 /** Default compression level for the channel.
  * Its value is an int from the \a grpc_compression_level enum. */
 #define GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL "grpc.default_compression_level"
-/** Default stream compression level for the channel.
- * Its value is an int from the \a grpc_stream_compression_level enum. */
-#define GRPC_STREAM_COMPRESSION_CHANNEL_DEFAULT_LEVEL \
-  "grpc.default_stream_compression_level"
 /** Compression algorithms supported by the channel.
  * Its value is a bitset (an int). Bits correspond to algorithms in \a
  * grpc_compression_algorithm. For example, its LSB corresponds to
@@ -63,80 +50,49 @@
  * be ignored). */
 #define GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET \
   "grpc.compression_enabled_algorithms_bitset"
-/** Stream compression algorithms supported by the channel.
- * Its value is a bitset (an int). Bits correspond to algorithms in \a
- * grpc_stream_compression_algorithm. For example, its LSB corresponds to
- * GRPC_STREAM_COMPRESS_NONE, the next bit to GRPC_STREAM_COMPRESS_DEFLATE, etc.
- * Unset bits disable support for the algorithm. By default all algorithms are
- * supported. It's not possible to disable GRPC_STREAM_COMPRESS_NONE (the
- * attempt will be ignored). */
-#define GRPC_STREAM_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET \
-  "grpc.stream_compression_enabled_algorithms_bitset"
 /** \} */
 
 /** The various compression algorithms supported by gRPC */
 typedef enum {
   GRPC_COMPRESS_NONE = 0,
-  GRPC_COMPRESS_DEFLATE,
-  GRPC_COMPRESS_GZIP,
+  GRPC_COMPRESS_MESSAGE_DEFLATE,
+  GRPC_COMPRESS_MESSAGE_GZIP,
+  GRPC_COMPRESS_STREAM_GZIP,
   /* TODO(ctiller): snappy */
   GRPC_COMPRESS_ALGORITHMS_COUNT
 } grpc_compression_algorithm;
 
-/** Stream compresssion algorithms supported by gRPC */
-typedef enum {
-  GRPC_STREAM_COMPRESS_NONE = 0,
-  GRPC_STREAM_COMPRESS_GZIP,
-  GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT
-} grpc_stream_compression_algorithm;
-
 /** Compression levels allow a party with knowledge of its peer's accepted
  * encodings to request compression in an abstract way. The level-algorithm
  * mapping is performed internally and depends on the peer's supported
  * compression algorithms. */
 typedef enum {
   GRPC_COMPRESS_LEVEL_NONE = 0,
-  GRPC_COMPRESS_LEVEL_LOW,
-  GRPC_COMPRESS_LEVEL_MED,
-  GRPC_COMPRESS_LEVEL_HIGH,
+  GRPC_COMPRESS_LEVEL_MESSAGE_LOW,
+  GRPC_COMPRESS_LEVEL_MESSAGE_MED,
+  GRPC_COMPRESS_LEVEL_MESSAGE_HIGH,
+  GRPC_COMPRESS_LEVEL_STREAM_LOW,
+  GRPC_COMPRESS_LEVEL_STREAM_MED,
+  GRPC_COMPRESS_LEVEL_STREAM_HIGH,
   GRPC_COMPRESS_LEVEL_COUNT
 } grpc_compression_level;
 
-/** Compression levels for stream compression algorithms */
-typedef enum {
-  GRPC_STREAM_COMPRESS_LEVEL_NONE = 0,
-  GRPC_STREAM_COMPRESS_LEVEL_LOW,
-  GRPC_STREAM_COMPRESS_LEVEL_MED,
-  GRPC_STREAM_COMPRESS_LEVEL_HIGH,
-  GRPC_STREAM_COMPRESS_LEVEL_COUNT
-} grpc_stream_compression_level;
-
 typedef struct grpc_compression_options {
   /** All algs are enabled by default. This option corresponds to the channel
    * argument key behind \a GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET
    */
   uint32_t enabled_algorithms_bitset;
-  uint32_t enabled_stream_compression_algorithms_bitset;
 
-  /** The default message-wise compression level. It'll be used in the absence
-   * of * call specific settings. This option corresponds to the channel
+  /** The default compression level. It'll be used in the absence of call
+   * specific settings. This option corresponds to the channel
    * argument key behind \a GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL. If present,
-   * takes precedence over \a default_algorithm and \a
-   * default_stream_compression_algorithm.
+   * takes precedence over \a default_algorithm.
    * TODO(dgq): currently only available for server channels. */
   struct grpc_compression_options_default_level {
     int is_set;
     grpc_compression_level level;
   } default_level;
 
-  /** The default stream compression level. It'll be used in the absence of call
-   * specefic settings. If present, takes precedence over \a default_level,
-   * \a default_algorithm and \a default_stream_compression_algorithm. */
-  struct grpc_stream_compression_options_default_level {
-    int is_set;
-    grpc_stream_compression_level level;
-  } default_stream_compression_level;
-
   /** The default message compression algorithm. It'll be used in the absence of
    * call specific settings. This option corresponds to the channel argument key
    * behind \a GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM. */
@@ -144,17 +100,6 @@
     int is_set;
     grpc_compression_algorithm algorithm;
   } default_algorithm;
-
-  /** The default stream compression algorithm. It'll be used in the absence of
-   * call specific settings. If present, takes precedence over \a
-   * default_algorithm. This option corresponds to the channel
-   * argument key behind \a GRPC_STREAM_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM.
-   */
-  struct grpc_stream_compression_options_default_algorithm {
-    int is_set;
-    grpc_stream_compression_algorithm algorithm;
-  } default_stream_compression_algorithm;
-
 } grpc_compression_options;
 
 #ifdef __cplusplus
diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index 65463bb..31577e9 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -513,10 +513,6 @@
         uint8_t is_set;
         grpc_compression_level level;
       } maybe_compression_level;
-      struct grpc_op_send_initial_metadata_maybe_stream_compression_level {
-        uint8_t is_set;
-        grpc_stream_compression_level level;
-      } maybe_stream_compression_level;
     } send_initial_metadata;
     struct grpc_op_send_message {
       /** This op takes ownership of the slices in send_message.  After
diff --git a/package.xml b/package.xml
index df01421..4c2bf0e 100644
--- a/package.xml
+++ b/package.xml
@@ -271,6 +271,7 @@
     <file baseinstalldir="/" name="src/core/lib/channel/handshaker_factory.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/handshaker_registry.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/algorithm_metadata.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/compression/compression_internal.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/message_compress.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/stream_compression.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/stream_compression_gzip.h" role="src" />
@@ -428,6 +429,7 @@
     <file baseinstalldir="/" name="src/core/lib/channel/handshaker_factory.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/handshaker_registry.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/compression.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/compression/compression_internal.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/message_compress.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/stream_compression.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/stream_compression_gzip.cc" role="src" />
diff --git a/src/core/ext/filters/http/message_compress/message_compress_filter.cc b/src/core/ext/filters/http/message_compress/message_compress_filter.cc
index f785e13..b7c50fd 100644
--- a/src/core/ext/filters/http/message_compress/message_compress_filter.cc
+++ b/src/core/ext/filters/http/message_compress/message_compress_filter.cc
@@ -27,6 +27,7 @@
 #include "src/core/ext/filters/http/message_compress/message_compress_filter.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/compression/algorithm_metadata.h"
+#include "src/core/lib/compression/compression_internal.h"
 #include "src/core/lib/compression/message_compress.h"
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/slice/slice_internal.h"
@@ -52,7 +53,7 @@
   grpc_linked_mdelem accept_stream_encoding_storage;
   /** Compression algorithm we'll try to use. It may be given by incoming
    * metadata, or by the channel's default compression settings. */
-  grpc_compression_algorithm compression_algorithm;
+  grpc_message_compression_algorithm message_compression_algorithm;
   initial_metadata_state send_initial_metadata_state;
   grpc_error *cancel_error;
   grpc_closure start_send_message_batch_in_call_combiner;
@@ -67,15 +68,10 @@
 typedef struct channel_data {
   /** The default, channel-level, compression algorithm */
   grpc_compression_algorithm default_compression_algorithm;
-  /** Bitset of enabled algorithms */
+  /** Bitset of enabled compression algorithms */
   uint32_t enabled_algorithms_bitset;
   /** Supported compression algorithms */
-  uint32_t supported_compression_algorithms;
-
-  /** The default, channel-level, stream compression algorithm */
-  grpc_stream_compression_algorithm default_stream_compression_algorithm;
-  /** Bitset of enabled stream compression algorithms */
-  uint32_t enabled_stream_compression_algorithms_bitset;
+  uint32_t supported_message_compression_algorithms;
   /** Supported stream compression algorithms */
   uint32_t supported_stream_compression_algorithms;
 } channel_data;
@@ -89,7 +85,7 @@
     return true;
   }
   if (has_compression_algorithm) {
-    if (calld->compression_algorithm == GRPC_COMPRESS_NONE) {
+    if (calld->message_compression_algorithm == GRPC_MESSAGE_COMPRESS_NONE) {
       return true;
     }
     return false; /* we have an actual call-specific algorithm */
@@ -109,70 +105,53 @@
   call_data *calld = (call_data *)elem->call_data;
   channel_data *channeld = (channel_data *)elem->channel_data;
   *has_compression_algorithm = false;
+  grpc_compression_algorithm compression_algorithm;
   grpc_stream_compression_algorithm stream_compression_algorithm =
       GRPC_STREAM_COMPRESS_NONE;
-  if (initial_metadata->idx.named.grpc_internal_stream_encoding_request !=
-      NULL) {
-    grpc_mdelem md =
-        initial_metadata->idx.named.grpc_internal_stream_encoding_request->md;
-    if (!grpc_stream_compression_algorithm_parse(
-            GRPC_MDVALUE(md), &stream_compression_algorithm)) {
-      char *val = grpc_slice_to_c_string(GRPC_MDVALUE(md));
-      gpr_log(GPR_ERROR,
-              "Invalid stream compression algorithm: '%s' (unknown). Ignoring.",
-              val);
-      gpr_free(val);
-      stream_compression_algorithm = GRPC_STREAM_COMPRESS_NONE;
-    }
-    if (!GPR_BITGET(channeld->enabled_stream_compression_algorithms_bitset,
-                    stream_compression_algorithm)) {
-      char *val = grpc_slice_to_c_string(GRPC_MDVALUE(md));
-      gpr_log(
-          GPR_ERROR,
-          "Invalid stream compression algorithm: '%s' (previously disabled). "
-          "Ignoring.",
-          val);
-      gpr_free(val);
-      stream_compression_algorithm = GRPC_STREAM_COMPRESS_NONE;
-    }
-    *has_compression_algorithm = true;
-    grpc_metadata_batch_remove(
-        exec_ctx, initial_metadata,
-        initial_metadata->idx.named.grpc_internal_stream_encoding_request);
-    /* Disable message-wise compression */
-    calld->compression_algorithm = GRPC_COMPRESS_NONE;
-    if (initial_metadata->idx.named.grpc_internal_encoding_request != NULL) {
-      grpc_metadata_batch_remove(
-          exec_ctx, initial_metadata,
-          initial_metadata->idx.named.grpc_internal_encoding_request);
-    }
-  } else if (initial_metadata->idx.named.grpc_internal_encoding_request !=
-             NULL) {
+  if (initial_metadata->idx.named.grpc_internal_encoding_request != NULL) {
     grpc_mdelem md =
         initial_metadata->idx.named.grpc_internal_encoding_request->md;
     if (!grpc_compression_algorithm_parse(GRPC_MDVALUE(md),
-                                          &calld->compression_algorithm)) {
+                                          &compression_algorithm)) {
       char *val = grpc_slice_to_c_string(GRPC_MDVALUE(md));
       gpr_log(GPR_ERROR,
               "Invalid compression algorithm: '%s' (unknown). Ignoring.", val);
       gpr_free(val);
-      calld->compression_algorithm = GRPC_COMPRESS_NONE;
+      calld->message_compression_algorithm = GRPC_MESSAGE_COMPRESS_NONE;
+      stream_compression_algorithm = GRPC_STREAM_COMPRESS_NONE;
+    }
+    if (!GPR_BITGET(channeld->enabled_algorithms_bitset,
+                    compression_algorithm)) {
+      char *val = grpc_slice_to_c_string(GRPC_MDVALUE(md));
+      gpr_log(GPR_ERROR,
+              "Invalid compression algorithm: '%s' (previously disabled). "
+              "Ignoring.",
+              val);
+      gpr_free(val);
+      calld->message_compression_algorithm = GRPC_MESSAGE_COMPRESS_NONE;
+      stream_compression_algorithm = GRPC_STREAM_COMPRESS_NONE;
     }
     *has_compression_algorithm = true;
     grpc_metadata_batch_remove(
         exec_ctx, initial_metadata,
         initial_metadata->idx.named.grpc_internal_encoding_request);
+    calld->message_compression_algorithm =
+        grpc_compression_algorithm_to_message_compression_algorithm(
+            compression_algorithm);
+    stream_compression_algorithm =
+        grpc_compression_algorithm_to_stream_compression_algorithm(
+            compression_algorithm);
   } else {
     /* If no algorithm was found in the metadata and we aren't
      * exceptionally skipping compression, fall back to the channel
      * default */
-    if (channeld->default_stream_compression_algorithm !=
-        GRPC_STREAM_COMPRESS_NONE) {
+    if (channeld->default_compression_algorithm != GRPC_COMPRESS_NONE) {
+      calld->message_compression_algorithm =
+          grpc_compression_algorithm_to_message_compression_algorithm(
+              channeld->default_compression_algorithm);
       stream_compression_algorithm =
-          channeld->default_stream_compression_algorithm;
-      calld->compression_algorithm = GRPC_COMPRESS_NONE;
-    } else {
-      calld->compression_algorithm = channeld->default_compression_algorithm;
+          grpc_compression_algorithm_to_stream_compression_algorithm(
+              channeld->default_compression_algorithm);
     }
     *has_compression_algorithm = true;
   }
@@ -184,10 +163,12 @@
         exec_ctx, initial_metadata,
         &calld->stream_compression_algorithm_storage,
         grpc_stream_compression_encoding_mdelem(stream_compression_algorithm));
-  } else if (calld->compression_algorithm != GRPC_COMPRESS_NONE) {
+  } else if (calld->message_compression_algorithm !=
+             GRPC_MESSAGE_COMPRESS_NONE) {
     error = grpc_metadata_batch_add_tail(
         exec_ctx, initial_metadata, &calld->compression_algorithm_storage,
-        grpc_compression_encoding_mdelem(calld->compression_algorithm));
+        grpc_message_compression_encoding_mdelem(
+            calld->message_compression_algorithm));
   }
 
   if (error != GRPC_ERROR_NONE) return error;
@@ -196,11 +177,12 @@
   error = grpc_metadata_batch_add_tail(
       exec_ctx, initial_metadata, &calld->accept_encoding_storage,
       GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(
-          channeld->supported_compression_algorithms));
+          channeld->supported_message_compression_algorithms));
 
   if (error != GRPC_ERROR_NONE) return error;
 
-  /* Do not overwrite accept-encoding header if it already presents. */
+  /* Do not overwrite accept-encoding header if it already presents (e.g. added
+   * by some proxy). */
   if (!initial_metadata->idx.named.accept_encoding) {
     error = grpc_metadata_batch_add_tail(
         exec_ctx, initial_metadata, &calld->accept_stream_encoding_storage,
@@ -240,16 +222,16 @@
   grpc_slice_buffer_init(&tmp);
   uint32_t send_flags =
       calld->send_message_batch->payload->send_message.send_message->flags;
-  bool did_compress = grpc_msg_compress(exec_ctx, calld->compression_algorithm,
-                                        &calld->slices, &tmp);
+  bool did_compress = grpc_msg_compress(
+      exec_ctx, calld->message_compression_algorithm, &calld->slices, &tmp);
   if (did_compress) {
     if (GRPC_TRACER_ON(grpc_compression_trace)) {
       const char *algo_name;
       const size_t before_size = calld->slices.length;
       const size_t after_size = tmp.length;
       const float savings_ratio = 1.0f - (float)after_size / (float)before_size;
-      GPR_ASSERT(grpc_compression_algorithm_name(calld->compression_algorithm,
-                                                 &algo_name));
+      GPR_ASSERT(grpc_message_compression_algorithm_name(
+          calld->message_compression_algorithm, &algo_name));
       gpr_log(GPR_DEBUG, "Compressed[%s] %" PRIuPTR " bytes vs. %" PRIuPTR
                          " bytes (%.2f%% savings)",
               algo_name, before_size, after_size, 100 * savings_ratio);
@@ -259,8 +241,8 @@
   } else {
     if (GRPC_TRACER_ON(grpc_compression_trace)) {
       const char *algo_name;
-      GPR_ASSERT(grpc_compression_algorithm_name(calld->compression_algorithm,
-                                                 &algo_name));
+      GPR_ASSERT(grpc_message_compression_algorithm_name(
+          calld->message_compression_algorithm, &algo_name));
       gpr_log(GPR_DEBUG,
               "Algorithm '%s' enabled but decided not to compress. Input size: "
               "%" PRIuPTR,
@@ -484,12 +466,11 @@
                                      grpc_channel_element_args *args) {
   channel_data *channeld = (channel_data *)elem->channel_data;
 
-  /* Configuration for message compression */
   channeld->enabled_algorithms_bitset =
       grpc_channel_args_compression_algorithm_get_states(args->channel_args);
-
   channeld->default_compression_algorithm =
       grpc_channel_args_get_compression_algorithm(args->channel_args);
+
   /* Make sure the default isn't disabled. */
   if (!GPR_BITGET(channeld->enabled_algorithms_bitset,
                   channeld->default_compression_algorithm)) {
@@ -499,31 +480,18 @@
     channeld->default_compression_algorithm = GRPC_COMPRESS_NONE;
   }
 
-  channeld->supported_compression_algorithms =
+  uint32_t supported_compression_algorithms =
       (((1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1) &
        channeld->enabled_algorithms_bitset) |
       1u;
 
-  /* Configuration for stream compression */
-  channeld->enabled_stream_compression_algorithms_bitset =
-      grpc_channel_args_stream_compression_algorithm_get_states(
-          args->channel_args);
-
-  channeld->default_stream_compression_algorithm =
-      grpc_channel_args_get_stream_compression_algorithm(args->channel_args);
-
-  if (!GPR_BITGET(channeld->enabled_stream_compression_algorithms_bitset,
-                  channeld->default_stream_compression_algorithm)) {
-    gpr_log(GPR_DEBUG,
-            "stream compression algorithm %d not enabled: switching to none",
-            channeld->default_stream_compression_algorithm);
-    channeld->default_stream_compression_algorithm = GRPC_STREAM_COMPRESS_NONE;
-  }
+  channeld->supported_message_compression_algorithms =
+      grpc_compression_bitset_to_message_bitset(
+          supported_compression_algorithms);
 
   channeld->supported_stream_compression_algorithms =
-      (((1u << GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT) - 1) &
-       channeld->enabled_stream_compression_algorithms_bitset) |
-      1u;
+      grpc_compression_bitset_to_stream_bitset(
+          supported_compression_algorithms);
 
   GPR_ASSERT(!args->is_last);
   return GRPC_ERROR_NONE;
diff --git a/src/core/lib/channel/channel_args.cc b/src/core/lib/channel/channel_args.cc
index 30248b3..6998058 100644
--- a/src/core/lib/channel/channel_args.cc
+++ b/src/core/lib/channel/channel_args.cc
@@ -223,21 +223,6 @@
   return GRPC_COMPRESS_NONE;
 }
 
-grpc_stream_compression_algorithm
-grpc_channel_args_get_stream_compression_algorithm(const grpc_channel_args *a) {
-  size_t i;
-  if (a == NULL) return GRPC_STREAM_COMPRESS_NONE;
-  for (i = 0; i < a->num_args; ++i) {
-    if (a->args[i].type == GRPC_ARG_INTEGER &&
-        !strcmp(GRPC_STREAM_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM,
-                a->args[i].key)) {
-      return (grpc_stream_compression_algorithm)a->args[i].value.integer;
-      break;
-    }
-  }
-  return GRPC_STREAM_COMPRESS_NONE;
-}
-
 grpc_channel_args *grpc_channel_args_set_compression_algorithm(
     grpc_channel_args *a, grpc_compression_algorithm algorithm) {
   GPR_ASSERT(algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT);
@@ -248,16 +233,6 @@
   return grpc_channel_args_copy_and_add(a, &tmp, 1);
 }
 
-grpc_channel_args *grpc_channel_args_set_stream_compression_algorithm(
-    grpc_channel_args *a, grpc_stream_compression_algorithm algorithm) {
-  GPR_ASSERT(algorithm < GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT);
-  grpc_arg tmp;
-  tmp.type = GRPC_ARG_INTEGER;
-  tmp.key = (char *)GRPC_STREAM_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM;
-  tmp.value.integer = algorithm;
-  return grpc_channel_args_copy_and_add(a, &tmp, 1);
-}
-
 /** Returns 1 if the argument for compression algorithm's enabled states bitset
  * was found in \a a, returning the arg's value in \a states. Otherwise, returns
  * 0. */
@@ -278,26 +253,6 @@
   return 0; /* GPR_FALSE */
 }
 
-/** Returns 1 if the argument for compression algorithm's enabled states bitset
- * was found in \a a, returning the arg's value in \a states. Otherwise, returns
- * 0. */
-static int find_stream_compression_algorithm_states_bitset(
-    const grpc_channel_args *a, int **states_arg) {
-  if (a != NULL) {
-    size_t i;
-    for (i = 0; i < a->num_args; ++i) {
-      if (a->args[i].type == GRPC_ARG_INTEGER &&
-          !strcmp(GRPC_STREAM_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET,
-                  a->args[i].key)) {
-        *states_arg = &a->args[i].value.integer;
-        **states_arg |= 0x1; /* forcefully enable support for no compression */
-        return 1;
-      }
-    }
-  }
-  return 0; /* GPR_FALSE */
-}
-
 grpc_channel_args *grpc_channel_args_compression_algorithm_set_state(
     grpc_exec_ctx *exec_ctx, grpc_channel_args **a,
     grpc_compression_algorithm algorithm, int state) {
@@ -339,48 +294,6 @@
   return result;
 }
 
-grpc_channel_args *grpc_channel_args_stream_compression_algorithm_set_state(
-    grpc_exec_ctx *exec_ctx, grpc_channel_args **a,
-    grpc_stream_compression_algorithm algorithm, int state) {
-  int *states_arg = NULL;
-  grpc_channel_args *result = *a;
-  const int states_arg_found =
-      find_stream_compression_algorithm_states_bitset(*a, &states_arg);
-
-  if (grpc_channel_args_get_stream_compression_algorithm(*a) == algorithm &&
-      state == 0) {
-    const char *algo_name = NULL;
-    GPR_ASSERT(grpc_stream_compression_algorithm_name(algorithm, &algo_name) !=
-               0);
-    gpr_log(GPR_ERROR,
-            "Tried to disable default stream compression algorithm '%s'. The "
-            "operation has been ignored.",
-            algo_name);
-  } else if (states_arg_found) {
-    if (state != 0) {
-      GPR_BITSET((unsigned *)states_arg, algorithm);
-    } else if (algorithm != GRPC_STREAM_COMPRESS_NONE) {
-      GPR_BITCLEAR((unsigned *)states_arg, algorithm);
-    }
-  } else {
-    /* create a new arg */
-    grpc_arg tmp;
-    tmp.type = GRPC_ARG_INTEGER;
-    tmp.key = (char *)GRPC_STREAM_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET;
-    /* all enabled by default */
-    tmp.value.integer = (1u << GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT) - 1;
-    if (state != 0) {
-      GPR_BITSET((unsigned *)&tmp.value.integer, algorithm);
-    } else if (algorithm != GRPC_STREAM_COMPRESS_NONE) {
-      GPR_BITCLEAR((unsigned *)&tmp.value.integer, algorithm);
-    }
-    result = grpc_channel_args_copy_and_add(*a, &tmp, 1);
-    grpc_channel_args_destroy(exec_ctx, *a);
-    *a = result;
-  }
-  return result;
-}
-
 uint32_t grpc_channel_args_compression_algorithm_get_states(
     const grpc_channel_args *a) {
   int *states_arg;
@@ -391,17 +304,6 @@
   }
 }
 
-uint32_t grpc_channel_args_stream_compression_algorithm_get_states(
-    const grpc_channel_args *a) {
-  int *states_arg;
-  if (find_stream_compression_algorithm_states_bitset(a, &states_arg)) {
-    return (uint32_t)*states_arg;
-  } else {
-    return (1u << GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT) -
-           1; /* All algs. enabled */
-  }
-}
-
 grpc_channel_args *grpc_channel_args_set_socket_mutator(
     grpc_channel_args *a, grpc_socket_mutator *mutator) {
   grpc_arg tmp = grpc_socket_mutator_to_arg(mutator);
diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h
index 2837174..c6a4b00 100644
--- a/src/core/lib/channel/channel_args.h
+++ b/src/core/lib/channel/channel_args.h
@@ -63,24 +63,12 @@
 grpc_compression_algorithm grpc_channel_args_get_compression_algorithm(
     const grpc_channel_args *a);
 
-/** Returns the stream compression algorithm set in \a a. */
-grpc_stream_compression_algorithm
-grpc_channel_args_get_stream_compression_algorithm(const grpc_channel_args *a);
-
 /** Returns a channel arg instance with compression enabled. If \a a is
  * non-NULL, its args are copied. N.B. GRPC_COMPRESS_NONE disables compression
  * for the channel. */
 grpc_channel_args *grpc_channel_args_set_compression_algorithm(
     grpc_channel_args *a, grpc_compression_algorithm algorithm);
 
-/** Returns a channel arg instance with stream compression enabled. If \a a is
- * non-NULL, its args are copied. N.B. GRPC_STREAM_COMPRESS_NONE disables
- * stream compression for the channel. If a value other than
- * GRPC_STREAM_COMPRESS_NONE is set, it takes precedence over message-wise
- * compression algorithms. */
-grpc_channel_args *grpc_channel_args_set_stream_compression_algorithm(
-    grpc_channel_args *a, grpc_stream_compression_algorithm algorithm);
-
 /** Sets the support for the given compression algorithm. By default, all
  * compression algorithms are enabled. It's an error to disable an algorithm set
  * by grpc_channel_args_set_compression_algorithm.
@@ -92,17 +80,6 @@
     grpc_exec_ctx *exec_ctx, grpc_channel_args **a,
     grpc_compression_algorithm algorithm, int enabled);
 
-/** Sets the support for the given stream compression algorithm. By default, all
- * stream compression algorithms are enabled. It's an error to disable an
- * algorithm set by grpc_channel_args_set_stream_compression_algorithm.
- *
- * Returns an instance with the updated algorithm states. The \a a pointer is
- * modified to point to the returned instance (which may be different from the
- * input value of \a a). */
-grpc_channel_args *grpc_channel_args_stream_compression_algorithm_set_state(
-    grpc_exec_ctx *exec_ctx, grpc_channel_args **a,
-    grpc_stream_compression_algorithm algorithm, int enabled);
-
 /** Returns the bitset representing the support state (true for enabled, false
  * for disabled) for compression algorithms.
  *
@@ -111,14 +88,6 @@
 uint32_t grpc_channel_args_compression_algorithm_get_states(
     const grpc_channel_args *a);
 
-/** Returns the bitset representing the support state (true for enabled, false
- * for disabled) for stream compression algorithms.
- *
- * The i-th bit of the returned bitset corresponds to the i-th entry in the
- * grpc_stream_compression_algorithm enum. */
-uint32_t grpc_channel_args_stream_compression_algorithm_get_states(
-    const grpc_channel_args *a);
-
 int grpc_channel_args_compare(const grpc_channel_args *a,
                               const grpc_channel_args *b);
 
diff --git a/src/core/lib/compression/algorithm_metadata.h b/src/core/lib/compression/algorithm_metadata.h
index 3eb7088..23333ac 100644
--- a/src/core/lib/compression/algorithm_metadata.h
+++ b/src/core/lib/compression/algorithm_metadata.h
@@ -20,6 +20,7 @@
 #define GRPC_CORE_LIB_COMPRESSION_ALGORITHM_METADATA_H
 
 #include <grpc/compression.h>
+#include "src/core/lib/compression/compression_internal.h"
 #include "src/core/lib/transport/metadata.h"
 
 #ifdef __cplusplus
@@ -30,14 +31,20 @@
 grpc_slice grpc_compression_algorithm_slice(
     grpc_compression_algorithm algorithm);
 
-/** Return stream compression algorithm based metadata value */
-grpc_slice grpc_stream_compression_algorithm_slice(
-    grpc_stream_compression_algorithm algorithm);
+/** Find compression algorithm based on passed in mdstr - returns
+ *  GRPC_COMPRESS_ALGORITHM_COUNT on failure */
+grpc_compression_algorithm grpc_compression_algorithm_from_slice(
+    grpc_slice str);
 
-/** Return compression algorithm based metadata element (grpc-encoding: xxx) */
+/** Return compression algorithm based metadata element */
 grpc_mdelem grpc_compression_encoding_mdelem(
     grpc_compression_algorithm algorithm);
 
+/** Return message compression algorithm based metadata element (grpc-encoding:
+ * xxx) */
+grpc_mdelem grpc_message_compression_encoding_mdelem(
+    grpc_message_compression_algorithm algorithm);
+
 /** Return stream compression algorithm based metadata element
  * (content-encoding: xxx) */
 grpc_mdelem grpc_stream_compression_encoding_mdelem(
@@ -45,8 +52,8 @@
 
 /** Find compression algorithm based on passed in mdstr - returns
  * GRPC_COMPRESS_ALGORITHM_COUNT on failure */
-grpc_compression_algorithm grpc_compression_algorithm_from_slice(
-    grpc_slice str);
+grpc_message_compression_algorithm
+grpc_message_compression_algorithm_from_slice(grpc_slice str);
 
 /** Find stream compression algorithm based on passed in mdstr - returns
  * GRPC_STREAM_COMPRESS_ALGORITHM_COUNT on failure */
diff --git a/src/core/lib/compression/compression.cc b/src/core/lib/compression/compression.cc
index 1cfac23..31349a5 100644
--- a/src/core/lib/compression/compression.cc
+++ b/src/core/lib/compression/compression.cc
@@ -23,40 +23,40 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/lib/compression/algorithm_metadata.h"
+#include "src/core/lib/compression/compression_internal.h"
 #include "src/core/lib/surface/api_trace.h"
 #include "src/core/lib/transport/static_metadata.h"
 
+int grpc_compression_algorithm_is_message(
+    grpc_compression_algorithm algorithm) {
+  return (algorithm >= GRPC_COMPRESS_MESSAGE_DEFLATE &&
+          algorithm <= GRPC_COMPRESS_MESSAGE_GZIP)
+             ? 1
+             : 0;
+}
+
+int grpc_compression_algorithm_is_stream(grpc_compression_algorithm algorithm) {
+  return (algorithm == GRPC_COMPRESS_STREAM_GZIP) ? 1 : 0;
+}
+
 int grpc_compression_algorithm_parse(grpc_slice name,
                                      grpc_compression_algorithm *algorithm) {
-  /* we use strncmp not only because it's safer (even though in this case it
-   * doesn't matter, given that we are comparing against string literals, but
-   * because this way we needn't have "name" nil-terminated (useful for slice
-   * data, for example) */
   if (grpc_slice_eq(name, GRPC_MDSTR_IDENTITY)) {
     *algorithm = GRPC_COMPRESS_NONE;
     return 1;
-  } else if (grpc_slice_eq(name, GRPC_MDSTR_GZIP)) {
-    *algorithm = GRPC_COMPRESS_GZIP;
-    return 1;
   } else if (grpc_slice_eq(name, GRPC_MDSTR_DEFLATE)) {
-    *algorithm = GRPC_COMPRESS_DEFLATE;
-    return 1;
-  } else {
-    return 0;
-  }
-}
-
-int grpc_stream_compression_algorithm_parse(
-    grpc_slice name, grpc_stream_compression_algorithm *algorithm) {
-  if (grpc_slice_eq(name, GRPC_MDSTR_IDENTITY)) {
-    *algorithm = GRPC_STREAM_COMPRESS_NONE;
+    *algorithm = GRPC_COMPRESS_MESSAGE_DEFLATE;
     return 1;
   } else if (grpc_slice_eq(name, GRPC_MDSTR_GZIP)) {
-    *algorithm = GRPC_STREAM_COMPRESS_GZIP;
+    *algorithm = GRPC_COMPRESS_MESSAGE_GZIP;
+    return 1;
+  } else if (grpc_slice_eq(name, GRPC_MDSTR_STREAM_GZIP)) {
+    *algorithm = GRPC_COMPRESS_STREAM_GZIP;
     return 1;
   } else {
     return 0;
   }
+  return 0;
 }
 
 int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm,
@@ -67,113 +67,53 @@
     case GRPC_COMPRESS_NONE:
       *name = "identity";
       return 1;
-    case GRPC_COMPRESS_DEFLATE:
+    case GRPC_COMPRESS_MESSAGE_DEFLATE:
       *name = "deflate";
       return 1;
-    case GRPC_COMPRESS_GZIP:
+    case GRPC_COMPRESS_MESSAGE_GZIP:
       *name = "gzip";
       return 1;
+    case GRPC_COMPRESS_STREAM_GZIP:
+      *name = "stream-gzip";
+      return 1;
     case GRPC_COMPRESS_ALGORITHMS_COUNT:
       return 0;
   }
   return 0;
 }
 
-int grpc_stream_compression_algorithm_name(
-    grpc_stream_compression_algorithm algorithm, const char **name) {
-  GRPC_API_TRACE(
-      "grpc_stream_compression_algorithm_parse(algorithm=%d, name=%p)", 2,
-      ((int)algorithm, name));
-  switch (algorithm) {
-    case GRPC_STREAM_COMPRESS_NONE:
-      *name = "identity";
-      return 1;
-    case GRPC_STREAM_COMPRESS_GZIP:
-      *name = "gzip";
-      return 1;
-    case GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT:
-      return 0;
+grpc_compression_algorithm grpc_compression_algorithm_for_level(
+    grpc_compression_level level, uint32_t accepted_encodings) {
+  grpc_compression_algorithm algo;
+  if (level == GRPC_COMPRESS_LEVEL_NONE) {
+    return GRPC_COMPRESS_NONE;
+  } else if (level <= GRPC_COMPRESS_LEVEL_MESSAGE_HIGH) {
+    GPR_ASSERT(
+        grpc_compression_algorithm_from_message_stream_compression_algorithm(
+            &algo,
+            grpc_message_compression_algorithm_for_level(
+                grpc_compression_level_to_message_compression_level(level),
+                grpc_compression_bitset_to_message_bitset(accepted_encodings)),
+            (grpc_stream_compression_algorithm)0));
+    return algo;
+  } else if (level <= GRPC_COMPRESS_LEVEL_STREAM_HIGH) {
+    GPR_ASSERT(
+        grpc_compression_algorithm_from_message_stream_compression_algorithm(
+            &algo, (grpc_message_compression_algorithm)0,
+            grpc_stream_compression_algorithm_for_level(
+                grpc_compression_level_to_stream_compression_level(level),
+                grpc_compression_bitset_to_stream_bitset(accepted_encodings))));
+    return algo;
+  } else {
+    gpr_log(GPR_ERROR, "Unknown compression level: %d", level);
+    return GRPC_COMPRESS_NONE;
   }
-  return 0;
-}
-
-grpc_compression_algorithm grpc_compression_algorithm_from_slice(
-    grpc_slice str) {
-  if (grpc_slice_eq(str, GRPC_MDSTR_IDENTITY)) return GRPC_COMPRESS_NONE;
-  if (grpc_slice_eq(str, GRPC_MDSTR_DEFLATE)) return GRPC_COMPRESS_DEFLATE;
-  if (grpc_slice_eq(str, GRPC_MDSTR_GZIP)) return GRPC_COMPRESS_GZIP;
-  return GRPC_COMPRESS_ALGORITHMS_COUNT;
-}
-
-grpc_stream_compression_algorithm grpc_stream_compression_algorithm_from_slice(
-    grpc_slice str) {
-  if (grpc_slice_eq(str, GRPC_MDSTR_IDENTITY)) return GRPC_STREAM_COMPRESS_NONE;
-  if (grpc_slice_eq(str, GRPC_MDSTR_GZIP)) return GRPC_STREAM_COMPRESS_GZIP;
-  return GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT;
-}
-
-grpc_slice grpc_compression_algorithm_slice(
-    grpc_compression_algorithm algorithm) {
-  switch (algorithm) {
-    case GRPC_COMPRESS_NONE:
-      return GRPC_MDSTR_IDENTITY;
-    case GRPC_COMPRESS_DEFLATE:
-      return GRPC_MDSTR_DEFLATE;
-    case GRPC_COMPRESS_GZIP:
-      return GRPC_MDSTR_GZIP;
-    case GRPC_COMPRESS_ALGORITHMS_COUNT:
-      return grpc_empty_slice();
-  }
-  return grpc_empty_slice();
-}
-
-grpc_slice grpc_stream_compression_algorithm_slice(
-    grpc_stream_compression_algorithm algorithm) {
-  switch (algorithm) {
-    case GRPC_STREAM_COMPRESS_NONE:
-      return GRPC_MDSTR_IDENTITY;
-    case GRPC_STREAM_COMPRESS_GZIP:
-      return GRPC_MDSTR_GZIP;
-    case GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT:
-      return grpc_empty_slice();
-  }
-  return grpc_empty_slice();
-}
-
-grpc_mdelem grpc_compression_encoding_mdelem(
-    grpc_compression_algorithm algorithm) {
-  switch (algorithm) {
-    case GRPC_COMPRESS_NONE:
-      return GRPC_MDELEM_GRPC_ENCODING_IDENTITY;
-    case GRPC_COMPRESS_DEFLATE:
-      return GRPC_MDELEM_GRPC_ENCODING_DEFLATE;
-    case GRPC_COMPRESS_GZIP:
-      return GRPC_MDELEM_GRPC_ENCODING_GZIP;
-    default:
-      break;
-  }
-  return GRPC_MDNULL;
-}
-
-grpc_mdelem grpc_stream_compression_encoding_mdelem(
-    grpc_stream_compression_algorithm algorithm) {
-  switch (algorithm) {
-    case GRPC_STREAM_COMPRESS_NONE:
-      return GRPC_MDELEM_CONTENT_ENCODING_IDENTITY;
-    case GRPC_STREAM_COMPRESS_GZIP:
-      return GRPC_MDELEM_CONTENT_ENCODING_GZIP;
-    default:
-      break;
-  }
-  return GRPC_MDNULL;
 }
 
 void grpc_compression_options_init(grpc_compression_options *opts) {
   memset(opts, 0, sizeof(*opts));
   /* all enabled by default */
   opts->enabled_algorithms_bitset = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1;
-  opts->enabled_stream_compression_algorithms_bitset =
-      (1u << GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT) - 1;
 }
 
 void grpc_compression_options_enable_algorithm(
@@ -192,92 +132,47 @@
   return GPR_BITGET(opts->enabled_algorithms_bitset, algorithm);
 }
 
-int grpc_compression_options_is_stream_compression_algorithm_enabled(
-    const grpc_compression_options *opts,
-    grpc_stream_compression_algorithm algorithm) {
-  return GPR_BITGET(opts->enabled_stream_compression_algorithms_bitset,
-                    algorithm);
+grpc_slice grpc_compression_algorithm_slice(
+    grpc_compression_algorithm algorithm) {
+  switch (algorithm) {
+    case GRPC_COMPRESS_NONE:
+      return GRPC_MDSTR_IDENTITY;
+    case GRPC_COMPRESS_MESSAGE_DEFLATE:
+      return GRPC_MDSTR_DEFLATE;
+    case GRPC_COMPRESS_MESSAGE_GZIP:
+      return GRPC_MDSTR_GZIP;
+    case GRPC_COMPRESS_STREAM_GZIP:
+      return GRPC_MDSTR_STREAM_GZIP;
+    case GRPC_COMPRESS_ALGORITHMS_COUNT:
+      return grpc_empty_slice();
+  }
+  return grpc_empty_slice();
 }
 
-/* TODO(dgq): Add the ability to specify parameters to the individual
- * compression algorithms */
-grpc_compression_algorithm grpc_compression_algorithm_for_level(
-    grpc_compression_level level, uint32_t accepted_encodings) {
-  GRPC_API_TRACE("grpc_compression_algorithm_for_level(level=%d)", 1,
-                 ((int)level));
-  if (level > GRPC_COMPRESS_LEVEL_HIGH) {
-    gpr_log(GPR_ERROR, "Unknown compression level %d.", (int)level);
-    abort();
-  }
-
-  const size_t num_supported =
-      GPR_BITCOUNT(accepted_encodings) - 1; /* discard NONE */
-  if (level == GRPC_COMPRESS_LEVEL_NONE || num_supported == 0) {
-    return GRPC_COMPRESS_NONE;
-  }
-
-  GPR_ASSERT(level > 0);
-
-  /* Establish a "ranking" or compression algorithms in increasing order of
-   * compression.
-   * This is simplistic and we will probably want to introduce other dimensions
-   * in the future (cpu/memory cost, etc). */
-  const grpc_compression_algorithm algos_ranking[] = {GRPC_COMPRESS_GZIP,
-                                                      GRPC_COMPRESS_DEFLATE};
-
-  /* intersect algos_ranking with the supported ones keeping the ranked order */
-  grpc_compression_algorithm
-      sorted_supported_algos[GRPC_COMPRESS_ALGORITHMS_COUNT];
-  size_t algos_supported_idx = 0;
-  for (size_t i = 0; i < GPR_ARRAY_SIZE(algos_ranking); i++) {
-    const grpc_compression_algorithm alg = algos_ranking[i];
-    for (size_t j = 0; j < num_supported; j++) {
-      if (GPR_BITGET(accepted_encodings, alg) == 1) {
-        /* if \a alg in supported */
-        sorted_supported_algos[algos_supported_idx++] = alg;
-        break;
-      }
-    }
-    if (algos_supported_idx == num_supported) break;
-  }
-
-  switch (level) {
-    case GRPC_COMPRESS_LEVEL_NONE:
-      abort(); /* should have been handled already */
-    case GRPC_COMPRESS_LEVEL_LOW:
-      return sorted_supported_algos[0];
-    case GRPC_COMPRESS_LEVEL_MED:
-      return sorted_supported_algos[num_supported / 2];
-    case GRPC_COMPRESS_LEVEL_HIGH:
-      return sorted_supported_algos[num_supported - 1];
-    default:
-      abort();
-  };
+grpc_compression_algorithm grpc_compression_algorithm_from_slice(
+    grpc_slice str) {
+  if (grpc_slice_eq(str, GRPC_MDSTR_IDENTITY)) return GRPC_COMPRESS_NONE;
+  if (grpc_slice_eq(str, GRPC_MDSTR_DEFLATE))
+    return GRPC_COMPRESS_MESSAGE_DEFLATE;
+  if (grpc_slice_eq(str, GRPC_MDSTR_GZIP)) return GRPC_COMPRESS_MESSAGE_GZIP;
+  if (grpc_slice_eq(str, GRPC_MDSTR_STREAM_GZIP))
+    return GRPC_COMPRESS_STREAM_GZIP;
+  return GRPC_COMPRESS_ALGORITHMS_COUNT;
 }
 
-GRPCAPI grpc_stream_compression_algorithm
-grpc_stream_compression_algorithm_for_level(
-    grpc_stream_compression_level level, uint32_t accepted_stream_encodings) {
-  GRPC_API_TRACE("grpc_stream_compression_algorithm_for_level(level=%d)", 1,
-                 ((int)level));
-  if (level > GRPC_STREAM_COMPRESS_LEVEL_HIGH) {
-    gpr_log(GPR_ERROR, "Unknown compression level %d.", (int)level);
-    abort();
-  }
-
-  switch (level) {
-    case GRPC_STREAM_COMPRESS_LEVEL_NONE:
-      return GRPC_STREAM_COMPRESS_NONE;
-    case GRPC_STREAM_COMPRESS_LEVEL_LOW:
-    case GRPC_STREAM_COMPRESS_LEVEL_MED:
-    case GRPC_STREAM_COMPRESS_LEVEL_HIGH:
-      if (GPR_BITGET(accepted_stream_encodings, GRPC_STREAM_COMPRESS_GZIP) ==
-          1) {
-        return GRPC_STREAM_COMPRESS_GZIP;
-      } else {
-        return GRPC_STREAM_COMPRESS_NONE;
-      }
+grpc_mdelem grpc_compression_encoding_mdelem(
+    grpc_compression_algorithm algorithm) {
+  switch (algorithm) {
+    case GRPC_COMPRESS_NONE:
+      return GRPC_MDELEM_GRPC_ENCODING_IDENTITY;
+    case GRPC_COMPRESS_MESSAGE_DEFLATE:
+      return GRPC_MDELEM_GRPC_ENCODING_DEFLATE;
+    case GRPC_COMPRESS_MESSAGE_GZIP:
+      return GRPC_MDELEM_GRPC_ENCODING_GZIP;
+    case GRPC_COMPRESS_STREAM_GZIP:
+      return GRPC_MDELEM_GRPC_ENCODING_GZIP;
     default:
-      abort();
+      break;
   }
+  return GRPC_MDNULL;
 }
diff --git a/src/core/lib/compression/compression_internal.cc b/src/core/lib/compression/compression_internal.cc
new file mode 100644
index 0000000..e31eb83
--- /dev/null
+++ b/src/core/lib/compression/compression_internal.cc
@@ -0,0 +1,313 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <grpc/compression.h>
+#include <grpc/support/useful.h>
+
+#include "src/core/lib/compression/algorithm_metadata.h"
+#include "src/core/lib/compression/compression_internal.h"
+#include "src/core/lib/surface/api_trace.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+/* Interfaces related to MD */
+
+grpc_message_compression_algorithm
+grpc_message_compression_algorithm_from_slice(grpc_slice str) {
+  if (grpc_slice_eq(str, GRPC_MDSTR_IDENTITY))
+    return GRPC_MESSAGE_COMPRESS_NONE;
+  if (grpc_slice_eq(str, GRPC_MDSTR_DEFLATE))
+    return GRPC_MESSAGE_COMPRESS_DEFLATE;
+  if (grpc_slice_eq(str, GRPC_MDSTR_GZIP)) return GRPC_MESSAGE_COMPRESS_GZIP;
+  return GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT;
+}
+
+grpc_stream_compression_algorithm grpc_stream_compression_algorithm_from_slice(
+    grpc_slice str) {
+  if (grpc_slice_eq(str, GRPC_MDSTR_IDENTITY)) return GRPC_STREAM_COMPRESS_NONE;
+  if (grpc_slice_eq(str, GRPC_MDSTR_GZIP)) return GRPC_STREAM_COMPRESS_GZIP;
+  return GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT;
+}
+
+grpc_mdelem grpc_message_compression_encoding_mdelem(
+    grpc_message_compression_algorithm algorithm) {
+  switch (algorithm) {
+    case GRPC_MESSAGE_COMPRESS_NONE:
+      return GRPC_MDELEM_GRPC_ENCODING_IDENTITY;
+    case GRPC_MESSAGE_COMPRESS_DEFLATE:
+      return GRPC_MDELEM_GRPC_ENCODING_DEFLATE;
+    case GRPC_MESSAGE_COMPRESS_GZIP:
+      return GRPC_MDELEM_GRPC_ENCODING_GZIP;
+    default:
+      break;
+  }
+  return GRPC_MDNULL;
+}
+
+grpc_mdelem grpc_stream_compression_encoding_mdelem(
+    grpc_stream_compression_algorithm algorithm) {
+  switch (algorithm) {
+    case GRPC_STREAM_COMPRESS_NONE:
+      return GRPC_MDELEM_CONTENT_ENCODING_IDENTITY;
+    case GRPC_STREAM_COMPRESS_GZIP:
+      return GRPC_MDELEM_CONTENT_ENCODING_GZIP;
+    default:
+      break;
+  }
+  return GRPC_MDNULL;
+}
+
+/* Interfaces performing transformation between compression algorithms and
+ * levels. */
+grpc_message_compression_level
+grpc_compression_level_to_message_compression_level(
+    grpc_compression_level level) {
+  if (level >= GRPC_COMPRESS_LEVEL_COUNT) {
+    return GRPC_MESSAGE_COMPRESS_LEVEL_NONE;
+  }
+  return (grpc_message_compression_level)(
+      (uint32_t)(level - GRPC_COMPRESS_LEVEL_NONE) +
+      (uint32_t)GRPC_MESSAGE_COMPRESS_LEVEL_NONE);
+}
+
+grpc_stream_compression_level
+grpc_compression_level_to_stream_compression_level(
+    grpc_compression_level level) {
+  if (level >= GRPC_COMPRESS_LEVEL_COUNT) {
+    return GRPC_STREAM_COMPRESS_LEVEL_NONE;
+  }
+  return (grpc_stream_compression_level)(
+      (uint32_t)(level - (GRPC_MESSAGE_COMPRESS_LEVEL_COUNT - 1) -
+                 GRPC_COMPRESS_LEVEL_NONE) +
+      (uint32_t)GRPC_STREAM_COMPRESS_LEVEL_NONE);
+}
+
+grpc_message_compression_algorithm
+grpc_compression_algorithm_to_message_compression_algorithm(
+    grpc_compression_algorithm algo) {
+  switch (algo) {
+    case GRPC_COMPRESS_MESSAGE_DEFLATE:
+      return GRPC_MESSAGE_COMPRESS_DEFLATE;
+    case GRPC_COMPRESS_MESSAGE_GZIP:
+      return GRPC_MESSAGE_COMPRESS_GZIP;
+    default:
+      return GRPC_MESSAGE_COMPRESS_NONE;
+  }
+}
+
+grpc_stream_compression_algorithm
+grpc_compression_algorithm_to_stream_compression_algorithm(
+    grpc_compression_algorithm algo) {
+  switch (algo) {
+    case GRPC_COMPRESS_STREAM_GZIP:
+      return GRPC_STREAM_COMPRESS_GZIP;
+    default:
+      return GRPC_STREAM_COMPRESS_NONE;
+  }
+}
+
+uint32_t grpc_compression_bitset_to_message_bitset(uint32_t bitset) {
+  return bitset & ((1u << GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT) - 1);
+}
+
+uint32_t grpc_compression_bitset_to_stream_bitset(uint32_t bitset) {
+  uint32_t identity = (bitset & 1u);
+  uint32_t other_bits =
+      (bitset >> (GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT - 1)) &
+      ((1u << GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT) - 2);
+  return identity | other_bits;
+}
+
+uint32_t grpc_compression_bitset_from_message_stream_compression_bitset(
+    uint32_t message_bitset, uint32_t stream_bitset) {
+  uint32_t offset_stream_bitset =
+      (stream_bitset & 1u) |
+      ((stream_bitset & (~1u)) << (GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT - 1));
+  return message_bitset | offset_stream_bitset;
+}
+
+int grpc_compression_algorithm_from_message_stream_compression_algorithm(
+    grpc_compression_algorithm *algorithm,
+    grpc_message_compression_algorithm message_algorithm,
+    grpc_stream_compression_algorithm stream_algorithm) {
+  if (message_algorithm != GRPC_MESSAGE_COMPRESS_NONE &&
+      stream_algorithm != GRPC_STREAM_COMPRESS_NONE) {
+    *algorithm = GRPC_COMPRESS_NONE;
+    return 0;
+  }
+  if (message_algorithm == GRPC_MESSAGE_COMPRESS_NONE) {
+    switch (stream_algorithm) {
+      case GRPC_STREAM_COMPRESS_NONE:
+        *algorithm = GRPC_COMPRESS_NONE;
+        return 1;
+      case GRPC_STREAM_COMPRESS_GZIP:
+        *algorithm = GRPC_COMPRESS_STREAM_GZIP;
+        return 1;
+      default:
+        *algorithm = GRPC_COMPRESS_NONE;
+        return 0;
+    }
+  } else {
+    switch (message_algorithm) {
+      case GRPC_MESSAGE_COMPRESS_NONE:
+        *algorithm = GRPC_COMPRESS_NONE;
+        return 1;
+      case GRPC_MESSAGE_COMPRESS_DEFLATE:
+        *algorithm = GRPC_COMPRESS_MESSAGE_DEFLATE;
+        return 1;
+      case GRPC_MESSAGE_COMPRESS_GZIP:
+        *algorithm = GRPC_COMPRESS_MESSAGE_GZIP;
+        return 1;
+      default:
+        *algorithm = GRPC_COMPRESS_NONE;
+        return 0;
+    }
+  }
+  return 0;
+}
+
+/* Interfaces for message compression. */
+
+int grpc_message_compression_algorithm_name(
+    grpc_message_compression_algorithm algorithm, const char **name) {
+  GRPC_API_TRACE(
+      "grpc_message_compression_algorithm_parse(algorithm=%d, name=%p)", 2,
+      ((int)algorithm, name));
+  switch (algorithm) {
+    case GRPC_MESSAGE_COMPRESS_NONE:
+      *name = "identity";
+      return 1;
+    case GRPC_MESSAGE_COMPRESS_DEFLATE:
+      *name = "deflate";
+      return 1;
+    case GRPC_MESSAGE_COMPRESS_GZIP:
+      *name = "gzip";
+      return 1;
+    case GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT:
+      return 0;
+  }
+  return 0;
+}
+
+/* TODO(dgq): Add the ability to specify parameters to the individual
+ * compression algorithms */
+grpc_message_compression_algorithm grpc_message_compression_algorithm_for_level(
+    grpc_message_compression_level level, uint32_t accepted_encodings) {
+  GRPC_API_TRACE("grpc_message_compression_algorithm_for_level(level=%d)", 1,
+                 ((int)level));
+  if (level > GRPC_MESSAGE_COMPRESS_LEVEL_HIGH) {
+    gpr_log(GPR_ERROR, "Unknown message compression level %d.", (int)level);
+    abort();
+  }
+
+  const size_t num_supported =
+      GPR_BITCOUNT(accepted_encodings) - 1; /* discard NONE */
+  if (level == GRPC_MESSAGE_COMPRESS_LEVEL_NONE || num_supported == 0) {
+    return GRPC_MESSAGE_COMPRESS_NONE;
+  }
+
+  GPR_ASSERT(level > 0);
+
+  /* Establish a "ranking" or compression algorithms in increasing order of
+   * compression.
+   * This is simplistic and we will probably want to introduce other dimensions
+   * in the future (cpu/memory cost, etc). */
+  const grpc_message_compression_algorithm algos_ranking[] = {
+      GRPC_MESSAGE_COMPRESS_GZIP, GRPC_MESSAGE_COMPRESS_DEFLATE};
+
+  /* intersect algos_ranking with the supported ones keeping the ranked order */
+  grpc_message_compression_algorithm
+      sorted_supported_algos[GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT];
+  size_t algos_supported_idx = 0;
+  for (size_t i = 0; i < GPR_ARRAY_SIZE(algos_ranking); i++) {
+    const grpc_message_compression_algorithm alg = algos_ranking[i];
+    for (size_t j = 0; j < num_supported; j++) {
+      if (GPR_BITGET(accepted_encodings, alg) == 1) {
+        /* if \a alg in supported */
+        sorted_supported_algos[algos_supported_idx++] = alg;
+        break;
+      }
+    }
+    if (algos_supported_idx == num_supported) break;
+  }
+
+  switch (level) {
+    case GRPC_MESSAGE_COMPRESS_LEVEL_NONE:
+      abort(); /* should have been handled already */
+    case GRPC_MESSAGE_COMPRESS_LEVEL_LOW:
+      return sorted_supported_algos[0];
+    case GRPC_MESSAGE_COMPRESS_LEVEL_MED:
+      return sorted_supported_algos[num_supported / 2];
+    case GRPC_MESSAGE_COMPRESS_LEVEL_HIGH:
+      return sorted_supported_algos[num_supported - 1];
+    default:
+      abort();
+  };
+}
+
+int grpc_message_compression_algorithm_parse(
+    grpc_slice value, grpc_message_compression_algorithm *algorithm) {
+  if (grpc_slice_eq(value, GRPC_MDSTR_IDENTITY)) {
+    *algorithm = GRPC_MESSAGE_COMPRESS_NONE;
+    return 1;
+  } else if (grpc_slice_eq(value, GRPC_MDSTR_DEFLATE)) {
+    *algorithm = GRPC_MESSAGE_COMPRESS_DEFLATE;
+    return 1;
+  } else if (grpc_slice_eq(value, GRPC_MDSTR_GZIP)) {
+    *algorithm = GRPC_MESSAGE_COMPRESS_GZIP;
+    return 1;
+  } else {
+    return 0;
+  }
+  return 0;
+}
+
+/* Interfaces for stream compression. */
+
+grpc_stream_compression_algorithm grpc_stream_compression_algorithm_for_level(
+    grpc_stream_compression_level level, uint32_t accepted_encodings) {
+  GRPC_API_TRACE("grpc_stream_compression_algorithm_for_level(level=%d)", 1,
+                 ((int)level));
+  if (level > GRPC_STREAM_COMPRESS_LEVEL_HIGH) {
+    gpr_log(GPR_ERROR, "Unknown stream compression level %d.", (int)level);
+    abort();
+  }
+
+  /* TODO(mxyan): Use more sophisticated scheme when more algorithms added. */
+  if (level != GRPC_STREAM_COMPRESS_LEVEL_NONE &&
+      GPR_BITGET(accepted_encodings, GRPC_STREAM_COMPRESS_GZIP)) {
+    return GRPC_STREAM_COMPRESS_GZIP;
+  }
+  return GRPC_STREAM_COMPRESS_NONE;
+}
+
+int grpc_stream_compression_algorithm_parse(
+    grpc_slice value, grpc_stream_compression_algorithm *algorithm) {
+  if (grpc_slice_eq(value, GRPC_MDSTR_IDENTITY)) {
+    *algorithm = GRPC_STREAM_COMPRESS_NONE;
+    return 1;
+  } else if (grpc_slice_eq(value, GRPC_MDSTR_GZIP)) {
+    *algorithm = GRPC_STREAM_COMPRESS_GZIP;
+    return 1;
+  } else {
+    return 0;
+  }
+  return 0;
+}
diff --git a/src/core/lib/compression/compression_internal.h b/src/core/lib/compression/compression_internal.h
new file mode 100644
index 0000000..aab5324
--- /dev/null
+++ b/src/core/lib/compression/compression_internal.h
@@ -0,0 +1,118 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_COMPRESSION_COMPRESSION_INTERNAL_H
+#define GRPC_CORE_LIB_COMPRESSION_COMPRESSION_INTERNAL_H
+
+#include <grpc/impl/codegen/compression_types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+  GRPC_MESSAGE_COMPRESS_NONE = 0,
+  GRPC_MESSAGE_COMPRESS_DEFLATE,
+  GRPC_MESSAGE_COMPRESS_GZIP,
+  /* TODO(ctiller): snappy */
+  GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT
+} grpc_message_compression_algorithm;
+
+/** Stream compresssion algorithms supported by gRPC */
+typedef enum {
+  GRPC_STREAM_COMPRESS_NONE = 0,
+  GRPC_STREAM_COMPRESS_GZIP,
+  GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT
+} grpc_stream_compression_algorithm;
+
+/** Compression levels allow a party with knowledge of its peer's accepted
+ * encodings to request compression in an abstract way. The level-algorithm
+ * mapping is performed internally and depends on the peer's supported
+ * compression algorithms. */
+typedef enum {
+  GRPC_MESSAGE_COMPRESS_LEVEL_NONE = 0,
+  GRPC_MESSAGE_COMPRESS_LEVEL_LOW,
+  GRPC_MESSAGE_COMPRESS_LEVEL_MED,
+  GRPC_MESSAGE_COMPRESS_LEVEL_HIGH,
+  GRPC_MESSAGE_COMPRESS_LEVEL_COUNT
+} grpc_message_compression_level;
+
+/** Compression levels for stream compression algorithms */
+typedef enum {
+  GRPC_STREAM_COMPRESS_LEVEL_NONE = 0,
+  GRPC_STREAM_COMPRESS_LEVEL_LOW,
+  GRPC_STREAM_COMPRESS_LEVEL_MED,
+  GRPC_STREAM_COMPRESS_LEVEL_HIGH,
+  GRPC_STREAM_COMPRESS_LEVEL_COUNT
+} grpc_stream_compression_level;
+
+/* Interfaces performing transformation between compression algorithms and
+ * levels. */
+
+grpc_message_compression_level
+grpc_compression_level_to_message_compression_level(
+    grpc_compression_level level);
+
+grpc_stream_compression_level
+grpc_compression_level_to_stream_compression_level(
+    grpc_compression_level level);
+
+grpc_message_compression_algorithm
+grpc_compression_algorithm_to_message_compression_algorithm(
+    grpc_compression_algorithm algo);
+
+grpc_stream_compression_algorithm
+grpc_compression_algorithm_to_stream_compression_algorithm(
+    grpc_compression_algorithm algo);
+
+uint32_t grpc_compression_bitset_to_message_bitset(uint32_t bitset);
+
+uint32_t grpc_compression_bitset_to_stream_bitset(uint32_t bitset);
+
+uint32_t grpc_compression_bitset_from_message_stream_compression_bitset(
+    uint32_t message_bitset, uint32_t stream_bitset);
+
+int grpc_compression_algorithm_from_message_stream_compression_algorithm(
+    grpc_compression_algorithm *algorithm,
+    grpc_message_compression_algorithm message_algorithm,
+    grpc_stream_compression_algorithm stream_algorithm);
+
+/* Interfaces for message compression. */
+
+int grpc_message_compression_algorithm_name(
+    grpc_message_compression_algorithm algorithm, const char **name);
+
+grpc_message_compression_algorithm grpc_message_compression_algorithm_for_level(
+    grpc_message_compression_level level, uint32_t accepted_encodings);
+
+int grpc_message_compression_algorithm_parse(
+    grpc_slice value, grpc_message_compression_algorithm *algorithm);
+
+/* Interfaces for stream compression. */
+
+grpc_stream_compression_algorithm grpc_stream_compression_algorithm_for_level(
+    grpc_stream_compression_level level, uint32_t accepted_encodings);
+
+int grpc_stream_compression_algorithm_parse(
+    grpc_slice value, grpc_stream_compression_algorithm *algorithm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_CORE_LIB_COMPRESSION_COMPRESSION_INTERNAL_H */
diff --git a/src/core/lib/compression/message_compress.cc b/src/core/lib/compression/message_compress.cc
index c051e28..d174992 100644
--- a/src/core/lib/compression/message_compress.cc
+++ b/src/core/lib/compression/message_compress.cc
@@ -143,18 +143,18 @@
 }
 
 static int compress_inner(grpc_exec_ctx* exec_ctx,
-                          grpc_compression_algorithm algorithm,
+                          grpc_message_compression_algorithm algorithm,
                           grpc_slice_buffer* input, grpc_slice_buffer* output) {
   switch (algorithm) {
-    case GRPC_COMPRESS_NONE:
+    case GRPC_MESSAGE_COMPRESS_NONE:
       /* the fallback path always needs to be send uncompressed: we simply
          rely on that here */
       return 0;
-    case GRPC_COMPRESS_DEFLATE:
+    case GRPC_MESSAGE_COMPRESS_DEFLATE:
       return zlib_compress(exec_ctx, input, output, 0);
-    case GRPC_COMPRESS_GZIP:
+    case GRPC_MESSAGE_COMPRESS_GZIP:
       return zlib_compress(exec_ctx, input, output, 1);
-    case GRPC_COMPRESS_ALGORITHMS_COUNT:
+    case GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT:
       break;
   }
   gpr_log(GPR_ERROR, "invalid compression algorithm %d", algorithm);
@@ -162,7 +162,7 @@
 }
 
 int grpc_msg_compress(grpc_exec_ctx* exec_ctx,
-                      grpc_compression_algorithm algorithm,
+                      grpc_message_compression_algorithm algorithm,
                       grpc_slice_buffer* input, grpc_slice_buffer* output) {
   if (!compress_inner(exec_ctx, algorithm, input, output)) {
     copy(input, output);
@@ -172,16 +172,16 @@
 }
 
 int grpc_msg_decompress(grpc_exec_ctx* exec_ctx,
-                        grpc_compression_algorithm algorithm,
+                        grpc_message_compression_algorithm algorithm,
                         grpc_slice_buffer* input, grpc_slice_buffer* output) {
   switch (algorithm) {
-    case GRPC_COMPRESS_NONE:
+    case GRPC_MESSAGE_COMPRESS_NONE:
       return copy(input, output);
-    case GRPC_COMPRESS_DEFLATE:
+    case GRPC_MESSAGE_COMPRESS_DEFLATE:
       return zlib_decompress(exec_ctx, input, output, 0);
-    case GRPC_COMPRESS_GZIP:
+    case GRPC_MESSAGE_COMPRESS_GZIP:
       return zlib_decompress(exec_ctx, input, output, 1);
-    case GRPC_COMPRESS_ALGORITHMS_COUNT:
+    case GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT:
       break;
   }
   gpr_log(GPR_ERROR, "invalid compression algorithm %d", algorithm);
diff --git a/src/core/lib/compression/message_compress.h b/src/core/lib/compression/message_compress.h
index d2545a0..7c2eb99 100644
--- a/src/core/lib/compression/message_compress.h
+++ b/src/core/lib/compression/message_compress.h
@@ -19,9 +19,10 @@
 #ifndef GRPC_CORE_LIB_COMPRESSION_MESSAGE_COMPRESS_H
 #define GRPC_CORE_LIB_COMPRESSION_MESSAGE_COMPRESS_H
 
-#include <grpc/compression.h>
 #include <grpc/slice_buffer.h>
 
+#include "src/core/lib/compression/compression_internal.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -30,18 +31,18 @@
    On success, appends compressed slices to output and returns 1.
    On failure, appends uncompressed slices to output and returns 0. */
 int grpc_msg_compress(grpc_exec_ctx* exec_ctx,
-                      grpc_compression_algorithm algorithm,
+                      grpc_message_compression_algorithm algorithm,
                       grpc_slice_buffer* input, grpc_slice_buffer* output);
 
 /* decompress 'input' to 'output' using 'algorithm'.
    On success, appends slices to output and returns 1.
    On failure, output is unchanged, and returns 0. */
 int grpc_msg_decompress(grpc_exec_ctx* exec_ctx,
-                        grpc_compression_algorithm algorithm,
+                        grpc_message_compression_algorithm algorithm,
                         grpc_slice_buffer* input, grpc_slice_buffer* output);
 
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* GRPC_CORE_LIB_COMPRESSION_MESSAGE_COMPRESS_H */
\ No newline at end of file
+#endif /* GRPC_CORE_LIB_COMPRESSION_MESSAGE_COMPRESS_H */
diff --git a/src/core/lib/slice/slice_string_helpers.cc b/src/core/lib/slice/slice_string_helpers.cc
index d461c47..3f054da 100644
--- a/src/core/lib/slice/slice_string_helpers.cc
+++ b/src/core/lib/slice/slice_string_helpers.cc
@@ -56,24 +56,59 @@
   return 0;
 }
 
-void grpc_slice_split(grpc_slice str, const char *sep, grpc_slice_buffer *dst) {
+static void skip_leading_trailing_spaces(const uint8_t *str_buffer,
+                                         size_t *begin, size_t *end) {
+  while (*begin < *end && str_buffer[*begin] == ' ') {
+    (*begin)++;
+  }
+  while (*begin < *end && str_buffer[*end - 1] == ' ') {
+    (*end)--;
+  }
+}
+
+static void grpc_slice_split_inner(grpc_slice str, const char *sep,
+                                   grpc_slice_buffer *dst, bool no_space) {
   const size_t sep_len = strlen(sep);
   size_t begin, end;
+  const uint8_t *str_buffer = GRPC_SLICE_START_PTR(str);
+  size_t sep_pos;
 
   GPR_ASSERT(sep_len > 0);
 
   if (slice_find_separator_offset(str, sep, 0, &begin, &end) != 0) {
     do {
+      sep_pos = end;
+      if (no_space) {
+        skip_leading_trailing_spaces(str_buffer, &begin, &end);
+      }
       grpc_slice_buffer_add_indexed(dst, grpc_slice_sub(str, begin, end));
-    } while (slice_find_separator_offset(str, sep, end + sep_len, &begin,
+    } while (slice_find_separator_offset(str, sep, sep_pos + sep_len, &begin,
                                          &end) != 0);
-    grpc_slice_buffer_add_indexed(
-        dst, grpc_slice_sub(str, end + sep_len, GRPC_SLICE_LENGTH(str)));
+    begin = sep_pos + sep_len;
+    end = GRPC_SLICE_LENGTH(str);
+    if (no_space) {
+      skip_leading_trailing_spaces(str_buffer, &begin, &end);
+    }
+    grpc_slice_buffer_add_indexed(dst, grpc_slice_sub(str, begin, end));
   } else { /* no sep found, add whole input */
-    grpc_slice_buffer_add_indexed(dst, grpc_slice_ref_internal(str));
+    begin = 0;
+    end = GRPC_SLICE_LENGTH(str);
+    if (no_space) {
+      skip_leading_trailing_spaces(str_buffer, &begin, &end);
+    }
+    grpc_slice_buffer_add_indexed(dst, grpc_slice_sub(str, begin, end));
   }
 }
 
+void grpc_slice_split(grpc_slice str, const char *sep, grpc_slice_buffer *dst) {
+  grpc_slice_split_inner(str, sep, dst, false);
+}
+
+void grpc_slice_split_without_space(grpc_slice str, const char *sep,
+                                    grpc_slice_buffer *dst) {
+  grpc_slice_split_inner(str, sep, dst, true);
+}
+
 bool grpc_parse_slice_to_uint32(grpc_slice str, uint32_t *result) {
   return gpr_parse_bytes_to_uint32((const char *)GRPC_SLICE_START_PTR(str),
                                    GRPC_SLICE_LENGTH(str), result) != 0;
diff --git a/src/core/lib/slice/slice_string_helpers.h b/src/core/lib/slice/slice_string_helpers.h
index bcfb33b..c034eb3 100644
--- a/src/core/lib/slice/slice_string_helpers.h
+++ b/src/core/lib/slice/slice_string_helpers.h
@@ -39,6 +39,12 @@
  * should be a properly initialized instance. */
 void grpc_slice_split(grpc_slice str, const char *sep, grpc_slice_buffer *dst);
 
+/** Split \a str by the separator \a sep and remove the leading and trailing
+ * spaces of each resulting token. Results are stored in \a dst, which should be
+ * a properly initialized instance. */
+void grpc_slice_split_without_space(grpc_slice str, const char *sep,
+                                    grpc_slice_buffer *dst);
+
 bool grpc_parse_slice_to_uint32(grpc_slice str, uint32_t *result);
 
 #ifdef __cplusplus
diff --git a/src/core/lib/surface/byte_buffer_reader.cc b/src/core/lib/surface/byte_buffer_reader.cc
index 87bd323..373ee1f 100644
--- a/src/core/lib/surface/byte_buffer_reader.cc
+++ b/src/core/lib/surface/byte_buffer_reader.cc
@@ -49,10 +49,12 @@
     case GRPC_BB_RAW:
       grpc_slice_buffer_init(&decompressed_slices_buffer);
       if (is_compressed(reader->buffer_in)) {
-        if (grpc_msg_decompress(&exec_ctx,
-                                reader->buffer_in->data.raw.compression,
-                                &reader->buffer_in->data.raw.slice_buffer,
-                                &decompressed_slices_buffer) == 0) {
+        if (grpc_msg_decompress(
+                &exec_ctx,
+                grpc_compression_algorithm_to_message_compression_algorithm(
+                    reader->buffer_in->data.raw.compression),
+                &reader->buffer_in->data.raw.slice_buffer,
+                &decompressed_slices_buffer) == 0) {
           gpr_log(GPR_ERROR,
                   "Unexpected error decompressing data for algorithm with enum "
                   "value '%d'.",
diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc
index 8216aa0..781100d 100644
--- a/src/core/lib/surface/call.cc
+++ b/src/core/lib/surface/call.cc
@@ -201,7 +201,7 @@
   grpc_call_final_info final_info;
 
   /* Compression algorithm for *incoming* data */
-  grpc_compression_algorithm incoming_compression_algorithm;
+  grpc_message_compression_algorithm incoming_message_compression_algorithm;
   /* Stream compression algorithm for *incoming* data */
   grpc_stream_compression_algorithm incoming_stream_compression_algorithm;
   /* Supported encodings (compression algorithms), a bitset */
@@ -345,7 +345,7 @@
   call->cq = args->cq;
   call->start_time = gpr_now(GPR_CLOCK_MONOTONIC);
   /* Always support no compression */
-  GPR_BITSET(&call->encodings_accepted_by_peer, GRPC_COMPRESS_NONE);
+  GPR_BITSET(&call->encodings_accepted_by_peer, GRPC_MESSAGE_COMPRESS_NONE);
   call->is_client = args->server_transport_data == NULL;
   if (call->is_client) {
     GRPC_STATS_INC_CLIENT_CALLS_CREATED(exec_ctx);
@@ -819,10 +819,10 @@
  * COMPRESSION
  */
 
-static void set_incoming_compression_algorithm(
-    grpc_call *call, grpc_compression_algorithm algo) {
-  GPR_ASSERT(algo < GRPC_COMPRESS_ALGORITHMS_COUNT);
-  call->incoming_compression_algorithm = algo;
+static void set_incoming_message_compression_algorithm(
+    grpc_call *call, grpc_message_compression_algorithm algo) {
+  GPR_ASSERT(algo < GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT);
+  call->incoming_message_compression_algorithm = algo;
 }
 
 static void set_incoming_stream_compression_algorithm(
@@ -833,8 +833,10 @@
 
 grpc_compression_algorithm grpc_call_test_only_get_compression_algorithm(
     grpc_call *call) {
-  grpc_compression_algorithm algorithm;
-  algorithm = call->incoming_compression_algorithm;
+  grpc_compression_algorithm algorithm = GRPC_COMPRESS_NONE;
+  grpc_compression_algorithm_from_message_stream_compression_algorithm(
+      &algorithm, call->incoming_message_compression_algorithm,
+      call->incoming_stream_compression_algorithm);
   return algorithm;
 }
 
@@ -844,13 +846,6 @@
                                               call->encodings_accepted_by_peer);
 }
 
-static grpc_stream_compression_algorithm
-stream_compression_algorithm_for_level_locked(
-    grpc_call *call, grpc_stream_compression_level level) {
-  return grpc_stream_compression_algorithm_for_level(
-      level, call->stream_encodings_accepted_by_peer);
-}
-
 uint32_t grpc_call_test_only_get_message_flags(grpc_call *call) {
   uint32_t flags;
   flags = call->test_only_last_message_flags;
@@ -860,9 +855,11 @@
 static void destroy_encodings_accepted_by_peer(void *p) { return; }
 
 static void set_encodings_accepted_by_peer(grpc_exec_ctx *exec_ctx,
-                                           grpc_call *call, grpc_mdelem mdel) {
+                                           grpc_call *call, grpc_mdelem mdel,
+                                           uint32_t *encodings_accepted_by_peer,
+                                           bool stream_encoding) {
   size_t i;
-  grpc_compression_algorithm algorithm;
+  uint32_t algorithm;
   grpc_slice_buffer accept_encoding_parts;
   grpc_slice accept_encoding_slice;
   void *accepted_user_data;
@@ -870,24 +867,33 @@
   accepted_user_data =
       grpc_mdelem_get_user_data(mdel, destroy_encodings_accepted_by_peer);
   if (accepted_user_data != NULL) {
-    call->encodings_accepted_by_peer =
+    *encodings_accepted_by_peer =
         (uint32_t)(((uintptr_t)accepted_user_data) - 1);
     return;
   }
 
+  *encodings_accepted_by_peer = 0;
+
   accept_encoding_slice = GRPC_MDVALUE(mdel);
   grpc_slice_buffer_init(&accept_encoding_parts);
-  grpc_slice_split(accept_encoding_slice, ",", &accept_encoding_parts);
+  grpc_slice_split_without_space(accept_encoding_slice, ",",
+                                 &accept_encoding_parts);
 
-  /* No need to zero call->encodings_accepted_by_peer: grpc_call_create already
-   * zeroes the whole grpc_call */
-  /* Always support no compression */
-  GPR_BITSET(&call->encodings_accepted_by_peer, GRPC_COMPRESS_NONE);
+  GPR_BITSET(encodings_accepted_by_peer, GRPC_COMPRESS_NONE);
   for (i = 0; i < accept_encoding_parts.count; i++) {
+    int r;
     grpc_slice accept_encoding_entry_slice = accept_encoding_parts.slices[i];
-    if (grpc_compression_algorithm_parse(accept_encoding_entry_slice,
-                                         &algorithm)) {
-      GPR_BITSET(&call->encodings_accepted_by_peer, algorithm);
+    if (!stream_encoding) {
+      r = grpc_message_compression_algorithm_parse(
+          accept_encoding_entry_slice,
+          (grpc_message_compression_algorithm *)&algorithm);
+    } else {
+      r = grpc_stream_compression_algorithm_parse(
+          accept_encoding_entry_slice,
+          (grpc_stream_compression_algorithm *)&algorithm);
+    }
+    if (r) {
+      GPR_BITSET(encodings_accepted_by_peer, algorithm);
     } else {
       char *accept_encoding_entry_str =
           grpc_slice_to_c_string(accept_encoding_entry_slice);
@@ -902,53 +908,7 @@
 
   grpc_mdelem_set_user_data(
       mdel, destroy_encodings_accepted_by_peer,
-      (void *)(((uintptr_t)call->encodings_accepted_by_peer) + 1));
-}
-
-static void set_stream_encodings_accepted_by_peer(grpc_exec_ctx *exec_ctx,
-                                                  grpc_call *call,
-                                                  grpc_mdelem mdel) {
-  size_t i;
-  grpc_stream_compression_algorithm algorithm;
-  grpc_slice_buffer accept_encoding_parts;
-  grpc_slice accept_encoding_slice;
-  void *accepted_user_data;
-
-  accepted_user_data =
-      grpc_mdelem_get_user_data(mdel, destroy_encodings_accepted_by_peer);
-  if (accepted_user_data != NULL) {
-    call->stream_encodings_accepted_by_peer =
-        (uint32_t)(((uintptr_t)accepted_user_data) - 1);
-    return;
-  }
-
-  accept_encoding_slice = GRPC_MDVALUE(mdel);
-  grpc_slice_buffer_init(&accept_encoding_parts);
-  grpc_slice_split(accept_encoding_slice, ",", &accept_encoding_parts);
-
-  /* Always support no compression */
-  GPR_BITSET(&call->stream_encodings_accepted_by_peer,
-             GRPC_STREAM_COMPRESS_NONE);
-  for (i = 0; i < accept_encoding_parts.count; i++) {
-    grpc_slice accept_encoding_entry_slice = accept_encoding_parts.slices[i];
-    if (grpc_stream_compression_algorithm_parse(accept_encoding_entry_slice,
-                                                &algorithm)) {
-      GPR_BITSET(&call->stream_encodings_accepted_by_peer, algorithm);
-    } else {
-      char *accept_encoding_entry_str =
-          grpc_slice_to_c_string(accept_encoding_entry_slice);
-      gpr_log(GPR_ERROR,
-              "Invalid entry in accept encoding metadata: '%s'. Ignoring.",
-              accept_encoding_entry_str);
-      gpr_free(accept_encoding_entry_str);
-    }
-  }
-
-  grpc_slice_buffer_destroy_internal(exec_ctx, &accept_encoding_parts);
-
-  grpc_mdelem_set_user_data(
-      mdel, destroy_encodings_accepted_by_peer,
-      (void *)(((uintptr_t)call->stream_encodings_accepted_by_peer) + 1));
+      (void *)(((uintptr_t)(*encodings_accepted_by_peer)) + 1));
 }
 
 uint32_t grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call) {
@@ -957,13 +917,6 @@
   return encodings_accepted_by_peer;
 }
 
-uint32_t grpc_call_test_only_get_stream_encodings_accepted_by_peer(
-    grpc_call *call) {
-  uint32_t stream_encodings_accepted_by_peer;
-  stream_encodings_accepted_by_peer = call->stream_encodings_accepted_by_peer;
-  return stream_encodings_accepted_by_peer;
-}
-
 grpc_stream_compression_algorithm
 grpc_call_test_only_get_incoming_stream_encodings(grpc_call *call) {
   return call->incoming_stream_compression_algorithm;
@@ -1065,17 +1018,18 @@
   return status;
 }
 
-static grpc_compression_algorithm decode_compression(grpc_mdelem md) {
-  grpc_compression_algorithm algorithm =
-      grpc_compression_algorithm_from_slice(GRPC_MDVALUE(md));
-  if (algorithm == GRPC_COMPRESS_ALGORITHMS_COUNT) {
+static grpc_message_compression_algorithm decode_message_compression(
+    grpc_mdelem md) {
+  grpc_message_compression_algorithm algorithm =
+      grpc_message_compression_algorithm_from_slice(GRPC_MDVALUE(md));
+  if (algorithm == GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT) {
     char *md_c_str = grpc_slice_to_c_string(GRPC_MDVALUE(md));
     gpr_log(GPR_ERROR,
-            "Invalid incoming compression algorithm: '%s'. Interpreting "
-            "incoming data as uncompressed.",
+            "Invalid incoming message compression algorithm: '%s'. "
+            "Interpreting incoming data as uncompressed.",
             md_c_str);
     gpr_free(md_c_str);
-    return GRPC_COMPRESS_NONE;
+    return GRPC_MESSAGE_COMPRESS_NONE;
   }
   return algorithm;
 }
@@ -1121,38 +1075,41 @@
 static void recv_initial_filter(grpc_exec_ctx *exec_ctx, grpc_call *call,
                                 grpc_metadata_batch *b) {
   if (b->idx.named.content_encoding != NULL) {
-    if (b->idx.named.grpc_encoding != NULL) {
-      gpr_log(GPR_ERROR,
-              "Received both content-encoding and grpc-encoding header. "
-              "Ignoring grpc-encoding.");
-      grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.grpc_encoding);
-    }
     GPR_TIMER_BEGIN("incoming_stream_compression_algorithm", 0);
     set_incoming_stream_compression_algorithm(
         call, decode_stream_compression(b->idx.named.content_encoding->md));
     GPR_TIMER_END("incoming_stream_compression_algorithm", 0);
     grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.content_encoding);
-  } else if (b->idx.named.grpc_encoding != NULL) {
-    GPR_TIMER_BEGIN("incoming_compression_algorithm", 0);
-    set_incoming_compression_algorithm(
-        call, decode_compression(b->idx.named.grpc_encoding->md));
-    GPR_TIMER_END("incoming_compression_algorithm", 0);
+  }
+  if (b->idx.named.grpc_encoding != NULL) {
+    GPR_TIMER_BEGIN("incoming_message_compression_algorithm", 0);
+    set_incoming_message_compression_algorithm(
+        call, decode_message_compression(b->idx.named.grpc_encoding->md));
+    GPR_TIMER_END("incoming_message_compression_algorithm", 0);
     grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.grpc_encoding);
   }
+  uint32_t message_encodings_accepted_by_peer = 1u;
+  uint32_t stream_encodings_accepted_by_peer = 1u;
   if (b->idx.named.grpc_accept_encoding != NULL) {
     GPR_TIMER_BEGIN("encodings_accepted_by_peer", 0);
     set_encodings_accepted_by_peer(exec_ctx, call,
-                                   b->idx.named.grpc_accept_encoding->md);
+                                   b->idx.named.grpc_accept_encoding->md,
+                                   &message_encodings_accepted_by_peer, false);
     grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.grpc_accept_encoding);
     GPR_TIMER_END("encodings_accepted_by_peer", 0);
   }
   if (b->idx.named.accept_encoding != NULL) {
     GPR_TIMER_BEGIN("stream_encodings_accepted_by_peer", 0);
-    set_stream_encodings_accepted_by_peer(exec_ctx, call,
-                                          b->idx.named.accept_encoding->md);
+    set_encodings_accepted_by_peer(exec_ctx, call,
+                                   b->idx.named.accept_encoding->md,
+                                   &stream_encodings_accepted_by_peer, true);
     grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.accept_encoding);
     GPR_TIMER_END("stream_encodings_accepted_by_peer", 0);
   }
+  call->encodings_accepted_by_peer =
+      grpc_compression_bitset_from_message_stream_compression_bitset(
+          message_encodings_accepted_by_peer,
+          stream_encodings_accepted_by_peer);
   publish_app_metadata(call, b, false);
 }
 
@@ -1451,9 +1408,15 @@
   } else {
     call->test_only_last_message_flags = call->receiving_stream->flags;
     if ((call->receiving_stream->flags & GRPC_WRITE_INTERNAL_COMPRESS) &&
-        (call->incoming_compression_algorithm > GRPC_COMPRESS_NONE)) {
-      *call->receiving_buffer = grpc_raw_compressed_byte_buffer_create(
-          NULL, 0, call->incoming_compression_algorithm);
+        (call->incoming_message_compression_algorithm >
+         GRPC_MESSAGE_COMPRESS_NONE)) {
+      grpc_compression_algorithm algo;
+      GPR_ASSERT(
+          grpc_compression_algorithm_from_message_stream_compression_algorithm(
+              &algo, call->incoming_message_compression_algorithm,
+              (grpc_stream_compression_algorithm)0));
+      *call->receiving_buffer =
+          grpc_raw_compressed_byte_buffer_create(NULL, 0, algo);
     } else {
       *call->receiving_buffer = grpc_raw_byte_buffer_create(NULL, 0);
     }
@@ -1499,88 +1462,66 @@
 
 static void validate_filtered_metadata(grpc_exec_ctx *exec_ctx,
                                        batch_control *bctl) {
+  grpc_compression_algorithm compression_algorithm;
   grpc_call *call = bctl->call;
-  /* validate compression algorithms */
   if (call->incoming_stream_compression_algorithm !=
-      GRPC_STREAM_COMPRESS_NONE) {
-    const grpc_stream_compression_algorithm algo =
-        call->incoming_stream_compression_algorithm;
+          GRPC_STREAM_COMPRESS_NONE &&
+      call->incoming_message_compression_algorithm !=
+          GRPC_MESSAGE_COMPRESS_NONE) {
     char *error_msg = NULL;
-    const grpc_compression_options compression_options =
-        grpc_channel_compression_options(call->channel);
-    if (algo >= GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT) {
-      gpr_asprintf(&error_msg,
-                   "Invalid stream compression algorithm value '%d'.", algo);
-      gpr_log(GPR_ERROR, "%s", error_msg);
-      cancel_with_status(exec_ctx, call, STATUS_FROM_SURFACE,
-                         GRPC_STATUS_UNIMPLEMENTED, error_msg);
-    } else if (grpc_compression_options_is_stream_compression_algorithm_enabled(
-                   &compression_options, algo) == 0) {
-      /* check if algorithm is supported by current channel config */
-      const char *algo_name = NULL;
-      grpc_stream_compression_algorithm_name(algo, &algo_name);
-      gpr_asprintf(&error_msg, "Stream compression algorithm '%s' is disabled.",
-                   algo_name);
-      gpr_log(GPR_ERROR, "%s", error_msg);
-      cancel_with_status(exec_ctx, call, STATUS_FROM_SURFACE,
-                         GRPC_STATUS_UNIMPLEMENTED, error_msg);
-    }
+    gpr_asprintf(&error_msg,
+                 "Incoming stream has both stream compression (%d) and message "
+                 "compression (%d).",
+                 call->incoming_stream_compression_algorithm,
+                 call->incoming_message_compression_algorithm);
+    gpr_log(GPR_ERROR, "%s", error_msg);
+    cancel_with_status(exec_ctx, call, STATUS_FROM_SURFACE,
+                       GRPC_STATUS_INTERNAL, error_msg);
     gpr_free(error_msg);
-
-    GPR_ASSERT(call->stream_encodings_accepted_by_peer != 0);
-    if (!GPR_BITGET(call->stream_encodings_accepted_by_peer,
-                    call->incoming_stream_compression_algorithm)) {
-      if (GRPC_TRACER_ON(grpc_compression_trace)) {
-        const char *algo_name = NULL;
-        grpc_stream_compression_algorithm_name(
-            call->incoming_stream_compression_algorithm, &algo_name);
-        gpr_log(
-            GPR_ERROR,
-            "Stream compression algorithm (content-encoding = '%s') not "
-            "present in the bitset of accepted encodings (accept-encodings: "
-            "'0x%x')",
-            algo_name, call->stream_encodings_accepted_by_peer);
-      }
-    }
-  } else if (call->incoming_compression_algorithm != GRPC_COMPRESS_NONE) {
-    const grpc_compression_algorithm algo =
-        call->incoming_compression_algorithm;
+  } else if (
+      grpc_compression_algorithm_from_message_stream_compression_algorithm(
+          &compression_algorithm, call->incoming_message_compression_algorithm,
+          call->incoming_stream_compression_algorithm) == 0) {
+    char *error_msg = NULL;
+    gpr_asprintf(&error_msg,
+                 "Error in incoming message compression (%d) or stream "
+                 "compression (%d).",
+                 call->incoming_stream_compression_algorithm,
+                 call->incoming_message_compression_algorithm);
+    cancel_with_status(exec_ctx, call, STATUS_FROM_SURFACE,
+                       GRPC_STATUS_INTERNAL, error_msg);
+    gpr_free(error_msg);
+  } else {
     char *error_msg = NULL;
     const grpc_compression_options compression_options =
         grpc_channel_compression_options(call->channel);
-    /* check if algorithm is known */
-    if (algo >= GRPC_COMPRESS_ALGORITHMS_COUNT) {
+    if (compression_algorithm >= GRPC_COMPRESS_ALGORITHMS_COUNT) {
       gpr_asprintf(&error_msg, "Invalid compression algorithm value '%d'.",
-                   algo);
+                   compression_algorithm);
       gpr_log(GPR_ERROR, "%s", error_msg);
       cancel_with_status(exec_ctx, call, STATUS_FROM_SURFACE,
                          GRPC_STATUS_UNIMPLEMENTED, error_msg);
     } else if (grpc_compression_options_is_algorithm_enabled(
-                   &compression_options, algo) == 0) {
+                   &compression_options, compression_algorithm) == 0) {
       /* check if algorithm is supported by current channel config */
       const char *algo_name = NULL;
-      grpc_compression_algorithm_name(algo, &algo_name);
+      grpc_compression_algorithm_name(compression_algorithm, &algo_name);
       gpr_asprintf(&error_msg, "Compression algorithm '%s' is disabled.",
                    algo_name);
       gpr_log(GPR_ERROR, "%s", error_msg);
       cancel_with_status(exec_ctx, call, STATUS_FROM_SURFACE,
                          GRPC_STATUS_UNIMPLEMENTED, error_msg);
-    } else {
-      call->incoming_compression_algorithm = algo;
     }
     gpr_free(error_msg);
 
     GPR_ASSERT(call->encodings_accepted_by_peer != 0);
-    if (!GPR_BITGET(call->encodings_accepted_by_peer,
-                    call->incoming_compression_algorithm)) {
+    if (!GPR_BITGET(call->encodings_accepted_by_peer, compression_algorithm)) {
       if (GRPC_TRACER_ON(grpc_compression_trace)) {
         const char *algo_name = NULL;
-        grpc_compression_algorithm_name(call->incoming_compression_algorithm,
-                                        &algo_name);
+        grpc_compression_algorithm_name(compression_algorithm, &algo_name);
         gpr_log(GPR_ERROR,
-                "Compression algorithm (grpc-encoding = '%s') not present in "
-                "the bitset of accepted encodings (grpc-accept-encodings: "
-                "'0x%x')",
+                "Compression algorithm ('%s') not present in the bitset of "
+                "accepted encodings ('0x%x')",
                 algo_name, call->encodings_accepted_by_peer);
       }
     }
@@ -1730,56 +1671,28 @@
         size_t additional_metadata_count = 0;
         grpc_compression_level effective_compression_level =
             GRPC_COMPRESS_LEVEL_NONE;
-        grpc_stream_compression_level effective_stream_compression_level =
-            GRPC_STREAM_COMPRESS_LEVEL_NONE;
         bool level_set = false;
-        bool stream_compression = false;
-        if (op->data.send_initial_metadata.maybe_stream_compression_level
-                .is_set) {
-          effective_stream_compression_level =
-              op->data.send_initial_metadata.maybe_stream_compression_level
-                  .level;
-          level_set = true;
-          stream_compression = true;
-        } else if (op->data.send_initial_metadata.maybe_compression_level
-                       .is_set) {
+        if (op->data.send_initial_metadata.maybe_compression_level.is_set) {
           effective_compression_level =
               op->data.send_initial_metadata.maybe_compression_level.level;
           level_set = true;
         } else {
           const grpc_compression_options copts =
               grpc_channel_compression_options(call->channel);
-          if (copts.default_stream_compression_level.is_set) {
-            level_set = true;
-            effective_stream_compression_level =
-                copts.default_stream_compression_level.level;
-            stream_compression = true;
-          } else if (copts.default_level.is_set) {
+          if (copts.default_level.is_set) {
             level_set = true;
             effective_compression_level = copts.default_level.level;
           }
         }
         if (level_set && !call->is_client) {
-          if (stream_compression) {
-            const grpc_stream_compression_algorithm calgo =
-                stream_compression_algorithm_for_level_locked(
-                    call, effective_stream_compression_level);
-            call->compression_md.key =
-                GRPC_MDSTR_GRPC_INTERNAL_STREAM_ENCODING_REQUEST;
-            call->compression_md.value =
-                grpc_stream_compression_algorithm_slice(calgo);
-          } else {
-            const grpc_compression_algorithm calgo =
-                compression_algorithm_for_level_locked(
-                    call, effective_compression_level);
-            /* the following will be picked up by the compress filter and used
-             * as the call's compression algorithm. */
-            call->compression_md.key =
-                GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST;
-            call->compression_md.value =
-                grpc_compression_algorithm_slice(calgo);
-            additional_metadata_count++;
-          }
+          const grpc_compression_algorithm calgo =
+              compression_algorithm_for_level_locked(
+                  call, effective_compression_level);
+          /* the following will be picked up by the compress filter and used
+           * as the call's compression algorithm. */
+          call->compression_md.key = GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST;
+          call->compression_md.value = grpc_compression_algorithm_slice(calgo);
+          additional_metadata_count++;
         }
 
         if (op->data.send_initial_metadata.count + additional_metadata_count >
diff --git a/src/core/lib/surface/call_test_only.h b/src/core/lib/surface/call_test_only.h
index a5a01b3..e0f4ba3 100644
--- a/src/core/lib/surface/call_test_only.h
+++ b/src/core/lib/surface/call_test_only.h
@@ -25,7 +25,7 @@
 extern "C" {
 #endif
 
-/** Return the compression algorithm from \a call.
+/** Return the message compression algorithm from \a call.
  *
  * \warning This function should \b only be used in test code. */
 grpc_compression_algorithm grpc_call_test_only_get_compression_algorithm(
@@ -42,18 +42,6 @@
  * To be indexed by grpc_compression_algorithm enum values. */
 uint32_t grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call);
 
-/** Returns a bitset for the stream encodings (stream compression algorithms)
- * supported by \a call's peer.
- *
- * To be indexed by grpc_stream_compression_algorithm enum values. */
-uint32_t grpc_call_test_only_get_stream_encodings_accepted_by_peer(
-    grpc_call *call);
-
-/** Returns the incoming stream compression algorithm (content-encoding header)
- * received by a call. */
-grpc_stream_compression_algorithm
-grpc_call_test_only_get_incoming_stream_encodings(grpc_call *call);
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc
index 860dcc8..b239530 100644
--- a/src/core/lib/surface/channel.cc
+++ b/src/core/lib/surface/channel.cc
@@ -148,45 +148,18 @@
               {GRPC_COMPRESS_LEVEL_NONE, GRPC_COMPRESS_LEVEL_NONE,
                GRPC_COMPRESS_LEVEL_COUNT - 1});
     } else if (0 == strcmp(args->args[i].key,
-                           GRPC_STREAM_COMPRESSION_CHANNEL_DEFAULT_LEVEL)) {
-      channel->compression_options.default_stream_compression_level.is_set =
-          true;
-      channel->compression_options.default_stream_compression_level.level =
-          (grpc_stream_compression_level)grpc_channel_arg_get_integer(
-              &args->args[i],
-              {GRPC_STREAM_COMPRESS_LEVEL_NONE, GRPC_STREAM_COMPRESS_LEVEL_NONE,
-               GRPC_STREAM_COMPRESS_LEVEL_COUNT - 1});
-    } else if (0 == strcmp(args->args[i].key,
                            GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM)) {
       channel->compression_options.default_algorithm.is_set = true;
       channel->compression_options.default_algorithm.algorithm =
           (grpc_compression_algorithm)grpc_channel_arg_get_integer(
               &args->args[i], {GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
                                GRPC_COMPRESS_ALGORITHMS_COUNT - 1});
-    } else if (0 == strcmp(args->args[i].key,
-                           GRPC_STREAM_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM)) {
-      channel->compression_options.default_stream_compression_algorithm.is_set =
-          true;
-      channel->compression_options.default_stream_compression_algorithm
-          .algorithm =
-          (grpc_stream_compression_algorithm)grpc_channel_arg_get_integer(
-              &args->args[i],
-              {GRPC_STREAM_COMPRESS_NONE, GRPC_STREAM_COMPRESS_NONE,
-               GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT - 1});
     } else if (0 ==
                strcmp(args->args[i].key,
                       GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET)) {
       channel->compression_options.enabled_algorithms_bitset =
           (uint32_t)args->args[i].value.integer |
           0x1; /* always support no compression */
-    } else if (0 ==
-               strcmp(
-                   args->args[i].key,
-                   GRPC_STREAM_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET)) {
-      channel->compression_options
-          .enabled_stream_compression_algorithms_bitset =
-          (uint32_t)args->args[i].value.integer |
-          0x1; /* always support no compression */
     }
   }
 
diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc
index 472cf88..8edb3bb 100644
--- a/src/core/lib/transport/static_metadata.cc
+++ b/src/core/lib/transport/static_metadata.cc
@@ -57,51 +57,52 @@
     112, 111, 110, 115, 101, 95,  109, 101, 115, 115, 97,  103, 101, 95,  98,
     121, 116, 101, 115, 47,  103, 114, 112, 99,  46,  108, 98,  46,  118, 49,
     46,  76,  111, 97,  100, 66,  97,  108, 97,  110, 99,  101, 114, 47,  66,
-    97,  108, 97,  110, 99,  101, 76,  111, 97,  100, 48,  49,  50,  105, 100,
-    101, 110, 116, 105, 116, 121, 103, 122, 105, 112, 100, 101, 102, 108, 97,
-    116, 101, 116, 114, 97,  105, 108, 101, 114, 115, 97,  112, 112, 108, 105,
-    99,  97,  116, 105, 111, 110, 47,  103, 114, 112, 99,  80,  79,  83,  84,
-    50,  48,  48,  52,  48,  52,  104, 116, 116, 112, 104, 116, 116, 112, 115,
-    103, 114, 112, 99,  71,  69,  84,  80,  85,  84,  47,  47,  105, 110, 100,
-    101, 120, 46,  104, 116, 109, 108, 50,  48,  52,  50,  48,  54,  51,  48,
-    52,  52,  48,  48,  53,  48,  48,  97,  99,  99,  101, 112, 116, 45,  99,
-    104, 97,  114, 115, 101, 116, 103, 122, 105, 112, 44,  32,  100, 101, 102,
-    108, 97,  116, 101, 97,  99,  99,  101, 112, 116, 45,  108, 97,  110, 103,
-    117, 97,  103, 101, 97,  99,  99,  101, 112, 116, 45,  114, 97,  110, 103,
-    101, 115, 97,  99,  99,  101, 112, 116, 97,  99,  99,  101, 115, 115, 45,
-    99,  111, 110, 116, 114, 111, 108, 45,  97,  108, 108, 111, 119, 45,  111,
-    114, 105, 103, 105, 110, 97,  103, 101, 97,  108, 108, 111, 119, 97,  117,
-    116, 104, 111, 114, 105, 122, 97,  116, 105, 111, 110, 99,  97,  99,  104,
-    101, 45,  99,  111, 110, 116, 114, 111, 108, 99,  111, 110, 116, 101, 110,
-    116, 45,  100, 105, 115, 112, 111, 115, 105, 116, 105, 111, 110, 99,  111,
-    110, 116, 101, 110, 116, 45,  108, 97,  110, 103, 117, 97,  103, 101, 99,
-    111, 110, 116, 101, 110, 116, 45,  108, 101, 110, 103, 116, 104, 99,  111,
-    110, 116, 101, 110, 116, 45,  108, 111, 99,  97,  116, 105, 111, 110, 99,
-    111, 110, 116, 101, 110, 116, 45,  114, 97,  110, 103, 101, 99,  111, 111,
-    107, 105, 101, 100, 97,  116, 101, 101, 116, 97,  103, 101, 120, 112, 101,
-    99,  116, 101, 120, 112, 105, 114, 101, 115, 102, 114, 111, 109, 105, 102,
-    45,  109, 97,  116, 99,  104, 105, 102, 45,  109, 111, 100, 105, 102, 105,
-    101, 100, 45,  115, 105, 110, 99,  101, 105, 102, 45,  110, 111, 110, 101,
-    45,  109, 97,  116, 99,  104, 105, 102, 45,  114, 97,  110, 103, 101, 105,
-    102, 45,  117, 110, 109, 111, 100, 105, 102, 105, 101, 100, 45,  115, 105,
-    110, 99,  101, 108, 97,  115, 116, 45,  109, 111, 100, 105, 102, 105, 101,
-    100, 108, 98,  45,  99,  111, 115, 116, 45,  98,  105, 110, 108, 105, 110,
-    107, 108, 111, 99,  97,  116, 105, 111, 110, 109, 97,  120, 45,  102, 111,
-    114, 119, 97,  114, 100, 115, 112, 114, 111, 120, 121, 45,  97,  117, 116,
-    104, 101, 110, 116, 105, 99,  97,  116, 101, 112, 114, 111, 120, 121, 45,
-    97,  117, 116, 104, 111, 114, 105, 122, 97,  116, 105, 111, 110, 114, 97,
-    110, 103, 101, 114, 101, 102, 101, 114, 101, 114, 114, 101, 102, 114, 101,
-    115, 104, 114, 101, 116, 114, 121, 45,  97,  102, 116, 101, 114, 115, 101,
-    114, 118, 101, 114, 115, 101, 116, 45,  99,  111, 111, 107, 105, 101, 115,
-    116, 114, 105, 99,  116, 45,  116, 114, 97,  110, 115, 112, 111, 114, 116,
-    45,  115, 101, 99,  117, 114, 105, 116, 121, 116, 114, 97,  110, 115, 102,
-    101, 114, 45,  101, 110, 99,  111, 100, 105, 110, 103, 118, 97,  114, 121,
-    118, 105, 97,  119, 119, 119, 45,  97,  117, 116, 104, 101, 110, 116, 105,
-    99,  97,  116, 101, 105, 100, 101, 110, 116, 105, 116, 121, 44,  100, 101,
-    102, 108, 97,  116, 101, 105, 100, 101, 110, 116, 105, 116, 121, 44,  103,
-    122, 105, 112, 100, 101, 102, 108, 97,  116, 101, 44,  103, 122, 105, 112,
+    97,  108, 97,  110, 99,  101, 76,  111, 97,  100, 115, 116, 114, 101, 97,
+    109, 45,  103, 122, 105, 112, 48,  49,  50,  105, 100, 101, 110, 116, 105,
+    116, 121, 103, 122, 105, 112, 100, 101, 102, 108, 97,  116, 101, 116, 114,
+    97,  105, 108, 101, 114, 115, 97,  112, 112, 108, 105, 99,  97,  116, 105,
+    111, 110, 47,  103, 114, 112, 99,  80,  79,  83,  84,  50,  48,  48,  52,
+    48,  52,  104, 116, 116, 112, 104, 116, 116, 112, 115, 103, 114, 112, 99,
+    71,  69,  84,  80,  85,  84,  47,  47,  105, 110, 100, 101, 120, 46,  104,
+    116, 109, 108, 50,  48,  52,  50,  48,  54,  51,  48,  52,  52,  48,  48,
+    53,  48,  48,  97,  99,  99,  101, 112, 116, 45,  99,  104, 97,  114, 115,
+    101, 116, 103, 122, 105, 112, 44,  32,  100, 101, 102, 108, 97,  116, 101,
+    97,  99,  99,  101, 112, 116, 45,  108, 97,  110, 103, 117, 97,  103, 101,
+    97,  99,  99,  101, 112, 116, 45,  114, 97,  110, 103, 101, 115, 97,  99,
+    99,  101, 112, 116, 97,  99,  99,  101, 115, 115, 45,  99,  111, 110, 116,
+    114, 111, 108, 45,  97,  108, 108, 111, 119, 45,  111, 114, 105, 103, 105,
+    110, 97,  103, 101, 97,  108, 108, 111, 119, 97,  117, 116, 104, 111, 114,
+    105, 122, 97,  116, 105, 111, 110, 99,  97,  99,  104, 101, 45,  99,  111,
+    110, 116, 114, 111, 108, 99,  111, 110, 116, 101, 110, 116, 45,  100, 105,
+    115, 112, 111, 115, 105, 116, 105, 111, 110, 99,  111, 110, 116, 101, 110,
+    116, 45,  108, 97,  110, 103, 117, 97,  103, 101, 99,  111, 110, 116, 101,
+    110, 116, 45,  108, 101, 110, 103, 116, 104, 99,  111, 110, 116, 101, 110,
+    116, 45,  108, 111, 99,  97,  116, 105, 111, 110, 99,  111, 110, 116, 101,
+    110, 116, 45,  114, 97,  110, 103, 101, 99,  111, 111, 107, 105, 101, 100,
+    97,  116, 101, 101, 116, 97,  103, 101, 120, 112, 101, 99,  116, 101, 120,
+    112, 105, 114, 101, 115, 102, 114, 111, 109, 105, 102, 45,  109, 97,  116,
+    99,  104, 105, 102, 45,  109, 111, 100, 105, 102, 105, 101, 100, 45,  115,
+    105, 110, 99,  101, 105, 102, 45,  110, 111, 110, 101, 45,  109, 97,  116,
+    99,  104, 105, 102, 45,  114, 97,  110, 103, 101, 105, 102, 45,  117, 110,
+    109, 111, 100, 105, 102, 105, 101, 100, 45,  115, 105, 110, 99,  101, 108,
+    97,  115, 116, 45,  109, 111, 100, 105, 102, 105, 101, 100, 108, 98,  45,
+    99,  111, 115, 116, 45,  98,  105, 110, 108, 105, 110, 107, 108, 111, 99,
+    97,  116, 105, 111, 110, 109, 97,  120, 45,  102, 111, 114, 119, 97,  114,
+    100, 115, 112, 114, 111, 120, 121, 45,  97,  117, 116, 104, 101, 110, 116,
+    105, 99,  97,  116, 101, 112, 114, 111, 120, 121, 45,  97,  117, 116, 104,
+    111, 114, 105, 122, 97,  116, 105, 111, 110, 114, 97,  110, 103, 101, 114,
+    101, 102, 101, 114, 101, 114, 114, 101, 102, 114, 101, 115, 104, 114, 101,
+    116, 114, 121, 45,  97,  102, 116, 101, 114, 115, 101, 114, 118, 101, 114,
+    115, 101, 116, 45,  99,  111, 111, 107, 105, 101, 115, 116, 114, 105, 99,
+    116, 45,  116, 114, 97,  110, 115, 112, 111, 114, 116, 45,  115, 101, 99,
+    117, 114, 105, 116, 121, 116, 114, 97,  110, 115, 102, 101, 114, 45,  101,
+    110, 99,  111, 100, 105, 110, 103, 118, 97,  114, 121, 118, 105, 97,  119,
+    119, 119, 45,  97,  117, 116, 104, 101, 110, 116, 105, 99,  97,  116, 101,
     105, 100, 101, 110, 116, 105, 116, 121, 44,  100, 101, 102, 108, 97,  116,
-    101, 44,  103, 122, 105, 112};
+    101, 105, 100, 101, 110, 116, 105, 116, 121, 44,  103, 122, 105, 112, 100,
+    101, 102, 108, 97,  116, 101, 44,  103, 122, 105, 112, 105, 100, 101, 110,
+    116, 105, 116, 121, 44,  100, 101, 102, 108, 97,  116, 101, 44,  103, 122,
+    105, 112};
 
 static void static_ref(void *unused) {}
 static void static_unref(grpc_exec_ctx *exec_ctx, void *unused) {}
@@ -213,6 +214,7 @@
     {&grpc_static_metadata_vtable, &static_sub_refcnt},
     {&grpc_static_metadata_vtable, &static_sub_refcnt},
     {&grpc_static_metadata_vtable, &static_sub_refcnt},
+    {&grpc_static_metadata_vtable, &static_sub_refcnt},
 };
 
 const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = {
@@ -245,77 +247,78 @@
     {&grpc_static_metadata_refcounts[26], {{g_bytes + 333, 30}}},
     {&grpc_static_metadata_refcounts[27], {{g_bytes + 363, 31}}},
     {&grpc_static_metadata_refcounts[28], {{g_bytes + 394, 36}}},
-    {&grpc_static_metadata_refcounts[29], {{g_bytes + 430, 1}}},
-    {&grpc_static_metadata_refcounts[30], {{g_bytes + 431, 1}}},
-    {&grpc_static_metadata_refcounts[31], {{g_bytes + 432, 1}}},
-    {&grpc_static_metadata_refcounts[32], {{g_bytes + 433, 8}}},
-    {&grpc_static_metadata_refcounts[33], {{g_bytes + 441, 4}}},
-    {&grpc_static_metadata_refcounts[34], {{g_bytes + 445, 7}}},
-    {&grpc_static_metadata_refcounts[35], {{g_bytes + 452, 8}}},
-    {&grpc_static_metadata_refcounts[36], {{g_bytes + 460, 16}}},
-    {&grpc_static_metadata_refcounts[37], {{g_bytes + 476, 4}}},
-    {&grpc_static_metadata_refcounts[38], {{g_bytes + 480, 3}}},
-    {&grpc_static_metadata_refcounts[39], {{g_bytes + 483, 3}}},
-    {&grpc_static_metadata_refcounts[40], {{g_bytes + 486, 4}}},
-    {&grpc_static_metadata_refcounts[41], {{g_bytes + 490, 5}}},
-    {&grpc_static_metadata_refcounts[42], {{g_bytes + 495, 4}}},
-    {&grpc_static_metadata_refcounts[43], {{g_bytes + 499, 3}}},
-    {&grpc_static_metadata_refcounts[44], {{g_bytes + 502, 3}}},
-    {&grpc_static_metadata_refcounts[45], {{g_bytes + 505, 1}}},
-    {&grpc_static_metadata_refcounts[46], {{g_bytes + 506, 11}}},
-    {&grpc_static_metadata_refcounts[47], {{g_bytes + 517, 3}}},
-    {&grpc_static_metadata_refcounts[48], {{g_bytes + 520, 3}}},
-    {&grpc_static_metadata_refcounts[49], {{g_bytes + 523, 3}}},
-    {&grpc_static_metadata_refcounts[50], {{g_bytes + 526, 3}}},
-    {&grpc_static_metadata_refcounts[51], {{g_bytes + 529, 3}}},
-    {&grpc_static_metadata_refcounts[52], {{g_bytes + 532, 14}}},
-    {&grpc_static_metadata_refcounts[53], {{g_bytes + 546, 13}}},
-    {&grpc_static_metadata_refcounts[54], {{g_bytes + 559, 15}}},
-    {&grpc_static_metadata_refcounts[55], {{g_bytes + 574, 13}}},
-    {&grpc_static_metadata_refcounts[56], {{g_bytes + 587, 6}}},
-    {&grpc_static_metadata_refcounts[57], {{g_bytes + 593, 27}}},
-    {&grpc_static_metadata_refcounts[58], {{g_bytes + 620, 3}}},
-    {&grpc_static_metadata_refcounts[59], {{g_bytes + 623, 5}}},
-    {&grpc_static_metadata_refcounts[60], {{g_bytes + 628, 13}}},
-    {&grpc_static_metadata_refcounts[61], {{g_bytes + 641, 13}}},
-    {&grpc_static_metadata_refcounts[62], {{g_bytes + 654, 19}}},
-    {&grpc_static_metadata_refcounts[63], {{g_bytes + 673, 16}}},
-    {&grpc_static_metadata_refcounts[64], {{g_bytes + 689, 14}}},
-    {&grpc_static_metadata_refcounts[65], {{g_bytes + 703, 16}}},
-    {&grpc_static_metadata_refcounts[66], {{g_bytes + 719, 13}}},
-    {&grpc_static_metadata_refcounts[67], {{g_bytes + 732, 6}}},
-    {&grpc_static_metadata_refcounts[68], {{g_bytes + 738, 4}}},
-    {&grpc_static_metadata_refcounts[69], {{g_bytes + 742, 4}}},
-    {&grpc_static_metadata_refcounts[70], {{g_bytes + 746, 6}}},
-    {&grpc_static_metadata_refcounts[71], {{g_bytes + 752, 7}}},
-    {&grpc_static_metadata_refcounts[72], {{g_bytes + 759, 4}}},
-    {&grpc_static_metadata_refcounts[73], {{g_bytes + 763, 8}}},
-    {&grpc_static_metadata_refcounts[74], {{g_bytes + 771, 17}}},
-    {&grpc_static_metadata_refcounts[75], {{g_bytes + 788, 13}}},
-    {&grpc_static_metadata_refcounts[76], {{g_bytes + 801, 8}}},
-    {&grpc_static_metadata_refcounts[77], {{g_bytes + 809, 19}}},
-    {&grpc_static_metadata_refcounts[78], {{g_bytes + 828, 13}}},
-    {&grpc_static_metadata_refcounts[79], {{g_bytes + 841, 11}}},
-    {&grpc_static_metadata_refcounts[80], {{g_bytes + 852, 4}}},
-    {&grpc_static_metadata_refcounts[81], {{g_bytes + 856, 8}}},
-    {&grpc_static_metadata_refcounts[82], {{g_bytes + 864, 12}}},
-    {&grpc_static_metadata_refcounts[83], {{g_bytes + 876, 18}}},
-    {&grpc_static_metadata_refcounts[84], {{g_bytes + 894, 19}}},
-    {&grpc_static_metadata_refcounts[85], {{g_bytes + 913, 5}}},
-    {&grpc_static_metadata_refcounts[86], {{g_bytes + 918, 7}}},
-    {&grpc_static_metadata_refcounts[87], {{g_bytes + 925, 7}}},
-    {&grpc_static_metadata_refcounts[88], {{g_bytes + 932, 11}}},
-    {&grpc_static_metadata_refcounts[89], {{g_bytes + 943, 6}}},
-    {&grpc_static_metadata_refcounts[90], {{g_bytes + 949, 10}}},
-    {&grpc_static_metadata_refcounts[91], {{g_bytes + 959, 25}}},
-    {&grpc_static_metadata_refcounts[92], {{g_bytes + 984, 17}}},
-    {&grpc_static_metadata_refcounts[93], {{g_bytes + 1001, 4}}},
-    {&grpc_static_metadata_refcounts[94], {{g_bytes + 1005, 3}}},
-    {&grpc_static_metadata_refcounts[95], {{g_bytes + 1008, 16}}},
-    {&grpc_static_metadata_refcounts[96], {{g_bytes + 1024, 16}}},
-    {&grpc_static_metadata_refcounts[97], {{g_bytes + 1040, 13}}},
-    {&grpc_static_metadata_refcounts[98], {{g_bytes + 1053, 12}}},
-    {&grpc_static_metadata_refcounts[99], {{g_bytes + 1065, 21}}},
+    {&grpc_static_metadata_refcounts[29], {{g_bytes + 430, 11}}},
+    {&grpc_static_metadata_refcounts[30], {{g_bytes + 441, 1}}},
+    {&grpc_static_metadata_refcounts[31], {{g_bytes + 442, 1}}},
+    {&grpc_static_metadata_refcounts[32], {{g_bytes + 443, 1}}},
+    {&grpc_static_metadata_refcounts[33], {{g_bytes + 444, 8}}},
+    {&grpc_static_metadata_refcounts[34], {{g_bytes + 452, 4}}},
+    {&grpc_static_metadata_refcounts[35], {{g_bytes + 456, 7}}},
+    {&grpc_static_metadata_refcounts[36], {{g_bytes + 463, 8}}},
+    {&grpc_static_metadata_refcounts[37], {{g_bytes + 471, 16}}},
+    {&grpc_static_metadata_refcounts[38], {{g_bytes + 487, 4}}},
+    {&grpc_static_metadata_refcounts[39], {{g_bytes + 491, 3}}},
+    {&grpc_static_metadata_refcounts[40], {{g_bytes + 494, 3}}},
+    {&grpc_static_metadata_refcounts[41], {{g_bytes + 497, 4}}},
+    {&grpc_static_metadata_refcounts[42], {{g_bytes + 501, 5}}},
+    {&grpc_static_metadata_refcounts[43], {{g_bytes + 506, 4}}},
+    {&grpc_static_metadata_refcounts[44], {{g_bytes + 510, 3}}},
+    {&grpc_static_metadata_refcounts[45], {{g_bytes + 513, 3}}},
+    {&grpc_static_metadata_refcounts[46], {{g_bytes + 516, 1}}},
+    {&grpc_static_metadata_refcounts[47], {{g_bytes + 517, 11}}},
+    {&grpc_static_metadata_refcounts[48], {{g_bytes + 528, 3}}},
+    {&grpc_static_metadata_refcounts[49], {{g_bytes + 531, 3}}},
+    {&grpc_static_metadata_refcounts[50], {{g_bytes + 534, 3}}},
+    {&grpc_static_metadata_refcounts[51], {{g_bytes + 537, 3}}},
+    {&grpc_static_metadata_refcounts[52], {{g_bytes + 540, 3}}},
+    {&grpc_static_metadata_refcounts[53], {{g_bytes + 543, 14}}},
+    {&grpc_static_metadata_refcounts[54], {{g_bytes + 557, 13}}},
+    {&grpc_static_metadata_refcounts[55], {{g_bytes + 570, 15}}},
+    {&grpc_static_metadata_refcounts[56], {{g_bytes + 585, 13}}},
+    {&grpc_static_metadata_refcounts[57], {{g_bytes + 598, 6}}},
+    {&grpc_static_metadata_refcounts[58], {{g_bytes + 604, 27}}},
+    {&grpc_static_metadata_refcounts[59], {{g_bytes + 631, 3}}},
+    {&grpc_static_metadata_refcounts[60], {{g_bytes + 634, 5}}},
+    {&grpc_static_metadata_refcounts[61], {{g_bytes + 639, 13}}},
+    {&grpc_static_metadata_refcounts[62], {{g_bytes + 652, 13}}},
+    {&grpc_static_metadata_refcounts[63], {{g_bytes + 665, 19}}},
+    {&grpc_static_metadata_refcounts[64], {{g_bytes + 684, 16}}},
+    {&grpc_static_metadata_refcounts[65], {{g_bytes + 700, 14}}},
+    {&grpc_static_metadata_refcounts[66], {{g_bytes + 714, 16}}},
+    {&grpc_static_metadata_refcounts[67], {{g_bytes + 730, 13}}},
+    {&grpc_static_metadata_refcounts[68], {{g_bytes + 743, 6}}},
+    {&grpc_static_metadata_refcounts[69], {{g_bytes + 749, 4}}},
+    {&grpc_static_metadata_refcounts[70], {{g_bytes + 753, 4}}},
+    {&grpc_static_metadata_refcounts[71], {{g_bytes + 757, 6}}},
+    {&grpc_static_metadata_refcounts[72], {{g_bytes + 763, 7}}},
+    {&grpc_static_metadata_refcounts[73], {{g_bytes + 770, 4}}},
+    {&grpc_static_metadata_refcounts[74], {{g_bytes + 774, 8}}},
+    {&grpc_static_metadata_refcounts[75], {{g_bytes + 782, 17}}},
+    {&grpc_static_metadata_refcounts[76], {{g_bytes + 799, 13}}},
+    {&grpc_static_metadata_refcounts[77], {{g_bytes + 812, 8}}},
+    {&grpc_static_metadata_refcounts[78], {{g_bytes + 820, 19}}},
+    {&grpc_static_metadata_refcounts[79], {{g_bytes + 839, 13}}},
+    {&grpc_static_metadata_refcounts[80], {{g_bytes + 852, 11}}},
+    {&grpc_static_metadata_refcounts[81], {{g_bytes + 863, 4}}},
+    {&grpc_static_metadata_refcounts[82], {{g_bytes + 867, 8}}},
+    {&grpc_static_metadata_refcounts[83], {{g_bytes + 875, 12}}},
+    {&grpc_static_metadata_refcounts[84], {{g_bytes + 887, 18}}},
+    {&grpc_static_metadata_refcounts[85], {{g_bytes + 905, 19}}},
+    {&grpc_static_metadata_refcounts[86], {{g_bytes + 924, 5}}},
+    {&grpc_static_metadata_refcounts[87], {{g_bytes + 929, 7}}},
+    {&grpc_static_metadata_refcounts[88], {{g_bytes + 936, 7}}},
+    {&grpc_static_metadata_refcounts[89], {{g_bytes + 943, 11}}},
+    {&grpc_static_metadata_refcounts[90], {{g_bytes + 954, 6}}},
+    {&grpc_static_metadata_refcounts[91], {{g_bytes + 960, 10}}},
+    {&grpc_static_metadata_refcounts[92], {{g_bytes + 970, 25}}},
+    {&grpc_static_metadata_refcounts[93], {{g_bytes + 995, 17}}},
+    {&grpc_static_metadata_refcounts[94], {{g_bytes + 1012, 4}}},
+    {&grpc_static_metadata_refcounts[95], {{g_bytes + 1016, 3}}},
+    {&grpc_static_metadata_refcounts[96], {{g_bytes + 1019, 16}}},
+    {&grpc_static_metadata_refcounts[97], {{g_bytes + 1035, 16}}},
+    {&grpc_static_metadata_refcounts[98], {{g_bytes + 1051, 13}}},
+    {&grpc_static_metadata_refcounts[99], {{g_bytes + 1064, 12}}},
+    {&grpc_static_metadata_refcounts[100], {{g_bytes + 1076, 21}}},
 };
 
 uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = {
@@ -325,16 +328,16 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 6, 6, 8, 8, 2, 4, 4};
 
 static const int8_t elems_r[] = {
-    11, 9,   -3, 0,   10,  27,  -74, 28,  0,   14, -7, 0,  0,  0,  18, 8,  -2,
-    0,  0,   13, 12,  11,  0,   0,   0,   0,   0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,   0,  0,   0,   0,   0,   0,   0,   0,  0,  0,  0,  0,  0,  0,  0,
-    0,  -50, 0,  -33, -55, -56, -57, -58, -57, 0,  40, 39, 38, 37, 36, 35, 34,
-    33, 32,  31, 30,  29,  28,  28,  27,  26,  25, 24, 23, 22, 21, 20, 19, 22,
-    21, 20,  19, 18,  17,  16,  15,  14,  13,  12, 12, 11, 0};
+    11, 9,  -3,  0,  10,  25,  -74, 28,  0,   15,  -7, 0,  0,  0,  12, 9,  -1,
+    0,  0,  14,  13, 13,  0,   0,   0,   0,   0,   0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,   0,  0,   0,   0,   0,   0,   0,   0,  0,  0,  0,  0,  0,  0,
+    0,  0,  -50, 0,  -53, -36, -56, -57, -58, -59, 0,  40, 39, 38, 37, 36, 35,
+    34, 33, 32,  31, 30,  29,  28,  28,  27,  26,  25, 24, 23, 22, 21, 20, 19,
+    22, 21, 20,  19, 18,  17,  16,  15,  14,  13,  12, 12, 11, 0};
 static uint32_t elems_phash(uint32_t i) {
-  i -= 45;
-  uint32_t x = i % 98;
-  uint32_t y = i / 98;
+  i -= 46;
+  uint32_t x = i % 99;
+  uint32_t y = i / 99;
   uint32_t h = x;
   if (y < GPR_ARRAY_SIZE(elems_r)) {
     uint32_t delta = (uint32_t)elems_r[y];
@@ -344,31 +347,31 @@
 }
 
 static const uint16_t elem_keys[] = {
-    1032, 1033, 1034, 247,  248,  249,  250,  251,  1623, 143,  144,  45,
-    46,   440,  441,  442,  1523, 1632, 1633, 932,  933,  934,  729,  730,
-    1423, 1532, 1533, 535,  731,  1923, 2023, 2123, 5223, 5523, 5623, 5723,
-    5823, 1436, 1653, 5923, 6023, 6123, 6223, 6323, 6423, 6523, 6623, 6723,
-    6823, 6923, 7023, 7123, 7223, 5423, 7323, 7423, 7523, 7623, 7723, 7823,
-    7923, 8023, 8123, 8223, 1096, 1097, 1098, 1099, 8323, 8423, 8523, 8623,
-    8723, 8823, 8923, 9023, 9123, 9223, 9323, 323,  9423, 9523, 1697, 0,
+    1043, 1044, 1045, 250,  251,  252,  253,  254,  1639, 145,  146,  46,
+    47,   445,  446,  447,  1538, 1437, 1649, 1650, 942,  943,  944,  737,
+    738,  541,  1548, 1549, 739,  1942, 2043, 1451, 2144, 5376, 5578, 5780,
+    5881, 5982, 6083, 1670, 6184, 6285, 6386, 6487, 6588, 6689, 6790, 6891,
+    6992, 7093, 7194, 7295, 7396, 5679, 7497, 7598, 7699, 7800, 7901, 8002,
+    8103, 8204, 8305, 8406, 1107, 1108, 1109, 1110, 8507, 8608, 8709, 8810,
+    8911, 9012, 9113, 9214, 9315, 9416, 9517, 326,  9618, 9719, 0,    1714,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    137,  238,  239,  0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    139,  241,  242,  0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0};
+    0,    0,    0,    0,    0,    0};
 static const uint8_t elem_idxs[] = {
     76,  79,  77,  19,  20,  21,  22,  23,  25,  15,  16,  17,  18,  11,
-    12,  13,  38,  83,  84,  3,   4,   5,   0,   1,   43,  36,  37,  6,
-    2,   72,  50,  57,  24,  28,  29,  30,  31,  7,   26,  32,  33,  34,
-    35,  39,  40,  41,  42,  44,  45,  46,  47,  48,  49,  27,  51,  52,
+    12,  13,  38,  43,  83,  84,  3,   4,   5,   0,   1,   6,   36,  37,
+    2,   72,  50,  7,   57,  24,  27,  29,  30,  31,  32,  26,  33,  34,
+    35,  39,  40,  41,  42,  44,  45,  46,  47,  48,  49,  28,  51,  52,
     53,  54,  55,  56,  58,  59,  60,  61,  78,  80,  81,  82,  62,  63,
-    64,  65,  66,  67,  68,  69,  70,  71,  73,  14,  74,  75,  85,  255,
+    64,  65,  66,  67,  68,  69,  70,  71,  73,  14,  74,  75,  255, 85,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-    255, 255, 255, 255, 255, 8,   9,   10};
+    255, 255, 255, 255, 255, 255, 8,   9,   10};
 
 grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) {
   if (a == -1 || b == -1) return GRPC_MDNULL;
-  uint32_t k = (uint32_t)(a * 100 + b);
+  uint32_t k = (uint32_t)(a * 101 + b);
   uint32_t h = elems_phash(k);
   return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k &&
                  elem_idxs[h] != 255
@@ -379,177 +382,177 @@
 
 grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {
     {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}},
-     {&grpc_static_metadata_refcounts[29], {{g_bytes + 430, 1}}}},
+     {&grpc_static_metadata_refcounts[30], {{g_bytes + 441, 1}}}},
     {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}},
-     {&grpc_static_metadata_refcounts[30], {{g_bytes + 431, 1}}}},
+     {&grpc_static_metadata_refcounts[31], {{g_bytes + 442, 1}}}},
     {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}},
-     {&grpc_static_metadata_refcounts[31], {{g_bytes + 432, 1}}}},
+     {&grpc_static_metadata_refcounts[32], {{g_bytes + 443, 1}}}},
     {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}},
-     {&grpc_static_metadata_refcounts[32], {{g_bytes + 433, 8}}}},
+     {&grpc_static_metadata_refcounts[33], {{g_bytes + 444, 8}}}},
     {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}},
-     {&grpc_static_metadata_refcounts[33], {{g_bytes + 441, 4}}}},
+     {&grpc_static_metadata_refcounts[34], {{g_bytes + 452, 4}}}},
     {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}},
-     {&grpc_static_metadata_refcounts[34], {{g_bytes + 445, 7}}}},
+     {&grpc_static_metadata_refcounts[35], {{g_bytes + 456, 7}}}},
     {{&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}},
-     {&grpc_static_metadata_refcounts[35], {{g_bytes + 452, 8}}}},
+     {&grpc_static_metadata_refcounts[36], {{g_bytes + 463, 8}}}},
     {{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}},
-     {&grpc_static_metadata_refcounts[36], {{g_bytes + 460, 16}}}},
+     {&grpc_static_metadata_refcounts[37], {{g_bytes + 471, 16}}}},
     {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}},
-     {&grpc_static_metadata_refcounts[37], {{g_bytes + 476, 4}}}},
+     {&grpc_static_metadata_refcounts[38], {{g_bytes + 487, 4}}}},
     {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
-     {&grpc_static_metadata_refcounts[38], {{g_bytes + 480, 3}}}},
+     {&grpc_static_metadata_refcounts[39], {{g_bytes + 491, 3}}}},
     {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
-     {&grpc_static_metadata_refcounts[39], {{g_bytes + 483, 3}}}},
+     {&grpc_static_metadata_refcounts[40], {{g_bytes + 494, 3}}}},
     {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}},
-     {&grpc_static_metadata_refcounts[40], {{g_bytes + 486, 4}}}},
+     {&grpc_static_metadata_refcounts[41], {{g_bytes + 497, 4}}}},
     {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}},
-     {&grpc_static_metadata_refcounts[41], {{g_bytes + 490, 5}}}},
+     {&grpc_static_metadata_refcounts[42], {{g_bytes + 501, 5}}}},
     {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}},
-     {&grpc_static_metadata_refcounts[42], {{g_bytes + 495, 4}}}},
+     {&grpc_static_metadata_refcounts[43], {{g_bytes + 506, 4}}}},
     {{&grpc_static_metadata_refcounts[3], {{g_bytes + 19, 10}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
     {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}},
-     {&grpc_static_metadata_refcounts[43], {{g_bytes + 499, 3}}}},
+     {&grpc_static_metadata_refcounts[44], {{g_bytes + 510, 3}}}},
     {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}},
-     {&grpc_static_metadata_refcounts[44], {{g_bytes + 502, 3}}}},
+     {&grpc_static_metadata_refcounts[45], {{g_bytes + 513, 3}}}},
     {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}},
-     {&grpc_static_metadata_refcounts[45], {{g_bytes + 505, 1}}}},
+     {&grpc_static_metadata_refcounts[46], {{g_bytes + 516, 1}}}},
     {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}},
-     {&grpc_static_metadata_refcounts[46], {{g_bytes + 506, 11}}}},
+     {&grpc_static_metadata_refcounts[47], {{g_bytes + 517, 11}}}},
     {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
-     {&grpc_static_metadata_refcounts[47], {{g_bytes + 517, 3}}}},
+     {&grpc_static_metadata_refcounts[48], {{g_bytes + 528, 3}}}},
     {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
-     {&grpc_static_metadata_refcounts[48], {{g_bytes + 520, 3}}}},
+     {&grpc_static_metadata_refcounts[49], {{g_bytes + 531, 3}}}},
     {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
-     {&grpc_static_metadata_refcounts[49], {{g_bytes + 523, 3}}}},
+     {&grpc_static_metadata_refcounts[50], {{g_bytes + 534, 3}}}},
     {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
-     {&grpc_static_metadata_refcounts[50], {{g_bytes + 526, 3}}}},
+     {&grpc_static_metadata_refcounts[51], {{g_bytes + 537, 3}}}},
     {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
-     {&grpc_static_metadata_refcounts[51], {{g_bytes + 529, 3}}}},
-    {{&grpc_static_metadata_refcounts[52], {{g_bytes + 532, 14}}},
+     {&grpc_static_metadata_refcounts[52], {{g_bytes + 540, 3}}}},
+    {{&grpc_static_metadata_refcounts[53], {{g_bytes + 543, 14}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
     {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
     {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
-     {&grpc_static_metadata_refcounts[53], {{g_bytes + 546, 13}}}},
-    {{&grpc_static_metadata_refcounts[54], {{g_bytes + 559, 15}}},
+     {&grpc_static_metadata_refcounts[54], {{g_bytes + 557, 13}}}},
+    {{&grpc_static_metadata_refcounts[55], {{g_bytes + 570, 15}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[55], {{g_bytes + 574, 13}}},
+    {{&grpc_static_metadata_refcounts[56], {{g_bytes + 585, 13}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[56], {{g_bytes + 587, 6}}},
+    {{&grpc_static_metadata_refcounts[57], {{g_bytes + 598, 6}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[57], {{g_bytes + 593, 27}}},
+    {{&grpc_static_metadata_refcounts[58], {{g_bytes + 604, 27}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[58], {{g_bytes + 620, 3}}},
+    {{&grpc_static_metadata_refcounts[59], {{g_bytes + 631, 3}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[59], {{g_bytes + 623, 5}}},
+    {{&grpc_static_metadata_refcounts[60], {{g_bytes + 634, 5}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[60], {{g_bytes + 628, 13}}},
+    {{&grpc_static_metadata_refcounts[61], {{g_bytes + 639, 13}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[61], {{g_bytes + 641, 13}}},
+    {{&grpc_static_metadata_refcounts[62], {{g_bytes + 652, 13}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[62], {{g_bytes + 654, 19}}},
+    {{&grpc_static_metadata_refcounts[63], {{g_bytes + 665, 19}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
     {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}},
-     {&grpc_static_metadata_refcounts[32], {{g_bytes + 433, 8}}}},
+     {&grpc_static_metadata_refcounts[33], {{g_bytes + 444, 8}}}},
     {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}},
-     {&grpc_static_metadata_refcounts[33], {{g_bytes + 441, 4}}}},
+     {&grpc_static_metadata_refcounts[34], {{g_bytes + 452, 4}}}},
     {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[63], {{g_bytes + 673, 16}}},
+    {{&grpc_static_metadata_refcounts[64], {{g_bytes + 684, 16}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[64], {{g_bytes + 689, 14}}},
+    {{&grpc_static_metadata_refcounts[65], {{g_bytes + 700, 14}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[65], {{g_bytes + 703, 16}}},
+    {{&grpc_static_metadata_refcounts[66], {{g_bytes + 714, 16}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[66], {{g_bytes + 719, 13}}},
+    {{&grpc_static_metadata_refcounts[67], {{g_bytes + 730, 13}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
     {{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[67], {{g_bytes + 732, 6}}},
+    {{&grpc_static_metadata_refcounts[68], {{g_bytes + 743, 6}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[68], {{g_bytes + 738, 4}}},
+    {{&grpc_static_metadata_refcounts[69], {{g_bytes + 749, 4}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[69], {{g_bytes + 742, 4}}},
+    {{&grpc_static_metadata_refcounts[70], {{g_bytes + 753, 4}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[70], {{g_bytes + 746, 6}}},
+    {{&grpc_static_metadata_refcounts[71], {{g_bytes + 757, 6}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[71], {{g_bytes + 752, 7}}},
+    {{&grpc_static_metadata_refcounts[72], {{g_bytes + 763, 7}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[72], {{g_bytes + 759, 4}}},
+    {{&grpc_static_metadata_refcounts[73], {{g_bytes + 770, 4}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
     {{&grpc_static_metadata_refcounts[20], {{g_bytes + 278, 4}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[73], {{g_bytes + 763, 8}}},
+    {{&grpc_static_metadata_refcounts[74], {{g_bytes + 774, 8}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[74], {{g_bytes + 771, 17}}},
+    {{&grpc_static_metadata_refcounts[75], {{g_bytes + 782, 17}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[75], {{g_bytes + 788, 13}}},
+    {{&grpc_static_metadata_refcounts[76], {{g_bytes + 799, 13}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[76], {{g_bytes + 801, 8}}},
+    {{&grpc_static_metadata_refcounts[77], {{g_bytes + 812, 8}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[77], {{g_bytes + 809, 19}}},
+    {{&grpc_static_metadata_refcounts[78], {{g_bytes + 820, 19}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[78], {{g_bytes + 828, 13}}},
+    {{&grpc_static_metadata_refcounts[79], {{g_bytes + 839, 13}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
     {{&grpc_static_metadata_refcounts[21], {{g_bytes + 282, 8}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[79], {{g_bytes + 841, 11}}},
+    {{&grpc_static_metadata_refcounts[80], {{g_bytes + 852, 11}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[80], {{g_bytes + 852, 4}}},
+    {{&grpc_static_metadata_refcounts[81], {{g_bytes + 863, 4}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[81], {{g_bytes + 856, 8}}},
+    {{&grpc_static_metadata_refcounts[82], {{g_bytes + 867, 8}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[82], {{g_bytes + 864, 12}}},
+    {{&grpc_static_metadata_refcounts[83], {{g_bytes + 875, 12}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[83], {{g_bytes + 876, 18}}},
+    {{&grpc_static_metadata_refcounts[84], {{g_bytes + 887, 18}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[84], {{g_bytes + 894, 19}}},
+    {{&grpc_static_metadata_refcounts[85], {{g_bytes + 905, 19}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[85], {{g_bytes + 913, 5}}},
+    {{&grpc_static_metadata_refcounts[86], {{g_bytes + 924, 5}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[86], {{g_bytes + 918, 7}}},
+    {{&grpc_static_metadata_refcounts[87], {{g_bytes + 929, 7}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[87], {{g_bytes + 925, 7}}},
+    {{&grpc_static_metadata_refcounts[88], {{g_bytes + 936, 7}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[88], {{g_bytes + 932, 11}}},
+    {{&grpc_static_metadata_refcounts[89], {{g_bytes + 943, 11}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[89], {{g_bytes + 943, 6}}},
+    {{&grpc_static_metadata_refcounts[90], {{g_bytes + 954, 6}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[90], {{g_bytes + 949, 10}}},
+    {{&grpc_static_metadata_refcounts[91], {{g_bytes + 960, 10}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[91], {{g_bytes + 959, 25}}},
+    {{&grpc_static_metadata_refcounts[92], {{g_bytes + 970, 25}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[92], {{g_bytes + 984, 17}}},
+    {{&grpc_static_metadata_refcounts[93], {{g_bytes + 995, 17}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
     {{&grpc_static_metadata_refcounts[19], {{g_bytes + 268, 10}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[93], {{g_bytes + 1001, 4}}},
+    {{&grpc_static_metadata_refcounts[94], {{g_bytes + 1012, 4}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[94], {{g_bytes + 1005, 3}}},
+    {{&grpc_static_metadata_refcounts[95], {{g_bytes + 1016, 3}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
-    {{&grpc_static_metadata_refcounts[95], {{g_bytes + 1008, 16}}},
+    {{&grpc_static_metadata_refcounts[96], {{g_bytes + 1019, 16}}},
      {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
     {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
-     {&grpc_static_metadata_refcounts[32], {{g_bytes + 433, 8}}}},
+     {&grpc_static_metadata_refcounts[33], {{g_bytes + 444, 8}}}},
     {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
-     {&grpc_static_metadata_refcounts[34], {{g_bytes + 445, 7}}}},
+     {&grpc_static_metadata_refcounts[35], {{g_bytes + 456, 7}}}},
     {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
-     {&grpc_static_metadata_refcounts[96], {{g_bytes + 1024, 16}}}},
+     {&grpc_static_metadata_refcounts[97], {{g_bytes + 1035, 16}}}},
     {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
-     {&grpc_static_metadata_refcounts[33], {{g_bytes + 441, 4}}}},
+     {&grpc_static_metadata_refcounts[34], {{g_bytes + 452, 4}}}},
     {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
-     {&grpc_static_metadata_refcounts[97], {{g_bytes + 1040, 13}}}},
+     {&grpc_static_metadata_refcounts[98], {{g_bytes + 1051, 13}}}},
     {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
-     {&grpc_static_metadata_refcounts[98], {{g_bytes + 1053, 12}}}},
+     {&grpc_static_metadata_refcounts[99], {{g_bytes + 1064, 12}}}},
     {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
-     {&grpc_static_metadata_refcounts[99], {{g_bytes + 1065, 21}}}},
+     {&grpc_static_metadata_refcounts[100], {{g_bytes + 1076, 21}}}},
     {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
-     {&grpc_static_metadata_refcounts[32], {{g_bytes + 433, 8}}}},
+     {&grpc_static_metadata_refcounts[33], {{g_bytes + 444, 8}}}},
     {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
-     {&grpc_static_metadata_refcounts[33], {{g_bytes + 441, 4}}}},
+     {&grpc_static_metadata_refcounts[34], {{g_bytes + 452, 4}}}},
     {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
-     {&grpc_static_metadata_refcounts[97], {{g_bytes + 1040, 13}}}},
+     {&grpc_static_metadata_refcounts[98], {{g_bytes + 1051, 13}}}},
 };
 bool grpc_static_callout_is_default[GRPC_BATCH_CALLOUTS_COUNT] = {
     true,  // :path
diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h
index 299410f..6b535ac 100644
--- a/src/core/lib/transport/static_metadata.h
+++ b/src/core/lib/transport/static_metadata.h
@@ -33,7 +33,7 @@
 
 #include "src/core/lib/transport/metadata.h"
 
-#define GRPC_STATIC_MDSTR_COUNT 100
+#define GRPC_STATIC_MDSTR_COUNT 101
 extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT];
 /* ":path" */
 #define GRPC_MDSTR_PATH (grpc_static_slice_table[0])
@@ -97,149 +97,151 @@
 /* "/grpc.lb.v1.LoadBalancer/BalanceLoad" */
 #define GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD \
   (grpc_static_slice_table[28])
+/* "stream-gzip" */
+#define GRPC_MDSTR_STREAM_GZIP (grpc_static_slice_table[29])
 /* "0" */
-#define GRPC_MDSTR_0 (grpc_static_slice_table[29])
+#define GRPC_MDSTR_0 (grpc_static_slice_table[30])
 /* "1" */
-#define GRPC_MDSTR_1 (grpc_static_slice_table[30])
+#define GRPC_MDSTR_1 (grpc_static_slice_table[31])
 /* "2" */
-#define GRPC_MDSTR_2 (grpc_static_slice_table[31])
+#define GRPC_MDSTR_2 (grpc_static_slice_table[32])
 /* "identity" */
-#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[32])
+#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[33])
 /* "gzip" */
-#define GRPC_MDSTR_GZIP (grpc_static_slice_table[33])
+#define GRPC_MDSTR_GZIP (grpc_static_slice_table[34])
 /* "deflate" */
-#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[34])
+#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[35])
 /* "trailers" */
-#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[35])
+#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[36])
 /* "application/grpc" */
-#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[36])
+#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[37])
 /* "POST" */
-#define GRPC_MDSTR_POST (grpc_static_slice_table[37])
+#define GRPC_MDSTR_POST (grpc_static_slice_table[38])
 /* "200" */
-#define GRPC_MDSTR_200 (grpc_static_slice_table[38])
+#define GRPC_MDSTR_200 (grpc_static_slice_table[39])
 /* "404" */
-#define GRPC_MDSTR_404 (grpc_static_slice_table[39])
+#define GRPC_MDSTR_404 (grpc_static_slice_table[40])
 /* "http" */
-#define GRPC_MDSTR_HTTP (grpc_static_slice_table[40])
+#define GRPC_MDSTR_HTTP (grpc_static_slice_table[41])
 /* "https" */
-#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[41])
+#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[42])
 /* "grpc" */
-#define GRPC_MDSTR_GRPC (grpc_static_slice_table[42])
+#define GRPC_MDSTR_GRPC (grpc_static_slice_table[43])
 /* "GET" */
-#define GRPC_MDSTR_GET (grpc_static_slice_table[43])
+#define GRPC_MDSTR_GET (grpc_static_slice_table[44])
 /* "PUT" */
-#define GRPC_MDSTR_PUT (grpc_static_slice_table[44])
+#define GRPC_MDSTR_PUT (grpc_static_slice_table[45])
 /* "/" */
-#define GRPC_MDSTR_SLASH (grpc_static_slice_table[45])
+#define GRPC_MDSTR_SLASH (grpc_static_slice_table[46])
 /* "/index.html" */
-#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[46])
+#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[47])
 /* "204" */
-#define GRPC_MDSTR_204 (grpc_static_slice_table[47])
+#define GRPC_MDSTR_204 (grpc_static_slice_table[48])
 /* "206" */
-#define GRPC_MDSTR_206 (grpc_static_slice_table[48])
+#define GRPC_MDSTR_206 (grpc_static_slice_table[49])
 /* "304" */
-#define GRPC_MDSTR_304 (grpc_static_slice_table[49])
+#define GRPC_MDSTR_304 (grpc_static_slice_table[50])
 /* "400" */
-#define GRPC_MDSTR_400 (grpc_static_slice_table[50])
+#define GRPC_MDSTR_400 (grpc_static_slice_table[51])
 /* "500" */
-#define GRPC_MDSTR_500 (grpc_static_slice_table[51])
+#define GRPC_MDSTR_500 (grpc_static_slice_table[52])
 /* "accept-charset" */
-#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[52])
+#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[53])
 /* "gzip, deflate" */
-#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[53])
+#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[54])
 /* "accept-language" */
-#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[54])
+#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[55])
 /* "accept-ranges" */
-#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[55])
+#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[56])
 /* "accept" */
-#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[56])
+#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[57])
 /* "access-control-allow-origin" */
-#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[57])
+#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[58])
 /* "age" */
-#define GRPC_MDSTR_AGE (grpc_static_slice_table[58])
+#define GRPC_MDSTR_AGE (grpc_static_slice_table[59])
 /* "allow" */
-#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[59])
+#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[60])
 /* "authorization" */
-#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[60])
+#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[61])
 /* "cache-control" */
-#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[61])
+#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[62])
 /* "content-disposition" */
-#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[62])
+#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[63])
 /* "content-language" */
-#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[63])
+#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[64])
 /* "content-length" */
-#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[64])
+#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[65])
 /* "content-location" */
-#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[65])
+#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[66])
 /* "content-range" */
-#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[66])
+#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[67])
 /* "cookie" */
-#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[67])
+#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[68])
 /* "date" */
-#define GRPC_MDSTR_DATE (grpc_static_slice_table[68])
+#define GRPC_MDSTR_DATE (grpc_static_slice_table[69])
 /* "etag" */
-#define GRPC_MDSTR_ETAG (grpc_static_slice_table[69])
+#define GRPC_MDSTR_ETAG (grpc_static_slice_table[70])
 /* "expect" */
-#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[70])
+#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[71])
 /* "expires" */
-#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[71])
+#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[72])
 /* "from" */
-#define GRPC_MDSTR_FROM (grpc_static_slice_table[72])
+#define GRPC_MDSTR_FROM (grpc_static_slice_table[73])
 /* "if-match" */
-#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[73])
+#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[74])
 /* "if-modified-since" */
-#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[74])
+#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[75])
 /* "if-none-match" */
-#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[75])
+#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[76])
 /* "if-range" */
-#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[76])
+#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[77])
 /* "if-unmodified-since" */
-#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[77])
+#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[78])
 /* "last-modified" */
-#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[78])
+#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[79])
 /* "lb-cost-bin" */
-#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[79])
+#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[80])
 /* "link" */
-#define GRPC_MDSTR_LINK (grpc_static_slice_table[80])
+#define GRPC_MDSTR_LINK (grpc_static_slice_table[81])
 /* "location" */
-#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[81])
+#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[82])
 /* "max-forwards" */
-#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[82])
+#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[83])
 /* "proxy-authenticate" */
-#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[83])
+#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[84])
 /* "proxy-authorization" */
-#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[84])
+#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[85])
 /* "range" */
-#define GRPC_MDSTR_RANGE (grpc_static_slice_table[85])
+#define GRPC_MDSTR_RANGE (grpc_static_slice_table[86])
 /* "referer" */
-#define GRPC_MDSTR_REFERER (grpc_static_slice_table[86])
+#define GRPC_MDSTR_REFERER (grpc_static_slice_table[87])
 /* "refresh" */
-#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[87])
+#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[88])
 /* "retry-after" */
-#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[88])
+#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[89])
 /* "server" */
-#define GRPC_MDSTR_SERVER (grpc_static_slice_table[89])
+#define GRPC_MDSTR_SERVER (grpc_static_slice_table[90])
 /* "set-cookie" */
-#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[90])
+#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[91])
 /* "strict-transport-security" */
-#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[91])
+#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[92])
 /* "transfer-encoding" */
-#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[92])
+#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[93])
 /* "vary" */
-#define GRPC_MDSTR_VARY (grpc_static_slice_table[93])
+#define GRPC_MDSTR_VARY (grpc_static_slice_table[94])
 /* "via" */
-#define GRPC_MDSTR_VIA (grpc_static_slice_table[94])
+#define GRPC_MDSTR_VIA (grpc_static_slice_table[95])
 /* "www-authenticate" */
-#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[95])
+#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[96])
 /* "identity,deflate" */
-#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[96])
+#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[97])
 /* "identity,gzip" */
-#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[97])
+#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[98])
 /* "deflate,gzip" */
-#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[98])
+#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[99])
 /* "identity,deflate,gzip" */
 #define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \
-  (grpc_static_slice_table[99])
+  (grpc_static_slice_table[100])
 
 extern const grpc_slice_refcount_vtable grpc_static_metadata_vtable;
 extern grpc_slice_refcount
diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
index b0b1223..94b2b79 100644
--- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
+++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
@@ -68,8 +68,6 @@
     _op.data.send_initial_metadata.metadata = metadata.grpc_metadataArray;
     _op.data.send_initial_metadata.maybe_compression_level.is_set = false;
     _op.data.send_initial_metadata.maybe_compression_level.level = 0;
-    _op.data.send_initial_metadata.maybe_stream_compression_level.is_set = false;
-    _op.data.send_initial_metadata.maybe_stream_compression_level.level = 0;
     _op.flags = flags;
     _handler = handler;
   }
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
index f115106..340584d 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
@@ -513,15 +513,19 @@
 
   ctypedef enum grpc_compression_algorithm:
     GRPC_COMPRESS_NONE
-    GRPC_COMPRESS_DEFLATE
-    GRPC_COMPRESS_GZIP
+    GRPC_COMPRESS_MESSAGE_DEFLATE
+    GRPC_COMPRESS_MESSAGE_GZIP
+    GRPC_COMPRESS_STREAM_GZIP
     GRPC_COMPRESS_ALGORITHMS_COUNT
 
   ctypedef enum grpc_compression_level:
     GRPC_COMPRESS_LEVEL_NONE
-    GRPC_COMPRESS_LEVEL_LOW
-    GRPC_COMPRESS_LEVEL_MED
-    GRPC_COMPRESS_LEVEL_HIGH
+    GRPC_COMPRESS_LEVEL_MESSAGE_LOW
+    GRPC_COMPRESS_LEVEL_MESSAGE_MED
+    GRPC_COMPRESS_LEVEL_MESSAGE_HIGH
+    GRPC_COMPRESS_LEVEL_STREAM_LOW
+    GRPC_COMPRESS_LEVEL_STREAM_MED
+    GRPC_COMPRESS_LEVEL_STREAM_HIGH
     GRPC_COMPRESS_LEVEL_COUNT
 
   ctypedef struct grpc_compression_options:
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
index 4f87261..e8e3aa9 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
@@ -112,15 +112,15 @@
 
 class CompressionAlgorithm:
   none = GRPC_COMPRESS_NONE
-  deflate = GRPC_COMPRESS_DEFLATE
-  gzip = GRPC_COMPRESS_GZIP
+  deflate = GRPC_COMPRESS_MESSAGE_DEFLATE
+  gzip = GRPC_COMPRESS_MESSAGE_GZIP
 
 
 class CompressionLevel:
   none = GRPC_COMPRESS_LEVEL_NONE
-  low = GRPC_COMPRESS_LEVEL_LOW
-  medium = GRPC_COMPRESS_LEVEL_MED
-  high = GRPC_COMPRESS_LEVEL_HIGH
+  low = GRPC_COMPRESS_LEVEL_MESSAGE_LOW
+  medium = GRPC_COMPRESS_LEVEL_MESSAGE_MED
+  high = GRPC_COMPRESS_LEVEL_MESSAGE_HIGH
 
 
 cdef class Timespec:
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 140f4ce..f631527 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -70,6 +70,7 @@
   'src/core/lib/channel/handshaker_factory.cc',
   'src/core/lib/channel/handshaker_registry.cc',
   'src/core/lib/compression/compression.cc',
+  'src/core/lib/compression/compression_internal.cc',
   'src/core/lib/compression/message_compress.cc',
   'src/core/lib/compression/stream_compression.cc',
   'src/core/lib/compression/stream_compression_gzip.cc',
diff --git a/src/ruby/ext/grpc/rb_compression_options.c b/src/ruby/ext/grpc/rb_compression_options.c
index 3365b17..507d5c3 100644
--- a/src/ruby/ext/grpc/rb_compression_options.c
+++ b/src/ruby/ext/grpc/rb_compression_options.c
@@ -127,11 +127,11 @@
   if (id_compress_level_none == SYM2ID(level_name)) {
     return GRPC_COMPRESS_LEVEL_NONE;
   } else if (id_compress_level_low == SYM2ID(level_name)) {
-    return GRPC_COMPRESS_LEVEL_LOW;
+    return GRPC_COMPRESS_LEVEL_MESSAGE_LOW;
   } else if (id_compress_level_medium == SYM2ID(level_name)) {
-    return GRPC_COMPRESS_LEVEL_MED;
+    return GRPC_COMPRESS_LEVEL_MESSAGE_MED;
   } else if (id_compress_level_high == SYM2ID(level_name)) {
-    return GRPC_COMPRESS_LEVEL_HIGH;
+    return GRPC_COMPRESS_LEVEL_MESSAGE_HIGH;
   }
 
   rb_raise(rb_eArgError,
@@ -264,11 +264,11 @@
   switch (compression_value) {
     case GRPC_COMPRESS_LEVEL_NONE:
       return ID2SYM(id_compress_level_none);
-    case GRPC_COMPRESS_LEVEL_LOW:
+    case GRPC_COMPRESS_LEVEL_MESSAGE_LOW:
       return ID2SYM(id_compress_level_low);
-    case GRPC_COMPRESS_LEVEL_MED:
+    case GRPC_COMPRESS_LEVEL_MESSAGE_MED:
       return ID2SYM(id_compress_level_medium);
-    case GRPC_COMPRESS_LEVEL_HIGH:
+    case GRPC_COMPRESS_LEVEL_MESSAGE_HIGH:
       return ID2SYM(id_compress_level_high);
     default:
       rb_raise(
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
index 7083149..9e6b026 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
@@ -50,16 +50,15 @@
 census_delete_resource_type census_delete_resource_import;
 census_resource_id_type census_resource_id_import;
 census_record_values_type census_record_values_import;
+grpc_compression_algorithm_is_message_type grpc_compression_algorithm_is_message_import;
+grpc_compression_algorithm_is_stream_type grpc_compression_algorithm_is_stream_import;
 grpc_compression_algorithm_parse_type grpc_compression_algorithm_parse_import;
 grpc_compression_algorithm_name_type grpc_compression_algorithm_name_import;
-grpc_stream_compression_algorithm_name_type grpc_stream_compression_algorithm_name_import;
 grpc_compression_algorithm_for_level_type grpc_compression_algorithm_for_level_import;
-grpc_stream_compression_algorithm_for_level_type grpc_stream_compression_algorithm_for_level_import;
 grpc_compression_options_init_type grpc_compression_options_init_import;
 grpc_compression_options_enable_algorithm_type grpc_compression_options_enable_algorithm_import;
 grpc_compression_options_disable_algorithm_type grpc_compression_options_disable_algorithm_import;
 grpc_compression_options_is_algorithm_enabled_type grpc_compression_options_is_algorithm_enabled_import;
-grpc_compression_options_is_stream_compression_algorithm_enabled_type grpc_compression_options_is_stream_compression_algorithm_enabled_import;
 grpc_metadata_array_init_type grpc_metadata_array_init_import;
 grpc_metadata_array_destroy_type grpc_metadata_array_destroy_import;
 grpc_call_details_init_type grpc_call_details_init_import;
@@ -358,16 +357,15 @@
   census_delete_resource_import = (census_delete_resource_type) GetProcAddress(library, "census_delete_resource");
   census_resource_id_import = (census_resource_id_type) GetProcAddress(library, "census_resource_id");
   census_record_values_import = (census_record_values_type) GetProcAddress(library, "census_record_values");
+  grpc_compression_algorithm_is_message_import = (grpc_compression_algorithm_is_message_type) GetProcAddress(library, "grpc_compression_algorithm_is_message");
+  grpc_compression_algorithm_is_stream_import = (grpc_compression_algorithm_is_stream_type) GetProcAddress(library, "grpc_compression_algorithm_is_stream");
   grpc_compression_algorithm_parse_import = (grpc_compression_algorithm_parse_type) GetProcAddress(library, "grpc_compression_algorithm_parse");
   grpc_compression_algorithm_name_import = (grpc_compression_algorithm_name_type) GetProcAddress(library, "grpc_compression_algorithm_name");
-  grpc_stream_compression_algorithm_name_import = (grpc_stream_compression_algorithm_name_type) GetProcAddress(library, "grpc_stream_compression_algorithm_name");
   grpc_compression_algorithm_for_level_import = (grpc_compression_algorithm_for_level_type) GetProcAddress(library, "grpc_compression_algorithm_for_level");
-  grpc_stream_compression_algorithm_for_level_import = (grpc_stream_compression_algorithm_for_level_type) GetProcAddress(library, "grpc_stream_compression_algorithm_for_level");
   grpc_compression_options_init_import = (grpc_compression_options_init_type) GetProcAddress(library, "grpc_compression_options_init");
   grpc_compression_options_enable_algorithm_import = (grpc_compression_options_enable_algorithm_type) GetProcAddress(library, "grpc_compression_options_enable_algorithm");
   grpc_compression_options_disable_algorithm_import = (grpc_compression_options_disable_algorithm_type) GetProcAddress(library, "grpc_compression_options_disable_algorithm");
   grpc_compression_options_is_algorithm_enabled_import = (grpc_compression_options_is_algorithm_enabled_type) GetProcAddress(library, "grpc_compression_options_is_algorithm_enabled");
-  grpc_compression_options_is_stream_compression_algorithm_enabled_import = (grpc_compression_options_is_stream_compression_algorithm_enabled_type) GetProcAddress(library, "grpc_compression_options_is_stream_compression_algorithm_enabled");
   grpc_metadata_array_init_import = (grpc_metadata_array_init_type) GetProcAddress(library, "grpc_metadata_array_init");
   grpc_metadata_array_destroy_import = (grpc_metadata_array_destroy_type) GetProcAddress(library, "grpc_metadata_array_destroy");
   grpc_call_details_init_import = (grpc_call_details_init_type) GetProcAddress(library, "grpc_call_details_init");
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
index 868772c..916deb4 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -131,21 +131,21 @@
 typedef void(*census_record_values_type)(census_context *context, census_value *values, size_t nvalues);
 extern census_record_values_type census_record_values_import;
 #define census_record_values census_record_values_import
+typedef int(*grpc_compression_algorithm_is_message_type)(grpc_compression_algorithm algorithm);
+extern grpc_compression_algorithm_is_message_type grpc_compression_algorithm_is_message_import;
+#define grpc_compression_algorithm_is_message grpc_compression_algorithm_is_message_import
+typedef int(*grpc_compression_algorithm_is_stream_type)(grpc_compression_algorithm algorithm);
+extern grpc_compression_algorithm_is_stream_type grpc_compression_algorithm_is_stream_import;
+#define grpc_compression_algorithm_is_stream grpc_compression_algorithm_is_stream_import
 typedef int(*grpc_compression_algorithm_parse_type)(grpc_slice value, grpc_compression_algorithm *algorithm);
 extern grpc_compression_algorithm_parse_type grpc_compression_algorithm_parse_import;
 #define grpc_compression_algorithm_parse grpc_compression_algorithm_parse_import
 typedef int(*grpc_compression_algorithm_name_type)(grpc_compression_algorithm algorithm, const char **name);
 extern grpc_compression_algorithm_name_type grpc_compression_algorithm_name_import;
 #define grpc_compression_algorithm_name grpc_compression_algorithm_name_import
-typedef int(*grpc_stream_compression_algorithm_name_type)(grpc_stream_compression_algorithm algorithm, const char **name);
-extern grpc_stream_compression_algorithm_name_type grpc_stream_compression_algorithm_name_import;
-#define grpc_stream_compression_algorithm_name grpc_stream_compression_algorithm_name_import
 typedef grpc_compression_algorithm(*grpc_compression_algorithm_for_level_type)(grpc_compression_level level, uint32_t accepted_encodings);
 extern grpc_compression_algorithm_for_level_type grpc_compression_algorithm_for_level_import;
 #define grpc_compression_algorithm_for_level grpc_compression_algorithm_for_level_import
-typedef grpc_stream_compression_algorithm(*grpc_stream_compression_algorithm_for_level_type)(grpc_stream_compression_level level, uint32_t accepted_stream_encodings);
-extern grpc_stream_compression_algorithm_for_level_type grpc_stream_compression_algorithm_for_level_import;
-#define grpc_stream_compression_algorithm_for_level grpc_stream_compression_algorithm_for_level_import
 typedef void(*grpc_compression_options_init_type)(grpc_compression_options *opts);
 extern grpc_compression_options_init_type grpc_compression_options_init_import;
 #define grpc_compression_options_init grpc_compression_options_init_import
@@ -158,9 +158,6 @@
 typedef int(*grpc_compression_options_is_algorithm_enabled_type)(const grpc_compression_options *opts, grpc_compression_algorithm algorithm);
 extern grpc_compression_options_is_algorithm_enabled_type grpc_compression_options_is_algorithm_enabled_import;
 #define grpc_compression_options_is_algorithm_enabled grpc_compression_options_is_algorithm_enabled_import
-typedef int(*grpc_compression_options_is_stream_compression_algorithm_enabled_type)(const grpc_compression_options *opts, grpc_stream_compression_algorithm algorithm);
-extern grpc_compression_options_is_stream_compression_algorithm_enabled_type grpc_compression_options_is_stream_compression_algorithm_enabled_import;
-#define grpc_compression_options_is_stream_compression_algorithm_enabled grpc_compression_options_is_stream_compression_algorithm_enabled_import
 typedef void(*grpc_metadata_array_init_type)(grpc_metadata_array *array);
 extern grpc_metadata_array_init_type grpc_metadata_array_init_import;
 #define grpc_metadata_array_init grpc_metadata_array_init_import
diff --git a/test/core/channel/channel_args_test.c b/test/core/channel/channel_args_test.c
index deaf293..ab0e045 100644
--- a/test/core/channel/channel_args_test.c
+++ b/test/core/channel/channel_args_test.c
@@ -63,8 +63,8 @@
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_channel_args *ch_args;
 
-  ch_args =
-      grpc_channel_args_set_compression_algorithm(NULL, GRPC_COMPRESS_GZIP);
+  ch_args = grpc_channel_args_set_compression_algorithm(
+      NULL, GRPC_COMPRESS_MESSAGE_GZIP);
   GPR_ASSERT(ch_args->num_args == 1);
   GPR_ASSERT(strcmp(ch_args->args[0].key,
                     GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM) == 0);
@@ -76,7 +76,8 @@
 
 static void test_compression_algorithm_states(void) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_channel_args *ch_args, *ch_args_wo_gzip, *ch_args_wo_gzip_deflate;
+  grpc_channel_args *ch_args, *ch_args_wo_gzip, *ch_args_wo_gzip_deflate,
+      *ch_args_wo_gzip_deflate_gzip;
   unsigned states_bitset;
   size_t i;
 
@@ -89,33 +90,40 @@
     GPR_ASSERT(GPR_BITGET(states_bitset, i));
   }
 
-  /* disable gzip and deflate */
+  /* disable gzip, deflate and stream-gzip */
   ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state(
-      &exec_ctx, &ch_args, GRPC_COMPRESS_GZIP, 0);
+      &exec_ctx, &ch_args, GRPC_COMPRESS_MESSAGE_GZIP, 0);
   GPR_ASSERT(ch_args == ch_args_wo_gzip);
   ch_args_wo_gzip_deflate = grpc_channel_args_compression_algorithm_set_state(
-      &exec_ctx, &ch_args_wo_gzip, GRPC_COMPRESS_DEFLATE, 0);
+      &exec_ctx, &ch_args_wo_gzip, GRPC_COMPRESS_MESSAGE_DEFLATE, 0);
   GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate);
+  ch_args_wo_gzip_deflate_gzip =
+      grpc_channel_args_compression_algorithm_set_state(
+          &exec_ctx, &ch_args_wo_gzip_deflate, GRPC_COMPRESS_STREAM_GZIP, 0);
+  GPR_ASSERT(ch_args_wo_gzip_deflate == ch_args_wo_gzip_deflate_gzip);
 
   states_bitset = (unsigned)grpc_channel_args_compression_algorithm_get_states(
       ch_args_wo_gzip_deflate);
   for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) {
-    if (i == GRPC_COMPRESS_GZIP || i == GRPC_COMPRESS_DEFLATE) {
+    if (i == GRPC_COMPRESS_MESSAGE_GZIP || i == GRPC_COMPRESS_MESSAGE_DEFLATE ||
+        i == GRPC_COMPRESS_STREAM_GZIP) {
       GPR_ASSERT(GPR_BITGET(states_bitset, i) == 0);
     } else {
       GPR_ASSERT(GPR_BITGET(states_bitset, i) != 0);
     }
   }
 
-  /* re-enabled gzip only */
+  /* re-enabled gzip and stream-gzip only */
   ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state(
-      &exec_ctx, &ch_args_wo_gzip_deflate, GRPC_COMPRESS_GZIP, 1);
-  GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate);
+      &exec_ctx, &ch_args_wo_gzip_deflate_gzip, GRPC_COMPRESS_MESSAGE_GZIP, 1);
+  ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state(
+      &exec_ctx, &ch_args_wo_gzip, GRPC_COMPRESS_STREAM_GZIP, 1);
+  GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate_gzip);
 
   states_bitset = (unsigned)grpc_channel_args_compression_algorithm_get_states(
       ch_args_wo_gzip);
   for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) {
-    if (i == GRPC_COMPRESS_DEFLATE) {
+    if (i == GRPC_COMPRESS_MESSAGE_DEFLATE) {
       GPR_ASSERT(GPR_BITGET(states_bitset, i) == 0);
     } else {
       GPR_ASSERT(GPR_BITGET(states_bitset, i) != 0);
diff --git a/test/core/compression/BUILD b/test/core/compression/BUILD
index 1ab6e35..dbeb89a 100644
--- a/test/core/compression/BUILD
+++ b/test/core/compression/BUILD
@@ -53,3 +53,15 @@
         "//test/core/util:grpc_test_util",
     ],
 )
+
+grpc_cc_test(
+    name = "stream_compress_test",
+    srcs = ["stream_compression_test.c"],
+    language = "C",
+    deps = [
+        "//:gpr",
+        "//:grpc",
+        "//test/core/util:gpr_test_util",
+        "//test/core/util:grpc_test_util",
+    ],
+)
diff --git a/test/core/compression/algorithm_test.c b/test/core/compression/algorithm_test.c
index a11e6e9..d637e2c 100644
--- a/test/core/compression/algorithm_test.c
+++ b/test/core/compression/algorithm_test.c
@@ -29,6 +29,8 @@
 #include "src/core/lib/transport/static_metadata.h"
 #include "test/core/util/test_config.h"
 
+const uint32_t message_prefix_length = 8;
+const uint32_t stream_prefix_length = 7;
 static void test_algorithm_mesh(void) {
   int i;
 
@@ -48,9 +50,26 @@
     mdstr = grpc_slice_from_copied_string(name);
     GPR_ASSERT(grpc_slice_eq(mdstr, grpc_compression_algorithm_slice(parsed)));
     GPR_ASSERT(parsed == grpc_compression_algorithm_from_slice(mdstr));
-    mdelem = grpc_compression_encoding_mdelem(parsed);
-    GPR_ASSERT(grpc_slice_eq(GRPC_MDVALUE(mdelem), mdstr));
-    GPR_ASSERT(grpc_slice_eq(GRPC_MDKEY(mdelem), GRPC_MDSTR_GRPC_ENCODING));
+    if (parsed == 0) {
+      continue;
+    } else if (grpc_compression_algorithm_is_message(parsed)) {
+      mdelem = grpc_message_compression_encoding_mdelem(
+          grpc_compression_algorithm_to_message_compression_algorithm(parsed));
+      grpc_slice value = GRPC_MDVALUE(mdelem);
+      GPR_ASSERT(0 == memcmp(&name[message_prefix_length],
+                             GRPC_SLICE_START_PTR(value),
+                             GRPC_SLICE_LENGTH(value)));
+      GPR_ASSERT(grpc_slice_eq(GRPC_MDKEY(mdelem), GRPC_MDSTR_GRPC_ENCODING));
+    } else {
+      mdelem = grpc_stream_compression_encoding_mdelem(
+          grpc_compression_algorithm_to_stream_compression_algorithm(parsed));
+      grpc_slice value = GRPC_MDVALUE(mdelem);
+      GPR_ASSERT(0 == memcmp(&name[stream_prefix_length],
+                             GRPC_SLICE_START_PTR(value),
+                             GRPC_SLICE_LENGTH(value)));
+      GPR_ASSERT(
+          grpc_slice_eq(GRPC_MDKEY(mdelem), GRPC_MDSTR_CONTENT_ENCODING));
+    }
     grpc_slice_unref_internal(&exec_ctx, mdstr);
     GRPC_MDELEM_UNREF(&exec_ctx, mdelem);
     grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/compression/compression_test.c b/test/core/compression/compression_test.c
index 326a800..45a1cf4 100644
--- a/test/core/compression/compression_test.c
+++ b/test/core/compression/compression_test.c
@@ -28,9 +28,10 @@
 
 static void test_compression_algorithm_parse(void) {
   size_t i;
-  const char *valid_names[] = {"identity", "gzip", "deflate"};
+  const char *valid_names[] = {"identity", "gzip", "deflate", "stream-gzip"};
   const grpc_compression_algorithm valid_algorithms[] = {
-      GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_DEFLATE};
+      GRPC_COMPRESS_NONE, GRPC_COMPRESS_MESSAGE_GZIP,
+      GRPC_COMPRESS_MESSAGE_DEFLATE, GRPC_COMPRESS_STREAM_GZIP};
   const char *invalid_names[] = {"gzip2", "foo", "", "2gzip"};
 
   gpr_log(GPR_DEBUG, "test_compression_algorithm_parse");
@@ -59,9 +60,10 @@
   int success;
   const char *name;
   size_t i;
-  const char *valid_names[] = {"identity", "gzip", "deflate"};
+  const char *valid_names[] = {"identity", "gzip", "deflate", "stream-gzip"};
   const grpc_compression_algorithm valid_algorithms[] = {
-      GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_DEFLATE};
+      GRPC_COMPRESS_NONE, GRPC_COMPRESS_MESSAGE_GZIP,
+      GRPC_COMPRESS_MESSAGE_DEFLATE, GRPC_COMPRESS_STREAM_GZIP};
 
   gpr_log(GPR_DEBUG, "test_compression_algorithm_name");
 
@@ -90,86 +92,206 @@
                                                     accepted_encodings));
 
     GPR_ASSERT(GRPC_COMPRESS_NONE ==
-               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_LOW,
-                                                    accepted_encodings));
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_MESSAGE_LOW, accepted_encodings));
 
     GPR_ASSERT(GRPC_COMPRESS_NONE ==
-               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_MED,
-                                                    accepted_encodings));
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_MESSAGE_MED, accepted_encodings));
 
     GPR_ASSERT(GRPC_COMPRESS_NONE ==
-               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_HIGH,
-                                                    accepted_encodings));
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_MESSAGE_HIGH, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_STREAM_LOW, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_STREAM_MED, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_STREAM_HIGH, accepted_encodings));
   }
 
   {
     /* accept only gzip */
     uint32_t accepted_encodings = 0;
     GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_NONE); /* always */
-    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_GZIP);
+    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_MESSAGE_GZIP);
 
     GPR_ASSERT(GRPC_COMPRESS_NONE ==
                grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_NONE,
                                                     accepted_encodings));
 
-    GPR_ASSERT(GRPC_COMPRESS_GZIP ==
-               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_LOW,
-                                                    accepted_encodings));
+    GPR_ASSERT(GRPC_COMPRESS_MESSAGE_GZIP ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_MESSAGE_LOW, accepted_encodings));
 
-    GPR_ASSERT(GRPC_COMPRESS_GZIP ==
-               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_MED,
-                                                    accepted_encodings));
+    GPR_ASSERT(GRPC_COMPRESS_MESSAGE_GZIP ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_MESSAGE_MED, accepted_encodings));
 
-    GPR_ASSERT(GRPC_COMPRESS_GZIP ==
-               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_HIGH,
-                                                    accepted_encodings));
+    GPR_ASSERT(GRPC_COMPRESS_MESSAGE_GZIP ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_MESSAGE_HIGH, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_STREAM_LOW, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_STREAM_MED, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_STREAM_HIGH, accepted_encodings));
   }
 
   {
     /* accept only deflate */
     uint32_t accepted_encodings = 0;
     GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_NONE); /* always */
-    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_DEFLATE);
+    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_MESSAGE_DEFLATE);
 
     GPR_ASSERT(GRPC_COMPRESS_NONE ==
                grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_NONE,
                                                     accepted_encodings));
 
-    GPR_ASSERT(GRPC_COMPRESS_DEFLATE ==
-               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_LOW,
-                                                    accepted_encodings));
+    GPR_ASSERT(GRPC_COMPRESS_MESSAGE_DEFLATE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_MESSAGE_LOW, accepted_encodings));
 
-    GPR_ASSERT(GRPC_COMPRESS_DEFLATE ==
-               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_MED,
-                                                    accepted_encodings));
+    GPR_ASSERT(GRPC_COMPRESS_MESSAGE_DEFLATE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_MESSAGE_MED, accepted_encodings));
 
-    GPR_ASSERT(GRPC_COMPRESS_DEFLATE ==
-               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_HIGH,
-                                                    accepted_encodings));
+    GPR_ASSERT(GRPC_COMPRESS_MESSAGE_DEFLATE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_MESSAGE_HIGH, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_STREAM_LOW, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_STREAM_MED, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_STREAM_HIGH, accepted_encodings));
   }
 
   {
     /* accept gzip and deflate */
     uint32_t accepted_encodings = 0;
     GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_NONE); /* always */
-    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_GZIP);
-    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_DEFLATE);
+    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_MESSAGE_GZIP);
+    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_MESSAGE_DEFLATE);
 
     GPR_ASSERT(GRPC_COMPRESS_NONE ==
                grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_NONE,
                                                     accepted_encodings));
 
-    GPR_ASSERT(GRPC_COMPRESS_GZIP ==
-               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_LOW,
+    GPR_ASSERT(GRPC_COMPRESS_MESSAGE_GZIP ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_MESSAGE_LOW, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_MESSAGE_DEFLATE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_MESSAGE_MED, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_MESSAGE_DEFLATE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_MESSAGE_HIGH, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_STREAM_LOW, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_STREAM_MED, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_STREAM_HIGH, accepted_encodings));
+  }
+
+  {
+    /* accept stream gzip */
+    uint32_t accepted_encodings = 0;
+    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_NONE); /* always */
+    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_STREAM_GZIP);
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_NONE,
                                                     accepted_encodings));
 
-    GPR_ASSERT(GRPC_COMPRESS_DEFLATE ==
-               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_MED,
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_MESSAGE_LOW, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_MESSAGE_MED, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_MESSAGE_HIGH, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_STREAM_GZIP ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_STREAM_LOW, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_STREAM_GZIP ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_STREAM_MED, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_STREAM_GZIP ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_STREAM_HIGH, accepted_encodings));
+  }
+
+  {
+    /* accept all algorithms */
+    uint32_t accepted_encodings = 0;
+    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_NONE); /* always */
+    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_MESSAGE_GZIP);
+    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_MESSAGE_DEFLATE);
+    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_STREAM_GZIP);
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_NONE,
                                                     accepted_encodings));
 
-    GPR_ASSERT(GRPC_COMPRESS_DEFLATE ==
-               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_HIGH,
-                                                    accepted_encodings));
+    GPR_ASSERT(GRPC_COMPRESS_MESSAGE_GZIP ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_MESSAGE_LOW, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_MESSAGE_DEFLATE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_MESSAGE_MED, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_MESSAGE_DEFLATE ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_MESSAGE_HIGH, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_STREAM_GZIP ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_STREAM_LOW, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_STREAM_GZIP ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_STREAM_MED, accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_STREAM_GZIP ==
+               grpc_compression_algorithm_for_level(
+                   GRPC_COMPRESS_LEVEL_STREAM_HIGH, accepted_encodings));
   }
 }
 
diff --git a/test/core/compression/message_compress_test.c b/test/core/compression/message_compress_test.c
index f7f4893..015664d 100644
--- a/test/core/compression/message_compress_test.c
+++ b/test/core/compression/message_compress_test.c
@@ -39,7 +39,7 @@
 } compressability;
 
 static void assert_passthrough(grpc_slice value,
-                               grpc_compression_algorithm algorithm,
+                               grpc_message_compression_algorithm algorithm,
                                grpc_slice_split_mode uncompressed_split_mode,
                                grpc_slice_split_mode compressed_split_mode,
                                compressability compress_result_check) {
@@ -51,7 +51,8 @@
   int was_compressed;
   const char *algorithm_name;
 
-  GPR_ASSERT(grpc_compression_algorithm_name(algorithm, &algorithm_name) != 0);
+  GPR_ASSERT(
+      grpc_message_compression_algorithm_name(algorithm, &algorithm_name) != 0);
   gpr_log(
       GPR_INFO, "assert_passthrough: value_length=%" PRIuPTR
                 " value_hash=0x%08x "
@@ -93,8 +94,8 @@
   {
     grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     GPR_ASSERT(grpc_msg_decompress(
-        &exec_ctx, was_compressed ? algorithm : GRPC_COMPRESS_NONE, &compressed,
-        &output));
+        &exec_ctx, was_compressed ? algorithm : GRPC_MESSAGE_COMPRESS_NONE,
+        &compressed, &output));
     grpc_exec_ctx_finish(&exec_ctx);
   }
 
@@ -115,8 +116,8 @@
 }
 
 static compressability get_compressability(
-    test_value id, grpc_compression_algorithm algorithm) {
-  if (algorithm == GRPC_COMPRESS_NONE) return SHOULD_NOT_COMPRESS;
+    test_value id, grpc_message_compression_algorithm algorithm) {
+  if (algorithm == GRPC_MESSAGE_COMPRESS_NONE) return SHOULD_NOT_COMPRESS;
   switch (id) {
     case ONE_A:
       return SHOULD_NOT_COMPRESS;
@@ -148,14 +149,14 @@
 static void test_tiny_data_compress(void) {
   grpc_slice_buffer input;
   grpc_slice_buffer output;
-  grpc_compression_algorithm i;
+  grpc_message_compression_algorithm i;
 
   grpc_slice_buffer_init(&input);
   grpc_slice_buffer_init(&output);
   grpc_slice_buffer_add(&input, create_test_value(ONE_A));
 
-  for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) {
-    if (i == GRPC_COMPRESS_NONE) continue;
+  for (i = 0; i < GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT; i++) {
+    if (i == GRPC_MESSAGE_COMPRESS_NONE) continue;
     grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
     GPR_ASSERT(0 == grpc_msg_compress(&exec_ctx, i, &input, &output));
     grpc_exec_ctx_finish(&exec_ctx);
@@ -180,7 +181,7 @@
 
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   /* compress it */
-  grpc_msg_compress(&exec_ctx, GRPC_COMPRESS_GZIP, &input, &corrupted);
+  grpc_msg_compress(&exec_ctx, GRPC_MESSAGE_COMPRESS_GZIP, &input, &corrupted);
   /* corrupt the output by smashing the CRC */
   GPR_ASSERT(corrupted.count > 1);
   GPR_ASSERT(GRPC_SLICE_LENGTH(corrupted.slices[1]) > 8);
@@ -188,8 +189,8 @@
   memcpy(GRPC_SLICE_START_PTR(corrupted.slices[1]) + idx, &bad, 4);
 
   /* try (and fail) to decompress the corrupted compresed buffer */
-  GPR_ASSERT(0 == grpc_msg_decompress(&exec_ctx, GRPC_COMPRESS_GZIP, &corrupted,
-                                      &output));
+  GPR_ASSERT(0 == grpc_msg_decompress(&exec_ctx, GRPC_MESSAGE_COMPRESS_GZIP,
+                                      &corrupted, &output));
   grpc_exec_ctx_finish(&exec_ctx);
 
   grpc_slice_buffer_destroy(&input);
@@ -210,8 +211,8 @@
 
   /* try (and fail) to decompress the invalid compresed buffer */
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  GPR_ASSERT(0 == grpc_msg_decompress(&exec_ctx, GRPC_COMPRESS_DEFLATE, &input,
-                                      &output));
+  GPR_ASSERT(0 == grpc_msg_decompress(&exec_ctx, GRPC_MESSAGE_COMPRESS_DEFLATE,
+                                      &input, &output));
   grpc_exec_ctx_finish(&exec_ctx);
 
   grpc_slice_buffer_destroy(&input);
@@ -229,8 +230,8 @@
 
   /* try (and fail) to decompress the invalid compresed buffer */
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  GPR_ASSERT(0 == grpc_msg_decompress(&exec_ctx, GRPC_COMPRESS_DEFLATE, &input,
-                                      &output));
+  GPR_ASSERT(0 == grpc_msg_decompress(&exec_ctx, GRPC_MESSAGE_COMPRESS_DEFLATE,
+                                      &input, &output));
   grpc_exec_ctx_finish(&exec_ctx);
 
   grpc_slice_buffer_destroy(&input);
@@ -248,12 +249,12 @@
       &input, grpc_slice_from_copied_string("Never gonna give you up"));
 
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  was_compressed = grpc_msg_compress(&exec_ctx, GRPC_COMPRESS_ALGORITHMS_COUNT,
-                                     &input, &output);
+  was_compressed = grpc_msg_compress(
+      &exec_ctx, GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT, &input, &output);
   GPR_ASSERT(0 == was_compressed);
 
   was_compressed = grpc_msg_compress(
-      &exec_ctx, GRPC_COMPRESS_ALGORITHMS_COUNT + 123, &input, &output);
+      &exec_ctx, GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT + 123, &input, &output);
   GPR_ASSERT(0 == was_compressed);
   grpc_exec_ctx_finish(&exec_ctx);
 
@@ -273,11 +274,11 @@
                             "I'm not really compressed but it doesn't matter"));
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   was_decompressed = grpc_msg_decompress(
-      &exec_ctx, GRPC_COMPRESS_ALGORITHMS_COUNT, &input, &output);
+      &exec_ctx, GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT, &input, &output);
   GPR_ASSERT(0 == was_decompressed);
 
   was_decompressed = grpc_msg_decompress(
-      &exec_ctx, GRPC_COMPRESS_ALGORITHMS_COUNT + 123, &input, &output);
+      &exec_ctx, GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT + 123, &input, &output);
   GPR_ASSERT(0 == was_decompressed);
   grpc_exec_ctx_finish(&exec_ctx);
 
@@ -296,7 +297,7 @@
   grpc_test_init(argc, argv);
   grpc_init();
 
-  for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) {
+  for (i = 0; i < GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT; i++) {
     for (j = 0; j < GPR_ARRAY_SIZE(uncompressed_split_modes); j++) {
       for (k = 0; k < GPR_ARRAY_SIZE(compressed_split_modes); k++) {
         for (m = 0; m < TEST_VALUE_COUNT; m++) {
diff --git a/test/core/end2end/fixtures/h2_compress.c b/test/core/end2end/fixtures/h2_compress.c
index 9866dea..0f4621a 100644
--- a/test/core/end2end/fixtures/h2_compress.c
+++ b/test/core/end2end/fixtures/h2_compress.c
@@ -69,7 +69,7 @@
     grpc_exec_ctx_finish(&exec_ctx);
   }
   ffd->client_args_compression = grpc_channel_args_set_compression_algorithm(
-      client_args, GRPC_COMPRESS_GZIP);
+      client_args, GRPC_COMPRESS_MESSAGE_GZIP);
   f->client = grpc_insecure_channel_create(ffd->localaddr,
                                            ffd->client_args_compression, NULL);
 }
@@ -83,7 +83,7 @@
     grpc_exec_ctx_finish(&exec_ctx);
   }
   ffd->server_args_compression = grpc_channel_args_set_compression_algorithm(
-      server_args, GRPC_COMPRESS_GZIP);
+      server_args, GRPC_COMPRESS_MESSAGE_GZIP);
   if (f->server) {
     grpc_server_destroy(f->server);
   }
diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary
index 7c77512..c834f1d 100644
--- a/test/core/end2end/fuzzers/hpack.dictionary
+++ b/test/core/end2end/fuzzers/hpack.dictionary
@@ -28,6 +28,7 @@
 "\x1Egrpc.max_request_message_bytes"
 "\x1Fgrpc.max_response_message_bytes"
 "$/grpc.lb.v1.LoadBalancer/BalanceLoad"
+"\x0Bstream-gzip"
 "\x010"
 "\x011"
 "\x012"
diff --git a/test/core/end2end/tests/compressed_payload.c b/test/core/end2end/tests/compressed_payload.c
index ba03773..4263eb1 100644
--- a/test/core/end2end/tests/compressed_payload.c
+++ b/test/core/end2end/tests/compressed_payload.c
@@ -385,9 +385,9 @@
   GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
                         GRPC_COMPRESS_NONE) != 0);
   GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
-                        GRPC_COMPRESS_DEFLATE) != 0);
+                        GRPC_COMPRESS_MESSAGE_DEFLATE) != 0);
   GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
-                        GRPC_COMPRESS_GZIP) != 0);
+                        GRPC_COMPRESS_MESSAGE_GZIP) != 0);
 
   memset(ops, 0, sizeof(ops));
   op = ops;
@@ -550,8 +550,9 @@
     grpc_end2end_test_config config) {
   request_with_payload_template(
       config, "test_invoke_request_with_exceptionally_uncompressed_payload",
-      GRPC_WRITE_NO_COMPRESS, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
-      GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP, NULL, false,
+      GRPC_WRITE_NO_COMPRESS, GRPC_COMPRESS_MESSAGE_GZIP,
+      GRPC_COMPRESS_MESSAGE_GZIP, GRPC_COMPRESS_NONE,
+      GRPC_COMPRESS_MESSAGE_GZIP, NULL, false,
       /* ignored */ GRPC_COMPRESS_LEVEL_NONE, false);
 }
 
@@ -568,18 +569,18 @@
     grpc_end2end_test_config config) {
   request_with_payload_template(
       config, "test_invoke_request_with_compressed_payload", 0,
-      GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
-      GRPC_COMPRESS_GZIP, NULL, false, /* ignored */ GRPC_COMPRESS_LEVEL_NONE,
-      false);
+      GRPC_COMPRESS_MESSAGE_GZIP, GRPC_COMPRESS_MESSAGE_GZIP,
+      GRPC_COMPRESS_MESSAGE_GZIP, GRPC_COMPRESS_MESSAGE_GZIP, NULL, false,
+      /* ignored */ GRPC_COMPRESS_LEVEL_NONE, false);
 }
 
 static void test_invoke_request_with_send_message_before_initial_metadata(
     grpc_end2end_test_config config) {
   request_with_payload_template(
       config, "test_invoke_request_with_compressed_payload", 0,
-      GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
-      GRPC_COMPRESS_GZIP, NULL, false, /* ignored */ GRPC_COMPRESS_LEVEL_NONE,
-      true);
+      GRPC_COMPRESS_MESSAGE_GZIP, GRPC_COMPRESS_MESSAGE_GZIP,
+      GRPC_COMPRESS_MESSAGE_GZIP, GRPC_COMPRESS_MESSAGE_GZIP, NULL, false,
+      /* ignored */ GRPC_COMPRESS_LEVEL_NONE, true);
 }
 
 static void test_invoke_request_with_server_level(
@@ -587,7 +588,7 @@
   request_with_payload_template(
       config, "test_invoke_request_with_server_level", 0, GRPC_COMPRESS_NONE,
       GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE /* ignored */,
-      NULL, true, GRPC_COMPRESS_LEVEL_HIGH, false);
+      NULL, true, GRPC_COMPRESS_LEVEL_MESSAGE_HIGH, false);
 }
 
 static void test_invoke_request_with_compressed_payload_md_override(
@@ -609,21 +610,22 @@
   /* Channel default NONE (aka IDENTITY), call override to GZIP */
   request_with_payload_template(
       config, "test_invoke_request_with_compressed_payload_md_override_1", 0,
-      GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP,
+      GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_MESSAGE_GZIP,
       GRPC_COMPRESS_NONE, &gzip_compression_override, false,
       /*ignored*/ GRPC_COMPRESS_LEVEL_NONE, false);
 
   /* Channel default DEFLATE, call override to GZIP */
   request_with_payload_template(
       config, "test_invoke_request_with_compressed_payload_md_override_2", 0,
-      GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP,
-      GRPC_COMPRESS_NONE, &gzip_compression_override, false,
+      GRPC_COMPRESS_MESSAGE_DEFLATE, GRPC_COMPRESS_NONE,
+      GRPC_COMPRESS_MESSAGE_GZIP, GRPC_COMPRESS_NONE,
+      &gzip_compression_override, false,
       /*ignored*/ GRPC_COMPRESS_LEVEL_NONE, false);
 
   /* Channel default DEFLATE, call override to NONE (aka IDENTITY) */
   request_with_payload_template(
       config, "test_invoke_request_with_compressed_payload_md_override_3", 0,
-      GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
+      GRPC_COMPRESS_MESSAGE_DEFLATE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
       GRPC_COMPRESS_NONE, &identity_compression_override, false,
       /*ignored*/ GRPC_COMPRESS_LEVEL_NONE, false);
 }
@@ -632,7 +634,8 @@
     grpc_end2end_test_config config) {
   request_for_disabled_algorithm(
       config, "test_invoke_request_with_disabled_algorithm", 0,
-      GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP, GRPC_STATUS_UNIMPLEMENTED, NULL);
+      GRPC_COMPRESS_MESSAGE_GZIP, GRPC_COMPRESS_MESSAGE_GZIP,
+      GRPC_STATUS_UNIMPLEMENTED, NULL);
 }
 
 void compressed_payload(grpc_end2end_test_config config) {
diff --git a/test/core/end2end/tests/stream_compression_compressed_payload.c b/test/core/end2end/tests/stream_compression_compressed_payload.c
index 8b47741..eb31a80 100644
--- a/test/core/end2end/tests/stream_compression_compressed_payload.c
+++ b/test/core/end2end/tests/stream_compression_compressed_payload.c
@@ -95,8 +95,8 @@
 static void request_for_disabled_algorithm(
     grpc_end2end_test_config config, const char *test_name,
     uint32_t send_flags_bitmask,
-    grpc_stream_compression_algorithm algorithm_to_disable,
-    grpc_stream_compression_algorithm requested_client_compression_algorithm,
+    grpc_compression_algorithm algorithm_to_disable,
+    grpc_compression_algorithm requested_client_compression_algorithm,
     grpc_status_code expected_error, grpc_metadata *client_metadata) {
   grpc_call *c;
   grpc_call *s;
@@ -124,13 +124,13 @@
   request_payload_slice = grpc_slice_from_copied_string(str);
   request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
 
-  client_args = grpc_channel_args_set_stream_compression_algorithm(
+  client_args = grpc_channel_args_set_compression_algorithm(
       NULL, requested_client_compression_algorithm);
-  server_args = grpc_channel_args_set_stream_compression_algorithm(
-      NULL, GRPC_STREAM_COMPRESS_NONE);
+  server_args =
+      grpc_channel_args_set_compression_algorithm(NULL, GRPC_COMPRESS_NONE);
   {
     grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-    server_args = grpc_channel_args_stream_compression_algorithm_set_state(
+    server_args = grpc_channel_args_compression_algorithm_set_state(
         &exec_ctx, &server_args, algorithm_to_disable, false);
     grpc_exec_ctx_finish(&exec_ctx);
   }
@@ -230,11 +230,10 @@
   GPR_ASSERT(status == expected_error);
 
   const char *algo_name = NULL;
-  GPR_ASSERT(
-      grpc_stream_compression_algorithm_name(algorithm_to_disable, &algo_name));
+  GPR_ASSERT(grpc_compression_algorithm_name(algorithm_to_disable, &algo_name));
   char *expected_details = NULL;
-  gpr_asprintf(&expected_details,
-               "Stream compression algorithm '%s' is disabled.", algo_name);
+  gpr_asprintf(&expected_details, "Compression algorithm '%s' is disabled.",
+               algo_name);
   /* and we expect a specific reason for it */
   GPR_ASSERT(0 == grpc_slice_str_cmp(details, expected_details));
   gpr_free(expected_details);
@@ -271,14 +270,12 @@
 static void request_with_payload_template(
     grpc_end2end_test_config config, const char *test_name,
     uint32_t client_send_flags_bitmask,
-    grpc_stream_compression_algorithm
-        default_client_channel_compression_algorithm,
-    grpc_stream_compression_algorithm
-        default_server_channel_compression_algorithm,
-    grpc_stream_compression_algorithm expected_client_compression_algorithm,
-    grpc_stream_compression_algorithm expected_server_compression_algorithm,
+    grpc_compression_algorithm default_client_channel_compression_algorithm,
+    grpc_compression_algorithm default_server_channel_compression_algorithm,
+    grpc_compression_algorithm expected_client_compression_algorithm,
+    grpc_compression_algorithm expected_server_compression_algorithm,
     grpc_metadata *client_init_metadata, bool set_server_level,
-    grpc_stream_compression_level server_compression_level,
+    grpc_compression_level server_compression_level,
     bool send_message_before_initial_metadata,
     bool set_default_server_message_compression_algorithm,
     grpc_compression_algorithm default_server_message_compression_algorithm) {
@@ -316,13 +313,13 @@
   grpc_slice response_payload_slice =
       grpc_slice_from_copied_string(response_str);
 
-  client_args = grpc_channel_args_set_stream_compression_algorithm(
+  client_args = grpc_channel_args_set_compression_algorithm(
       NULL, default_client_channel_compression_algorithm);
   if (set_default_server_message_compression_algorithm) {
     server_args = grpc_channel_args_set_compression_algorithm(
         NULL, default_server_message_compression_algorithm);
   } else {
-    server_args = grpc_channel_args_set_stream_compression_algorithm(
+    server_args = grpc_channel_args_set_compression_algorithm(
         NULL, default_server_channel_compression_algorithm);
   }
 
@@ -395,26 +392,21 @@
   GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
                         GRPC_COMPRESS_NONE) != 0);
   GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
-                        GRPC_COMPRESS_DEFLATE) != 0);
+                        GRPC_COMPRESS_MESSAGE_DEFLATE) != 0);
   GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
-                        GRPC_COMPRESS_GZIP) != 0);
-  GPR_ASSERT(
-      GPR_BITCOUNT(grpc_call_test_only_get_stream_encodings_accepted_by_peer(
-          s)) == GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT);
-  GPR_ASSERT(
-      GPR_BITGET(grpc_call_test_only_get_stream_encodings_accepted_by_peer(s),
-                 GRPC_STREAM_COMPRESS_NONE) != 0);
-  GPR_ASSERT(
-      GPR_BITGET(grpc_call_test_only_get_stream_encodings_accepted_by_peer(s),
-                 GRPC_STREAM_COMPRESS_GZIP) != 0);
+                        GRPC_COMPRESS_MESSAGE_GZIP) != 0);
+  GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
+                        GRPC_COMPRESS_STREAM_GZIP) != 0);
+  GPR_ASSERT(GPR_BITCOUNT(grpc_call_test_only_get_encodings_accepted_by_peer(
+                 s)) == GRPC_COMPRESS_ALGORITHMS_COUNT);
 
   memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
   if (set_server_level) {
-    op->data.send_initial_metadata.maybe_stream_compression_level.is_set = true;
-    op->data.send_initial_metadata.maybe_stream_compression_level.level =
+    op->data.send_initial_metadata.maybe_compression_level.is_set = true;
+    op->data.send_initial_metadata.maybe_compression_level.level =
         server_compression_level;
   }
   op->flags = 0;
@@ -558,29 +550,28 @@
     grpc_end2end_test_config config) {
   request_with_payload_template(
       config, "test_invoke_request_with_compressed_payload", 0,
-      GRPC_STREAM_COMPRESS_GZIP, GRPC_STREAM_COMPRESS_GZIP,
-      GRPC_STREAM_COMPRESS_GZIP, GRPC_STREAM_COMPRESS_GZIP, NULL,
+      GRPC_COMPRESS_STREAM_GZIP, GRPC_COMPRESS_STREAM_GZIP,
+      GRPC_COMPRESS_STREAM_GZIP, GRPC_COMPRESS_STREAM_GZIP, NULL,
       false, /* ignored */
-      GRPC_STREAM_COMPRESS_LEVEL_NONE, false, false, GRPC_COMPRESS_NONE);
+      GRPC_COMPRESS_LEVEL_NONE, false, false, GRPC_COMPRESS_NONE);
 }
 
 static void test_invoke_request_with_send_message_before_initial_metadata(
     grpc_end2end_test_config config) {
   request_with_payload_template(
       config, "test_invoke_request_with_send_message_before_initial_metadata",
-      0, GRPC_STREAM_COMPRESS_GZIP, GRPC_STREAM_COMPRESS_GZIP,
-      GRPC_STREAM_COMPRESS_GZIP, GRPC_STREAM_COMPRESS_GZIP, NULL,
+      0, GRPC_COMPRESS_STREAM_GZIP, GRPC_COMPRESS_STREAM_GZIP,
+      GRPC_COMPRESS_STREAM_GZIP, GRPC_COMPRESS_STREAM_GZIP, NULL,
       false, /* ignored */
-      GRPC_STREAM_COMPRESS_LEVEL_NONE, true, false, GRPC_COMPRESS_NONE);
+      GRPC_COMPRESS_LEVEL_NONE, true, false, GRPC_COMPRESS_NONE);
 }
 
 static void test_invoke_request_with_server_level(
     grpc_end2end_test_config config) {
   request_with_payload_template(
-      config, "test_invoke_request_with_server_level", 0,
-      GRPC_STREAM_COMPRESS_NONE, GRPC_STREAM_COMPRESS_NONE,
-      GRPC_STREAM_COMPRESS_NONE, GRPC_STREAM_COMPRESS_GZIP,
-      /* ignored */ NULL, true, GRPC_STREAM_COMPRESS_LEVEL_HIGH, false, false,
+      config, "test_invoke_request_with_server_level", 0, GRPC_COMPRESS_NONE,
+      GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_STREAM_GZIP,
+      /* ignored */ NULL, true, GRPC_COMPRESS_LEVEL_STREAM_HIGH, false, false,
       GRPC_COMPRESS_NONE);
 }
 
@@ -591,7 +582,8 @@
 
   gzip_compression_override.key =
       GRPC_MDSTR_GRPC_INTERNAL_STREAM_ENCODING_REQUEST;
-  gzip_compression_override.value = grpc_slice_from_static_string("gzip");
+  gzip_compression_override.value =
+      grpc_slice_from_static_string("stream-gzip");
   memset(&gzip_compression_override.internal_data, 0,
          sizeof(gzip_compression_override.internal_data));
 
@@ -605,40 +597,35 @@
   /* Channel default NONE (aka IDENTITY), call override to stream GZIP */
   request_with_payload_template(
       config, "test_invoke_request_with_compressed_payload_md_override_1", 0,
-      GRPC_STREAM_COMPRESS_NONE, GRPC_STREAM_COMPRESS_NONE,
-      GRPC_STREAM_COMPRESS_GZIP, GRPC_STREAM_COMPRESS_NONE,
-      &gzip_compression_override, false,
-      /*ignored*/ GRPC_STREAM_COMPRESS_LEVEL_NONE, false, false,
-      GRPC_COMPRESS_NONE);
+      GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_STREAM_GZIP,
+      GRPC_COMPRESS_NONE, &gzip_compression_override, false,
+      /*ignored*/ GRPC_COMPRESS_LEVEL_NONE, false, false, GRPC_COMPRESS_NONE);
 
   /* Channel default stream GZIP, call override to NONE (aka IDENTITY) */
   request_with_payload_template(
       config, "test_invoke_request_with_compressed_payload_md_override_3", 0,
-      GRPC_STREAM_COMPRESS_GZIP, GRPC_STREAM_COMPRESS_NONE,
-      GRPC_STREAM_COMPRESS_NONE, GRPC_STREAM_COMPRESS_NONE,
-      &identity_compression_override, false,
-      /*ignored*/ GRPC_STREAM_COMPRESS_LEVEL_NONE, false, false,
-      GRPC_COMPRESS_NONE);
+      GRPC_COMPRESS_STREAM_GZIP, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
+      GRPC_COMPRESS_NONE, &identity_compression_override, false,
+      /*ignored*/ GRPC_COMPRESS_LEVEL_NONE, false, false, GRPC_COMPRESS_NONE);
 }
 
 static void test_invoke_request_with_disabled_algorithm(
     grpc_end2end_test_config config) {
   request_for_disabled_algorithm(
       config, "test_invoke_request_with_disabled_algorithm", 0,
-      GRPC_STREAM_COMPRESS_GZIP, GRPC_STREAM_COMPRESS_GZIP,
+      GRPC_COMPRESS_STREAM_GZIP, GRPC_COMPRESS_STREAM_GZIP,
       GRPC_STATUS_UNIMPLEMENTED, NULL);
 }
 
 static void test_stream_compression_override_message_compression(
     grpc_end2end_test_config config) {
-  grpc_stream_compression_level level = GRPC_STREAM_COMPRESS_LEVEL_MED;
+  grpc_compression_level level = GRPC_COMPRESS_LEVEL_STREAM_MED;
   request_with_payload_template(
       config, "test_stream_compression_override_message_compression", 0,
-      GRPC_STREAM_COMPRESS_NONE, GRPC_STREAM_COMPRESS_NONE,
-      GRPC_STREAM_COMPRESS_NONE,
-      grpc_stream_compression_algorithm_for_level(
-          level, (1u << GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT) - 1),
-      /* ignored */ NULL, true, level, false, true, GRPC_COMPRESS_GZIP);
+      GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
+      grpc_compression_algorithm_for_level(
+          level, (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1),
+      /* ignored */ NULL, true, level, false, true, GRPC_COMPRESS_MESSAGE_GZIP);
 }
 
 void stream_compression_compressed_payload(grpc_end2end_test_config config) {
diff --git a/test/core/end2end/tests/stream_compression_payload.c b/test/core/end2end/tests/stream_compression_payload.c
index e47d2aa..6b5b6d4 100644
--- a/test/core/end2end/tests/stream_compression_payload.c
+++ b/test/core/end2end/tests/stream_compression_payload.c
@@ -265,12 +265,10 @@
    payload and status. */
 static void test_invoke_request_response_with_payload(
     grpc_end2end_test_config config) {
-  grpc_channel_args *client_args =
-      grpc_channel_args_set_stream_compression_algorithm(
-          NULL, GRPC_STREAM_COMPRESS_GZIP);
-  grpc_channel_args *server_args =
-      grpc_channel_args_set_stream_compression_algorithm(
-          NULL, GRPC_STREAM_COMPRESS_GZIP);
+  grpc_channel_args *client_args = grpc_channel_args_set_compression_algorithm(
+      NULL, GRPC_COMPRESS_STREAM_GZIP);
+  grpc_channel_args *server_args = grpc_channel_args_set_compression_algorithm(
+      NULL, GRPC_COMPRESS_STREAM_GZIP);
   grpc_end2end_test_fixture f =
       begin_test(config, "test_invoke_request_response_with_payload",
                  client_args, server_args);
diff --git a/test/core/end2end/tests/stream_compression_ping_pong_streaming.c b/test/core/end2end/tests/stream_compression_ping_pong_streaming.c
index 4c1a34c..4dd3568 100644
--- a/test/core/end2end/tests/stream_compression_ping_pong_streaming.c
+++ b/test/core/end2end/tests/stream_compression_ping_pong_streaming.c
@@ -90,12 +90,10 @@
 /* Client pings and server pongs. Repeat messages rounds before finishing. */
 static void test_pingpong_streaming(grpc_end2end_test_config config,
                                     int messages) {
-  grpc_channel_args *client_args =
-      grpc_channel_args_set_stream_compression_algorithm(
-          NULL, GRPC_STREAM_COMPRESS_GZIP);
-  grpc_channel_args *server_args =
-      grpc_channel_args_set_stream_compression_algorithm(
-          NULL, GRPC_STREAM_COMPRESS_GZIP);
+  grpc_channel_args *client_args = grpc_channel_args_set_compression_algorithm(
+      NULL, GRPC_COMPRESS_STREAM_GZIP);
+  grpc_channel_args *server_args = grpc_channel_args_set_compression_algorithm(
+      NULL, GRPC_COMPRESS_STREAM_GZIP);
   grpc_end2end_test_fixture f =
       begin_test(config, "test_pingpong_streaming", client_args, server_args);
   grpc_call *c;
diff --git a/test/core/end2end/tests/workaround_cronet_compression.c b/test/core/end2end/tests/workaround_cronet_compression.c
index 44e8e04..4ca018c 100644
--- a/test/core/end2end/tests/workaround_cronet_compression.c
+++ b/test/core/end2end/tests/workaround_cronet_compression.c
@@ -208,9 +208,9 @@
   GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
                         GRPC_COMPRESS_NONE) != 0);
   GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
-                        GRPC_COMPRESS_DEFLATE) != 0);
+                        GRPC_COMPRESS_MESSAGE_DEFLATE) != 0);
   GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
-                        GRPC_COMPRESS_GZIP) != 0);
+                        GRPC_COMPRESS_MESSAGE_GZIP) != 0);
 
   memset(ops, 0, sizeof(ops));
   op = ops;
@@ -365,13 +365,13 @@
 } workaround_cronet_compression_config;
 
 static workaround_cronet_compression_config workaround_configs[] = {
-    {NULL, GRPC_COMPRESS_GZIP},
+    {NULL, GRPC_COMPRESS_MESSAGE_GZIP},
     {"grpc-objc/1.3.0-dev grpc-c/3.0.0-dev (ios; cronet_http; gentle)",
      GRPC_COMPRESS_NONE},
     {"grpc-objc/1.3.0-dev grpc-c/3.0.0-dev (ios; chttp2; gentle)",
-     GRPC_COMPRESS_GZIP},
+     GRPC_COMPRESS_MESSAGE_GZIP},
     {"grpc-objc/1.4.0 grpc-c/3.0.0-dev (ios; cronet_http; gentle)",
-     GRPC_COMPRESS_GZIP}};
+     GRPC_COMPRESS_MESSAGE_GZIP}};
 static const size_t workaround_configs_num =
     sizeof(workaround_configs) / sizeof(*workaround_configs);
 
@@ -380,7 +380,8 @@
   for (uint32_t i = 0; i < workaround_configs_num; i++) {
     request_with_payload_template(
         config, "test_invoke_request_with_compressed_payload", 0,
-        GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
+        GRPC_COMPRESS_MESSAGE_GZIP, GRPC_COMPRESS_MESSAGE_GZIP,
+        GRPC_COMPRESS_MESSAGE_GZIP,
         workaround_configs[i].expected_algorithm_from_server, NULL, false,
         /* ignored */ GRPC_COMPRESS_LEVEL_NONE,
         workaround_configs[i].user_agent_override);
diff --git a/test/core/slice/slice_string_helpers_test.c b/test/core/slice/slice_string_helpers_test.c
index 504acf8..48f3701 100644
--- a/test/core/slice/slice_string_helpers_test.c
+++ b/test/core/slice/slice_string_helpers_test.c
@@ -127,9 +127,76 @@
   gpr_free(parts);
 }
 
+static void test_strsplit_nospace(void) {
+  grpc_slice_buffer *parts;
+  grpc_slice str;
+
+  LOG_TEST_NAME("test_strsplit_nospace");
+
+  parts = gpr_malloc(sizeof(grpc_slice_buffer));
+  grpc_slice_buffer_init(parts);
+
+  str = grpc_slice_from_copied_string("one  ,two,   three  , four");
+  grpc_slice_split_without_space(str, ",", parts);
+  GPR_ASSERT(4 == parts->count);
+  GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], "one"));
+  GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[1], "two"));
+  GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[2], "three"));
+  GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[3], "four"));
+  grpc_slice_buffer_reset_and_unref(parts);
+  grpc_slice_unref(str);
+
+  /* separator not present in string */
+  str = grpc_slice_from_copied_string("one two three four ");
+  grpc_slice_split_without_space(str, ",", parts);
+  GPR_ASSERT(1 == parts->count);
+  GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], "one two three four"));
+  grpc_slice_buffer_reset_and_unref(parts);
+  grpc_slice_unref(str);
+
+  /* separator at the end */
+  str = grpc_slice_from_copied_string("foo,");
+  grpc_slice_split_without_space(str, ",", parts);
+  GPR_ASSERT(2 == parts->count);
+  GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], "foo"));
+  GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[1], ""));
+  grpc_slice_buffer_reset_and_unref(parts);
+  grpc_slice_unref(str);
+
+  /* separator at the beginning */
+  str = grpc_slice_from_copied_string(" , foo");
+  grpc_slice_split_without_space(str, ",", parts);
+  GPR_ASSERT(2 == parts->count);
+  GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], ""));
+  GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[1], "foo"));
+  grpc_slice_buffer_reset_and_unref(parts);
+  grpc_slice_unref(str);
+
+  /* standalone separator */
+  str = grpc_slice_from_copied_string(", ");
+  grpc_slice_split_without_space(str, ", ", parts);
+  GPR_ASSERT(2 == parts->count);
+  GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], ""));
+  GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[1], ""));
+  grpc_slice_buffer_reset_and_unref(parts);
+  grpc_slice_unref(str);
+
+  /* empty input */
+  str = grpc_slice_from_copied_string("");
+  grpc_slice_split_without_space(str, ",", parts);
+  GPR_ASSERT(1 == parts->count);
+  GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], ""));
+  grpc_slice_buffer_reset_and_unref(parts);
+  grpc_slice_unref(str);
+
+  grpc_slice_buffer_destroy(parts);
+  gpr_free(parts);
+}
+
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
   test_dump_slice();
   test_strsplit();
+  test_strsplit_nospace();
   return 0;
 }
diff --git a/test/core/surface/byte_buffer_reader_test.c b/test/core/surface/byte_buffer_reader_test.c
index a6b4c86..40bb4a2 100644
--- a/test/core/surface/byte_buffer_reader_test.c
+++ b/test/core/surface/byte_buffer_reader_test.c
@@ -109,7 +109,7 @@
   LOG_TEST("test_read_corrupted_slice");
   slice = grpc_slice_from_copied_string("test");
   buffer = grpc_raw_byte_buffer_create(&slice, 1);
-  buffer->data.raw.compression = GRPC_COMPRESS_GZIP; /* lies! */
+  buffer->data.raw.compression = GRPC_COMPRESS_MESSAGE_GZIP; /* lies! */
   grpc_slice_unref(slice);
   GPR_ASSERT(!grpc_byte_buffer_reader_init(&reader, buffer));
   grpc_byte_buffer_destroy(buffer);
@@ -133,8 +133,10 @@
   grpc_slice_buffer_add(&sliceb_in, input_slice); /* takes ownership */
   {
     grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-    GPR_ASSERT(
-        grpc_msg_compress(&exec_ctx, algorithm, &sliceb_in, &sliceb_out));
+    GPR_ASSERT(grpc_msg_compress(
+        &exec_ctx,
+        grpc_compression_algorithm_to_message_compression_algorithm(algorithm),
+        &sliceb_in, &sliceb_out));
     grpc_exec_ctx_finish(&exec_ctx);
   }
 
@@ -160,13 +162,13 @@
 static void test_read_gzip_compressed_slice(void) {
   const size_t INPUT_SIZE = 2048;
   LOG_TEST("test_read_gzip_compressed_slice");
-  read_compressed_slice(GRPC_COMPRESS_GZIP, INPUT_SIZE);
+  read_compressed_slice(GRPC_COMPRESS_MESSAGE_GZIP, INPUT_SIZE);
 }
 
 static void test_read_deflate_compressed_slice(void) {
   const size_t INPUT_SIZE = 2048;
   LOG_TEST("test_read_deflate_compressed_slice");
-  read_compressed_slice(GRPC_COMPRESS_DEFLATE, INPUT_SIZE);
+  read_compressed_slice(GRPC_COMPRESS_MESSAGE_DEFLATE, INPUT_SIZE);
 }
 
 static void test_byte_buffer_from_reader(void) {
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 810ee30..7f5d6f9 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -342,7 +342,7 @@
       char bytes[8] = {'\0', '\1', '\2', '\3', '\4', '\5', '\6', (char)i};
       context.AddMetadata("custom-bin", grpc::string(bytes, 8));
     }
-    context.set_compression_algorithm(GRPC_COMPRESS_GZIP);
+    context.set_compression_algorithm(GRPC_COMPRESS_MESSAGE_GZIP);
     Status s = stub->Echo(&context, request, &response);
     EXPECT_EQ(response.message(), request.message());
     EXPECT_TRUE(s.ok());
diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc
index f260ea0..f984a77 100644
--- a/test/cpp/end2end/filter_end2end_test.cc
+++ b/test/cpp/end2end/filter_end2end_test.cc
@@ -266,7 +266,7 @@
   GenericServerContext srv_ctx;
   GenericServerAsyncReaderWriter srv_stream(&srv_ctx);
 
-  cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP);
+  cli_ctx.set_compression_algorithm(GRPC_COMPRESS_MESSAGE_GZIP);
   send_request.set_message("Hello");
   std::unique_ptr<GenericClientAsyncReaderWriter> cli_stream =
       generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1));
diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc
index 9450182..b37452d 100644
--- a/test/cpp/end2end/generic_end2end_test.cc
+++ b/test/cpp/end2end/generic_end2end_test.cc
@@ -267,7 +267,7 @@
   GenericServerContext srv_ctx;
   GenericServerAsyncReaderWriter srv_stream(&srv_ctx);
 
-  cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP);
+  cli_ctx.set_compression_algorithm(GRPC_COMPRESS_MESSAGE_GZIP);
   send_request.set_message("Hello");
   std::unique_ptr<GenericClientAsyncReaderWriter> cli_stream =
       generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1));
diff --git a/test/cpp/end2end/server_builder_plugin_test.cc b/test/cpp/end2end/server_builder_plugin_test.cc
index 2951a2e..a1ce4eb 100644
--- a/test/cpp/end2end/server_builder_plugin_test.cc
+++ b/test/cpp/end2end/server_builder_plugin_test.cc
@@ -251,7 +251,7 @@
   EchoResponse response;
   request.set_message("Hello hello hello hello");
   ClientContext context;
-  context.set_compression_algorithm(GRPC_COMPRESS_GZIP);
+  context.set_compression_algorithm(GRPC_COMPRESS_MESSAGE_GZIP);
   Status s = stub_->Echo(&context, request, &response);
   EXPECT_EQ(response.message(), request.message());
   EXPECT_TRUE(s.ok());
diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc
index af97fe0..24c6b3f 100644
--- a/test/cpp/interop/interop_client.cc
+++ b/test/cpp/interop/interop_client.cc
@@ -184,7 +184,7 @@
   request->mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
   if (request->has_expect_compressed()) {
     if (request->expect_compressed().value()) {
-      context.set_compression_algorithm(GRPC_COMPRESS_GZIP);
+      context.set_compression_algorithm(GRPC_COMPRESS_MESSAGE_GZIP);
     } else {
       context.set_compression_algorithm(GRPC_COMPRESS_NONE);
     }
@@ -492,7 +492,7 @@
   StreamingInputCallRequest request;
   StreamingInputCallResponse response;
 
-  context.set_compression_algorithm(GRPC_COMPRESS_GZIP);
+  context.set_compression_algorithm(GRPC_COMPRESS_MESSAGE_GZIP);
   std::unique_ptr<ClientWriter<StreamingInputCallRequest>> stream(
       serviceStub_.Get()->StreamingInputCall(&context, &response));
 
diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc
index 4149724..26d9b3c 100644
--- a/test/cpp/interop/interop_server.cc
+++ b/test/cpp/interop/interop_server.cc
@@ -163,7 +163,7 @@
               compression_requested ? "enabled" : "disabled", __func__);
       if (compression_requested) {
         // Any level would do, let's go for HIGH because we are overachievers.
-        context->set_compression_level(GRPC_COMPRESS_LEVEL_HIGH);
+        context->set_compression_level(GRPC_COMPRESS_LEVEL_MESSAGE_HIGH);
       } else {
         context->set_compression_level(GRPC_COMPRESS_LEVEL_NONE);
       }
@@ -204,7 +204,7 @@
       WriteOptions wopts;
       if (request->response_parameters(i).has_compressed()) {
         // Compress by default. Disabled on a per-message basis.
-        context->set_compression_level(GRPC_COMPRESS_LEVEL_HIGH);
+        context->set_compression_level(GRPC_COMPRESS_LEVEL_MESSAGE_HIGH);
         const bool compression_requested =
             request->response_parameters(i).compressed().value();
         gpr_log(GPR_DEBUG, "Request for compression (%s) present for %s",
diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py
index 355f3f4..8184681 100755
--- a/tools/codegen/core/gen_static_metadata.py
+++ b/tools/codegen/core/gen_static_metadata.py
@@ -53,6 +53,8 @@
     'grpc.max_response_message_bytes',
     # well known method names
     '/grpc.lb.v1.LoadBalancer/BalanceLoad',
+    # stream compression algorithm names
+    'stream-gzip',
     # metadata elements
     ('grpc-status', '0'),
     ('grpc-status', '1'),
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 0f7e8cd..0014cf5 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -943,6 +943,7 @@
 src/core/lib/channel/handshaker_factory.h \
 src/core/lib/channel/handshaker_registry.h \
 src/core/lib/compression/algorithm_metadata.h \
+src/core/lib/compression/compression_internal.h \
 src/core/lib/compression/message_compress.h \
 src/core/lib/compression/stream_compression.h \
 src/core/lib/compression/stream_compression_gzip.h \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index d465403..2c54eac 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1076,6 +1076,8 @@
 src/core/lib/channel/handshaker_registry.h \
 src/core/lib/compression/algorithm_metadata.h \
 src/core/lib/compression/compression.cc \
+src/core/lib/compression/compression_internal.cc \
+src/core/lib/compression/compression_internal.h \
 src/core/lib/compression/message_compress.cc \
 src/core/lib/compression/message_compress.h \
 src/core/lib/compression/stream_compression.cc \
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index babdfeb..5d9a0f6 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -8003,6 +8003,7 @@
       "src/core/lib/channel/handshaker_factory.cc", 
       "src/core/lib/channel/handshaker_registry.cc", 
       "src/core/lib/compression/compression.cc", 
+      "src/core/lib/compression/compression_internal.cc", 
       "src/core/lib/compression/message_compress.cc", 
       "src/core/lib/compression/stream_compression.cc", 
       "src/core/lib/compression/stream_compression_gzip.cc", 
@@ -8158,6 +8159,7 @@
       "src/core/lib/channel/handshaker_factory.h", 
       "src/core/lib/channel/handshaker_registry.h", 
       "src/core/lib/compression/algorithm_metadata.h", 
+      "src/core/lib/compression/compression_internal.h", 
       "src/core/lib/compression/message_compress.h", 
       "src/core/lib/compression/stream_compression.h", 
       "src/core/lib/compression/stream_compression_gzip.h", 
@@ -8293,6 +8295,7 @@
       "src/core/lib/channel/handshaker_factory.h", 
       "src/core/lib/channel/handshaker_registry.h", 
       "src/core/lib/compression/algorithm_metadata.h", 
+      "src/core/lib/compression/compression_internal.h", 
       "src/core/lib/compression/message_compress.h", 
       "src/core/lib/compression/stream_compression.h", 
       "src/core/lib/compression/stream_compression_gzip.h",