Tests are starting to compile
diff --git a/src/core/ext/census/grpc_filter.c b/src/core/ext/census/grpc_filter.c
index 397dbc4..5008879 100644
--- a/src/core/ext/census/grpc_filter.c
+++ b/src/core/ext/census/grpc_filter.c
@@ -67,9 +67,7 @@
                                             channel_data *chand) {
   grpc_linked_mdelem *m;
   for (m = md->list.head; m != NULL; m = m->next) {
-    if (m->md->key == GRPC_MDSTR_PATH) {
-      gpr_log(GPR_DEBUG, "%s",
-              (const char *)GRPC_SLICE_START_PTR(m->md->value->slice));
+    if (grpc_slice_cmp(m->md->key, GRPC_MDSTR_PATH) == 0) {
       /* Add method tag here */
     }
   }
diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c
index 011a841..5faad33 100644
--- a/src/core/ext/client_channel/client_channel.c
+++ b/src/core/ext/client_channel/client_channel.c
@@ -51,6 +51,7 @@
 #include "src/core/lib/iomgr/iomgr.h"
 #include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/transport/connectivity_state.h"
@@ -972,7 +973,7 @@
   call_data *calld = elem->call_data;
   // Initialize data members.
   grpc_deadline_state_init(exec_ctx, elem, args->call_stack);
-  calld->path = GRPC_MDSTR_REF(args->path);
+  calld->path = grpc_slice_ref_internal(args->path);
   calld->call_start_time = args->start_time;
   calld->deadline = gpr_convert_clock_type(args->deadline, GPR_CLOCK_MONOTONIC);
   calld->wait_for_ready_from_service_config = WAIT_FOR_READY_UNSET;
@@ -1041,7 +1042,7 @@
                                  void *and_free_memory) {
   call_data *calld = elem->call_data;
   grpc_deadline_state_destroy(exec_ctx, elem);
-  GRPC_MDSTR_UNREF(exec_ctx, calld->path);
+  grpc_slice_unref_internal(exec_ctx, calld->path);
   GRPC_ERROR_UNREF(calld->cancel_error);
   grpc_subchannel_call *call = GET_CALL(calld);
   if (call != NULL && call != CANCELLED_CALL) {
diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c
index 3e5c039..1a673e9 100644
--- a/src/core/ext/lb_policy/grpclb/grpclb.c
+++ b/src/core/ext/lb_policy/grpclb/grpclb.c
@@ -333,8 +333,7 @@
 
   /* call status code and details, set in lb_on_server_status_received() */
   grpc_status_code lb_call_status;
-  char *lb_call_status_details;
-  size_t lb_call_status_details_capacity;
+  grpc_slice lb_call_status_details;
 
   /** LB call retry backoff state */
   gpr_backoff lb_call_backoff_state;
@@ -447,10 +446,10 @@
           GPR_ARRAY_SIZE(server->load_balance_token);
       const size_t lb_token_length =
           strnlen(server->load_balance_token, lb_token_max_length);
-      grpc_slice lb_token_mdstr = grpc_mdstr_from_buffer(
-          (uint8_t *)server->load_balance_token, lb_token_length);
-      user_data = grpc_mdelem_from_metadata_strings(
-          exec_ctx, GRPC_MDSTR_LB_TOKEN, lb_token_mdstr);
+      grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer(
+          server->load_balance_token, lb_token_length);
+      user_data = grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_LB_TOKEN,
+                                          lb_token_mdstr);
     } else {
       gpr_log(GPR_ERROR,
               "Missing LB token for backend address '%s'. The empty token will "
@@ -972,11 +971,12 @@
   /* Note the following LB call progresses every time there's activity in \a
    * glb_policy->base.interested_parties, which is comprised of the polling
    * entities from \a client_channel. */
+  grpc_slice host = grpc_slice_from_copied_string(glb_policy->server_name);
   glb_policy->lb_call = grpc_channel_create_pollset_set_call(
       exec_ctx, glb_policy->lb_channel, NULL, GRPC_PROPAGATE_DEFAULTS,
       glb_policy->base.interested_parties,
-      "/grpc.lb.v1.LoadBalancer/BalanceLoad", glb_policy->server_name,
-      glb_policy->deadline, NULL);
+      GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD,
+      &host, glb_policy->deadline, NULL);
 
   grpc_metadata_array_init(&glb_policy->lb_initial_metadata_recv);
   grpc_metadata_array_init(&glb_policy->lb_trailing_metadata_recv);
@@ -989,9 +989,6 @@
   grpc_slice_unref_internal(exec_ctx, request_payload_slice);
   grpc_grpclb_request_destroy(request);
 
-  glb_policy->lb_call_status_details = NULL;
-  glb_policy->lb_call_status_details_capacity = 0;
-
   grpc_closure_init(&glb_policy->lb_on_server_status_received,
                     lb_on_server_status_received, glb_policy);
   grpc_closure_init(&glb_policy->lb_on_response_received,
@@ -1002,7 +999,8 @@
                    BACKOFF_MAX_SECONDS * 1000);
 }
 
-static void lb_call_destroy_locked(glb_lb_policy *glb_policy) {
+static void lb_call_destroy_locked(grpc_exec_ctx *exec_ctx,
+                                   glb_lb_policy *glb_policy) {
   GPR_ASSERT(glb_policy->lb_call != NULL);
   grpc_call_destroy(glb_policy->lb_call);
   glb_policy->lb_call = NULL;
@@ -1011,7 +1009,7 @@
   grpc_metadata_array_destroy(&glb_policy->lb_trailing_metadata_recv);
 
   grpc_byte_buffer_destroy(glb_policy->lb_request_payload);
-  gpr_free(glb_policy->lb_call_status_details);
+  grpc_slice_unref_internal(exec_ctx, glb_policy->lb_call_status_details);
 }
 
 /*
@@ -1060,8 +1058,6 @@
   op->data.recv_status_on_client.status = &glb_policy->lb_call_status;
   op->data.recv_status_on_client.status_details =
       &glb_policy->lb_call_status_details;
-  op->data.recv_status_on_client.status_details_capacity =
-      &glb_policy->lb_call_status_details_capacity;
   op->flags = 0;
   op->reserved = NULL;
   op++;
@@ -1201,15 +1197,18 @@
   GPR_ASSERT(glb_policy->lb_call != NULL);
 
   if (grpc_lb_glb_trace) {
+    char *status_details =
+        grpc_dump_slice(glb_policy->lb_call_status_details, GPR_DUMP_ASCII);
     gpr_log(GPR_DEBUG,
             "Status from LB server received. Status = %d, Details = '%s', "
             "(call: %p)",
-            glb_policy->lb_call_status, glb_policy->lb_call_status_details,
+            glb_policy->lb_call_status, status_details,
             (void *)glb_policy->lb_call);
+    gpr_free(status_details);
   }
 
-  /* We need to performe cleanups no matter what. */
-  lb_call_destroy_locked(glb_policy);
+  /* We need to perform cleanups no matter what. */
+  lb_call_destroy_locked(exec_ctx, glb_policy);
 
   if (!glb_policy->shutting_down) {
     /* if we aren't shutting down, restart the LB client call after some time */
diff --git a/src/core/ext/load_reporting/load_reporting_filter.c b/src/core/ext/load_reporting/load_reporting_filter.c
index f50e652..c152e3d 100644
--- a/src/core/ext/load_reporting/load_reporting_filter.c
+++ b/src/core/ext/load_reporting/load_reporting_filter.c
@@ -41,13 +41,17 @@
 #include "src/core/ext/load_reporting/load_reporting_filter.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/transport/static_metadata.h"
 
 typedef struct call_data {
   intptr_t id; /**< an id unique to the call */
-  char *trailing_md_string;
-  char *initial_md_string;
-  const char *service_method;
+  bool have_trailing_md_string;
+  grpc_slice trailing_md_string;
+  bool have_initial_md_string;
+  grpc_slice initial_md_string;
+  bool have_service_method;
+  grpc_slice service_method;
 
   /* stores the recv_initial_metadata op's ready closure, which we wrap with our
    * own (on_initial_md_ready) in order to capture the incoming initial metadata
@@ -74,10 +78,12 @@
   grpc_call_element *elem = a->elem;
   call_data *calld = elem->call_data;
 
-  if (md->key == GRPC_MDSTR_PATH) {
-    calld->service_method = grpc_mdstr_as_c_string(md->value);
-  } else if (md->key == GRPC_MDSTR_LB_TOKEN) {
-    calld->initial_md_string = gpr_strdup(grpc_mdstr_as_c_string(md->value));
+  if (grpc_slice_cmp(md->key, GRPC_MDSTR_PATH) == 0) {
+    calld->service_method = grpc_slice_ref_internal(md->value);
+    calld->have_service_method = true;
+  } else if (grpc_slice_cmp(md->key, GRPC_MDSTR_LB_TOKEN) == 0) {
+    calld->initial_md_string = grpc_slice_ref_internal(md->value);
+    calld->have_initial_md_string = true;
     return NULL;
   }
 
@@ -95,7 +101,7 @@
     a.exec_ctx = exec_ctx;
     grpc_metadata_batch_filter(exec_ctx, calld->recv_initial_metadata,
                                recv_md_filter, &a);
-    if (calld->service_method == NULL) {
+    if (!calld->have_service_method) {
       err =
           grpc_error_add_child(err, GRPC_ERROR_CREATE("Missing :path header"));
     }
@@ -148,8 +154,8 @@
                                                 calld->service_method};
   */
 
-  gpr_free(calld->initial_md_string);
-  gpr_free(calld->trailing_md_string);
+  grpc_slice_unref_internal(exec_ctx, calld->initial_md_string);
+  grpc_slice_unref_internal(exec_ctx, calld->trailing_md_string);
 }
 
 /* Constructor for channel_data */
@@ -195,8 +201,9 @@
   grpc_call_element *elem = user_data;
   call_data *calld = elem->call_data;
 
-  if (md->key == GRPC_MDSTR_LB_COST_BIN) {
-    calld->trailing_md_string = gpr_strdup(grpc_mdstr_as_c_string(md->value));
+  if (grpc_slice_cmp(md->key, GRPC_MDSTR_LB_COST_BIN) == 0) {
+    calld->trailing_md_string = grpc_slice_ref_internal(md->value);
+    calld->have_trailing_md_string = true;
     return NULL;
   }
 
diff --git a/src/core/lib/security/transport/server_auth_filter.c b/src/core/lib/security/transport/server_auth_filter.c
index db0d0d6..1824cf3 100644
--- a/src/core/lib/security/transport/server_auth_filter.c
+++ b/src/core/lib/security/transport/server_auth_filter.c
@@ -33,12 +33,13 @@
 
 #include <string.h>
 
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
 #include "src/core/lib/security/context/security_context.h"
 #include "src/core/lib/security/credentials/credentials.h"
 #include "src/core/lib/security/transport/auth_filters.h"
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
+#include "src/core/lib/slice/slice_internal.h"
 
 typedef struct call_data {
   grpc_metadata_batch *recv_initial_metadata;
@@ -76,9 +77,8 @@
           gpr_realloc(result.metadata, result.capacity * sizeof(grpc_metadata));
     }
     usr_md = &result.metadata[result.count++];
-    usr_md->key = grpc_mdstr_as_c_string(key);
-    usr_md->value = grpc_mdstr_as_c_string(value);
-    usr_md->value_length = GRPC_SLICE_LENGTH(value->slice);
+    usr_md->key = grpc_slice_ref_internal(key);
+    usr_md->value = grpc_slice_ref_internal(value);
   }
   return result;
 }
@@ -90,19 +90,9 @@
   size_t i;
   for (i = 0; i < calld->num_consumed_md; i++) {
     const grpc_metadata *consumed_md = &calld->consumed_md[i];
-    /* Maybe we could do a pointer comparison but we do not have any guarantee
-       that the metadata processor used the same pointers for consumed_md in the
-       callback. */
-    if (GRPC_SLICE_LENGTH(md->key->slice) != strlen(consumed_md->key) ||
-        GRPC_SLICE_LENGTH(md->value->slice) != consumed_md->value_length) {
-      continue;
-    }
-    if (memcmp(GRPC_SLICE_START_PTR(md->key->slice), consumed_md->key,
-               GRPC_SLICE_LENGTH(md->key->slice)) == 0 &&
-        memcmp(GRPC_SLICE_START_PTR(md->value->slice), consumed_md->value,
-               GRPC_SLICE_LENGTH(md->value->slice)) == 0) {
-      return NULL; /* Delete. */
-    }
+    if (grpc_slice_cmp(md->key, consumed_md->key) == 0 &&
+        grpc_slice_cmp(md->value, consumed_md->value) == 0)
+      return NULL;
   }
   return md;
 }
diff --git a/src/core/lib/transport/static_metadata.c b/src/core/lib/transport/static_metadata.c
index e24f3fa..0eb5cd5 100644
--- a/src/core/lib/transport/static_metadata.c
+++ b/src/core/lib/transport/static_metadata.c
@@ -101,14 +101,16 @@
     110, 103, 101, 114, 101, 102, 101, 114, 101, 114, 114, 101, 102, 114, 101,
     115, 104, 114, 101, 116, 114, 121, 45,  97,  102, 116, 101, 114, 58,  115,
     99,  104, 101, 109, 101, 115, 101, 114, 118, 101, 114, 115, 101, 116, 45,
-    99,  111, 111, 107, 105, 101, 47,  47,  105, 110, 100, 101, 120, 46,  104,
-    116, 109, 108, 58,  115, 116, 97,  116, 117, 115, 115, 116, 114, 105, 99,
-    116, 45,  116, 114, 97,  110, 115, 112, 111, 114, 116, 45,  115, 101, 99,
-    117, 114, 105, 116, 121, 116, 101, 116, 114, 97,  105, 108, 101, 114, 115,
-    116, 114, 97,  110, 115, 102, 101, 114, 45,  101, 110, 99,  111, 100, 105,
-    110, 103, 117, 115, 101, 114, 45,  97,  103, 101, 110, 116, 118, 97,  114,
-    121, 118, 105, 97,  119, 119, 119, 45,  97,  117, 116, 104, 101, 110, 116,
-    105, 99,  97,  116, 101};
+    99,  111, 111, 107, 105, 101, 47,  47,  103, 114, 112, 99,  46,  108, 98,
+    46,  118, 49,  46,  76,  111, 97,  100, 66,  97,  108, 97,  110, 99,  101,
+    114, 47,  66,  97,  108, 97,  110, 99,  101, 76,  111, 97,  100, 47,  105,
+    110, 100, 101, 120, 46,  104, 116, 109, 108, 58,  115, 116, 97,  116, 117,
+    115, 115, 116, 114, 105, 99,  116, 45,  116, 114, 97,  110, 115, 112, 111,
+    114, 116, 45,  115, 101, 99,  117, 114, 105, 116, 121, 116, 101, 116, 114,
+    97,  105, 108, 101, 114, 115, 116, 114, 97,  110, 115, 102, 101, 114, 45,
+    101, 110, 99,  111, 100, 105, 110, 103, 117, 115, 101, 114, 45,  97,  103,
+    101, 110, 116, 118, 97,  114, 121, 118, 105, 97,  119, 119, 119, 45,  97,
+    117, 116, 104, 101, 110, 116, 105, 99,  97,  116, 101};
 
 static void static_ref(void *unused) {}
 static void static_unref(grpc_exec_ctx *exec_ctx, void *unused) {}
@@ -116,7 +118,7 @@
 
 bool grpc_is_static_metadata_string(grpc_slice slice) {
   return slice.refcount != NULL && slice.refcount->ref == static_ref;
-};
+}
 
 const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = {
     {.refcount = &g_refcnt,
@@ -294,25 +296,27 @@
     {.refcount = &g_refcnt,
      .data.refcounted = {.bytes = g_raw_bytes + 891, .length = 1}},
     {.refcount = &g_refcnt,
-     .data.refcounted = {.bytes = g_raw_bytes + 892, .length = 11}},
+     .data.refcounted = {.bytes = g_raw_bytes + 892, .length = 36}},
     {.refcount = &g_refcnt,
-     .data.refcounted = {.bytes = g_raw_bytes + 903, .length = 7}},
+     .data.refcounted = {.bytes = g_raw_bytes + 928, .length = 11}},
     {.refcount = &g_refcnt,
-     .data.refcounted = {.bytes = g_raw_bytes + 910, .length = 25}},
+     .data.refcounted = {.bytes = g_raw_bytes + 939, .length = 7}},
     {.refcount = &g_refcnt,
-     .data.refcounted = {.bytes = g_raw_bytes + 935, .length = 2}},
+     .data.refcounted = {.bytes = g_raw_bytes + 946, .length = 25}},
     {.refcount = &g_refcnt,
-     .data.refcounted = {.bytes = g_raw_bytes + 937, .length = 8}},
+     .data.refcounted = {.bytes = g_raw_bytes + 971, .length = 2}},
     {.refcount = &g_refcnt,
-     .data.refcounted = {.bytes = g_raw_bytes + 945, .length = 17}},
+     .data.refcounted = {.bytes = g_raw_bytes + 973, .length = 8}},
     {.refcount = &g_refcnt,
-     .data.refcounted = {.bytes = g_raw_bytes + 962, .length = 10}},
+     .data.refcounted = {.bytes = g_raw_bytes + 981, .length = 17}},
     {.refcount = &g_refcnt,
-     .data.refcounted = {.bytes = g_raw_bytes + 972, .length = 4}},
+     .data.refcounted = {.bytes = g_raw_bytes + 998, .length = 10}},
     {.refcount = &g_refcnt,
-     .data.refcounted = {.bytes = g_raw_bytes + 976, .length = 3}},
+     .data.refcounted = {.bytes = g_raw_bytes + 1008, .length = 4}},
     {.refcount = &g_refcnt,
-     .data.refcounted = {.bytes = g_raw_bytes + 979, .length = 16}},
+     .data.refcounted = {.bytes = g_raw_bytes + 1012, .length = 3}},
+    {.refcount = &g_refcnt,
+     .data.refcounted = {.bytes = g_raw_bytes + 1015, .length = 16}},
 };
 
 static const uint8_t g_revmap[] = {
@@ -376,13 +380,15 @@
     255, 255, 82,  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 83,  255,
     255, 255, 255, 255, 255, 84,  255, 255, 255, 255, 255, 85,  255, 255, 255,
     255, 255, 255, 255, 255, 255, 86,  87,  255, 255, 255, 255, 255, 255, 255,
-    255, 255, 255, 88,  255, 255, 255, 255, 255, 255, 89,  255, 255, 255, 255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-    255, 255, 255, 255, 255, 90,  255, 91,  255, 255, 255, 255, 255, 255, 255,
-    92,  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-    255, 255, 93,  255, 255, 255, 255, 255, 255, 255, 255, 255, 94,  255, 255,
-    255, 95,  255, 255, 96,  255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-    255, 255, 255, 255, 255};
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 88,  255,
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 89,  255, 255, 255, 255, 255,
+    255, 90,  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 91,  255, 92,  255,
+    255, 255, 255, 255, 255, 255, 93,  255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255, 94,  255, 255, 255, 255, 255, 255,
+    255, 255, 255, 95,  255, 255, 255, 96,  255, 255, 97,  255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255};
 
 int grpc_static_metadata_index(grpc_slice slice) {
   if (GRPC_SLICE_LENGTH(slice) == 0) return 33;
@@ -390,7 +396,7 @@
   if (ofs > sizeof(g_revmap)) return -1;
   uint8_t id = g_revmap[ofs];
   return id == 255 ? -1 : id;
-};
+}
 
 grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
 uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = {
@@ -405,14 +411,14 @@
 #define ELEMS_PHASHSALT 0x9e3779b9
 
 static const uint8_t elems_tab[] = {
-    47, 1,  61, 0,  32, 0,  47, 1,  37, 0,  0,  0,  47, 61, 76, 0,
-    76, 0,  61, 0,  32, 37, 51, 0,  47, 47, 79, 4,  76, 1,  0,  0,
-    0,  76, 0,  47, 85, 34, 0,  10, 0,  28, 0,  76, 0,  61, 0,  0,
-    46, 4,  12, 47, 88, 28, 61, 79, 28, 70, 0,  68, 85, 0,  87, 0,
+    0,  17, 61, 28, 4,  12, 47, 0,  0,  0,  61, 0,  47, 0,  61, 76,
+    61, 70, 76, 0,  0,  10, 4,  60, 0,  0,  0,  16, 88, 47, 1,  76,
+    76, 0,  76, 0,  61, 0,  23, 0,  0,  51, 1,  92, 32, 0,  25, 0,
+    34, 0,  37, 0,  76, 76, 32, 38, 70, 79, 81, 0,  64, 0,  0,  0,
 };
 
 static uint32_t elems_phash(uint32_t val) {
-  val -= 1003;
+  val -= 917;
 
   uint32_t a, b, rsl;
 
@@ -423,27 +429,27 @@
 }
 
 static const uint16_t elem_keys[] = {
-    1218, 8544, 2652, 1973, 7264, 2458, 2734, 3933, 1682, 6435, 3912, 3941,
-    4396, 4418, 4850, 4852, 7890, 8541, 6726, 9345, 6338, 6629, 6920, 3939,
-    7156, 8540, 8108, 8090, 8181, 8666, 8821, 1876, 8545, 1391, 8957, 1488,
-    7405, 7265, 3331, 2943, 2846, 6241, 4851, 2167, 5368, 1585, 1294, 1003,
-    9054, 6144, 8542, 8539, 8107, 7793, 7502, 7159, 7696, 2264, 6532, 2749,
-    9248, 1197, 7987, 9151, 7017, 4423, 7119, 6823, 3938, 8543, 3525, 3911,
-    2070, 2361, 2555, 6047, 1100, 3940, 3622, 3428, 8278, 0,    0,    0,
+    2091, 1405, 8728, 2777, 7192, 2287, 2581, 2483, 2973, 4441, 3561, 3951,
+    6403, 4463, 9441, 8726, 2875, 5423, 8730, 7338, 6109, 6207, 6697, 6893,
+    7229, 8363, 8729, 3952, 8173, 8191, 8725, 8853, 9245, 9343, 1601, 8727,
+    7481, 7340, 7971, 7775, 6501, 3973, 3659, 3979, 3463, 3980, 1307, 8190,
+    9010, 8731, 4901, 6599, 3365, 7579, 6795, 9147, 9539, 8069, 6305, 7873,
+    1209, 1111, 1699, 1503, 7089, 4468, 2189, 4900, 7232, 2385, 6991, 3978,
+    1993, 4902, 2679, 2762, 1013, 3981, 1230, 1895, 8265, 0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0};
 static const uint8_t elem_idxs[] = {
-    3,  72, 17, 10, 54, 15, 18, 28, 8,  44, 27, 32, 33, 34, 36, 38, 60,
-    69, 47, 80, 43, 46, 49, 30, 52, 68, 64, 62, 65, 74, 75, 9,  73, 5,
-    76, 6,  56, 55, 22, 21, 20, 42, 37, 12, 39, 7,  4,  1,  77, 41, 70,
-    67, 63, 59, 57, 53, 58, 13, 45, 19, 79, 2,  61, 78, 50, 35, 51, 48,
-    29, 71, 24, 26, 11, 14, 16, 40, 0,  31, 25, 23, 66};
+    11, 5,  70, 19, 51, 13, 16, 15, 21, 33, 24, 26, 43, 34, 79, 68, 20,
+    39, 72, 54, 40, 41, 46, 48, 52, 66, 71, 27, 62, 64, 67, 74, 77, 78,
+    7,  69, 56, 55, 60, 58, 44, 28, 25, 30, 23, 31, 4,  63, 75, 73, 37,
+    45, 22, 57, 47, 76, 80, 61, 42, 59, 2,  0,  8,  6,  50, 35, 12, 36,
+    53, 14, 49, 29, 10, 38, 17, 18, 1,  32, 3,  9,  65};
 
 grpc_mdelem *grpc_static_mdelem_for_static_strings(int a, int b) {
   if (a == -1 || b == -1) return NULL;
-  uint32_t k = (uint32_t)(a * 97 + b);
+  uint32_t k = (uint32_t)(a * 98 + b);
   uint32_t h = elems_phash(k);
   return elem_keys[h] == k ? &grpc_static_mdelem_table[elem_idxs[h]] : NULL;
 }
@@ -455,9 +461,9 @@
      40, 32, 40, 53, 40, 58, 40, 59, 40, 60, 40, 61, 45, 31, 45, 53, 45, 58,
      50, 0,  50, 1,  50, 2,  55, 33, 62, 33, 63, 33, 64, 33, 65, 33, 66, 33,
      67, 33, 68, 33, 69, 33, 70, 33, 71, 33, 72, 33, 73, 38, 73, 75, 73, 78,
-     74, 86, 74, 87, 76, 33, 77, 33, 79, 33, 80, 33, 81, 33, 82, 33, 83, 39,
-     83, 56, 83, 57, 84, 33, 85, 33, 88, 3,  88, 4,  88, 5,  88, 6,  88, 7,
-     88, 8,  88, 9,  89, 33, 90, 91, 92, 33, 93, 33, 94, 33, 95, 33, 96, 33};
+     74, 86, 74, 88, 76, 33, 77, 33, 79, 33, 80, 33, 81, 33, 82, 33, 83, 39,
+     83, 56, 83, 57, 84, 33, 85, 33, 89, 3,  89, 4,  89, 5,  89, 6,  89, 7,
+     89, 8,  89, 9,  90, 33, 91, 92, 93, 33, 94, 33, 95, 33, 96, 33, 97, 33};
 
 const uint8_t grpc_static_accept_encoding_metadata[8] = {0,  29, 26, 30,
                                                          28, 32, 27, 31};
diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h
index c6348a5..282a323 100644
--- a/src/core/lib/transport/static_metadata.h
+++ b/src/core/lib/transport/static_metadata.h
@@ -44,7 +44,7 @@
 
 #include "src/core/lib/transport/metadata.h"
 
-#define GRPC_STATIC_MDSTR_COUNT 97
+#define GRPC_STATIC_MDSTR_COUNT 98
 extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT];
 /* "0" */
 #define GRPC_MDSTR_0 (grpc_static_slice_table[0])
@@ -223,26 +223,29 @@
 #define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[85])
 /* "/" */
 #define GRPC_MDSTR_SLASH (grpc_static_slice_table[86])
+/* "/grpc.lb.v1.LoadBalancer/BalanceLoad" */
+#define GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD \
+  (grpc_static_slice_table[87])
 /* "/index.html" */
-#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[87])
+#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[88])
 /* ":status" */
-#define GRPC_MDSTR_STATUS (grpc_static_slice_table[88])
+#define GRPC_MDSTR_STATUS (grpc_static_slice_table[89])
 /* "strict-transport-security" */
-#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[89])
+#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[90])
 /* "te" */
-#define GRPC_MDSTR_TE (grpc_static_slice_table[90])
+#define GRPC_MDSTR_TE (grpc_static_slice_table[91])
 /* "trailers" */
-#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[91])
+#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[92])
 /* "transfer-encoding" */
-#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[92])
+#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[93])
 /* "user-agent" */
-#define GRPC_MDSTR_USER_AGENT (grpc_static_slice_table[93])
+#define GRPC_MDSTR_USER_AGENT (grpc_static_slice_table[94])
 /* "vary" */
-#define GRPC_MDSTR_VARY (grpc_static_slice_table[94])
+#define GRPC_MDSTR_VARY (grpc_static_slice_table[95])
 /* "via" */
-#define GRPC_MDSTR_VIA (grpc_static_slice_table[95])
+#define GRPC_MDSTR_VIA (grpc_static_slice_table[96])
 /* "www-authenticate" */
-#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[96])
+#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[97])
 
 bool grpc_is_static_metadata_string(grpc_slice slice);
 
diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary
index 7563482..d5ee01b 100644
--- a/test/core/end2end/fuzzers/hpack.dictionary
+++ b/test/core/end2end/fuzzers/hpack.dictionary
@@ -86,6 +86,7 @@
 "\x06server"
 "\x0Aset-cookie"
 "\x01/"
+"$/grpc.lb.v1.LoadBalancer/BalanceLoad"
 "\x0B/index.html"
 "\x07:status"
 "\x19strict-transport-security"
diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py
index a9001a6..d632c97 100755
--- a/tools/codegen/core/gen_static_metadata.py
+++ b/tools/codegen/core/gen_static_metadata.py
@@ -63,6 +63,8 @@
     'grpc.timeout',
     'grpc.max_request_message_bytes',
     'grpc.max_response_message_bytes',
+    # well known method names
+    '/grpc.lb.v1.LoadBalancer/BalanceLoad',
     # metadata elements
     ('grpc-status', '0'),
     ('grpc-status', '1'),
@@ -191,24 +193,30 @@
     print >>f
 
 # build a list of all the strings we need
-all_strs = set()
-all_elems = set()
+all_strs = list()
+all_elems = list()
 static_userdata = {}
 for elem in CONFIG:
   if isinstance(elem, tuple):
-    all_strs.add(elem[0])
-    all_strs.add(elem[1])
-    all_elems.add(elem)
+    if elem[0] not in all_strs:
+      all_strs.append(elem[0])
+    if elem[1] not in all_strs:
+      all_strs.append(elem[1])
+    if elem not in all_elems:
+      all_elems.append(elem)
   else:
-    all_strs.add(elem)
+    if elem not in all_strs:
+      all_strs.append(elem)
 compression_elems = []
 for mask in range(1, 1<<len(COMPRESSION_ALGORITHMS)):
   val = ','.join(COMPRESSION_ALGORITHMS[alg]
                  for alg in range(0, len(COMPRESSION_ALGORITHMS))
                  if (1 << alg) & mask)
   elem = ('grpc-accept-encoding', val)
-  all_strs.add(val)
-  all_elems.add(elem)
+  if val not in all_strs:
+    all_strs.append(val)
+  if elem not in all_elems:
+    all_elems.append(elem)
   compression_elems.append(elem)
   static_userdata[elem] = 1 + (mask | 1)
 all_strs = sorted(list(all_strs), key=mangle)
@@ -306,7 +314,7 @@
 print >>C
 print >>C, 'bool grpc_is_static_metadata_string(grpc_slice slice) {'
 print >>C, '  return slice.refcount != NULL && slice.refcount->ref == static_ref;'
-print >>C, '};'
+print >>C, '}'
 print >>C
 print >>C, 'const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = {'
 str_ofs = 0
@@ -327,7 +335,7 @@
 print >>C, '  if (ofs > sizeof(g_revmap)) return -1;'
 print >>C, '  uint8_t id = g_revmap[ofs];'
 print >>C, '  return id == 255 ? -1 : id;'
-print >>C, '};'
+print >>C, '}'
 print >>C
 
 print >>D, '# hpack fuzzing dictionary'
@@ -361,11 +369,19 @@
       return i
 
 def perfect_hash(keys, name):
-    tmp = open('/tmp/keys.txt', 'w')
-    tmp.write(''.join('%d\n' % (x - min(keys)) for x in keys))
-    tmp.close()
-    cmd = '%s/perfect/run.sh %s -ds' % (os.path.dirname(sys.argv[0]), tmp.name)
+    ok = False
+    cmd = '%s/perfect/build.sh' % (os.path.dirname(sys.argv[0]))
     subprocess.check_call(cmd, shell=True)
+    for offset in reversed(range(0, min(keys))):
+        tmp = open('/tmp/keys.txt', 'w')
+        tmp.write(''.join('%d\n' % (x - offset) for x in keys))
+        tmp.close()
+        cmd = '%s/perfect/run.sh %s -dms' % (os.path.dirname(sys.argv[0]), tmp.name)
+        out = subprocess.check_output(cmd, shell=True)
+        if 'fatal error' not in out:
+            ok = True
+            break
+    assert ok, "Failed to find hash of keys in /tmp/keys.txt"
 
     code = ''
 
@@ -378,14 +394,14 @@
             results[var] = val
     code += '\n'
     pycode = 'def f(val):\n'
-    pycode += '  val -= %d\n' % min(keys)
+    pycode += '  val -= %d\n' % offset
     with open('%s/perfect/phash.c' % os.path.dirname(sys.argv[0])) as f:
         txt = f.read()
         tabdata = re.search(r'ub1 tab\[\] = \{([^}]+)\}', txt, re.MULTILINE).group(1)
         code += 'static const uint8_t %s_tab[] = {%s};\n\n' % (name, tabdata)
         func_body = re.search(r'ub4 phash\(val\)\nub4 val;\n\{([^}]+)\}', txt, re.MULTILINE).group(1).replace('ub4', 'uint32_t')
         code += 'static uint32_t %s_phash(uint32_t val) {\nval -= %d;\n%s}\n' % (name,
-            min(keys), func_body.replace('tab', '%s_tab' % name))
+            offset, func_body.replace('tab', '%s_tab' % name))
         pycode += '  tab=(%s)' % tabdata.replace('\n', '')
         pycode += '\n'.join('  %s' % s.strip() for s in func_body.splitlines()[2:])
     g = {}
diff --git a/tools/codegen/core/perfect/build.sh b/tools/codegen/core/perfect/build.sh
new file mode 100755
index 0000000..139556e
--- /dev/null
+++ b/tools/codegen/core/perfect/build.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+set -e
+cd $(dirname $0)
+gcc -o perfect perfect.c recycle.c lookupa.c perfhex.c 2> compile.txt
diff --git a/tools/codegen/core/perfect/run.sh b/tools/codegen/core/perfect/run.sh
index 8dc5911..c0d1fc3 100755
--- a/tools/codegen/core/perfect/run.sh
+++ b/tools/codegen/core/perfect/run.sh
@@ -1,7 +1,6 @@
 #!/bin/bash
 set -e
 cd $(dirname $0)
-gcc -o perfect perfect.c recycle.c lookupa.c perfhex.c 2> compile.txt
 fn=$1
 shift
-./perfect $* < $fn &> hash.txt
+./perfect $* < $fn