Merge remote-tracking branch 'upstream/master' into string_ref
diff --git a/Makefile b/Makefile
index 48ecea9..77cb620 100644
--- a/Makefile
+++ b/Makefile
@@ -4793,6 +4793,7 @@
     $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc \
     test/cpp/util/cli_call.cc \
     test/cpp/util/create_test_channel.cc \
+    test/cpp/util/string_ref_helper.cc \
     test/cpp/util/subprocess.cc \
 
 
@@ -4839,6 +4840,7 @@
 endif
 $(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/util/subprocess.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc
 
 
@@ -20672,6 +20674,7 @@
 test/cpp/util/benchmark_config.cc: $(OPENSSL_DEP)
 test/cpp/util/cli_call.cc: $(OPENSSL_DEP)
 test/cpp/util/create_test_channel.cc: $(OPENSSL_DEP)
+test/cpp/util/string_ref_helper.cc: $(OPENSSL_DEP)
 test/cpp/util/subprocess.cc: $(OPENSSL_DEP)
 test/cpp/util/test_config.cc: $(OPENSSL_DEP)
 endif
diff --git a/build.json b/build.json
index 54cae41..c974250 100644
--- a/build.json
+++ b/build.json
@@ -663,6 +663,7 @@
       "headers": [
         "test/cpp/util/cli_call.h",
         "test/cpp/util/create_test_channel.h",
+        "test/cpp/util/string_ref_helper.h",
         "test/cpp/util/subprocess.h"
       ],
       "src": [
@@ -671,6 +672,7 @@
         "test/cpp/util/echo_duplicate.proto",
         "test/cpp/util/cli_call.cc",
         "test/cpp/util/create_test_channel.cc",
+        "test/cpp/util/string_ref_helper.cc",
         "test/cpp/util/subprocess.cc"
       ],
       "deps": [
diff --git a/include/grpc++/client_context.h b/include/grpc++/client_context.h
index ee28f36..62e5260 100644
--- a/include/grpc++/client_context.h
+++ b/include/grpc++/client_context.h
@@ -45,6 +45,7 @@
 #include <grpc++/support/auth_context.h>
 #include <grpc++/support/config.h>
 #include <grpc++/support/status.h>
+#include <grpc++/support/string_ref.h>
 #include <grpc++/support/time.h>
 
 struct census_context;
@@ -138,12 +139,14 @@
   void AddMetadata(const grpc::string& meta_key,
                    const grpc::string& meta_value);
 
-  const std::multimap<grpc::string, grpc::string>& GetServerInitialMetadata() {
+  const std::multimap<grpc::string_ref, grpc::string_ref>&
+  GetServerInitialMetadata() {
     GPR_ASSERT(initial_metadata_received_);
     return recv_initial_metadata_;
   }
 
-  const std::multimap<grpc::string, grpc::string>& GetServerTrailingMetadata() {
+  const std::multimap<grpc::string_ref, grpc::string_ref>&
+  GetServerTrailingMetadata() {
     // TODO(yangg) check finished
     return trailing_metadata_;
   }
@@ -234,8 +237,8 @@
   mutable std::shared_ptr<const AuthContext> auth_context_;
   struct census_context* census_context_;
   std::multimap<grpc::string, grpc::string> send_initial_metadata_;
-  std::multimap<grpc::string, grpc::string> recv_initial_metadata_;
-  std::multimap<grpc::string, grpc::string> trailing_metadata_;
+  std::multimap<grpc::string_ref, grpc::string_ref> recv_initial_metadata_;
+  std::multimap<grpc::string_ref, grpc::string_ref> trailing_metadata_;
 
   grpc_call* propagate_from_call_;
   PropagationOptions propagation_options_;
diff --git a/include/grpc++/impl/call.h b/include/grpc++/impl/call.h
index e5da6c9..fca5603 100644
--- a/include/grpc++/impl/call.h
+++ b/include/grpc++/impl/call.h
@@ -54,8 +54,9 @@
 class ByteBuffer;
 class Call;
 
-void FillMetadataMap(grpc_metadata_array* arr,
-                     std::multimap<grpc::string, grpc::string>* metadata);
+void FillMetadataMap(
+    grpc_metadata_array* arr,
+    std::multimap<grpc::string_ref, grpc::string_ref>* metadata);
 grpc_metadata* FillMetadataArray(
     const std::multimap<grpc::string, grpc::string>& metadata);
 
@@ -418,7 +419,7 @@
   }
 
  private:
-  std::multimap<grpc::string, grpc::string>* recv_initial_metadata_;
+  std::multimap<grpc::string_ref, grpc::string_ref>* recv_initial_metadata_;
   grpc_metadata_array recv_initial_metadata_arr_;
 };
 
@@ -461,7 +462,7 @@
   }
 
  private:
-  std::multimap<grpc::string, grpc::string>* recv_trailing_metadata_;
+  std::multimap<grpc::string_ref, grpc::string_ref>* recv_trailing_metadata_;
   Status* recv_status_;
   grpc_metadata_array recv_trailing_metadata_arr_;
   grpc_status_code status_code_;
diff --git a/include/grpc++/server_context.h b/include/grpc++/server_context.h
index ce3cb47..4b17a28 100644
--- a/include/grpc++/server_context.h
+++ b/include/grpc++/server_context.h
@@ -41,6 +41,7 @@
 #include <grpc/support/time.h>
 #include <grpc++/support/auth_context.h>
 #include <grpc++/support/config.h>
+#include <grpc++/support/string_ref.h>
 #include <grpc++/support/time.h>
 
 struct gpr_timespec;
@@ -103,7 +104,7 @@
 
   bool IsCancelled() const;
 
-  const std::multimap<grpc::string, grpc::string>& client_metadata() {
+  const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata() {
     return client_metadata_;
   }
 
@@ -185,7 +186,7 @@
   CompletionQueue* cq_;
   bool sent_initial_metadata_;
   mutable std::shared_ptr<const AuthContext> auth_context_;
-  std::multimap<grpc::string, grpc::string> client_metadata_;
+  std::multimap<grpc::string_ref, grpc::string_ref> client_metadata_;
   std::multimap<grpc::string, grpc::string> initial_metadata_;
   std::multimap<grpc::string, grpc::string> trailing_metadata_;
 
diff --git a/include/grpc++/support/string_ref.h b/include/grpc++/support/string_ref.h
index 0ec39a9..348c42c 100644
--- a/include/grpc++/support/string_ref.h
+++ b/include/grpc++/support/string_ref.h
@@ -50,22 +50,22 @@
   typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
 
   // constants
-  static constexpr size_t npos = size_t(-1);
+  const static size_t npos = size_t(-1);
 
   // construct/copy.
-  constexpr string_ref() : data_(nullptr), length_(0) {}
-  constexpr string_ref(const string_ref& other)
+  string_ref() : data_(nullptr), length_(0) {}
+  string_ref(const string_ref& other)
       : data_(other.data_), length_(other.length_) {}
   string_ref& operator=(const string_ref& rhs);
   string_ref(const char* s);
-  constexpr string_ref(const char* s, size_t l) : data_(s), length_(l) {}
+  string_ref(const char* s, size_t l) : data_(s), length_(l) {}
   string_ref(const grpc::string& s) : data_(s.data()), length_(s.length()) {}
 
   // iterators
-  constexpr const_iterator begin() const { return data_; }
-  constexpr const_iterator end() const { return data_ + length_; }
-  constexpr const_iterator cbegin() const { return data_; }
-  constexpr const_iterator cend() const { return data_ + length_; }
+  const_iterator begin() const { return data_; }
+  const_iterator end() const { return data_ + length_; }
+  const_iterator cbegin() const { return data_; }
+  const_iterator cend() const { return data_ + length_; }
   const_reverse_iterator rbegin() const {
     return const_reverse_iterator(end());
   }
@@ -80,10 +80,10 @@
   }
 
   // capacity
-  constexpr size_t size() const { return length_; }
-  constexpr size_t length() const { return length_; }
-  constexpr size_t max_size() const { return length_; }
-  constexpr bool empty() const { return length_ == 0; }
+  size_t size() const { return length_; }
+  size_t length() const { return length_; }
+  size_t max_size() const { return length_; }
+  bool empty() const { return length_ == 0; }
 
   // element access
   const char* data() const { return data_; }
@@ -95,9 +95,7 @@
   size_t find(string_ref s) const;
   size_t find(char c) const;
 
-  // Defined as constexpr in n3442 but C++11 constexpr semantics do not allow
-  // the implementation of this function to comply.
-  /* constrexpr */ string_ref substr(size_t pos, size_t n = npos) const;
+  string_ref substr(size_t pos, size_t n = npos) const;
 
  private:
   const char* data_;
diff --git a/src/cpp/common/call.cc b/src/cpp/common/call.cc
index 16aa2c9..5b87c2a 100644
--- a/src/cpp/common/call.cc
+++ b/src/cpp/common/call.cc
@@ -41,13 +41,14 @@
 
 namespace grpc {
 
-void FillMetadataMap(grpc_metadata_array* arr,
-                     std::multimap<grpc::string, grpc::string>* metadata) {
+void FillMetadataMap(
+    grpc_metadata_array* arr,
+    std::multimap<grpc::string_ref, grpc::string_ref>* metadata) {
   for (size_t i = 0; i < arr->count; i++) {
     // TODO(yangg) handle duplicates?
-    metadata->insert(std::pair<grpc::string, grpc::string>(
-        arr->metadata[i].key,
-        grpc::string(arr->metadata[i].value, arr->metadata[i].value_length)));
+    metadata->insert(std::pair<grpc::string_ref, grpc::string_ref>(
+        arr->metadata[i].key, grpc::string_ref(arr->metadata[i].value,
+                                               arr->metadata[i].value_length)));
   }
   grpc_metadata_array_destroy(arr);
   grpc_metadata_array_init(arr);
diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc
index 66cd27c..bb83c7d 100644
--- a/src/cpp/server/server.cc
+++ b/src/cpp/server/server.cc
@@ -439,11 +439,12 @@
 bool Server::BaseAsyncRequest::FinalizeResult(void** tag, bool* status) {
   if (*status) {
     for (size_t i = 0; i < initial_metadata_array_.count; i++) {
-      context_->client_metadata_.insert(std::make_pair(
-          grpc::string(initial_metadata_array_.metadata[i].key),
-          grpc::string(initial_metadata_array_.metadata[i].value,
-                       initial_metadata_array_.metadata[i].value +
-                           initial_metadata_array_.metadata[i].value_length)));
+      context_->client_metadata_.insert(
+          std::pair<grpc::string_ref, grpc::string_ref>(
+              initial_metadata_array_.metadata[i].key,
+              grpc::string_ref(
+                  initial_metadata_array_.metadata[i].value,
+                  initial_metadata_array_.metadata[i].value_length)));
     }
   }
   grpc_metadata_array_destroy(&initial_metadata_array_);
diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc
index acc163d..8193e70 100644
--- a/src/cpp/server/server_context.cc
+++ b/src/cpp/server/server_context.cc
@@ -136,10 +136,9 @@
       cq_(nullptr),
       sent_initial_metadata_(false) {
   for (size_t i = 0; i < metadata_count; i++) {
-    client_metadata_.insert(std::make_pair(
-        grpc::string(metadata[i].key),
-        grpc::string(metadata[i].value,
-                     metadata[i].value + metadata[i].value_length)));
+    client_metadata_.insert(std::pair<grpc::string_ref, grpc::string_ref>(
+        metadata[i].key,
+        grpc::string_ref(metadata[i].value, metadata[i].value_length)));
   }
 }
 
diff --git a/src/cpp/util/string_ref.cc b/src/cpp/util/string_ref.cc
index 8483e8c..d9c9019 100644
--- a/src/cpp/util/string_ref.cc
+++ b/src/cpp/util/string_ref.cc
@@ -39,7 +39,7 @@
 
 namespace grpc {
 
-constexpr size_t string_ref::npos;
+const size_t string_ref::npos;
 
 string_ref& string_ref::operator=(const string_ref& rhs) {
   data_ = rhs.data_;
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index 6343810..41b91e4 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -50,6 +50,7 @@
 #include "test/core/util/test_config.h"
 #include "test/cpp/util/echo_duplicate.grpc.pb.h"
 #include "test/cpp/util/echo.grpc.pb.h"
+#include "test/cpp/util/string_ref_helper.h"
 
 #ifdef GPR_POSIX_SOCKET
 #include "src/core/iomgr/pollset_posix.h"
@@ -484,8 +485,10 @@
   Verifier(GetParam()).Expect(2, true).Verify(cq_.get());
   EXPECT_EQ(send_request.message(), recv_request.message());
   auto client_initial_metadata = srv_ctx.client_metadata();
-  EXPECT_EQ(meta1.second, client_initial_metadata.find(meta1.first)->second);
-  EXPECT_EQ(meta2.second, client_initial_metadata.find(meta2.first)->second);
+  EXPECT_EQ(meta1.second,
+            ToString(client_initial_metadata.find(meta1.first)->second));
+  EXPECT_EQ(meta2.second,
+            ToString(client_initial_metadata.find(meta2.first)->second));
   EXPECT_GE(client_initial_metadata.size(), static_cast<size_t>(2));
 
   send_response.set_message(recv_request.message());
@@ -532,8 +535,10 @@
   response_reader->ReadInitialMetadata(tag(4));
   Verifier(GetParam()).Expect(4, true).Verify(cq_.get());
   auto server_initial_metadata = cli_ctx.GetServerInitialMetadata();
-  EXPECT_EQ(meta1.second, server_initial_metadata.find(meta1.first)->second);
-  EXPECT_EQ(meta2.second, server_initial_metadata.find(meta2.first)->second);
+  EXPECT_EQ(meta1.second,
+            ToString(server_initial_metadata.find(meta1.first)->second));
+  EXPECT_EQ(meta2.second,
+            ToString(server_initial_metadata.find(meta2.first)->second));
   EXPECT_EQ(static_cast<size_t>(2), server_initial_metadata.size());
 
   send_response.set_message(recv_request.message());
@@ -586,8 +591,10 @@
   EXPECT_EQ(send_response.message(), recv_response.message());
   EXPECT_TRUE(recv_status.ok());
   auto server_trailing_metadata = cli_ctx.GetServerTrailingMetadata();
-  EXPECT_EQ(meta1.second, server_trailing_metadata.find(meta1.first)->second);
-  EXPECT_EQ(meta2.second, server_trailing_metadata.find(meta2.first)->second);
+  EXPECT_EQ(meta1.second,
+            ToString(server_trailing_metadata.find(meta1.first)->second));
+  EXPECT_EQ(meta2.second,
+            ToString(server_trailing_metadata.find(meta2.first)->second));
   EXPECT_EQ(static_cast<size_t>(2), server_trailing_metadata.size());
 }
 
@@ -631,8 +638,10 @@
   Verifier(GetParam()).Expect(2, true).Verify(cq_.get());
   EXPECT_EQ(send_request.message(), recv_request.message());
   auto client_initial_metadata = srv_ctx.client_metadata();
-  EXPECT_EQ(meta1.second, client_initial_metadata.find(meta1.first)->second);
-  EXPECT_EQ(meta2.second, client_initial_metadata.find(meta2.first)->second);
+  EXPECT_EQ(meta1.second,
+            ToString(client_initial_metadata.find(meta1.first)->second));
+  EXPECT_EQ(meta2.second,
+            ToString(client_initial_metadata.find(meta2.first)->second));
   EXPECT_GE(client_initial_metadata.size(), static_cast<size_t>(2));
 
   srv_ctx.AddInitialMetadata(meta3.first, meta3.second);
@@ -642,8 +651,10 @@
   response_reader->ReadInitialMetadata(tag(4));
   Verifier(GetParam()).Expect(4, true).Verify(cq_.get());
   auto server_initial_metadata = cli_ctx.GetServerInitialMetadata();
-  EXPECT_EQ(meta3.second, server_initial_metadata.find(meta3.first)->second);
-  EXPECT_EQ(meta4.second, server_initial_metadata.find(meta4.first)->second);
+  EXPECT_EQ(meta3.second,
+            ToString(server_initial_metadata.find(meta3.first)->second));
+  EXPECT_EQ(meta4.second,
+            ToString(server_initial_metadata.find(meta4.first)->second));
   EXPECT_GE(server_initial_metadata.size(), static_cast<size_t>(2));
 
   send_response.set_message(recv_request.message());
@@ -658,8 +669,10 @@
   EXPECT_EQ(send_response.message(), recv_response.message());
   EXPECT_TRUE(recv_status.ok());
   auto server_trailing_metadata = cli_ctx.GetServerTrailingMetadata();
-  EXPECT_EQ(meta5.second, server_trailing_metadata.find(meta5.first)->second);
-  EXPECT_EQ(meta6.second, server_trailing_metadata.find(meta6.first)->second);
+  EXPECT_EQ(meta5.second,
+            ToString(server_trailing_metadata.find(meta5.first)->second));
+  EXPECT_EQ(meta6.second,
+            ToString(server_trailing_metadata.find(meta6.first)->second));
   EXPECT_GE(server_trailing_metadata.size(), static_cast<size_t>(2));
 }
 
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 2728dce..0d5bf36 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -53,6 +53,7 @@
 #include "test/core/util/test_config.h"
 #include "test/cpp/util/echo_duplicate.grpc.pb.h"
 #include "test/cpp/util/echo.grpc.pb.h"
+#include "test/cpp/util/string_ref_helper.h"
 
 using grpc::cpp::test::util::EchoRequest;
 using grpc::cpp::test::util::EchoResponse;
@@ -152,12 +153,13 @@
     }
 
     if (request->has_param() && request->param().echo_metadata()) {
-      const std::multimap<grpc::string, grpc::string>& client_metadata =
+      const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata =
           context->client_metadata();
-      for (std::multimap<grpc::string, grpc::string>::const_iterator iter =
-               client_metadata.begin();
+      for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator
+               iter = client_metadata.begin();
            iter != client_metadata.end(); ++iter) {
-        context->AddTrailingMetadata((*iter).first, (*iter).second);
+        context->AddTrailingMetadata(ToString(iter->first),
+                                     ToString(iter->second));
       }
     }
     if (request->has_param() && request->param().check_auth_context()) {
@@ -182,12 +184,12 @@
     EchoRequest request;
     response->set_message("");
     int cancel_after_reads = 0;
-    const std::multimap<grpc::string, grpc::string> client_initial_metadata =
-        context->client_metadata();
+    const std::multimap<grpc::string_ref, grpc::string_ref>&
+        client_initial_metadata = context->client_metadata();
     if (client_initial_metadata.find(kServerCancelAfterReads) !=
         client_initial_metadata.end()) {
-      std::istringstream iss(
-          client_initial_metadata.find(kServerCancelAfterReads)->second);
+      std::istringstream iss(ToString(
+          client_initial_metadata.find(kServerCancelAfterReads)->second));
       iss >> cancel_after_reads;
       gpr_log(GPR_INFO, "cancel_after_reads %d", cancel_after_reads);
     }
@@ -721,14 +723,15 @@
   EXPECT_FALSE(s.ok());
 }
 
-bool MetadataContains(const std::multimap<grpc::string, grpc::string>& metadata,
-                      const grpc::string& key, const grpc::string& value) {
+bool MetadataContains(
+    const std::multimap<grpc::string_ref, grpc::string_ref>& metadata,
+    const grpc::string& key, const grpc::string& value) {
   int count = 0;
 
-  for (std::multimap<grpc::string, grpc::string>::const_iterator iter =
+  for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator iter =
            metadata.begin();
        iter != metadata.end(); ++iter) {
-    if ((*iter).first == key && (*iter).second == value) {
+    if (ToString(iter->first) == key && ToString(iter->second) == value) {
       count++;
     }
   }
diff --git a/test/cpp/util/cli_call.cc b/test/cpp/util/cli_call.cc
index d60cee9..9a76984 100644
--- a/test/cpp/util/cli_call.cc
+++ b/test/cpp/util/cli_call.cc
@@ -51,14 +51,14 @@
 
 Status CliCall::Call(std::shared_ptr<grpc::Channel> channel,
                      const grpc::string& method, const grpc::string& request,
-                     grpc::string* response, const MetadataContainer& metadata,
-                     MetadataContainer* server_initial_metadata,
-                     MetadataContainer* server_trailing_metadata) {
+                     grpc::string* response,
+                     const OutgoingMetadataContainer& metadata,
+                     IncomingMetadataContainer* server_initial_metadata,
+                     IncomingMetadataContainer* server_trailing_metadata) {
   std::unique_ptr<grpc::GenericStub> stub(new grpc::GenericStub(channel));
   grpc::ClientContext ctx;
   if (!metadata.empty()) {
-    for (std::multimap<grpc::string, grpc::string>::const_iterator iter =
-             metadata.begin();
+    for (OutgoingMetadataContainer::const_iterator iter = metadata.begin();
          iter != metadata.end(); ++iter) {
       ctx.AddMetadata(iter->first, iter->second);
     }
diff --git a/test/cpp/util/cli_call.h b/test/cpp/util/cli_call.h
index 7a3dcf2..2fbc961 100644
--- a/test/cpp/util/cli_call.h
+++ b/test/cpp/util/cli_call.h
@@ -38,18 +38,22 @@
 
 #include <grpc++/channel.h>
 #include <grpc++/support/status.h>
+#include <grpc++/support/string_ref.h>
 
 namespace grpc {
 namespace testing {
 
 class CliCall GRPC_FINAL {
  public:
-  typedef std::multimap<grpc::string, grpc::string> MetadataContainer;
+  typedef std::multimap<grpc::string, grpc::string> OutgoingMetadataContainer;
+  typedef std::multimap<grpc::string_ref, grpc::string_ref>
+      IncomingMetadataContainer;
   static Status Call(std::shared_ptr<grpc::Channel> channel,
                      const grpc::string& method, const grpc::string& request,
-                     grpc::string* response, const MetadataContainer& metadata,
-                     MetadataContainer* server_initial_metadata,
-                     MetadataContainer* server_trailing_metadata);
+                     grpc::string* response,
+                     const OutgoingMetadataContainer& metadata,
+                     IncomingMetadataContainer* server_initial_metadata,
+                     IncomingMetadataContainer* server_trailing_metadata);
 };
 
 }  // namespace testing
diff --git a/test/cpp/util/cli_call_test.cc b/test/cpp/util/cli_call_test.cc
index 35bfad2..111a0e9 100644
--- a/test/cpp/util/cli_call_test.cc
+++ b/test/cpp/util/cli_call_test.cc
@@ -47,6 +47,7 @@
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 #include "test/cpp/util/echo.grpc.pb.h"
+#include "test/cpp/util/string_ref_helper.h"
 
 using grpc::cpp::test::util::EchoRequest;
 using grpc::cpp::test::util::EchoResponse;
@@ -59,10 +60,11 @@
   Status Echo(ServerContext* context, const EchoRequest* request,
               EchoResponse* response) GRPC_OVERRIDE {
     if (!context->client_metadata().empty()) {
-      for (std::multimap<grpc::string, grpc::string>::const_iterator iter =
-               context->client_metadata().begin();
+      for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator
+               iter = context->client_metadata().begin();
            iter != context->client_metadata().end(); ++iter) {
-        context->AddInitialMetadata(iter->first, iter->second);
+        context->AddInitialMetadata(ToString(iter->first),
+                                    ToString(iter->second));
       }
     }
     context->AddTrailingMetadata("trailing_key", "trailing_value");
@@ -119,8 +121,9 @@
   grpc::string request_bin, response_bin, expected_response_bin;
   EXPECT_TRUE(request.SerializeToString(&request_bin));
   EXPECT_TRUE(response.SerializeToString(&expected_response_bin));
-  std::multimap<grpc::string, grpc::string> client_metadata,
-      server_initial_metadata, server_trailing_metadata;
+  std::multimap<grpc::string, grpc::string> client_metadata;
+  std::multimap<grpc::string_ref, grpc::string_ref> server_initial_metadata,
+      server_trailing_metadata;
   client_metadata.insert(std::pair<grpc::string, grpc::string>("key1", "val1"));
   Status s2 = CliCall::Call(channel_, kMethod, request_bin, &response_bin,
                             client_metadata, &server_initial_metadata,
diff --git a/test/cpp/util/grpc_cli.cc b/test/cpp/util/grpc_cli.cc
index 746d67d..a4888ef 100644
--- a/test/cpp/util/grpc_cli.cc
+++ b/test/cpp/util/grpc_cli.cc
@@ -68,8 +68,10 @@
 #include <grpc++/channel.h>
 #include <grpc++/create_channel.h>
 #include <grpc++/credentials.h>
+#include <grpc++/support/string_ref.h>
 
 #include "test/cpp/util/cli_call.h"
+#include "test/cpp/util/string_ref_helper.h"
 #include "test/cpp/util/test_config.h"
 
 DEFINE_bool(enable_ssl, true, "Whether to use ssl/tls.");
@@ -104,16 +106,19 @@
   }
 }
 
-void PrintMetadata(const std::multimap<grpc::string, grpc::string>& m,
-                   const grpc::string& message) {
+template <typename T>
+void PrintMetadata(const T& m, const grpc::string& message) {
   if (m.empty()) {
     return;
   }
   std::cout << message << std::endl;
-  for (std::multimap<grpc::string, grpc::string>::const_iterator iter =
-           m.begin();
-       iter != m.end(); ++iter) {
-    std::cout << iter->first << " : " << iter->second << std::endl;
+  grpc::string pair;
+  for (typename T::const_iterator iter = m.begin(); iter != m.end(); ++iter) {
+    pair.clear();
+    pair.append(iter->first.data(), iter->first.size());
+    pair.append(" : ");
+    pair.append(iter->second.data(), iter->second.size());
+    std::cout << pair << std::endl;
   }
 }
 
@@ -157,8 +162,9 @@
       grpc::CreateChannel(server_address, creds, grpc::ChannelArguments());
 
   grpc::string response;
-  std::multimap<grpc::string, grpc::string> client_metadata,
-      server_initial_metadata, server_trailing_metadata;
+  std::multimap<grpc::string, grpc::string> client_metadata;
+  std::multimap<grpc::string_ref, grpc::string_ref> server_initial_metadata,
+      server_trailing_metadata;
   ParseMetadataFlag(&client_metadata);
   PrintMetadata(client_metadata, "Sending client initial metadata:");
   grpc::Status s = grpc::testing::CliCall::Call(
diff --git a/test/cpp/util/string_ref_helper.cc b/test/cpp/util/string_ref_helper.cc
new file mode 100644
index 0000000..4eb4fe0
--- /dev/null
+++ b/test/cpp/util/string_ref_helper.cc
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/cpp/util/string_ref_helper.h"
+
+namespace grpc {
+namespace testing {
+
+grpc::string ToString(const grpc::string_ref& r) {
+  return grpc::string(r.data(), r.size());
+}
+
+}  // namespace testing
+}  // namespace grpc
diff --git a/test/cpp/util/string_ref_helper.h b/test/cpp/util/string_ref_helper.h
new file mode 100644
index 0000000..ac94bcd
--- /dev/null
+++ b/test/cpp/util/string_ref_helper.h
@@ -0,0 +1,47 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_TEST_CPP_UTIL_STRING_REF_HELPER_H
+#define GRPC_TEST_CPP_UTIL_STRING_REF_HELPER_H
+
+#include <grpc++/support/string_ref.h>
+
+namespace grpc {
+namespace testing {
+
+grpc::string ToString(const grpc::string_ref& r);
+
+}  // namespace testing
+}  // namespace grpc
+
+#endif  // GRPC_TEST_CPP_UTIL_STRING_REF_HELPER_H
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index c7df23a..a89e534 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -13280,6 +13280,7 @@
       "test/cpp/util/echo_duplicate.pb.h", 
       "test/cpp/util/messages.grpc.pb.h", 
       "test/cpp/util/messages.pb.h", 
+      "test/cpp/util/string_ref_helper.h", 
       "test/cpp/util/subprocess.h"
     ], 
     "language": "c++", 
@@ -13289,6 +13290,8 @@
       "test/cpp/util/cli_call.h", 
       "test/cpp/util/create_test_channel.cc", 
       "test/cpp/util/create_test_channel.h", 
+      "test/cpp/util/string_ref_helper.cc", 
+      "test/cpp/util/string_ref_helper.h", 
       "test/cpp/util/subprocess.cc", 
       "test/cpp/util/subprocess.h"
     ]
diff --git a/vsprojects/Grpc.mak b/vsprojects/Grpc.mak
index 2893b72..19cb397 100644
--- a/vsprojects/Grpc.mak
+++ b/vsprojects/Grpc.mak
@@ -4744,8 +4744,8 @@
 
 Debug\grpc++_test_util.lib: $(OUT_DIR)
 	echo Building grpc++_test_util
-    $(CC) $(CXXFLAGS) /Fo:$(OUT_DIR)\ $(REPO_ROOT)\test\cpp\util\cli_call.cc $(REPO_ROOT)\test\cpp\util\create_test_channel.cc $(REPO_ROOT)\test\cpp\util\subprocess.cc $(REPO_ROOT)\test\cpp\util\messages.pb.cc $(REPO_ROOT)\test\cpp\util\messages.grpc.pb.cc $(REPO_ROOT)\test\cpp\util\echo.pb.cc $(REPO_ROOT)\test\cpp\util\echo.grpc.pb.cc $(REPO_ROOT)\test\cpp\util\echo_duplicate.pb.cc $(REPO_ROOT)\test\cpp\util\echo_duplicate.grpc.pb.cc 
-	$(LIBTOOL) /OUT:"Debug\grpc++_test_util.lib" $(OUT_DIR)\cli_call.obj $(OUT_DIR)\create_test_channel.obj $(OUT_DIR)\subprocess.obj $(OUT_DIR)\messages.pb.obj $(OUT_DIR)\messages.grpc.pb.obj $(OUT_DIR)\echo.pb.obj $(OUT_DIR)\echo.grpc.pb.obj $(OUT_DIR)\echo_duplicate.pb.obj $(OUT_DIR)\echo_duplicate.grpc.pb.obj 
+    $(CC) $(CXXFLAGS) /Fo:$(OUT_DIR)\ $(REPO_ROOT)\test\cpp\util\cli_call.cc $(REPO_ROOT)\test\cpp\util\create_test_channel.cc $(REPO_ROOT)\test\cpp\util\string_ref_helper.cc $(REPO_ROOT)\test\cpp\util\subprocess.cc $(REPO_ROOT)\test\cpp\util\messages.pb.cc $(REPO_ROOT)\test\cpp\util\messages.grpc.pb.cc $(REPO_ROOT)\test\cpp\util\echo.pb.cc $(REPO_ROOT)\test\cpp\util\echo.grpc.pb.cc $(REPO_ROOT)\test\cpp\util\echo_duplicate.pb.cc $(REPO_ROOT)\test\cpp\util\echo_duplicate.grpc.pb.cc 
+	$(LIBTOOL) /OUT:"Debug\grpc++_test_util.lib" $(OUT_DIR)\cli_call.obj $(OUT_DIR)\create_test_channel.obj $(OUT_DIR)\string_ref_helper.obj $(OUT_DIR)\subprocess.obj $(OUT_DIR)\messages.pb.obj $(OUT_DIR)\messages.grpc.pb.obj $(OUT_DIR)\echo.pb.obj $(OUT_DIR)\echo.grpc.pb.obj $(OUT_DIR)\echo_duplicate.pb.obj $(OUT_DIR)\echo_duplicate.grpc.pb.obj 
 
 build_grpc++_unsecure:
 	msbuild grpc.sln /t:grpc++_unsecure /p:Configuration=Debug /p:Linkage-grpc_dependencies_zlib=static