Merge branch 'compression_incoming_checks' into compression_md_level_bis
diff --git a/BUILD b/BUILD
index 793c1c7..42eec6a 100644
--- a/BUILD
+++ b/BUILD
@@ -303,7 +303,7 @@
     "src/core/lib/channel/connected_channel.c",
     "src/core/lib/channel/http_client_filter.c",
     "src/core/lib/channel/http_server_filter.c",
-    "src/core/lib/compression/compression_algorithm.c",
+    "src/core/lib/compression/compression.c",
     "src/core/lib/compression/message_compress.c",
     "src/core/lib/debug/trace.c",
     "src/core/lib/http/format_request.c",
@@ -642,7 +642,7 @@
     "src/core/lib/channel/connected_channel.c",
     "src/core/lib/channel/http_client_filter.c",
     "src/core/lib/channel/http_server_filter.c",
-    "src/core/lib/compression/compression_algorithm.c",
+    "src/core/lib/compression/compression.c",
     "src/core/lib/compression/message_compress.c",
     "src/core/lib/debug/trace.c",
     "src/core/lib/http/format_request.c",
@@ -1335,7 +1335,7 @@
     "src/core/lib/channel/connected_channel.c",
     "src/core/lib/channel/http_client_filter.c",
     "src/core/lib/channel/http_server_filter.c",
-    "src/core/lib/compression/compression_algorithm.c",
+    "src/core/lib/compression/compression.c",
     "src/core/lib/compression/message_compress.c",
     "src/core/lib/debug/trace.c",
     "src/core/lib/http/format_request.c",
diff --git a/Makefile b/Makefile
index 42cedf5..c733b03 100644
--- a/Makefile
+++ b/Makefile
@@ -2500,7 +2500,7 @@
     src/core/lib/channel/connected_channel.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
-    src/core/lib/compression/compression_algorithm.c \
+    src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
     src/core/lib/http/format_request.c \
@@ -2847,7 +2847,7 @@
     src/core/lib/channel/connected_channel.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
-    src/core/lib/compression/compression_algorithm.c \
+    src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
     src/core/lib/http/format_request.c \
diff --git a/binding.gyp b/binding.gyp
index 760bb24..30d2b41 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -571,7 +571,7 @@
         'src/core/lib/channel/connected_channel.c',
         'src/core/lib/channel/http_client_filter.c',
         'src/core/lib/channel/http_server_filter.c',
-        'src/core/lib/compression/compression_algorithm.c',
+        'src/core/lib/compression/compression.c',
         'src/core/lib/compression/message_compress.c',
         'src/core/lib/debug/trace.c',
         'src/core/lib/http/format_request.c',
diff --git a/build.yaml b/build.yaml
index ac61612..06dd1c8 100644
--- a/build.yaml
+++ b/build.yaml
@@ -230,7 +230,7 @@
   - src/core/lib/channel/connected_channel.c
   - src/core/lib/channel/http_client_filter.c
   - src/core/lib/channel/http_server_filter.c
-  - src/core/lib/compression/compression_algorithm.c
+  - src/core/lib/compression/compression.c
   - src/core/lib/compression/message_compress.c
   - src/core/lib/debug/trace.c
   - src/core/lib/http/format_request.c
diff --git a/config.m4 b/config.m4
index 6ed1887..b995158 100644
--- a/config.m4
+++ b/config.m4
@@ -90,7 +90,7 @@
     src/core/lib/channel/connected_channel.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
-    src/core/lib/compression/compression_algorithm.c \
+    src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
     src/core/lib/http/format_request.c \
diff --git a/gRPC.podspec b/gRPC.podspec
index 67e7a81..3b2fe51 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -340,7 +340,7 @@
                       'src/core/lib/channel/connected_channel.c',
                       'src/core/lib/channel/http_client_filter.c',
                       'src/core/lib/channel/http_server_filter.c',
-                      'src/core/lib/compression/compression_algorithm.c',
+                      'src/core/lib/compression/compression.c',
                       'src/core/lib/compression/message_compress.c',
                       'src/core/lib/debug/trace.c',
                       'src/core/lib/http/format_request.c',
diff --git a/grpc.gemspec b/grpc.gemspec
index 13aed6b..11f7707 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -319,7 +319,7 @@
   s.files += %w( src/core/lib/channel/connected_channel.c )
   s.files += %w( src/core/lib/channel/http_client_filter.c )
   s.files += %w( src/core/lib/channel/http_server_filter.c )
-  s.files += %w( src/core/lib/compression/compression_algorithm.c )
+  s.files += %w( src/core/lib/compression/compression.c )
   s.files += %w( src/core/lib/compression/message_compress.c )
   s.files += %w( src/core/lib/debug/trace.c )
   s.files += %w( src/core/lib/http/format_request.c )
diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h
index d457f03..a9e5978 100644
--- a/include/grpc++/impl/codegen/call.h
+++ b/include/grpc++/impl/codegen/call.h
@@ -47,7 +47,9 @@
 #include <grpc++/impl/codegen/serialization_traits.h>
 #include <grpc++/impl/codegen/status.h>
 #include <grpc++/impl/codegen/string_ref.h>
+
 #include <grpc/impl/codegen/alloc.h>
+#include <grpc/impl/codegen/compression_types.h>
 #include <grpc/impl/codegen/grpc_types.h>
 
 struct grpc_byte_buffer;
@@ -187,6 +189,8 @@
     flags_ = flags;
     initial_metadata_count_ = metadata.size();
     initial_metadata_ = FillMetadataArray(metadata);
+    // TODO(dgq): expose compression level in API so it can be properly set.
+    maybe_compression_level_.is_set = false;
   }
 
  protected:
@@ -198,6 +202,8 @@
     op->reserved = NULL;
     op->data.send_initial_metadata.count = initial_metadata_count_;
     op->data.send_initial_metadata.metadata = initial_metadata_;
+    memcpy(&op->data.send_initial_metadata.maybe_compression_level,
+           &maybe_compression_level_, sizeof(maybe_compression_level_));
   }
   void FinishOp(bool* status, int max_message_size) {
     if (!send_) return;
@@ -209,6 +215,10 @@
   uint32_t flags_;
   size_t initial_metadata_count_;
   grpc_metadata* initial_metadata_;
+  struct {
+    bool is_set;
+    grpc_compression_level level;
+  } maybe_compression_level_;
 };
 
 class CallOpSendMessage {
diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h
index ad62952..c48c86d 100644
--- a/include/grpc++/server_builder.h
+++ b/include/grpc++/server_builder.h
@@ -66,29 +66,43 @@
   /// The service must exist for the lifetime of the \a Server instance returned
   /// by \a BuildAndStart().
   /// Matches requests with any :authority
-  void RegisterService(Service* service);
+  ServerBuilder& RegisterService(Service* service);
 
   /// Register a generic service.
   /// Matches requests with any :authority
-  void RegisterAsyncGenericService(AsyncGenericService* service);
+  ServerBuilder& RegisterAsyncGenericService(AsyncGenericService* service);
 
   /// Register a service. This call does not take ownership of the service.
   /// The service must exist for the lifetime of the \a Server instance returned
   /// by BuildAndStart().
   /// Only matches requests with :authority \a host
-  void RegisterService(const grpc::string& host, Service* service);
+  ServerBuilder& RegisterService(const grpc::string& host, Service* service);
 
   /// Set max message size in bytes.
-  void SetMaxMessageSize(int max_message_size) {
+  ServerBuilder& SetMaxMessageSize(int max_message_size) {
     max_message_size_ = max_message_size;
+    return *this;
   }
 
-  /// Set the compression options to be used by the server.
-  void SetCompressionOptions(const grpc_compression_options& options) {
-    compression_options_ = options;
-  }
+  /// Set the support status for compression algorithms. All algorithms are
+  /// enabled by default.
+  ///
+  /// Incoming calls compressed with an unsupported algorithm will fail with
+  /// GRPC_STATUS_UNIMPLEMENTED.
+  ServerBuilder& SetCompressionAlgorithmSupportStatus(
+      grpc_compression_algorithm algorithm, bool enabled);
 
-  void SetOption(std::unique_ptr<ServerBuilderOption> option);
+  /// The default compression level to use for all channel calls in the
+  /// absence of a call-specific level.
+  ServerBuilder& SetDefaultCompressionLevel(grpc_compression_level level);
+
+  /// The default compression algorithm to use for all channel calls in the
+  /// absence of a call-specific level. Note that it overrides any compression
+  /// level set by \a SetDefaultCompressionLevel.
+  ServerBuilder& SetDefaultCompressionAlgorithm(
+      grpc_compression_algorithm algorithm);
+
+  ServerBuilder& SetOption(std::unique_ptr<ServerBuilderOption> option);
 
   /// Tries to bind \a server to the given \a addr.
   ///
@@ -101,9 +115,9 @@
   /// number. \a nullptr otherwise.
   ///
   // TODO(dgq): the "port" part seems to be a misnomer.
-  void AddListeningPort(const grpc::string& addr,
-                        std::shared_ptr<ServerCredentials> creds,
-                        int* selected_port = nullptr);
+  ServerBuilder& AddListeningPort(const grpc::string& addr,
+                                  std::shared_ptr<ServerCredentials> creds,
+                                  int* selected_port = nullptr);
 
   /// Add a completion queue for handling asynchronous services
   /// Caller is required to keep this completion queue live until
@@ -136,7 +150,6 @@
   };
 
   int max_message_size_;
-  grpc_compression_options compression_options_;
   std::vector<std::unique_ptr<ServerBuilderOption>> options_;
   std::vector<std::unique_ptr<NamedService>> services_;
   std::vector<Port> ports_;
@@ -144,6 +157,15 @@
   std::shared_ptr<ServerCredentials> creds_;
   std::map<grpc::string, std::unique_ptr<ServerBuilderPlugin>> plugins_;
   AsyncGenericService* generic_service_;
+  struct {
+    bool is_set;
+    grpc_compression_level level;
+  } maybe_default_compression_level_;
+  struct {
+    bool is_set;
+    grpc_compression_algorithm algorithm;
+  } maybe_default_compression_algorithm_;
+  uint32_t enabled_compression_algorithms_bitset_;
 };
 
 }  // namespace grpc
diff --git a/include/grpc/impl/codegen/compression_types.h b/include/grpc/impl/codegen/compression_types.h
index 8d2ec3b..9065d1e 100644
--- a/include/grpc/impl/codegen/compression_types.h
+++ b/include/grpc/impl/codegen/compression_types.h
@@ -35,11 +35,17 @@
 #define GRPC_IMPL_CODEGEN_COMPRESSION_TYPES_H
 
 #include <grpc/impl/codegen/port_platform.h>
+#include <stdbool.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/** To be used as initial metadata key for the request of a concrete compression
+ * algorithm */
+#define GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY \
+  "grpc-internal-encoding-request"
+
 /** To be used in channel arguments */
 #define GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM \
   "grpc.default_compression_algorithm"
@@ -74,15 +80,24 @@
    */
   uint32_t enabled_algorithms_bitset;
 
-  /** The default channel 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 */
-  grpc_compression_algorithm default_compression_algorithm;
-
   /** The default channel 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 */
-  grpc_compression_algorithm default_compression_level;
+   * behind \a GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL. If present, takes
+   * precedence over \a default_algorithm.
+   * TODO(dgq): currently only available for server channels. */
+  struct {
+    bool is_set;
+    grpc_compression_level level;
+  } default_level;
+
+  /** The default channel 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. */
+  struct {
+    bool is_set;
+    grpc_compression_algorithm algorithm;
+  } default_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 af3d0c2..b4ccafd 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -332,6 +332,12 @@
     struct {
       size_t count;
       grpc_metadata *metadata;
+      /** If \a is_set, \a compression_level will be used for the call.
+       * Otherwise, \a compression_level won't be considered */
+      struct {
+        uint8_t is_set;
+        grpc_compression_level compression_level;
+      } maybe_compression_level;
     } send_initial_metadata;
     grpc_byte_buffer *send_message;
     struct {
diff --git a/package.xml b/package.xml
index 33a769a..2dafaee 100644
--- a/package.xml
+++ b/package.xml
@@ -326,7 +326,7 @@
     <file baseinstalldir="/" name="src/core/lib/channel/connected_channel.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/http_client_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/http_server_filter.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/compression/compression_algorithm.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/compression/compression.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/message_compress.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/debug/trace.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/http/format_request.c" role="src" />
diff --git a/src/core/lib/channel/channel_args.c b/src/core/lib/channel/channel_args.c
index 589e11f..c14b9aa 100644
--- a/src/core/lib/channel/channel_args.c
+++ b/src/core/lib/channel/channel_args.c
@@ -201,7 +201,8 @@
           !strcmp(GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET,
                   a->args[i].key)) {
         *states_arg = &a->args[i].value.integer;
-        return 1; /* GPR_TRUE */
+        **states_arg |= 0x1; /* forcefully enable support for no compression */
+        return 1;
       }
     }
   }
@@ -226,7 +227,7 @@
   } else if (states_arg_found) {
     if (state != 0) {
       GPR_BITSET((unsigned *)states_arg, algorithm);
-    } else {
+    } else if (algorithm != GRPC_COMPRESS_NONE) {
       GPR_BITCLEAR((unsigned *)states_arg, algorithm);
     }
   } else {
@@ -238,7 +239,7 @@
     tmp.value.integer = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1;
     if (state != 0) {
       GPR_BITSET((unsigned *)&tmp.value.integer, algorithm);
-    } else {
+    } else if (algorithm != GRPC_COMPRESS_NONE) {
       GPR_BITCLEAR((unsigned *)&tmp.value.integer, algorithm);
     }
     result = grpc_channel_args_copy_and_add(*a, &tmp, 1);
@@ -248,11 +249,11 @@
   return result;
 }
 
-int grpc_channel_args_compression_algorithm_get_states(
+uint32_t grpc_channel_args_compression_algorithm_get_states(
     const grpc_channel_args *a) {
   int *states_arg;
   if (find_compression_algorithm_states_bitset(a, &states_arg)) {
-    return *states_arg;
+    return (uint32_t)*states_arg;
   } else {
     return (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; /* All algs. enabled */
   }
diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h
index 23c7b7b..653d04f 100644
--- a/src/core/lib/channel/channel_args.h
+++ b/src/core/lib/channel/channel_args.h
@@ -81,7 +81,7 @@
  *
  * The i-th bit of the returned bitset corresponds to the i-th entry in the
  * grpc_compression_algorithm enum. */
-int grpc_channel_args_compression_algorithm_get_states(
+uint32_t grpc_channel_args_compression_algorithm_get_states(
     const grpc_channel_args *a);
 
 int grpc_channel_args_compare(const grpc_channel_args *a,
diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c
index 0e548c6..16e82dd 100644
--- a/src/core/lib/channel/compress_filter.c
+++ b/src/core/lib/channel/compress_filter.c
@@ -73,8 +73,8 @@
 typedef struct channel_data {
   /** The default, channel-level, compression algorithm */
   grpc_compression_algorithm default_compression_algorithm;
-  /** Compression options for the channel */
-  grpc_compression_options compression_options;
+  /** Bitset of enabled algorithms */
+  uint32_t enabled_algorithms_bitset;
   /** Supported compression algorithms */
   uint32_t supported_compression_algorithms;
 } channel_data;
@@ -96,9 +96,8 @@
               md_c_str);
       calld->compression_algorithm = GRPC_COMPRESS_NONE;
     }
-    if (grpc_compression_options_is_algorithm_enabled(
-            &channeld->compression_options, calld->compression_algorithm) ==
-        0) {
+    if (!GPR_BITGET(channeld->enabled_algorithms_bitset,
+                    calld->compression_algorithm)) {
       gpr_log(GPR_ERROR,
               "Invalid compression algorithm: '%s' (previously disabled). "
               "Ignoring.",
@@ -282,32 +281,26 @@
                               grpc_channel_element *elem,
                               grpc_channel_element_args *args) {
   channel_data *channeld = elem->channel_data;
-  grpc_compression_algorithm algo_idx;
 
-  grpc_compression_options_init(&channeld->compression_options);
-  channeld->compression_options.enabled_algorithms_bitset =
-      (uint32_t)grpc_channel_args_compression_algorithm_get_states(
-          args->channel_args);
+  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 (!grpc_compression_options_is_algorithm_enabled(
-          &channeld->compression_options,
-          channeld->default_compression_algorithm)) {
+  if (!GPR_BITGET(channeld->enabled_algorithms_bitset,
+                  channeld->default_compression_algorithm)) {
     gpr_log(GPR_DEBUG,
             "compression algorithm %d not enabled: switching to none",
             channeld->default_compression_algorithm);
     channeld->default_compression_algorithm = GRPC_COMPRESS_NONE;
   }
-  channeld->compression_options.default_compression_algorithm =
-      channeld->default_compression_algorithm;
 
-  channeld->supported_compression_algorithms = 0;
-  for (algo_idx = 0; algo_idx < GRPC_COMPRESS_ALGORITHMS_COUNT; ++algo_idx) {
+  channeld->supported_compression_algorithms = 1; /* always support identity */
+  for (grpc_compression_algorithm algo_idx = 1;
+       algo_idx < GRPC_COMPRESS_ALGORITHMS_COUNT; ++algo_idx) {
     /* skip disabled algorithms */
-    if (grpc_compression_options_is_algorithm_enabled(
-            &channeld->compression_options, algo_idx) == 0) {
+    if (!GPR_BITGET(channeld->enabled_algorithms_bitset, algo_idx)) {
       continue;
     }
     channeld->supported_compression_algorithms |= 1u << algo_idx;
diff --git a/src/core/lib/channel/compress_filter.h b/src/core/lib/channel/compress_filter.h
index 0ce5d08..e4a2a82 100644
--- a/src/core/lib/channel/compress_filter.h
+++ b/src/core/lib/channel/compress_filter.h
@@ -34,9 +34,9 @@
 #ifndef GRPC_CORE_LIB_CHANNEL_COMPRESS_FILTER_H
 #define GRPC_CORE_LIB_CHANNEL_COMPRESS_FILTER_H
 
-#include "src/core/lib/channel/channel_stack.h"
+#include <grpc/impl/codegen/compression_types.h>
 
-#define GRPC_COMPRESS_REQUEST_ALGORITHM_KEY "grpc-internal-encoding-request"
+#include "src/core/lib/channel/channel_stack.h"
 
 extern int grpc_compression_trace;
 
@@ -48,7 +48,7 @@
  *  - Channel configuration, as established at channel creation time.
  *  - The metadata accompanying the outgoing data to be compressed. This is
  *    taken as a request only. We may choose not to honor it. The metadata key
- *    is given by \a GRPC_COMPRESS_REQUEST_ALGORITHM_KEY.
+ *    is given by \a GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY.
  *
  * Compression can be disabled for concrete messages (for instance in order to
  * prevent CRIME/BEAST type attacks) by having the GRPC_WRITE_NO_COMPRESS set in
diff --git a/src/core/lib/compression/compression_algorithm.c b/src/core/lib/compression/compression.c
similarity index 98%
rename from src/core/lib/compression/compression_algorithm.c
rename to src/core/lib/compression/compression.c
index 7039364..54efb5e 100644
--- a/src/core/lib/compression/compression_algorithm.c
+++ b/src/core/lib/compression/compression.c
@@ -125,6 +125,28 @@
   return NULL;
 }
 
+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;
+}
+
+void grpc_compression_options_enable_algorithm(
+    grpc_compression_options *opts, grpc_compression_algorithm algorithm) {
+  GPR_BITSET(&opts->enabled_algorithms_bitset, algorithm);
+}
+
+void grpc_compression_options_disable_algorithm(
+    grpc_compression_options *opts, grpc_compression_algorithm algorithm) {
+  GPR_BITCLEAR(&opts->enabled_algorithms_bitset, algorithm);
+}
+
+int grpc_compression_options_is_algorithm_enabled(
+    const grpc_compression_options *opts,
+    grpc_compression_algorithm algorithm) {
+  return GPR_BITGET(opts->enabled_algorithms_bitset, algorithm);
+}
+
 /* TODO(dgq): Add the ability to specify parameters to the individual
  * compression algorithms */
 grpc_compression_algorithm grpc_compression_algorithm_for_level(
@@ -180,24 +202,3 @@
       abort();
   };
 }
-
-void grpc_compression_options_init(grpc_compression_options *opts) {
-  opts->enabled_algorithms_bitset = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1;
-  opts->default_compression_algorithm = GRPC_COMPRESS_NONE;
-}
-
-void grpc_compression_options_enable_algorithm(
-    grpc_compression_options *opts, grpc_compression_algorithm algorithm) {
-  GPR_BITSET(&opts->enabled_algorithms_bitset, algorithm);
-}
-
-void grpc_compression_options_disable_algorithm(
-    grpc_compression_options *opts, grpc_compression_algorithm algorithm) {
-  GPR_BITCLEAR(&opts->enabled_algorithms_bitset, algorithm);
-}
-
-int grpc_compression_options_is_algorithm_enabled(
-    const grpc_compression_options *opts,
-    grpc_compression_algorithm algorithm) {
-  return GPR_BITGET(opts->enabled_algorithms_bitset, algorithm);
-}
diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c
index e7e1434..d081e03 100644
--- a/src/core/lib/surface/call.c
+++ b/src/core/lib/surface/call.c
@@ -181,8 +181,8 @@
   /* Call stats: only valid after trailing metadata received */
   grpc_transport_stream_stats stats;
 
-  /* Compression algorithm for the call */
-  grpc_compression_algorithm compression_algorithm;
+  /* Compression algorithm for *incoming* data */
+  grpc_compression_algorithm incoming_compression_algorithm;
   /* Supported encodings (compression algorithms), a bitset */
   uint32_t encodings_accepted_by_peer;
 
@@ -414,21 +414,27 @@
   /* TODO(ctiller): what to do about the flush that was previously here */
 }
 
-static void set_compression_algorithm(grpc_call *call,
-                                      grpc_compression_algorithm algo) {
+static void set_incoming_compression_algorithm(
+    grpc_call *call, grpc_compression_algorithm algo) {
   GPR_ASSERT(algo < GRPC_COMPRESS_ALGORITHMS_COUNT);
-  call->compression_algorithm = algo;
+  call->incoming_compression_algorithm = algo;
 }
 
 grpc_compression_algorithm grpc_call_test_only_get_compression_algorithm(
     grpc_call *call) {
   grpc_compression_algorithm algorithm;
   gpr_mu_lock(&call->mu);
-  algorithm = call->compression_algorithm;
+  algorithm = call->incoming_compression_algorithm;
   gpr_mu_unlock(&call->mu);
   return algorithm;
 }
 
+static grpc_compression_algorithm compression_algorithm_for_level_locked(
+    grpc_call *call, grpc_compression_level level) {
+  return grpc_compression_algorithm_for_level(level,
+                                              call->encodings_accepted_by_peer);
+}
+
 uint32_t grpc_call_test_only_get_message_flags(grpc_call *call) {
   uint32_t flags;
   gpr_mu_lock(&call->mu);
@@ -554,15 +560,28 @@
   return (grpc_linked_mdelem *)&md->internal_data;
 }
 
+static grpc_metadata *get_md_elem(grpc_metadata *metadata,
+                                  grpc_metadata *additional_metadata, int i,
+                                  int count) {
+  grpc_metadata *res =
+      i < count ? &metadata[i] : &additional_metadata[i - count];
+  GPR_ASSERT(res);
+  return res;
+}
+
 static int prepare_application_metadata(grpc_call *call, int count,
                                         grpc_metadata *metadata,
                                         int is_trailing,
-                                        int prepend_extra_metadata) {
+                                        int prepend_extra_metadata,
+                                        grpc_metadata *additional_metadata,
+                                        int additional_metadata_count) {
+  int total_count = count + additional_metadata_count;
   int i;
   grpc_metadata_batch *batch =
       &call->metadata_batch[0 /* is_receiving */][is_trailing];
-  for (i = 0; i < count; i++) {
-    grpc_metadata *md = &metadata[i];
+  for (i = 0; i < total_count; i++) {
+    const grpc_metadata *md =
+        get_md_elem(metadata, additional_metadata, i, count);
     grpc_linked_mdelem *l = (grpc_linked_mdelem *)&md->internal_data;
     GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data));
     l->md = grpc_mdelem_from_string_and_buffer(
@@ -581,9 +600,10 @@
       break;
     }
   }
-  if (i != count) {
+  if (i != total_count) {
     for (int j = 0; j <= i; j++) {
-      grpc_metadata *md = &metadata[j];
+      const grpc_metadata *md =
+          get_md_elem(metadata, additional_metadata, j, count);
       grpc_linked_mdelem *l = (grpc_linked_mdelem *)&md->internal_data;
       GRPC_MDELEM_UNREF(l->md);
     }
@@ -604,24 +624,36 @@
       }
     }
   }
-  for (i = 1; i < count; i++) {
-    linked_from_md(&metadata[i])->prev = linked_from_md(&metadata[i - 1]);
+  for (i = 1; i < total_count; i++) {
+    grpc_metadata *md = get_md_elem(metadata, additional_metadata, i, count);
+    grpc_metadata *prev_md =
+        get_md_elem(metadata, additional_metadata, i - 1, count);
+    linked_from_md(md)->prev = linked_from_md(prev_md);
   }
-  for (i = 0; i < count - 1; i++) {
-    linked_from_md(&metadata[i])->next = linked_from_md(&metadata[i + 1]);
+  for (i = 0; i < total_count - 1; i++) {
+    grpc_metadata *md = get_md_elem(metadata, additional_metadata, i, count);
+    grpc_metadata *next_md =
+        get_md_elem(metadata, additional_metadata, i + 1, count);
+    linked_from_md(md)->next = linked_from_md(next_md);
   }
-  switch (prepend_extra_metadata * 2 + (count != 0)) {
+
+  switch (prepend_extra_metadata * 2 + (total_count != 0)) {
     case 0:
       /* no prepend, no metadata => nothing to do */
       batch->list.head = batch->list.tail = NULL;
       break;
-    case 1:
+    case 1: {
       /* metadata, but no prepend */
-      batch->list.head = linked_from_md(&metadata[0]);
-      batch->list.tail = linked_from_md(&metadata[count - 1]);
+      grpc_metadata *first_md =
+          get_md_elem(metadata, additional_metadata, 0, count);
+      grpc_metadata *last_md =
+          get_md_elem(metadata, additional_metadata, total_count - 1, count);
+      batch->list.head = linked_from_md(first_md);
+      batch->list.tail = linked_from_md(last_md);
       batch->list.head->prev = NULL;
       batch->list.tail->next = NULL;
       break;
+    }
     case 2:
       /* prepend, but no md */
       batch->list.head = &call->send_extra_metadata[0];
@@ -630,17 +662,22 @@
       batch->list.head->prev = NULL;
       batch->list.tail->next = NULL;
       break;
-    case 3:
+    case 3: {
       /* prepend AND md */
+      grpc_metadata *first_md =
+          get_md_elem(metadata, additional_metadata, 0, count);
+      grpc_metadata *last_md =
+          get_md_elem(metadata, additional_metadata, total_count - 1, count);
       batch->list.head = &call->send_extra_metadata[0];
       call->send_extra_metadata[call->send_extra_metadata_count - 1].next =
-          linked_from_md(&metadata[0]);
-      linked_from_md(&metadata[0])->prev =
+          linked_from_md(first_md);
+      linked_from_md(first_md)->prev =
           &call->send_extra_metadata[call->send_extra_metadata_count - 1];
-      batch->list.tail = linked_from_md(&metadata[count - 1]);
+      batch->list.tail = linked_from_md(last_md);
       batch->list.head->prev = NULL;
       batch->list.tail->next = NULL;
       break;
+    }
     default:
       GPR_UNREACHABLE_CODE(return 0);
   }
@@ -945,9 +982,9 @@
   if (elem == NULL) {
     return NULL;
   } else if (elem->key == GRPC_MDSTR_GRPC_ENCODING) {
-    GPR_TIMER_BEGIN("compression_algorithm", 0);
-    set_compression_algorithm(call, decode_compression(elem));
-    GPR_TIMER_END("compression_algorithm", 0);
+    GPR_TIMER_BEGIN("incoming_compression_algorithm", 0);
+    set_incoming_compression_algorithm(call, decode_compression(elem));
+    GPR_TIMER_END("incoming_compression_algorithm", 0);
     return NULL;
   } else if (elem->key == GRPC_MDSTR_GRPC_ACCEPT_ENCODING) {
     GPR_TIMER_BEGIN("encodings_accepted_by_peer", 0);
@@ -1110,9 +1147,9 @@
   } else {
     call->test_only_last_message_flags = call->receiving_stream->flags;
     if ((call->receiving_stream->flags & GRPC_WRITE_INTERNAL_COMPRESS) &&
-        (call->compression_algorithm > GRPC_COMPRESS_NONE)) {
+        (call->incoming_compression_algorithm > GRPC_COMPRESS_NONE)) {
       *call->receiving_buffer = grpc_raw_compressed_byte_buffer_create(
-          NULL, 0, call->compression_algorithm);
+          NULL, 0, call->incoming_compression_algorithm);
     } else {
       *call->receiving_buffer = grpc_raw_byte_buffer_create(NULL, 0);
     }
@@ -1143,12 +1180,13 @@
 static void validate_filtered_metadata(grpc_exec_ctx *exec_ctx,
                                        batch_control *bctl) {
   grpc_call *call = bctl->call;
-  /* validate call->compression_algorithm */
-  if (call->compression_algorithm != GRPC_COMPRESS_NONE) {
-    const grpc_compression_algorithm algo = call->compression_algorithm;
+  /* validate call->incoming_compression_algorithm */
+  if (call->incoming_compression_algorithm != GRPC_COMPRESS_NONE) {
+    const grpc_compression_algorithm algo =
+        call->incoming_compression_algorithm;
     char *error_msg = NULL;
     const grpc_compression_options compression_options =
-        grpc_channel_get_compression_options(call->channel);
+        grpc_channel_compression_options(call->channel);
     /* check if algorithm is known */
     if (algo >= GRPC_COMPRESS_ALGORITHMS_COUNT) {
       gpr_asprintf(&error_msg, "Invalid compression algorithm value '%d'.",
@@ -1165,7 +1203,7 @@
       gpr_log(GPR_ERROR, error_msg);
       close_with_status(exec_ctx, call, GRPC_STATUS_UNIMPLEMENTED, error_msg);
     } else {
-      call->compression_algorithm = algo;
+      call->incoming_compression_algorithm = algo;
     }
     gpr_free(error_msg);
   }
@@ -1174,11 +1212,12 @@
    * grpc-accept-encoding */
   GPR_ASSERT(call->encodings_accepted_by_peer != 0);
   if (!GPR_BITGET(call->encodings_accepted_by_peer,
-                  call->compression_algorithm)) {
+                  call->incoming_compression_algorithm)) {
     extern int grpc_compression_trace;
     if (grpc_compression_trace) {
       char *algo_name;
-      grpc_compression_algorithm_name(call->compression_algorithm, &algo_name);
+      grpc_compression_algorithm_name(call->incoming_compression_algorithm,
+                                      &algo_name);
       gpr_log(GPR_ERROR,
               "Compression algorithm (grpc-encoding = '%s') not present in "
               "the bitset of accepted encodings (grpc-accept-encodings: "
@@ -1348,7 +1387,39 @@
           error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
           goto done_with_error;
         }
-        if (op->data.send_initial_metadata.count > INT_MAX) {
+        /* process compression level */
+        grpc_metadata compression_md;
+        memset(&compression_md, 0, sizeof(grpc_metadata));
+        size_t additional_metadata_count = 0;
+        grpc_compression_level effective_compression_level;
+        bool level_set = false;
+        if (op->data.send_initial_metadata.maybe_compression_level.is_set) {
+          effective_compression_level =
+              op->data.send_initial_metadata.maybe_compression_level
+                  .compression_level;
+          level_set = true;
+        } else {
+          const grpc_compression_options copts =
+              grpc_channel_compression_options(call->channel);
+          level_set = copts.default_level.is_set;
+          if (level_set) {
+            effective_compression_level = copts.default_level.level;
+          }
+        }
+        if (level_set) {
+          const grpc_compression_algorithm calgo =
+              compression_algorithm_for_level_locked(
+                  call, effective_compression_level);
+          char *calgo_name;
+          grpc_compression_algorithm_name(calgo, &calgo_name);
+          compression_md.key = GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY;
+          compression_md.value = calgo_name;
+          compression_md.value_length = strlen(calgo_name);
+          additional_metadata_count++;
+        }
+
+        if (op->data.send_initial_metadata.count + additional_metadata_count >
+            INT_MAX) {
           error = GRPC_CALL_ERROR_INVALID_METADATA;
           goto done_with_error;
         }
@@ -1356,7 +1427,8 @@
         call->sent_initial_metadata = 1;
         if (!prepare_application_metadata(
                 call, (int)op->data.send_initial_metadata.count,
-                op->data.send_initial_metadata.metadata, 0, call->is_client)) {
+                op->data.send_initial_metadata.metadata, 0, call->is_client,
+                &compression_md, (int)additional_metadata_count)) {
           error = GRPC_CALL_ERROR_INVALID_METADATA;
           goto done_with_error;
         }
@@ -1444,7 +1516,8 @@
         if (!prepare_application_metadata(
                 call,
                 (int)op->data.send_status_from_server.trailing_metadata_count,
-                op->data.send_status_from_server.trailing_metadata, 1, 1)) {
+                op->data.send_status_from_server.trailing_metadata, 1, 1, NULL,
+                0)) {
           error = GRPC_CALL_ERROR_INVALID_METADATA;
           goto done_with_error;
         }
@@ -1633,9 +1706,10 @@
 grpc_compression_algorithm grpc_call_compression_for_level(
     grpc_call *call, grpc_compression_level level) {
   gpr_mu_lock(&call->mu);
-  const uint32_t accepted_encodings = call->encodings_accepted_by_peer;
+  grpc_compression_algorithm algo =
+      compression_algorithm_for_level_locked(call, level);
   gpr_mu_unlock(&call->mu);
-  return grpc_compression_algorithm_for_level(level, accepted_encodings);
+  return algo;
 }
 
 const char *grpc_call_error_to_string(grpc_call_error error) {
diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c
index 72d0cfa..a71190f 100644
--- a/src/core/lib/surface/channel.c
+++ b/src/core/lib/surface/channel.c
@@ -70,6 +70,7 @@
 
   gpr_mu registered_call_mu;
   registered_call *registered_calls;
+
   char *target;
 };
 
@@ -154,14 +155,29 @@
                 ":authority", args->args[i].value.string);
           }
         }
+      } else if (0 == strcmp(args->args[i].key,
+                             GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL)) {
+        channel->compression_options.default_level.is_set = true;
+        GPR_ASSERT(args->args[i].value.integer >= 0 &&
+                   args->args[i].value.integer < GRPC_COMPRESS_LEVEL_COUNT);
+        channel->compression_options.default_level.level =
+            (grpc_compression_level)args->args[i].value.integer;
+      } else if (0 == strcmp(args->args[i].key,
+                             GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM)) {
+        channel->compression_options.default_algorithm.is_set = true;
+        GPR_ASSERT(args->args[i].value.integer >= 0 &&
+                   args->args[i].value.integer <
+                       GRPC_COMPRESS_ALGORITHMS_COUNT);
+        channel->compression_options.default_algorithm.algorithm =
+            (grpc_compression_algorithm)args->args[i].value.integer;
+      } 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 */
       }
     }
-    /* extract compression options */
-    channel->compression_options.enabled_algorithms_bitset =
-        (uint32_t)grpc_channel_args_compression_algorithm_get_states(args);
-    channel->compression_options.default_compression_algorithm =
-        grpc_channel_args_get_compression_algorithm(args);
-
     grpc_channel_args_destroy(args);
   }
 
@@ -315,7 +331,7 @@
   return CHANNEL_STACK_FROM_CHANNEL(channel);
 }
 
-grpc_compression_options grpc_channel_get_compression_options(
+grpc_compression_options grpc_channel_compression_options(
     const grpc_channel *channel) {
   return channel->compression_options;
 }
diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h
index 8f153fb..c3279fe 100644
--- a/src/core/lib/surface/channel.h
+++ b/src/core/lib/surface/channel.h
@@ -45,10 +45,6 @@
 /** Get a (borrowed) pointer to this channels underlying channel stack */
 grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel);
 
-/** Return the compression options for \a channel */
-grpc_compression_options grpc_channel_get_compression_options(
-    const grpc_channel *channel);
-
 /** Get a grpc_mdelem of grpc-status: X where X is the numeric value of
     status_code.
 
@@ -75,4 +71,8 @@
   grpc_channel_internal_unref(exec_ctx, channel)
 #endif
 
+/** Return the channel's compression options. */
+grpc_compression_options grpc_channel_compression_options(
+    const grpc_channel *channel);
+
 #endif /* GRPC_CORE_LIB_SURFACE_CHANNEL_H */
diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc
index 32c7794..d3e5ce0 100644
--- a/src/cpp/client/client_context.cc
+++ b/src/cpp/client/client_context.cc
@@ -33,15 +33,14 @@
 
 #include <grpc++/client_context.h>
 
-#include <grpc++/security/credentials.h>
-#include <grpc++/server_context.h>
-#include <grpc++/support/time.h>
 #include <grpc/compression.h>
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/lib/channel/compress_filter.h"
+#include <grpc++/security/credentials.h>
+#include <grpc++/server_context.h>
+#include <grpc++/support/time.h>
 
 namespace grpc {
 
@@ -112,7 +111,7 @@
     abort();
   }
   GPR_ASSERT(algorithm_name != nullptr);
-  AddMetadata(GRPC_COMPRESS_REQUEST_ALGORITHM_KEY, algorithm_name);
+  AddMetadata(GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY, algorithm_name);
 }
 
 void ClientContext::TryCancel() {
diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc
index 61f0f6a..bbea935 100644
--- a/src/cpp/server/server_builder.cc
+++ b/src/cpp/server/server_builder.cc
@@ -37,6 +37,8 @@
 #include <grpc++/server.h>
 #include <grpc/support/cpu.h>
 #include <grpc/support/log.h>
+
+#include "include/grpc/support/useful.h"
 #include "src/cpp/server/thread_pool_interface.h"
 
 namespace grpc {
@@ -52,12 +54,18 @@
 
 ServerBuilder::ServerBuilder()
     : max_message_size_(-1), generic_service_(nullptr) {
-  grpc_compression_options_init(&compression_options_);
   gpr_once_init(&once_init_plugin_list, do_plugin_list_init);
   for (auto factory : (*g_plugin_factory_list)) {
     std::unique_ptr<ServerBuilderPlugin> plugin = factory();
     plugins_[plugin->name()] = std::move(plugin);
   }
+  // all compression algorithms enabled by default.
+  enabled_compression_algorithms_bitset_ =
+      (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1;
+  memset(&maybe_default_compression_level_, 0,
+         sizeof(maybe_default_compression_level_));
+  memset(&maybe_default_compression_algorithm_, 0,
+         sizeof(maybe_default_compression_algorithm_));
 }
 
 std::unique_ptr<ServerCompletionQueue> ServerBuilder::AddCompletionQueue() {
@@ -66,35 +74,65 @@
   return std::unique_ptr<ServerCompletionQueue>(cq);
 }
 
-void ServerBuilder::RegisterService(Service* service) {
+ServerBuilder& ServerBuilder::RegisterService(Service* service) {
   services_.emplace_back(new NamedService(service));
+  return *this;
 }
 
-void ServerBuilder::RegisterService(const grpc::string& addr,
-                                    Service* service) {
+ServerBuilder& ServerBuilder::RegisterService(const grpc::string& addr,
+                                              Service* service) {
   services_.emplace_back(new NamedService(addr, service));
+  return *this;
 }
 
-void ServerBuilder::RegisterAsyncGenericService(AsyncGenericService* service) {
+ServerBuilder& ServerBuilder::RegisterAsyncGenericService(
+    AsyncGenericService* service) {
   if (generic_service_) {
     gpr_log(GPR_ERROR,
             "Adding multiple AsyncGenericService is unsupported for now. "
             "Dropping the service %p",
             service);
-    return;
+  } else {
+    generic_service_ = service;
   }
-  generic_service_ = service;
+  return *this;
 }
 
-void ServerBuilder::SetOption(std::unique_ptr<ServerBuilderOption> option) {
+ServerBuilder& ServerBuilder::SetOption(
+    std::unique_ptr<ServerBuilderOption> option) {
   options_.push_back(std::move(option));
+  return *this;
 }
 
-void ServerBuilder::AddListeningPort(const grpc::string& addr,
-                                     std::shared_ptr<ServerCredentials> creds,
-                                     int* selected_port) {
+ServerBuilder& ServerBuilder::SetCompressionAlgorithmSupportStatus(
+    grpc_compression_algorithm algorithm, bool enabled) {
+  if (enabled) {
+    GPR_BITSET(&enabled_compression_algorithms_bitset_, algorithm);
+  } else {
+    GPR_BITCLEAR(&enabled_compression_algorithms_bitset_, algorithm);
+  }
+  return *this;
+}
+
+ServerBuilder& ServerBuilder::SetDefaultCompressionLevel(
+    grpc_compression_level level) {
+  maybe_default_compression_level_.level = level;
+  return *this;
+}
+
+ServerBuilder& ServerBuilder::SetDefaultCompressionAlgorithm(
+    grpc_compression_algorithm algorithm) {
+  maybe_default_compression_algorithm_.is_set = true;
+  maybe_default_compression_algorithm_.algorithm = algorithm;
+  return *this;
+}
+
+ServerBuilder& ServerBuilder::AddListeningPort(
+    const grpc::string& addr, std::shared_ptr<ServerCredentials> creds,
+    int* selected_port) {
   Port port = {addr, creds, selected_port};
   ports_.push_back(port);
+  return *this;
 }
 
 std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
@@ -124,7 +162,15 @@
     args.SetInt(GRPC_ARG_MAX_MESSAGE_LENGTH, max_message_size_);
   }
   args.SetInt(GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET,
-              compression_options_.enabled_algorithms_bitset);
+              enabled_compression_algorithms_bitset_);
+  if (maybe_default_compression_level_.is_set) {
+    args.SetInt(GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL,
+                maybe_default_compression_level_.level);
+  }
+  if (maybe_default_compression_algorithm_.is_set) {
+    args.SetInt(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM,
+                maybe_default_compression_algorithm_.algorithm);
+  }
   std::unique_ptr<Server> server(
       new Server(thread_pool.release(), true, max_message_size_, &args));
   ServerInitializer* initializer = server->initializer();
diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc
index 204fef1..43117fd 100644
--- a/src/cpp/server/server_context.cc
+++ b/src/cpp/server/server_context.cc
@@ -42,7 +42,6 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
-#include "src/core/lib/channel/compress_filter.h"
 #include "src/core/lib/surface/call.h"
 
 namespace grpc {
@@ -196,6 +195,9 @@
 }
 
 void ServerContext::set_compression_level(grpc_compression_level level) {
+  // TODO(dgq): get rid of grpc_call_compression_for_level and propagate the
+  // compression level by adding a new argument to
+  // CallOpSendInitialMetadata::SendInitialMetadata.
   const grpc_compression_algorithm algorithm_for_level =
       grpc_call_compression_for_level(call_, level);
   set_compression_algorithm(algorithm_for_level);
@@ -210,7 +212,7 @@
     abort();
   }
   GPR_ASSERT(algorithm_name != NULL);
-  AddInitialMetadata(GRPC_COMPRESS_REQUEST_ALGORITHM_KEY, algorithm_name);
+  AddInitialMetadata(GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY, algorithm_name);
 }
 
 grpc::string ServerContext::peer() const {
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index 5b8ff9b..49198cb 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -503,6 +503,7 @@
                            grpc_metadata_array *initial_metadata, uint32_t write_flags) {
   /* TODO: don't use magic number */
   grpc_op ops[6];
+  memset(ops, 0, sizeof(ops));
   ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
   grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
                                 initial_metadata);
@@ -555,6 +556,7 @@
                                       grpc_metadata_array *initial_metadata) {
   /* TODO: don't use magic number */
   grpc_op ops[4];
+  memset(ops, 0, sizeof(ops));
   ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
   grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
                                 initial_metadata);
@@ -596,6 +598,7 @@
     size_t send_buffer_len, grpc_metadata_array *initial_metadata, uint32_t write_flags) {
   /* TODO: don't use magic number */
   grpc_op ops[4];
+  memset(ops, 0, sizeof(ops));
   ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
   grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
                                 initial_metadata);
@@ -638,6 +641,7 @@
                                       grpc_metadata_array *initial_metadata) {
   /* TODO: don't use magic number */
   grpc_op ops[2];
+  memset(ops, 0, sizeof(ops));
   ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
   grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
                                 initial_metadata);
@@ -684,6 +688,7 @@
                             int32_t send_empty_initial_metadata) {
   /* TODO: don't use magic number */
   grpc_op ops[2];
+  memset(ops, 0, sizeof(ops));
   size_t nops = send_empty_initial_metadata ? 2 : 1;
   ops[0].op = GRPC_OP_SEND_MESSAGE;
   ctx->send_message = string_to_byte_buffer(send_buffer, send_buffer_len);
@@ -691,8 +696,6 @@
   ops[0].flags = write_flags;
   ops[0].reserved = NULL;
   ops[1].op = GRPC_OP_SEND_INITIAL_METADATA;
-  ops[1].data.send_initial_metadata.count = 0;
-  ops[1].data.send_initial_metadata.metadata = NULL;
   ops[1].flags = 0;
   ops[1].reserved = NULL;
 
@@ -719,6 +722,7 @@
     size_t optional_send_buffer_len, uint32_t write_flags) {
   /* TODO: don't use magic number */
   grpc_op ops[3];
+  memset(ops, 0, sizeof(ops));
   size_t nops = 1;
   ops[0].op = GRPC_OP_SEND_STATUS_FROM_SERVER;
   ops[0].data.send_status_from_server.status = status_code;
@@ -743,8 +747,6 @@
   }
   if (send_empty_initial_metadata) {
     ops[nops].op = GRPC_OP_SEND_INITIAL_METADATA;
-    ops[nops].data.send_initial_metadata.count = 0;
-    ops[nops].data.send_initial_metadata.metadata = NULL;
     ops[nops].flags = 0;
     ops[nops].reserved = NULL;
     nops++;
@@ -784,6 +786,7 @@
                                      grpc_metadata_array *initial_metadata) {
   /* TODO: don't use magic number */
   grpc_op ops[1];
+  memset(ops, 0, sizeof(ops));
   ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
   grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
                                 initial_metadata);
diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
index 16e5bff..27723af 100644
--- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
+++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
@@ -72,6 +72,8 @@
     _op.op = GRPC_OP_SEND_INITIAL_METADATA;
     _op.data.send_initial_metadata.count = metadata.count;
     _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.compression_level = 0;
     _handler = handler;
   }
   return self;
diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c
index 884130e..0ec5022 100644
--- a/src/php/ext/grpc/call.c
+++ b/src/php/ext/grpc/call.c
@@ -292,6 +292,7 @@
   grpc_metadata_array_init(&recv_trailing_metadata);
   MAKE_STD_ZVAL(result);
   object_init(result);
+  memset(ops, 0, sizeof(ops));
   /* "a" == 1 array */
   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) ==
       FAILURE) {
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 162191b..907b7b4 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -84,7 +84,7 @@
   'src/core/lib/channel/connected_channel.c',
   'src/core/lib/channel/http_client_filter.c',
   'src/core/lib/channel/http_server_filter.c',
-  'src/core/lib/compression/compression_algorithm.c',
+  'src/core/lib/compression/compression.c',
   'src/core/lib/compression/message_compress.c',
   'src/core/lib/debug/trace.c',
   'src/core/lib/http/format_request.c',
diff --git a/test/core/bad_client/tests/large_metadata.c b/test/core/bad_client/tests/large_metadata.c
index b7d329c..ded5f17 100644
--- a/test/core/bad_client/tests/large_metadata.c
+++ b/test/core/bad_client/tests/large_metadata.c
@@ -163,6 +163,7 @@
   meta.value_length = metadata_value_size;
 
   grpc_op op;
+  memset(&op, 0, sizeof(op));
   op.op = GRPC_OP_SEND_INITIAL_METADATA;
   op.data.send_initial_metadata.count = 1;
   op.data.send_initial_metadata.metadata = &meta;
diff --git a/test/core/bad_ssl/bad_ssl_test.c b/test/core/bad_ssl/bad_ssl_test.c
index c4ae212..bb06ab0 100644
--- a/test/core/bad_ssl/bad_ssl_test.c
+++ b/test/core/bad_ssl/bad_ssl_test.c
@@ -84,6 +84,7 @@
                                "/foo", "foo.test.google.fr:1234", deadline,
                                NULL);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/client_config/lb_policies_test.c b/test/core/client_config/lb_policies_test.c
index 2ec4612..0fbab5c 100644
--- a/test/core/client_config/lb_policies_test.c
+++ b/test/core/client_config/lb_policies_test.c
@@ -275,6 +275,7 @@
     GPR_ASSERT(c);
     completed_client = 0;
 
+    memset(ops, 0, sizeof(ops));
     op = ops;
     op->op = GRPC_OP_SEND_INITIAL_METADATA;
     op->data.send_initial_metadata.count = 0;
@@ -327,6 +328,7 @@
     }
 
     if (s_idx >= 0) {
+      memset(ops, 0, sizeof(ops));
       op = ops;
       op->op = GRPC_OP_SEND_INITIAL_METADATA;
       op->data.send_initial_metadata.count = 0;
@@ -415,6 +417,7 @@
     kill_server(f, i);
   }
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/client_config/set_initial_connect_string_test.c b/test/core/client_config/set_initial_connect_string_test.c
index c1b8452..7b0092a 100644
--- a/test/core/client_config/set_initial_connect_string_test.c
+++ b/test/core/client_config/set_initial_connect_string_test.c
@@ -134,6 +134,7 @@
   state.call = grpc_channel_create_call(
       state.channel, NULL, GRPC_PROPAGATE_DEFAULTS, state.cq, "/Service/Method",
       "localhost", gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+  memset(&state.op, 0, sizeof(state.op));
   state.op.op = GRPC_OP_SEND_INITIAL_METADATA;
   state.op.data.send_initial_metadata.count = 0;
   state.op.flags = 0;
diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c
index 202fb3b..46e060e 100644
--- a/test/core/end2end/dualstack_socket_test.c
+++ b/test/core/end2end/dualstack_socket_test.c
@@ -167,6 +167,7 @@
                                "/foo", "foo.test.google.fr", deadline, NULL);
   GPR_ASSERT(c);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -201,6 +202,7 @@
     cq_expect_completion(cqv, tag(101), 1);
     cq_verify(cqv);
 
+    memset(ops, 0, sizeof(ops));
     op = ops;
     op->op = GRPC_OP_SEND_INITIAL_METADATA;
     op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/fixtures/h2_ssl_cert.c b/test/core/end2end/fixtures/h2_ssl_cert.c
index f4dea2c..b94d67f 100644
--- a/test/core/end2end/fixtures/h2_ssl_cert.c
+++ b/test/core/end2end/fixtures/h2_ssl_cert.c
@@ -321,6 +321,7 @@
                                NULL);
   GPR_ASSERT(c);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/fixtures/proxy.c b/test/core/end2end/fixtures/proxy.c
index f6e01ec..38093ea 100644
--- a/test/core/end2end/fixtures/proxy.c
+++ b/test/core/end2end/fixtures/proxy.c
@@ -170,6 +170,7 @@
   grpc_op op;
   grpc_call_error err;
 
+  memset(&op, 0, sizeof(op));
   if (!pc->proxy->shutdown) {
     op.op = GRPC_OP_SEND_INITIAL_METADATA;
     op.flags = 0;
@@ -327,6 +328,7 @@
 
   if (success) {
     grpc_op op;
+    memset(&op, 0, sizeof(op));
     proxy_call *pc = gpr_malloc(sizeof(*pc));
     memset(pc, 0, sizeof(*pc));
     pc->proxy = proxy;
diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c
index b133a94..6d07350 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.c
+++ b/test/core/end2end/fuzzers/api_fuzzer.c
@@ -697,6 +697,7 @@
           break;
         }
         grpc_op *ops = gpr_malloc(sizeof(grpc_op) * num_ops);
+        memset(ops, 0, sizeof(grpc_op) * num_ops);
         bool ok = true;
         size_t i;
         grpc_op *op;
diff --git a/test/core/end2end/fuzzers/client_fuzzer.c b/test/core/end2end/fuzzers/client_fuzzer.c
index afcf763..5612b66 100644
--- a/test/core/end2end/fuzzers/client_fuzzer.c
+++ b/test/core/end2end/fuzzers/client_fuzzer.c
@@ -31,6 +31,8 @@
  *
  */
 
+#include <string.h>
+
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 
@@ -78,6 +80,7 @@
   size_t details_capacity = 0;
 
   grpc_op ops[6];
+  memset(ops, 0, sizeof(ops));
   grpc_op *op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/goaway_server_test.c b/test/core/end2end/goaway_server_test.c
index 5f8c264..3266793 100644
--- a/test/core/end2end/goaway_server_test.c
+++ b/test/core/end2end/goaway_server_test.c
@@ -132,6 +132,7 @@
       chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq, "/foo", "127.0.0.1",
       GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20), NULL);
   /* send initial metadata to probe connectivity */
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -142,6 +143,7 @@
                                                    (size_t)(op - ops),
                                                    tag(0x101), NULL));
   /* and receive status to probe termination */
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv1;
@@ -183,6 +185,7 @@
                                         tag(0x9999));
 
   /* listen for close on the server call to probe for finishing */
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled1;
@@ -205,6 +208,7 @@
       chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq, "/foo", "127.0.0.1",
       GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20), NULL);
   /* send initial metadata to probe connectivity */
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -215,6 +219,7 @@
                                                    (size_t)(op - ops),
                                                    tag(0x201), NULL));
   /* and receive status to probe termination */
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv2;
@@ -249,6 +254,7 @@
   cq_verify(cqv);
 
   /* listen for close on the server call to probe for finishing */
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled2;
diff --git a/test/core/end2end/invalid_call_argument_test.c b/test/core/end2end/invalid_call_argument_test.c
index cf42e92..3545660 100644
--- a/test/core/end2end/invalid_call_argument_test.c
+++ b/test/core/end2end/invalid_call_argument_test.c
@@ -30,11 +30,15 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
+#include <limits.h>
+#include <string.h>
+
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
-#include <limits.h>
+
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
@@ -74,6 +78,7 @@
   g_state.cqv = cq_verifier_create(g_state.cq);
   g_state.details = NULL;
   g_state.details_capacity = 0;
+  memset(g_state.ops, 0, sizeof(g_state.ops));
 
   if (is_client) {
     /* create a call, channel to a non existant server */
diff --git a/test/core/end2end/no_server_test.c b/test/core/end2end/no_server_test.c
index 7a5cd23..08af382 100644
--- a/test/core/end2end/no_server_test.c
+++ b/test/core/end2end/no_server_test.c
@@ -31,9 +31,12 @@
  *
  */
 
+#include <string.h>
+
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/util/test_config.h"
 
@@ -65,6 +68,7 @@
   call = grpc_channel_create_call(chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
                                   "/Foo", "nonexistant", deadline, NULL);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/bad_hostname.c b/test/core/end2end/tests/bad_hostname.c
index 3cb9b3d..c9663c2 100644
--- a/test/core/end2end/tests/bad_hostname.c
+++ b/test/core/end2end/tests/bad_hostname.c
@@ -123,6 +123,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/binary_metadata.c b/test/core/end2end/tests/binary_metadata.c
index 994c3bf..3dd2612 100644
--- a/test/core/end2end/tests/binary_metadata.c
+++ b/test/core/end2end/tests/binary_metadata.c
@@ -157,6 +157,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 2;
@@ -201,6 +202,7 @@
   cq_expect_completion(cqv, tag(101), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 2;
@@ -219,6 +221,7 @@
   cq_expect_completion(cqv, tag(102), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
diff --git a/test/core/end2end/tests/call_creds.c b/test/core/end2end/tests/call_creds.c
index b555bea..eee0cb8 100644
--- a/test/core/end2end/tests/call_creds.c
+++ b/test/core/end2end/tests/call_creds.c
@@ -193,6 +193,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -248,6 +249,7 @@
   /* Cannot set creds on the server call object. */
   GPR_ASSERT(grpc_call_set_credentials(s, NULL) != GRPC_CALL_OK);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -265,6 +267,7 @@
   cq_expect_completion(cqv, tag(102), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
@@ -410,6 +413,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c
index fc2a64a..51c13da 100644
--- a/test/core/end2end/tests/cancel_after_accept.c
+++ b/test/core/end2end/tests/cancel_after_accept.c
@@ -136,6 +136,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
@@ -174,6 +175,7 @@
   cq_expect_completion(cqv, tag(2), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_MESSAGE;
   op->data.recv_message = &request_payload_recv;
diff --git a/test/core/end2end/tests/cancel_after_client_done.c b/test/core/end2end/tests/cancel_after_client_done.c
index 3bafa8c..2b5a409 100644
--- a/test/core/end2end/tests/cancel_after_client_done.c
+++ b/test/core/end2end/tests/cancel_after_client_done.c
@@ -136,6 +136,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
@@ -178,6 +179,7 @@
   cq_expect_completion(cqv, tag(2), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_MESSAGE;
   op->data.recv_message = &request_payload_recv;
diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c
index fc2751a..85fbe9d 100644
--- a/test/core/end2end/tests/cancel_after_invoke.c
+++ b/test/core/end2end/tests/cancel_after_invoke.c
@@ -131,6 +131,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
diff --git a/test/core/end2end/tests/cancel_before_invoke.c b/test/core/end2end/tests/cancel_before_invoke.c
index 33005db..d99062c 100644
--- a/test/core/end2end/tests/cancel_before_invoke.c
+++ b/test/core/end2end/tests/cancel_before_invoke.c
@@ -131,6 +131,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
diff --git a/test/core/end2end/tests/cancel_with_status.c b/test/core/end2end/tests/cancel_with_status.c
index c3ee4a6..83629a9 100644
--- a/test/core/end2end/tests/cancel_with_status.c
+++ b/test/core/end2end/tests/cancel_with_status.c
@@ -122,6 +122,7 @@
   grpc_metadata_array_init(&initial_metadata_recv);
   grpc_metadata_array_init(&trailing_metadata_recv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
diff --git a/test/core/end2end/tests/compressed_payload.c b/test/core/end2end/tests/compressed_payload.c
index a0fb8c0..34947fb 100644
--- a/test/core/end2end/tests/compressed_payload.c
+++ b/test/core/end2end/tests/compressed_payload.c
@@ -46,7 +46,7 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/channel/compress_filter.h"
+#include "src/core/lib/surface/call.h"
 #include "src/core/lib/surface/call_test_only.h"
 #include "test/core/end2end/cq_verifier.h"
 
@@ -157,6 +157,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   if (client_metadata != NULL) {
@@ -269,10 +270,13 @@
 
 static void request_with_payload_template(
     grpc_end2end_test_config config, const char *test_name,
-    uint32_t send_flags_bitmask,
-    grpc_compression_algorithm requested_compression_algorithm,
-    grpc_compression_algorithm expected_compression_algorithm,
-    grpc_metadata *client_metadata) {
+    uint32_t client_send_flags_bitmask,
+    grpc_compression_algorithm default_client_channel_compression_algorithm,
+    grpc_compression_algorithm default_server_channel_compression_algorithm,
+    grpc_compression_algorithm expected_algorithm_from_client,
+    grpc_compression_algorithm expected_algorithm_from_server,
+    grpc_metadata *client_init_metadata, bool set_server_level,
+    grpc_compression_level server_compression_level) {
   grpc_call *c;
   grpc_call *s;
   gpr_slice request_payload_slice;
@@ -287,6 +291,8 @@
   grpc_metadata_array trailing_metadata_recv;
   grpc_metadata_array request_metadata_recv;
   grpc_byte_buffer *request_payload_recv = NULL;
+  grpc_byte_buffer *response_payload;
+  grpc_byte_buffer *response_payload_recv;
   grpc_call_details call_details;
   grpc_status_code status;
   grpc_call_error error;
@@ -294,17 +300,22 @@
   size_t details_capacity = 0;
   int was_cancelled = 2;
   cq_verifier *cqv;
-  char str[1024];
+  char request_str[1024];
+  char response_str[1024];
 
-  memset(str, 'x', 1023);
-  str[1023] = '\0';
-  request_payload_slice = gpr_slice_from_copied_string(str);
-  request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+  memset(request_str, 'x', 1023);
+  request_str[1023] = '\0';
+
+  memset(response_str, 'y', 1023);
+  response_str[1023] = '\0';
+
+  request_payload_slice = gpr_slice_from_copied_string(request_str);
+  gpr_slice response_payload_slice = gpr_slice_from_copied_string(response_str);
 
   client_args = grpc_channel_args_set_compression_algorithm(
-      NULL, requested_compression_algorithm);
+      NULL, default_client_channel_compression_algorithm);
   server_args = grpc_channel_args_set_compression_algorithm(
-      NULL, requested_compression_algorithm);
+      NULL, default_server_channel_compression_algorithm);
 
   f = begin_test(config, test_name, client_args, server_args);
   cqv = cq_verifier_create(f.cq);
@@ -318,26 +329,18 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
-  if (client_metadata != NULL) {
+  if (client_init_metadata != NULL) {
     op->data.send_initial_metadata.count = 1;
-    op->data.send_initial_metadata.metadata = client_metadata;
+    op->data.send_initial_metadata.metadata = client_init_metadata;
   } else {
     op->data.send_initial_metadata.count = 0;
   }
   op->flags = 0;
   op->reserved = NULL;
   op++;
-  op->op = GRPC_OP_SEND_MESSAGE;
-  op->data.send_message = request_payload;
-  op->flags = send_flags_bitmask;
-  op->reserved = NULL;
-  op++;
-  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
-  op->flags = 0;
-  op->reserved = NULL;
-  op++;
   op->op = GRPC_OP_RECV_INITIAL_METADATA;
   op->data.recv_initial_metadata = &initial_metadata_recv;
   op->flags = 0;
@@ -356,9 +359,9 @@
 
   error =
       grpc_server_request_call(f.server, &s, &call_details,
-                               &request_metadata_recv, f.cq, f.cq, tag(101));
+                               &request_metadata_recv, f.cq, f.cq, tag(100));
   GPR_ASSERT(GRPC_CALL_OK == error);
-  cq_expect_completion(cqv, tag(101), true);
+  cq_expect_completion(cqv, tag(100), true);
   cq_verify(cqv);
 
   GPR_ASSERT(GPR_BITCOUNT(grpc_call_test_only_get_encodings_accepted_by_peer(
@@ -370,29 +373,107 @@
   GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
                         GRPC_COMPRESS_GZIP) != 0);
 
+  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_compression_level.is_set = true;
+    op->data.send_initial_metadata.maybe_compression_level.compression_level =
+        server_compression_level;
+  }
   op->flags = 0;
   op->reserved = NULL;
   op++;
-  op->op = GRPC_OP_RECV_MESSAGE;
-  op->data.recv_message = &request_payload_recv;
-  op->flags = 0;
-  op->reserved = NULL;
-  op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL);
-  GPR_ASSERT(GRPC_CALL_OK == error);
-
-  cq_expect_completion(cqv, tag(102), true);
-  cq_verify(cqv);
-
-  op = ops;
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
   op->flags = 0;
   op->reserved = NULL;
   op++;
+  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(101), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  for (int i = 0; i < 2; i++) {
+    request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+    response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1);
+
+    memset(ops, 0, sizeof(ops));
+    op = ops;
+    op->op = GRPC_OP_SEND_MESSAGE;
+    op->data.send_message = request_payload;
+    op->flags = client_send_flags_bitmask;
+    op->reserved = NULL;
+    op++;
+    op->op = GRPC_OP_RECV_MESSAGE;
+    op->data.recv_message = &response_payload_recv;
+    op->flags = 0;
+    op->reserved = NULL;
+    op++;
+    error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), NULL);
+    GPR_ASSERT(GRPC_CALL_OK == error);
+
+    memset(ops, 0, sizeof(ops));
+    op = ops;
+    op->op = GRPC_OP_RECV_MESSAGE;
+    op->data.recv_message = &request_payload_recv;
+    op->flags = 0;
+    op->reserved = NULL;
+    op++;
+    error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL);
+    GPR_ASSERT(GRPC_CALL_OK == error);
+    cq_expect_completion(cqv, tag(102), 1);
+    cq_verify(cqv);
+
+    GPR_ASSERT(request_payload_recv->type == GRPC_BB_RAW);
+    GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, request_str));
+    GPR_ASSERT(request_payload_recv->data.raw.compression ==
+               expected_algorithm_from_client);
+
+    memset(ops, 0, sizeof(ops));
+    op = ops;
+    op->op = GRPC_OP_SEND_MESSAGE;
+    op->data.send_message = response_payload;
+    op->flags = 0;
+    op->reserved = NULL;
+    op++;
+    error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL);
+    GPR_ASSERT(GRPC_CALL_OK == error);
+    cq_expect_completion(cqv, tag(103), 1);
+    cq_expect_completion(cqv, tag(2), 1);
+    cq_verify(cqv);
+
+    GPR_ASSERT(response_payload_recv->type == GRPC_BB_RAW);
+    GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, response_str));
+    if (server_compression_level > GRPC_COMPRESS_LEVEL_NONE) {
+      const grpc_compression_algorithm algo_for_server_level =
+          grpc_call_compression_for_level(s, server_compression_level);
+      GPR_ASSERT(response_payload_recv->data.raw.compression ==
+                 algo_for_server_level);
+    } else {
+      GPR_ASSERT(response_payload_recv->data.raw.compression ==
+                 expected_algorithm_from_server);
+    }
+
+    grpc_byte_buffer_destroy(request_payload);
+    grpc_byte_buffer_destroy(response_payload);
+    grpc_byte_buffer_destroy(request_payload_recv);
+    grpc_byte_buffer_destroy(response_payload_recv);
+  }
+
+  gpr_slice_unref(request_payload_slice);
+  gpr_slice_unref(response_payload_slice);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
   op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
   op->data.send_status_from_server.trailing_metadata_count = 0;
   op->data.send_status_from_server.status = GRPC_STATUS_OK;
@@ -400,11 +481,13 @@
   op->flags = 0;
   op->reserved = NULL;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL);
+  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), NULL);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
-  cq_expect_completion(cqv, tag(103), true);
-  cq_expect_completion(cqv, tag(1), true);
+  cq_expect_completion(cqv, tag(1), 1);
+  cq_expect_completion(cqv, tag(3), 1);
+  cq_expect_completion(cqv, tag(101), 1);
+  cq_expect_completion(cqv, tag(104), 1);
   cq_verify(cqv);
 
   GPR_ASSERT(status == GRPC_STATUS_OK);
@@ -413,12 +496,6 @@
   GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr"));
   GPR_ASSERT(was_cancelled == 0);
 
-  GPR_ASSERT(request_payload_recv->type == GRPC_BB_RAW);
-  GPR_ASSERT(request_payload_recv->data.raw.compression ==
-             expected_compression_algorithm);
-
-  GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, str));
-
   gpr_free(details);
   grpc_metadata_array_destroy(&initial_metadata_recv);
   grpc_metadata_array_destroy(&trailing_metadata_recv);
@@ -430,10 +507,6 @@
 
   cq_verifier_destroy(cqv);
 
-  gpr_slice_unref(request_payload_slice);
-  grpc_byte_buffer_destroy(request_payload);
-  grpc_byte_buffer_destroy(request_payload_recv);
-
   grpc_channel_args_destroy(client_args);
   grpc_channel_args_destroy(server_args);
 
@@ -445,54 +518,74 @@
     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_NONE, NULL);
+      GRPC_WRITE_NO_COMPRESS, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
+      GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP, NULL, false,
+      /* ignored */ GRPC_COMPRESS_LEVEL_NONE);
 }
 
 static void test_invoke_request_with_uncompressed_payload(
     grpc_end2end_test_config config) {
   request_with_payload_template(
       config, "test_invoke_request_with_uncompressed_payload", 0,
-      GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, NULL);
+      GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
+      GRPC_COMPRESS_NONE, NULL, false, /* ignored */ GRPC_COMPRESS_LEVEL_NONE);
 }
 
 static void test_invoke_request_with_compressed_payload(
     grpc_end2end_test_config config) {
   request_with_payload_template(
       config, "test_invoke_request_with_compressed_payload", 0,
-      GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP, NULL);
+      GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
+      GRPC_COMPRESS_GZIP, NULL, false, /* ignored */ GRPC_COMPRESS_LEVEL_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_COMPRESS_NONE,
+      GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE /* ignored */,
+      NULL, true, GRPC_COMPRESS_LEVEL_HIGH);
 }
 
 static void test_invoke_request_with_compressed_payload_md_override(
     grpc_end2end_test_config config) {
   grpc_metadata gzip_compression_override;
-  grpc_metadata none_compression_override;
+  grpc_metadata identity_compression_override;
 
-  gzip_compression_override.key = GRPC_COMPRESS_REQUEST_ALGORITHM_KEY;
+  gzip_compression_override.key = GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY;
   gzip_compression_override.value = "gzip";
-  gzip_compression_override.value_length = 4;
+  gzip_compression_override.value_length =
+      strlen(gzip_compression_override.value);
   memset(&gzip_compression_override.internal_data, 0,
          sizeof(gzip_compression_override.internal_data));
 
-  none_compression_override.key = GRPC_COMPRESS_REQUEST_ALGORITHM_KEY;
-  none_compression_override.value = "identity";
-  none_compression_override.value_length = 4;
-  memset(&none_compression_override.internal_data, 0,
-         sizeof(none_compression_override.internal_data));
+  identity_compression_override.key = GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY;
+  identity_compression_override.value = "identity";
+  identity_compression_override.value_length =
+      strlen(identity_compression_override.value);
+  memset(&identity_compression_override.internal_data, 0,
+         sizeof(identity_compression_override.internal_data));
 
   /* 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_GZIP, &gzip_compression_override);
+      GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP,
+      GRPC_COMPRESS_NONE, &gzip_compression_override, false,
+      /*ignored*/ GRPC_COMPRESS_LEVEL_NONE);
 
   /* 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_GZIP, &gzip_compression_override);
+      GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP,
+      GRPC_COMPRESS_NONE, &gzip_compression_override, false,
+      /*ignored*/ GRPC_COMPRESS_LEVEL_NONE);
 
   /* 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, &none_compression_override);
+      GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
+      GRPC_COMPRESS_NONE, &identity_compression_override, false,
+      /*ignored*/ GRPC_COMPRESS_LEVEL_NONE);
 }
 
 static void test_invoke_request_with_disabled_algorithm(
@@ -506,6 +599,7 @@
   test_invoke_request_with_exceptionally_uncompressed_payload(config);
   test_invoke_request_with_uncompressed_payload(config);
   test_invoke_request_with_compressed_payload(config);
+  test_invoke_request_with_server_level(config);
   test_invoke_request_with_compressed_payload_md_override(config);
   test_invoke_request_with_disabled_algorithm(config);
 }
diff --git a/test/core/end2end/tests/default_host.c b/test/core/end2end/tests/default_host.c
index 44384a7..728ee59 100644
--- a/test/core/end2end/tests/default_host.c
+++ b/test/core/end2end/tests/default_host.c
@@ -131,6 +131,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -173,6 +174,7 @@
   gpr_log(GPR_DEBUG, "client_peer=%s", peer);
   gpr_free(peer);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/disappearing_server.c b/test/core/end2end/tests/disappearing_server.c
index 03d1ded..536fbd0 100644
--- a/test/core/end2end/tests/disappearing_server.c
+++ b/test/core/end2end/tests/disappearing_server.c
@@ -108,6 +108,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -145,6 +146,7 @@
      - and still complete the request */
   grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/filter_causes_close.c b/test/core/end2end/tests/filter_causes_close.c
index 99049aa..dae9823 100644
--- a/test/core/end2end/tests/filter_causes_close.c
+++ b/test/core/end2end/tests/filter_causes_close.c
@@ -134,6 +134,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/graceful_server_shutdown.c b/test/core/end2end/tests/graceful_server_shutdown.c
index 26198f3..f527b86 100644
--- a/test/core/end2end/tests/graceful_server_shutdown.c
+++ b/test/core/end2end/tests/graceful_server_shutdown.c
@@ -122,6 +122,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -160,6 +161,7 @@
   grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead));
   cq_verify_empty(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/high_initial_seqno.c b/test/core/end2end/tests/high_initial_seqno.c
index 374606d..50e3c9c 100644
--- a/test/core/end2end/tests/high_initial_seqno.c
+++ b/test/core/end2end/tests/high_initial_seqno.c
@@ -128,6 +128,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -161,6 +162,7 @@
   cq_expect_completion(cqv, tag(101), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/hpack_size.c b/test/core/end2end/tests/hpack_size.c
index 07d5d38..ee889b7 100644
--- a/test/core/end2end/tests/hpack_size.c
+++ b/test/core/end2end/tests/hpack_size.c
@@ -323,6 +323,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = GPR_ARRAY_SIZE(extra_metadata);
@@ -357,6 +358,7 @@
   cq_expect_completion(cqv, tag(101), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/idempotent_request.c b/test/core/end2end/tests/idempotent_request.c
index e53f3b2..dfedcfe 100644
--- a/test/core/end2end/tests/idempotent_request.c
+++ b/test/core/end2end/tests/idempotent_request.c
@@ -132,6 +132,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -174,6 +175,7 @@
   gpr_log(GPR_DEBUG, "client_peer=%s", peer);
   gpr_free(peer);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/invoke_large_request.c b/test/core/end2end/tests/invoke_large_request.c
index 6410305..9c9ca95 100644
--- a/test/core/end2end/tests/invoke_large_request.c
+++ b/test/core/end2end/tests/invoke_large_request.c
@@ -138,6 +138,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -181,6 +182,7 @@
   cq_expect_completion(cqv, tag(101), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -198,6 +200,7 @@
   cq_expect_completion(cqv, tag(102), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
diff --git a/test/core/end2end/tests/large_metadata.c b/test/core/end2end/tests/large_metadata.c
index ae1f68a..1f27896 100644
--- a/test/core/end2end/tests/large_metadata.c
+++ b/test/core/end2end/tests/large_metadata.c
@@ -142,6 +142,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   // Client: send request.
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
@@ -183,6 +184,7 @@
   cq_expect_completion(cqv, tag(101), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   // Server: send initial metadata and receive request.
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
@@ -201,6 +203,7 @@
   cq_expect_completion(cqv, tag(102), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   // Server: receive close and send status.  This should trigger
   // completion of request on client.
   op = ops;
diff --git a/test/core/end2end/tests/max_concurrent_streams.c b/test/core/end2end/tests/max_concurrent_streams.c
index 1bb5307..41de74f 100644
--- a/test/core/end2end/tests/max_concurrent_streams.c
+++ b/test/core/end2end/tests/max_concurrent_streams.c
@@ -124,6 +124,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -157,6 +158,7 @@
   cq_expect_completion(cqv, tag(101), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -270,6 +272,7 @@
                                  f.server, &s1, &call_details,
                                  &request_metadata_recv, f.cq, f.cq, tag(101)));
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -283,6 +286,7 @@
   error = grpc_call_start_batch(c1, ops, (size_t)(op - ops), tag(301), NULL);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv1;
@@ -300,6 +304,7 @@
   error = grpc_call_start_batch(c1, ops, (size_t)(op - ops), tag(302), NULL);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -313,6 +318,7 @@
   error = grpc_call_start_batch(c2, ops, (size_t)(op - ops), tag(401), NULL);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv2;
@@ -354,6 +360,7 @@
   }
   GPR_ASSERT(live_call == 300 || live_call == 400);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -388,6 +395,7 @@
   cq_expect_completion(cqv, tag(201), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/max_message_length.c b/test/core/end2end/tests/max_message_length.c
index 4f57278..08d326a 100644
--- a/test/core/end2end/tests/max_message_length.c
+++ b/test/core/end2end/tests/max_message_length.c
@@ -143,6 +143,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -181,6 +182,7 @@
   cq_expect_completion(cqv, tag(101), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
diff --git a/test/core/end2end/tests/negative_deadline.c b/test/core/end2end/tests/negative_deadline.c
index 03e57a9..fd56c8b 100644
--- a/test/core/end2end/tests/negative_deadline.c
+++ b/test/core/end2end/tests/negative_deadline.c
@@ -122,6 +122,7 @@
   grpc_metadata_array_init(&initial_metadata_recv);
   grpc_metadata_array_init(&trailing_metadata_recv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
diff --git a/test/core/end2end/tests/payload.c b/test/core/end2end/tests/payload.c
index bdfb135..443d85e 100644
--- a/test/core/end2end/tests/payload.c
+++ b/test/core/end2end/tests/payload.c
@@ -131,6 +131,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -174,6 +175,7 @@
   cq_expect_completion(cqv, tag(101), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -191,6 +193,7 @@
   cq_expect_completion(cqv, tag(102), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
diff --git a/test/core/end2end/tests/ping_pong_streaming.c b/test/core/end2end/tests/ping_pong_streaming.c
index 15e1c6e..1d2f794 100644
--- a/test/core/end2end/tests/ping_pong_streaming.c
+++ b/test/core/end2end/tests/ping_pong_streaming.c
@@ -135,6 +135,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -164,6 +165,7 @@
   cq_expect_completion(cqv, tag(100), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -182,6 +184,7 @@
     request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
     response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1);
 
+    memset(ops, 0, sizeof(ops));
     op = ops;
     op->op = GRPC_OP_SEND_MESSAGE;
     op->data.send_message = request_payload;
@@ -196,6 +199,7 @@
     error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), NULL);
     GPR_ASSERT(GRPC_CALL_OK == error);
 
+    memset(ops, 0, sizeof(ops));
     op = ops;
     op->op = GRPC_OP_RECV_MESSAGE;
     op->data.recv_message = &request_payload_recv;
@@ -207,6 +211,7 @@
     cq_expect_completion(cqv, tag(102), 1);
     cq_verify(cqv);
 
+    memset(ops, 0, sizeof(ops));
     op = ops;
     op->op = GRPC_OP_SEND_MESSAGE;
     op->data.send_message = response_payload;
@@ -228,6 +233,7 @@
   gpr_slice_unref(request_payload_slice);
   gpr_slice_unref(response_payload_slice);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
   op->flags = 0;
@@ -236,6 +242,7 @@
   error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), NULL);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
   op->data.send_status_from_server.trailing_metadata_count = 0;
diff --git a/test/core/end2end/tests/registered_call.c b/test/core/end2end/tests/registered_call.c
index 3c4edba..ece6250 100644
--- a/test/core/end2end/tests/registered_call.c
+++ b/test/core/end2end/tests/registered_call.c
@@ -125,6 +125,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -158,6 +159,7 @@
   cq_expect_completion(cqv, tag(101), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/request_with_flags.c b/test/core/end2end/tests/request_with_flags.c
index 779895b..6854528 100644
--- a/test/core/end2end/tests/request_with_flags.c
+++ b/test/core/end2end/tests/request_with_flags.c
@@ -131,6 +131,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/request_with_payload.c b/test/core/end2end/tests/request_with_payload.c
index 7706404..d94267e 100644
--- a/test/core/end2end/tests/request_with_payload.c
+++ b/test/core/end2end/tests/request_with_payload.c
@@ -130,6 +130,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -167,6 +168,7 @@
   cq_expect_completion(cqv, tag(101), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -184,6 +186,7 @@
   cq_expect_completion(cqv, tag(102), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
diff --git a/test/core/end2end/tests/server_finishes_request.c b/test/core/end2end/tests/server_finishes_request.c
index a4f5319..a723c6f 100644
--- a/test/core/end2end/tests/server_finishes_request.c
+++ b/test/core/end2end/tests/server_finishes_request.c
@@ -126,6 +126,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -155,6 +156,7 @@
   cq_expect_completion(cqv, tag(101), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/shutdown_finishes_calls.c b/test/core/end2end/tests/shutdown_finishes_calls.c
index 80287cd..abb6b26 100644
--- a/test/core/end2end/tests/shutdown_finishes_calls.c
+++ b/test/core/end2end/tests/shutdown_finishes_calls.c
@@ -115,6 +115,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -149,6 +150,7 @@
   cq_expect_completion(cqv, tag(101), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
diff --git a/test/core/end2end/tests/simple_delayed_request.c b/test/core/end2end/tests/simple_delayed_request.c
index 400b3a0..e1fcc03 100644
--- a/test/core/end2end/tests/simple_delayed_request.c
+++ b/test/core/end2end/tests/simple_delayed_request.c
@@ -117,6 +117,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -152,6 +153,7 @@
   cq_expect_completion(cqv, tag(101), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/simple_metadata.c b/test/core/end2end/tests/simple_metadata.c
index 707b3c9..c9b1a03 100644
--- a/test/core/end2end/tests/simple_metadata.c
+++ b/test/core/end2end/tests/simple_metadata.c
@@ -141,6 +141,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 2;
@@ -185,6 +186,7 @@
   cq_expect_completion(cqv, tag(101), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 2;
@@ -203,6 +205,7 @@
   cq_expect_completion(cqv, tag(102), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
diff --git a/test/core/end2end/tests/simple_request.c b/test/core/end2end/tests/simple_request.c
index 4210842..a8014e6 100644
--- a/test/core/end2end/tests/simple_request.c
+++ b/test/core/end2end/tests/simple_request.c
@@ -132,6 +132,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -174,6 +175,7 @@
   gpr_log(GPR_DEBUG, "client_peer=%s", peer);
   gpr_free(peer);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/trailing_metadata.c b/test/core/end2end/tests/trailing_metadata.c
index 4dd8c12..41e0f00 100644
--- a/test/core/end2end/tests/trailing_metadata.c
+++ b/test/core/end2end/tests/trailing_metadata.c
@@ -144,6 +144,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 2;
@@ -188,6 +189,7 @@
   cq_expect_completion(cqv, tag(101), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 2;
@@ -206,6 +208,7 @@
   cq_expect_completion(cqv, tag(102), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
diff --git a/test/core/fling/client.c b/test/core/fling/client.c
index 8156227..123f2b5 100644
--- a/test/core/fling/client.c
+++ b/test/core/fling/client.c
@@ -65,6 +65,7 @@
   grpc_metadata_array_init(&initial_metadata_recv);
   grpc_metadata_array_init(&trailing_metadata_recv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
 
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
diff --git a/test/core/surface/lame_client_test.c b/test/core/surface/lame_client_test.c
index 12fa9de..285d8ea 100644
--- a/test/core/surface/lame_client_test.c
+++ b/test/core/surface/lame_client_test.c
@@ -115,6 +115,7 @@
   GPR_ASSERT(call);
   cqv = cq_verifier_create(cq);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -133,6 +134,7 @@
   cq_expect_completion(cqv, tag(1), 0);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 212dfc3..bbda184 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -936,7 +936,7 @@
 src/core/lib/channel/connected_channel.c \
 src/core/lib/channel/http_client_filter.c \
 src/core/lib/channel/http_server_filter.c \
-src/core/lib/compression/compression_algorithm.c \
+src/core/lib/compression/compression.c \
 src/core/lib/compression/message_compress.c \
 src/core/lib/debug/trace.c \
 src/core/lib/http/format_request.c \
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 3866ebb..11c96ea 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -5727,7 +5727,7 @@
       "src/core/lib/channel/http_server_filter.c", 
       "src/core/lib/channel/http_server_filter.h", 
       "src/core/lib/compression/algorithm_metadata.h", 
-      "src/core/lib/compression/compression_algorithm.c", 
+      "src/core/lib/compression/compression.c", 
       "src/core/lib/compression/message_compress.c", 
       "src/core/lib/compression/message_compress.h", 
       "src/core/lib/debug/trace.c", 
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index a20d386..2fbc5db 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -455,7 +455,7 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression_algorithm.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
     </ClCompile>
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index d546517..1afd816 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -25,7 +25,7 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression_algorithm.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
       <Filter>src\core\lib\compression</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index 09748f0..56b85a8 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -430,7 +430,7 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression_algorithm.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
     </ClCompile>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index a85bfee..0b29b4c 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -28,7 +28,7 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression_algorithm.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
       <Filter>src\core\lib\compression</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">