Merge pull request #14315 from kpayson64/fix_refcounting

Fixes refcounting issue
diff --git a/BUILD b/BUILD
index 186d664..8456c06 100644
--- a/BUILD
+++ b/BUILD
@@ -56,9 +56,9 @@
 # This should be updated along with build.yaml
 g_stands_for = "glossy"
 
-core_version = "5.0.0-dev"
+core_version = "5.0.0"
 
-version = "1.9.0-dev"
+version = "1.9.0"
 
 GPR_PUBLIC_HDRS = [
     "include/grpc/support/alloc.h",
@@ -448,75 +448,67 @@
     srcs = [
         "src/core/lib/profiling/basic_timers.cc",
         "src/core/lib/profiling/stap_timers.cc",
-        "src/core/lib/support/alloc.cc",
-        "src/core/lib/support/arena.cc",
-        "src/core/lib/support/atm.cc",
-        "src/core/lib/support/avl.cc",
-        "src/core/lib/support/cmdline.cc",
-        "src/core/lib/support/cpu_iphone.cc",
-        "src/core/lib/support/cpu_linux.cc",
-        "src/core/lib/support/cpu_posix.cc",
-        "src/core/lib/support/cpu_windows.cc",
-        "src/core/lib/support/env_linux.cc",
-        "src/core/lib/support/env_posix.cc",
-        "src/core/lib/support/env_windows.cc",
-        "src/core/lib/support/fork.cc",
-        "src/core/lib/support/host_port.cc",
-        "src/core/lib/support/log.cc",
-        "src/core/lib/support/log_android.cc",
-        "src/core/lib/support/log_linux.cc",
-        "src/core/lib/support/log_posix.cc",
-        "src/core/lib/support/log_windows.cc",
-        "src/core/lib/support/mpscq.cc",
-        "src/core/lib/support/murmur_hash.cc",
-        "src/core/lib/support/string.cc",
-        "src/core/lib/support/string_posix.cc",
-        "src/core/lib/support/string_util_windows.cc",
-        "src/core/lib/support/string_windows.cc",
-        "src/core/lib/support/subprocess_posix.cc",
-        "src/core/lib/support/subprocess_windows.cc",
-        "src/core/lib/support/sync.cc",
-        "src/core/lib/support/sync_posix.cc",
-        "src/core/lib/support/sync_windows.cc",
-        "src/core/lib/support/thd.cc",
-        "src/core/lib/support/thd_posix.cc",
-        "src/core/lib/support/thd_windows.cc",
-        "src/core/lib/support/time.cc",
-        "src/core/lib/support/time_posix.cc",
-        "src/core/lib/support/time_precise.cc",
-        "src/core/lib/support/time_windows.cc",
-        "src/core/lib/support/tls_pthread.cc",
-        "src/core/lib/support/tmpfile_msys.cc",
-        "src/core/lib/support/tmpfile_posix.cc",
-        "src/core/lib/support/tmpfile_windows.cc",
-        "src/core/lib/support/wrap_memcpy.cc",
+        "src/core/lib/gpr/alloc.cc",
+        "src/core/lib/gpr/arena.cc",
+        "src/core/lib/gpr/atm.cc",
+        "src/core/lib/gpr/avl.cc",
+        "src/core/lib/gpr/cmdline.cc",
+        "src/core/lib/gpr/cpu_iphone.cc",
+        "src/core/lib/gpr/cpu_linux.cc",
+        "src/core/lib/gpr/cpu_posix.cc",
+        "src/core/lib/gpr/cpu_windows.cc",
+        "src/core/lib/gpr/env_linux.cc",
+        "src/core/lib/gpr/env_posix.cc",
+        "src/core/lib/gpr/env_windows.cc",
+        "src/core/lib/gpr/fork.cc",
+        "src/core/lib/gpr/host_port.cc",
+        "src/core/lib/gpr/log.cc",
+        "src/core/lib/gpr/log_android.cc",
+        "src/core/lib/gpr/log_linux.cc",
+        "src/core/lib/gpr/log_posix.cc",
+        "src/core/lib/gpr/log_windows.cc",
+        "src/core/lib/gpr/mpscq.cc",
+        "src/core/lib/gpr/murmur_hash.cc",
+        "src/core/lib/gpr/string.cc",
+        "src/core/lib/gpr/string_posix.cc",
+        "src/core/lib/gpr/string_util_windows.cc",
+        "src/core/lib/gpr/string_windows.cc",
+        "src/core/lib/gpr/subprocess_posix.cc",
+        "src/core/lib/gpr/subprocess_windows.cc",
+        "src/core/lib/gpr/sync.cc",
+        "src/core/lib/gpr/sync_posix.cc",
+        "src/core/lib/gpr/sync_windows.cc",
+        "src/core/lib/gpr/thd.cc",
+        "src/core/lib/gpr/thd_posix.cc",
+        "src/core/lib/gpr/thd_windows.cc",
+        "src/core/lib/gpr/time.cc",
+        "src/core/lib/gpr/time_posix.cc",
+        "src/core/lib/gpr/time_precise.cc",
+        "src/core/lib/gpr/time_windows.cc",
+        "src/core/lib/gpr/tls_pthread.cc",
+        "src/core/lib/gpr/tmpfile_msys.cc",
+        "src/core/lib/gpr/tmpfile_posix.cc",
+        "src/core/lib/gpr/tmpfile_windows.cc",
+        "src/core/lib/gpr/wrap_memcpy.cc",
     ],
     hdrs = [
         "src/core/lib/profiling/timers.h",
-        "src/core/lib/support/abstract.h",
-        "src/core/lib/support/arena.h",
-        "src/core/lib/support/atomic.h",
-        "src/core/lib/support/atomic_with_atm.h",
-        "src/core/lib/support/atomic_with_std.h",
-        "src/core/lib/support/env.h",
-        "src/core/lib/support/fork.h",
-        "src/core/lib/support/manual_constructor.h",
-        "src/core/lib/support/memory.h",
-        "src/core/lib/support/mpscq.h",
-        "src/core/lib/support/murmur_hash.h",
-        "src/core/lib/support/spinlock.h",
-        "src/core/lib/support/string.h",
-        "src/core/lib/support/string_windows.h",
-        "src/core/lib/support/thd_internal.h",
-        "src/core/lib/support/time_precise.h",
-        "src/core/lib/support/tmpfile.h",
-        "src/core/lib/support/vector.h",
+        "src/core/lib/gpr/arena.h",
+        "src/core/lib/gpr/env.h",
+        "src/core/lib/gpr/fork.h",
+        "src/core/lib/gpr/mpscq.h",
+        "src/core/lib/gpr/murmur_hash.h",
+        "src/core/lib/gpr/spinlock.h",
+        "src/core/lib/gpr/string.h",
+        "src/core/lib/gpr/string_windows.h",
+        "src/core/lib/gpr/thd_internal.h",
+        "src/core/lib/gpr/time_precise.h",
+        "src/core/lib/gpr/tmpfile.h",
     ],
     language = "c++",
     public_hdrs = GPR_PUBLIC_HDRS,
     deps = [
         "gpr_codegen",
-        "@com_google_absl//absl/container:inlined_vector",
     ],
 )
 
@@ -553,15 +545,48 @@
 )
 
 grpc_cc_library(
+    name = "gpr++_base",
+    language = "c++",
+    public_hdrs = [
+        "src/core/lib/gpr++/abstract.h",
+        "src/core/lib/gpr++/manual_constructor.h",
+        "src/core/lib/gpr++/memory.h",
+    ],
+)
+
+grpc_cc_library(
+    name = "atomic",
+    language = "c++",
+    public_hdrs = [
+        "src/core/lib/gpr++/atomic.h",
+    ],
+    hdrs = [
+        "src/core/lib/gpr++/atomic_with_atm.h",
+        "src/core/lib/gpr++/atomic_with_std.h",
+    ],
+    deps = [
+        "gpr",
+    ],
+)
+
+grpc_cc_library(
+    name = "inlined_vector",
+    language = "c++",
+    public_hdrs = [
+        "src/core/lib/gpr++/inlined_vector.h",
+    ],
+)
+
+grpc_cc_library(
     name = "debug_location",
     language = "c++",
-    public_hdrs = ["src/core/lib/support/debug_location.h"],
+    public_hdrs = ["src/core/lib/gpr++/debug_location.h"],
 )
 
 grpc_cc_library(
     name = "orphanable",
     language = "c++",
-    public_hdrs = ["src/core/lib/support/orphanable.h"],
+    public_hdrs = ["src/core/lib/gpr++/orphanable.h"],
     deps = [
         "debug_location",
         "grpc_trace",
@@ -571,7 +596,7 @@
 grpc_cc_library(
     name = "ref_counted",
     language = "c++",
-    public_hdrs = ["src/core/lib/support/ref_counted.h"],
+    public_hdrs = ["src/core/lib/gpr++/ref_counted.h"],
     deps = [
         "debug_location",
         "grpc_trace",
@@ -581,7 +606,7 @@
 grpc_cc_library(
     name = "ref_counted_ptr",
     language = "c++",
-    public_hdrs = ["src/core/lib/support/ref_counted_ptr.h"],
+    public_hdrs = ["src/core/lib/gpr++/ref_counted_ptr.h"],
 )
 
 grpc_cc_library(
@@ -848,6 +873,7 @@
     public_hdrs = GRPC_PUBLIC_HDRS,
     deps = [
         "gpr_base",
+        "gpr++_base",
         "grpc_codegen",
         "grpc_trace",
     ],
@@ -860,6 +886,7 @@
     ],
     language = "c++",
     deps = [
+        "atomic",
         "grpc_base_c",
     ],
 )
@@ -1320,6 +1347,7 @@
     ],
     language = "c++",
     deps = [
+        "gpr++_base",
         "grpc_base",
         "grpc_http_filters",
         "grpc_transport_chttp2_alpn",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 97d68cc..0a9f6dc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -24,7 +24,7 @@
 cmake_minimum_required(VERSION 2.8)
 
 set(PACKAGE_NAME      "grpc")
-set(PACKAGE_VERSION   "1.9.0-dev")
+set(PACKAGE_VERSION   "1.9.0")
 set(PACKAGE_STRING    "${PACKAGE_NAME} ${PACKAGE_VERSION}")
 set(PACKAGE_TARNAME   "${PACKAGE_NAME}-${PACKAGE_VERSION}")
 set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
@@ -389,6 +389,7 @@
 add_dependencies(buildtests_c public_headers_must_be_c89)
 add_dependencies(buildtests_c badreq_bad_client_test)
 add_dependencies(buildtests_c connection_prefix_bad_client_test)
+add_dependencies(buildtests_c duplicate_header_bad_client_test)
 add_dependencies(buildtests_c head_of_line_blocking_bad_client_test)
 add_dependencies(buildtests_c headers_bad_client_test)
 add_dependencies(buildtests_c initial_settings_frame_bad_client_test)
@@ -544,6 +545,7 @@
 add_dependencies(buildtests_cxx http2_client)
 endif()
 add_dependencies(buildtests_cxx hybrid_end2end_test)
+add_dependencies(buildtests_cxx inlined_vector_test)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 add_dependencies(buildtests_cxx inproc_sync_unary_ping_pong_test)
 endif()
@@ -600,7 +602,6 @@
 add_dependencies(buildtests_cxx thread_manager_test)
 add_dependencies(buildtests_cxx thread_stress_test)
 add_dependencies(buildtests_cxx transport_pid_controller_test)
-add_dependencies(buildtests_cxx vector_test)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 add_dependencies(buildtests_cxx writes_per_rpc_test)
 endif()
@@ -623,50 +624,50 @@
 
 
 add_library(gpr
+  src/core/lib/gpr/alloc.cc
+  src/core/lib/gpr/arena.cc
+  src/core/lib/gpr/atm.cc
+  src/core/lib/gpr/avl.cc
+  src/core/lib/gpr/cmdline.cc
+  src/core/lib/gpr/cpu_iphone.cc
+  src/core/lib/gpr/cpu_linux.cc
+  src/core/lib/gpr/cpu_posix.cc
+  src/core/lib/gpr/cpu_windows.cc
+  src/core/lib/gpr/env_linux.cc
+  src/core/lib/gpr/env_posix.cc
+  src/core/lib/gpr/env_windows.cc
+  src/core/lib/gpr/fork.cc
+  src/core/lib/gpr/host_port.cc
+  src/core/lib/gpr/log.cc
+  src/core/lib/gpr/log_android.cc
+  src/core/lib/gpr/log_linux.cc
+  src/core/lib/gpr/log_posix.cc
+  src/core/lib/gpr/log_windows.cc
+  src/core/lib/gpr/mpscq.cc
+  src/core/lib/gpr/murmur_hash.cc
+  src/core/lib/gpr/string.cc
+  src/core/lib/gpr/string_posix.cc
+  src/core/lib/gpr/string_util_windows.cc
+  src/core/lib/gpr/string_windows.cc
+  src/core/lib/gpr/subprocess_posix.cc
+  src/core/lib/gpr/subprocess_windows.cc
+  src/core/lib/gpr/sync.cc
+  src/core/lib/gpr/sync_posix.cc
+  src/core/lib/gpr/sync_windows.cc
+  src/core/lib/gpr/thd.cc
+  src/core/lib/gpr/thd_posix.cc
+  src/core/lib/gpr/thd_windows.cc
+  src/core/lib/gpr/time.cc
+  src/core/lib/gpr/time_posix.cc
+  src/core/lib/gpr/time_precise.cc
+  src/core/lib/gpr/time_windows.cc
+  src/core/lib/gpr/tls_pthread.cc
+  src/core/lib/gpr/tmpfile_msys.cc
+  src/core/lib/gpr/tmpfile_posix.cc
+  src/core/lib/gpr/tmpfile_windows.cc
+  src/core/lib/gpr/wrap_memcpy.cc
   src/core/lib/profiling/basic_timers.cc
   src/core/lib/profiling/stap_timers.cc
-  src/core/lib/support/alloc.cc
-  src/core/lib/support/arena.cc
-  src/core/lib/support/atm.cc
-  src/core/lib/support/avl.cc
-  src/core/lib/support/cmdline.cc
-  src/core/lib/support/cpu_iphone.cc
-  src/core/lib/support/cpu_linux.cc
-  src/core/lib/support/cpu_posix.cc
-  src/core/lib/support/cpu_windows.cc
-  src/core/lib/support/env_linux.cc
-  src/core/lib/support/env_posix.cc
-  src/core/lib/support/env_windows.cc
-  src/core/lib/support/fork.cc
-  src/core/lib/support/host_port.cc
-  src/core/lib/support/log.cc
-  src/core/lib/support/log_android.cc
-  src/core/lib/support/log_linux.cc
-  src/core/lib/support/log_posix.cc
-  src/core/lib/support/log_windows.cc
-  src/core/lib/support/mpscq.cc
-  src/core/lib/support/murmur_hash.cc
-  src/core/lib/support/string.cc
-  src/core/lib/support/string_posix.cc
-  src/core/lib/support/string_util_windows.cc
-  src/core/lib/support/string_windows.cc
-  src/core/lib/support/subprocess_posix.cc
-  src/core/lib/support/subprocess_windows.cc
-  src/core/lib/support/sync.cc
-  src/core/lib/support/sync_posix.cc
-  src/core/lib/support/sync_windows.cc
-  src/core/lib/support/thd.cc
-  src/core/lib/support/thd_posix.cc
-  src/core/lib/support/thd_windows.cc
-  src/core/lib/support/time.cc
-  src/core/lib/support/time_posix.cc
-  src/core/lib/support/time_precise.cc
-  src/core/lib/support/time_windows.cc
-  src/core/lib/support/tls_pthread.cc
-  src/core/lib/support/tmpfile_msys.cc
-  src/core/lib/support/tmpfile_posix.cc
-  src/core/lib/support/tmpfile_windows.cc
-  src/core/lib/support/wrap_memcpy.cc
 )
 
 if(WIN32 AND MSVC)
@@ -4784,7 +4785,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(alloc_test
-  test/core/support/alloc_test.cc
+  test/core/gpr/alloc_test.cc
 )
 
 
@@ -4836,7 +4837,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(arena_test
-  test/core/support/arena_test.cc
+  test/core/gpr/arena_test.cc
 )
 
 
@@ -5635,7 +5636,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(gpr_avl_test
-  test/core/support/avl_test.cc
+  test/core/gpr/avl_test.cc
 )
 
 
@@ -5660,7 +5661,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(gpr_cmdline_test
-  test/core/support/cmdline_test.cc
+  test/core/gpr/cmdline_test.cc
 )
 
 
@@ -5685,7 +5686,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(gpr_cpu_test
-  test/core/support/cpu_test.cc
+  test/core/gpr/cpu_test.cc
 )
 
 
@@ -5710,7 +5711,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(gpr_env_test
-  test/core/support/env_test.cc
+  test/core/gpr/env_test.cc
 )
 
 
@@ -5735,7 +5736,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(gpr_host_port_test
-  test/core/support/host_port_test.cc
+  test/core/gpr/host_port_test.cc
 )
 
 
@@ -5760,7 +5761,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(gpr_log_test
-  test/core/support/log_test.cc
+  test/core/gpr/log_test.cc
 )
 
 
@@ -5785,7 +5786,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(gpr_manual_constructor_test
-  test/core/support/manual_constructor_test.cc
+  test/core/gpr++/manual_constructor_test.cc
 )
 
 
@@ -5810,7 +5811,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(gpr_mpscq_test
-  test/core/support/mpscq_test.cc
+  test/core/gpr/mpscq_test.cc
 )
 
 
@@ -5835,7 +5836,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(gpr_spinlock_test
-  test/core/support/spinlock_test.cc
+  test/core/gpr/spinlock_test.cc
 )
 
 
@@ -5860,7 +5861,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(gpr_string_test
-  test/core/support/string_test.cc
+  test/core/gpr/string_test.cc
 )
 
 
@@ -5885,7 +5886,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(gpr_sync_test
-  test/core/support/sync_test.cc
+  test/core/gpr/sync_test.cc
 )
 
 
@@ -5910,7 +5911,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(gpr_thd_test
-  test/core/support/thd_test.cc
+  test/core/gpr/thd_test.cc
 )
 
 
@@ -5935,7 +5936,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(gpr_time_test
-  test/core/support/time_test.cc
+  test/core/gpr/time_test.cc
 )
 
 
@@ -5960,7 +5961,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(gpr_tls_test
-  test/core/support/tls_test.cc
+  test/core/gpr/tls_test.cc
 )
 
 
@@ -5985,7 +5986,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(gpr_useful_test
-  test/core/support/useful_test.cc
+  test/core/gpr/useful_test.cc
 )
 
 
@@ -7202,7 +7203,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(murmur_hash_test
-  test/core/support/murmur_hash_test.cc
+  test/core/gpr/murmur_hash_test.cc
 )
 
 
@@ -10554,6 +10555,43 @@
 
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
+
+add_executable(inlined_vector_test
+  test/core/gpr++/inlined_vector_test.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+
+target_include_directories(inlined_vector_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
+  PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
+  PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
+  PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
+  PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
+  PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
+  PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(inlined_vector_test
+  ${_gRPC_PROTOBUF_LIBRARIES}
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_test_util
+  grpc++
+  grpc
+  gpr_test_util
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
 add_executable(inproc_sync_unary_ping_pong_test
@@ -10764,7 +10802,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(memory_test
-  test/core/support/memory_test.cc
+  test/core/gpr++/memory_test.cc
   third_party/googletest/googletest/src/gtest-all.cc
   third_party/googletest/googlemock/src/gmock-all.cc
 )
@@ -10915,7 +10953,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(orphanable_test
-  test/core/support/orphanable_test.cc
+  test/core/gpr++/orphanable_test.cc
   third_party/googletest/googletest/src/gtest-all.cc
   third_party/googletest/googlemock/src/gmock-all.cc
 )
@@ -11315,7 +11353,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(ref_counted_ptr_test
-  test/core/support/ref_counted_ptr_test.cc
+  test/core/gpr++/ref_counted_ptr_test.cc
   third_party/googletest/googletest/src/gtest-all.cc
   third_party/googletest/googlemock/src/gmock-all.cc
 )
@@ -11352,7 +11390,7 @@
 if (gRPC_BUILD_TESTS)
 
 add_executable(ref_counted_test
-  test/core/support/ref_counted_test.cc
+  test/core/gpr++/ref_counted_test.cc
   third_party/googletest/googletest/src/gtest-all.cc
   third_party/googletest/googlemock/src/gmock-all.cc
 )
@@ -12059,43 +12097,6 @@
 
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
-
-add_executable(vector_test
-  test/core/support/vector_test.cc
-  third_party/googletest/googletest/src/gtest-all.cc
-  third_party/googletest/googlemock/src/gmock-all.cc
-)
-
-
-target_include_directories(vector_test
-  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
-  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
-  PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
-  PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
-  PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
-  PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
-  PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
-  PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
-  PRIVATE third_party/googletest/googletest/include
-  PRIVATE third_party/googletest/googletest
-  PRIVATE third_party/googletest/googlemock/include
-  PRIVATE third_party/googletest/googlemock
-  PRIVATE ${_gRPC_PROTO_GENS_DIR}
-)
-
-target_link_libraries(vector_test
-  ${_gRPC_PROTOBUF_LIBRARIES}
-  ${_gRPC_ALLTARGETS_LIBRARIES}
-  grpc_test_util
-  grpc++
-  grpc
-  gpr_test_util
-  gpr
-  ${_gRPC_GFLAGS_LIBRARIES}
-)
-
-endif (gRPC_BUILD_TESTS)
-if (gRPC_BUILD_TESTS)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
 add_executable(writes_per_rpc_test
@@ -12312,6 +12313,35 @@
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 
+add_executable(duplicate_header_bad_client_test
+  test/core/bad_client/tests/duplicate_header.cc
+)
+
+
+target_include_directories(duplicate_header_bad_client_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
+  PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
+  PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
+  PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
+  PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
+  PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
+)
+
+target_link_libraries(duplicate_header_bad_client_test
+  ${_gRPC_SSL_LIBRARIES}
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  bad_client_test
+  grpc_test_util_unsecure
+  grpc_unsecure
+  gpr_test_util
+  gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
 add_executable(head_of_line_blocking_bad_client_test
   test/core/bad_client/tests/head_of_line_blocking.cc
 )
diff --git a/Makefile b/Makefile
index 3265cea..8556b21 100644
--- a/Makefile
+++ b/Makefile
@@ -418,9 +418,9 @@
 Q = @
 endif
 
-CORE_VERSION = 5.0.0-dev
-CPP_VERSION = 1.9.0-dev
-CSHARP_VERSION = 1.9.0-dev
+CORE_VERSION = 5.0.0
+CPP_VERSION = 1.9.0
+CSHARP_VERSION = 1.9.0
 
 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
 CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@@ -1151,6 +1151,7 @@
 health_service_end2end_test: $(BINDIR)/$(CONFIG)/health_service_end2end_test
 http2_client: $(BINDIR)/$(CONFIG)/http2_client
 hybrid_end2end_test: $(BINDIR)/$(CONFIG)/hybrid_end2end_test
+inlined_vector_test: $(BINDIR)/$(CONFIG)/inlined_vector_test
 inproc_sync_unary_ping_pong_test: $(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test
 interop_client: $(BINDIR)/$(CONFIG)/interop_client
 interop_server: $(BINDIR)/$(CONFIG)/interop_server
@@ -1187,7 +1188,6 @@
 thread_manager_test: $(BINDIR)/$(CONFIG)/thread_manager_test
 thread_stress_test: $(BINDIR)/$(CONFIG)/thread_stress_test
 transport_pid_controller_test: $(BINDIR)/$(CONFIG)/transport_pid_controller_test
-vector_test: $(BINDIR)/$(CONFIG)/vector_test
 writes_per_rpc_test: $(BINDIR)/$(CONFIG)/writes_per_rpc_test
 public_headers_must_be_c89: $(BINDIR)/$(CONFIG)/public_headers_must_be_c89
 gen_hpack_tables: $(BINDIR)/$(CONFIG)/gen_hpack_tables
@@ -1233,6 +1233,7 @@
 boringssl_v3name_test: $(BINDIR)/$(CONFIG)/boringssl_v3name_test
 badreq_bad_client_test: $(BINDIR)/$(CONFIG)/badreq_bad_client_test
 connection_prefix_bad_client_test: $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test
+duplicate_header_bad_client_test: $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test
 head_of_line_blocking_bad_client_test: $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test
 headers_bad_client_test: $(BINDIR)/$(CONFIG)/headers_bad_client_test
 initial_settings_frame_bad_client_test: $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test
@@ -1485,6 +1486,7 @@
   $(BINDIR)/$(CONFIG)/public_headers_must_be_c89 \
   $(BINDIR)/$(CONFIG)/badreq_bad_client_test \
   $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \
+  $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test \
   $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test \
   $(BINDIR)/$(CONFIG)/headers_bad_client_test \
   $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test \
@@ -1594,6 +1596,7 @@
   $(BINDIR)/$(CONFIG)/health_service_end2end_test \
   $(BINDIR)/$(CONFIG)/http2_client \
   $(BINDIR)/$(CONFIG)/hybrid_end2end_test \
+  $(BINDIR)/$(CONFIG)/inlined_vector_test \
   $(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test \
   $(BINDIR)/$(CONFIG)/interop_client \
   $(BINDIR)/$(CONFIG)/interop_server \
@@ -1630,7 +1633,6 @@
   $(BINDIR)/$(CONFIG)/thread_manager_test \
   $(BINDIR)/$(CONFIG)/thread_stress_test \
   $(BINDIR)/$(CONFIG)/transport_pid_controller_test \
-  $(BINDIR)/$(CONFIG)/vector_test \
   $(BINDIR)/$(CONFIG)/writes_per_rpc_test \
   $(BINDIR)/$(CONFIG)/boringssl_aes_test \
   $(BINDIR)/$(CONFIG)/boringssl_asn1_test \
@@ -1726,6 +1728,7 @@
   $(BINDIR)/$(CONFIG)/health_service_end2end_test \
   $(BINDIR)/$(CONFIG)/http2_client \
   $(BINDIR)/$(CONFIG)/hybrid_end2end_test \
+  $(BINDIR)/$(CONFIG)/inlined_vector_test \
   $(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test \
   $(BINDIR)/$(CONFIG)/interop_client \
   $(BINDIR)/$(CONFIG)/interop_server \
@@ -1762,7 +1765,6 @@
   $(BINDIR)/$(CONFIG)/thread_manager_test \
   $(BINDIR)/$(CONFIG)/thread_stress_test \
   $(BINDIR)/$(CONFIG)/transport_pid_controller_test \
-  $(BINDIR)/$(CONFIG)/vector_test \
   $(BINDIR)/$(CONFIG)/writes_per_rpc_test \
   $(BINDIR)/$(CONFIG)/resolver_component_test_unsecure \
   $(BINDIR)/$(CONFIG)/resolver_component_test \
@@ -2023,6 +2025,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/badreq_bad_client_test || ( echo test badreq_bad_client_test failed ; exit 1 )
 	$(E) "[RUN]     Testing connection_prefix_bad_client_test"
 	$(Q) $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test || ( echo test connection_prefix_bad_client_test failed ; exit 1 )
+	$(E) "[RUN]     Testing duplicate_header_bad_client_test"
+	$(Q) $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test || ( echo test duplicate_header_bad_client_test failed ; exit 1 )
 	$(E) "[RUN]     Testing head_of_line_blocking_bad_client_test"
 	$(Q) $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test || ( echo test head_of_line_blocking_bad_client_test failed ; exit 1 )
 	$(E) "[RUN]     Testing headers_bad_client_test"
@@ -2135,6 +2139,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/h2_ssl_cert_test || ( echo test h2_ssl_cert_test failed ; exit 1 )
 	$(E) "[RUN]     Testing health_service_end2end_test"
 	$(Q) $(BINDIR)/$(CONFIG)/health_service_end2end_test || ( echo test health_service_end2end_test failed ; exit 1 )
+	$(E) "[RUN]     Testing inlined_vector_test"
+	$(Q) $(BINDIR)/$(CONFIG)/inlined_vector_test || ( echo test inlined_vector_test failed ; exit 1 )
 	$(E) "[RUN]     Testing inproc_sync_unary_ping_pong_test"
 	$(Q) $(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test || ( echo test inproc_sync_unary_ping_pong_test failed ; exit 1 )
 	$(E) "[RUN]     Testing interop_test"
@@ -2185,8 +2191,6 @@
 	$(Q) $(BINDIR)/$(CONFIG)/thread_stress_test || ( echo test thread_stress_test failed ; exit 1 )
 	$(E) "[RUN]     Testing transport_pid_controller_test"
 	$(Q) $(BINDIR)/$(CONFIG)/transport_pid_controller_test || ( echo test transport_pid_controller_test failed ; exit 1 )
-	$(E) "[RUN]     Testing vector_test"
-	$(Q) $(BINDIR)/$(CONFIG)/vector_test || ( echo test vector_test failed ; exit 1 )
 	$(E) "[RUN]     Testing writes_per_rpc_test"
 	$(Q) $(BINDIR)/$(CONFIG)/writes_per_rpc_test || ( echo test writes_per_rpc_test failed ; exit 1 )
 	$(E) "[RUN]     Testing resolver_component_tests_runner_invoker_unsecure"
@@ -2840,50 +2844,50 @@
 
 
 LIBGPR_SRC = \
+    src/core/lib/gpr/alloc.cc \
+    src/core/lib/gpr/arena.cc \
+    src/core/lib/gpr/atm.cc \
+    src/core/lib/gpr/avl.cc \
+    src/core/lib/gpr/cmdline.cc \
+    src/core/lib/gpr/cpu_iphone.cc \
+    src/core/lib/gpr/cpu_linux.cc \
+    src/core/lib/gpr/cpu_posix.cc \
+    src/core/lib/gpr/cpu_windows.cc \
+    src/core/lib/gpr/env_linux.cc \
+    src/core/lib/gpr/env_posix.cc \
+    src/core/lib/gpr/env_windows.cc \
+    src/core/lib/gpr/fork.cc \
+    src/core/lib/gpr/host_port.cc \
+    src/core/lib/gpr/log.cc \
+    src/core/lib/gpr/log_android.cc \
+    src/core/lib/gpr/log_linux.cc \
+    src/core/lib/gpr/log_posix.cc \
+    src/core/lib/gpr/log_windows.cc \
+    src/core/lib/gpr/mpscq.cc \
+    src/core/lib/gpr/murmur_hash.cc \
+    src/core/lib/gpr/string.cc \
+    src/core/lib/gpr/string_posix.cc \
+    src/core/lib/gpr/string_util_windows.cc \
+    src/core/lib/gpr/string_windows.cc \
+    src/core/lib/gpr/subprocess_posix.cc \
+    src/core/lib/gpr/subprocess_windows.cc \
+    src/core/lib/gpr/sync.cc \
+    src/core/lib/gpr/sync_posix.cc \
+    src/core/lib/gpr/sync_windows.cc \
+    src/core/lib/gpr/thd.cc \
+    src/core/lib/gpr/thd_posix.cc \
+    src/core/lib/gpr/thd_windows.cc \
+    src/core/lib/gpr/time.cc \
+    src/core/lib/gpr/time_posix.cc \
+    src/core/lib/gpr/time_precise.cc \
+    src/core/lib/gpr/time_windows.cc \
+    src/core/lib/gpr/tls_pthread.cc \
+    src/core/lib/gpr/tmpfile_msys.cc \
+    src/core/lib/gpr/tmpfile_posix.cc \
+    src/core/lib/gpr/tmpfile_windows.cc \
+    src/core/lib/gpr/wrap_memcpy.cc \
     src/core/lib/profiling/basic_timers.cc \
     src/core/lib/profiling/stap_timers.cc \
-    src/core/lib/support/alloc.cc \
-    src/core/lib/support/arena.cc \
-    src/core/lib/support/atm.cc \
-    src/core/lib/support/avl.cc \
-    src/core/lib/support/cmdline.cc \
-    src/core/lib/support/cpu_iphone.cc \
-    src/core/lib/support/cpu_linux.cc \
-    src/core/lib/support/cpu_posix.cc \
-    src/core/lib/support/cpu_windows.cc \
-    src/core/lib/support/env_linux.cc \
-    src/core/lib/support/env_posix.cc \
-    src/core/lib/support/env_windows.cc \
-    src/core/lib/support/fork.cc \
-    src/core/lib/support/host_port.cc \
-    src/core/lib/support/log.cc \
-    src/core/lib/support/log_android.cc \
-    src/core/lib/support/log_linux.cc \
-    src/core/lib/support/log_posix.cc \
-    src/core/lib/support/log_windows.cc \
-    src/core/lib/support/mpscq.cc \
-    src/core/lib/support/murmur_hash.cc \
-    src/core/lib/support/string.cc \
-    src/core/lib/support/string_posix.cc \
-    src/core/lib/support/string_util_windows.cc \
-    src/core/lib/support/string_windows.cc \
-    src/core/lib/support/subprocess_posix.cc \
-    src/core/lib/support/subprocess_windows.cc \
-    src/core/lib/support/sync.cc \
-    src/core/lib/support/sync_posix.cc \
-    src/core/lib/support/sync_windows.cc \
-    src/core/lib/support/thd.cc \
-    src/core/lib/support/thd_posix.cc \
-    src/core/lib/support/thd_windows.cc \
-    src/core/lib/support/time.cc \
-    src/core/lib/support/time_posix.cc \
-    src/core/lib/support/time_precise.cc \
-    src/core/lib/support/time_windows.cc \
-    src/core/lib/support/tls_pthread.cc \
-    src/core/lib/support/tmpfile_msys.cc \
-    src/core/lib/support/tmpfile_posix.cc \
-    src/core/lib/support/tmpfile_windows.cc \
-    src/core/lib/support/wrap_memcpy.cc \
 
 PUBLIC_HEADERS_C += \
     include/grpc/support/alloc.h \
@@ -8798,7 +8802,7 @@
 
 
 ALLOC_TEST_SRC = \
-    test/core/support/alloc_test.cc \
+    test/core/gpr/alloc_test.cc \
 
 ALLOC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(ALLOC_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -8818,7 +8822,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/alloc_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr/alloc_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_alloc_test: $(ALLOC_TEST_OBJS:.o=.dep)
 
@@ -8894,7 +8898,7 @@
 
 
 ARENA_TEST_SRC = \
-    test/core/support/arena_test.cc \
+    test/core/gpr/arena_test.cc \
 
 ARENA_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(ARENA_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -8914,7 +8918,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/arena_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr/arena_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_arena_test: $(ARENA_TEST_OBJS:.o=.dep)
 
@@ -9857,7 +9861,7 @@
 
 
 GPR_AVL_TEST_SRC = \
-    test/core/support/avl_test.cc \
+    test/core/gpr/avl_test.cc \
 
 GPR_AVL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_AVL_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -9877,7 +9881,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/avl_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr/avl_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_gpr_avl_test: $(GPR_AVL_TEST_OBJS:.o=.dep)
 
@@ -9889,7 +9893,7 @@
 
 
 GPR_CMDLINE_TEST_SRC = \
-    test/core/support/cmdline_test.cc \
+    test/core/gpr/cmdline_test.cc \
 
 GPR_CMDLINE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_CMDLINE_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -9909,7 +9913,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/cmdline_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr/cmdline_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_gpr_cmdline_test: $(GPR_CMDLINE_TEST_OBJS:.o=.dep)
 
@@ -9921,7 +9925,7 @@
 
 
 GPR_CPU_TEST_SRC = \
-    test/core/support/cpu_test.cc \
+    test/core/gpr/cpu_test.cc \
 
 GPR_CPU_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_CPU_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -9941,7 +9945,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/cpu_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr/cpu_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_gpr_cpu_test: $(GPR_CPU_TEST_OBJS:.o=.dep)
 
@@ -9953,7 +9957,7 @@
 
 
 GPR_ENV_TEST_SRC = \
-    test/core/support/env_test.cc \
+    test/core/gpr/env_test.cc \
 
 GPR_ENV_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_ENV_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -9973,7 +9977,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/env_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr/env_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_gpr_env_test: $(GPR_ENV_TEST_OBJS:.o=.dep)
 
@@ -9985,7 +9989,7 @@
 
 
 GPR_HOST_PORT_TEST_SRC = \
-    test/core/support/host_port_test.cc \
+    test/core/gpr/host_port_test.cc \
 
 GPR_HOST_PORT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_HOST_PORT_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -10005,7 +10009,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/host_port_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr/host_port_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_gpr_host_port_test: $(GPR_HOST_PORT_TEST_OBJS:.o=.dep)
 
@@ -10017,7 +10021,7 @@
 
 
 GPR_LOG_TEST_SRC = \
-    test/core/support/log_test.cc \
+    test/core/gpr/log_test.cc \
 
 GPR_LOG_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_LOG_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -10037,7 +10041,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/log_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr/log_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_gpr_log_test: $(GPR_LOG_TEST_OBJS:.o=.dep)
 
@@ -10049,7 +10053,7 @@
 
 
 GPR_MANUAL_CONSTRUCTOR_TEST_SRC = \
-    test/core/support/manual_constructor_test.cc \
+    test/core/gpr++/manual_constructor_test.cc \
 
 GPR_MANUAL_CONSTRUCTOR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_MANUAL_CONSTRUCTOR_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -10069,7 +10073,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/manual_constructor_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr++/manual_constructor_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_gpr_manual_constructor_test: $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS:.o=.dep)
 
@@ -10081,7 +10085,7 @@
 
 
 GPR_MPSCQ_TEST_SRC = \
-    test/core/support/mpscq_test.cc \
+    test/core/gpr/mpscq_test.cc \
 
 GPR_MPSCQ_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_MPSCQ_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -10101,7 +10105,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/mpscq_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr/mpscq_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_gpr_mpscq_test: $(GPR_MPSCQ_TEST_OBJS:.o=.dep)
 
@@ -10113,7 +10117,7 @@
 
 
 GPR_SPINLOCK_TEST_SRC = \
-    test/core/support/spinlock_test.cc \
+    test/core/gpr/spinlock_test.cc \
 
 GPR_SPINLOCK_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_SPINLOCK_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -10133,7 +10137,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/spinlock_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr/spinlock_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_gpr_spinlock_test: $(GPR_SPINLOCK_TEST_OBJS:.o=.dep)
 
@@ -10145,7 +10149,7 @@
 
 
 GPR_STRING_TEST_SRC = \
-    test/core/support/string_test.cc \
+    test/core/gpr/string_test.cc \
 
 GPR_STRING_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_STRING_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -10165,7 +10169,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/string_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr/string_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_gpr_string_test: $(GPR_STRING_TEST_OBJS:.o=.dep)
 
@@ -10177,7 +10181,7 @@
 
 
 GPR_SYNC_TEST_SRC = \
-    test/core/support/sync_test.cc \
+    test/core/gpr/sync_test.cc \
 
 GPR_SYNC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_SYNC_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -10197,7 +10201,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/sync_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr/sync_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_gpr_sync_test: $(GPR_SYNC_TEST_OBJS:.o=.dep)
 
@@ -10209,7 +10213,7 @@
 
 
 GPR_THD_TEST_SRC = \
-    test/core/support/thd_test.cc \
+    test/core/gpr/thd_test.cc \
 
 GPR_THD_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_THD_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -10229,7 +10233,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/thd_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr/thd_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_gpr_thd_test: $(GPR_THD_TEST_OBJS:.o=.dep)
 
@@ -10241,7 +10245,7 @@
 
 
 GPR_TIME_TEST_SRC = \
-    test/core/support/time_test.cc \
+    test/core/gpr/time_test.cc \
 
 GPR_TIME_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_TIME_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -10261,7 +10265,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/time_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr/time_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_gpr_time_test: $(GPR_TIME_TEST_OBJS:.o=.dep)
 
@@ -10273,7 +10277,7 @@
 
 
 GPR_TLS_TEST_SRC = \
-    test/core/support/tls_test.cc \
+    test/core/gpr/tls_test.cc \
 
 GPR_TLS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_TLS_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -10293,7 +10297,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/tls_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr/tls_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_gpr_tls_test: $(GPR_TLS_TEST_OBJS:.o=.dep)
 
@@ -10305,7 +10309,7 @@
 
 
 GPR_USEFUL_TEST_SRC = \
-    test/core/support/useful_test.cc \
+    test/core/gpr/useful_test.cc \
 
 GPR_USEFUL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_USEFUL_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -10325,7 +10329,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/useful_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr/useful_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_gpr_useful_test: $(GPR_USEFUL_TEST_OBJS:.o=.dep)
 
@@ -11879,7 +11883,7 @@
 
 
 MURMUR_HASH_TEST_SRC = \
-    test/core/support/murmur_hash_test.cc \
+    test/core/gpr/murmur_hash_test.cc \
 
 MURMUR_HASH_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MURMUR_HASH_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -11899,7 +11903,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/murmur_hash_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr/murmur_hash_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_murmur_hash_test: $(MURMUR_HASH_TEST_OBJS:.o=.dep)
 
@@ -15778,6 +15782,49 @@
 endif
 
 
+INLINED_VECTOR_TEST_SRC = \
+    test/core/gpr++/inlined_vector_test.cc \
+
+INLINED_VECTOR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INLINED_VECTOR_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/inlined_vector_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/inlined_vector_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/inlined_vector_test: $(PROTOBUF_DEP) $(INLINED_VECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(INLINED_VECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/inlined_vector_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/gpr++/inlined_vector_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_inlined_vector_test: $(INLINED_VECTOR_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(INLINED_VECTOR_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 INPROC_SYNC_UNARY_PING_PONG_TEST_SRC = \
     test/cpp/qps/inproc_sync_unary_ping_pong_test.cc \
 
@@ -15970,7 +16017,7 @@
 
 
 MEMORY_TEST_SRC = \
-    test/core/support/memory_test.cc \
+    test/core/gpr++/memory_test.cc \
 
 MEMORY_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MEMORY_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -16001,7 +16048,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/memory_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr++/memory_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_memory_test: $(MEMORY_TEST_OBJS:.o=.dep)
 
@@ -16147,7 +16194,7 @@
 
 
 ORPHANABLE_TEST_SRC = \
-    test/core/support/orphanable_test.cc \
+    test/core/gpr++/orphanable_test.cc \
 
 ORPHANABLE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(ORPHANABLE_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -16178,7 +16225,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/orphanable_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr++/orphanable_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_orphanable_test: $(ORPHANABLE_TEST_OBJS:.o=.dep)
 
@@ -16554,7 +16601,7 @@
 
 
 REF_COUNTED_PTR_TEST_SRC = \
-    test/core/support/ref_counted_ptr_test.cc \
+    test/core/gpr++/ref_counted_ptr_test.cc \
 
 REF_COUNTED_PTR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(REF_COUNTED_PTR_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -16585,7 +16632,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/ref_counted_ptr_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr++/ref_counted_ptr_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_ref_counted_ptr_test: $(REF_COUNTED_PTR_TEST_OBJS:.o=.dep)
 
@@ -16597,7 +16644,7 @@
 
 
 REF_COUNTED_TEST_SRC = \
-    test/core/support/ref_counted_test.cc \
+    test/core/gpr++/ref_counted_test.cc \
 
 REF_COUNTED_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(REF_COUNTED_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -16628,7 +16675,7 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/support/ref_counted_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gpr++/ref_counted_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_ref_counted_test: $(REF_COUNTED_TEST_OBJS:.o=.dep)
 
@@ -17366,49 +17413,6 @@
 endif
 
 
-VECTOR_TEST_SRC = \
-    test/core/support/vector_test.cc \
-
-VECTOR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(VECTOR_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL.
-
-$(BINDIR)/$(CONFIG)/vector_test: openssl_dep_error
-
-else
-
-
-
-
-ifeq ($(NO_PROTOBUF),true)
-
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
-
-$(BINDIR)/$(CONFIG)/vector_test: protobuf_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/vector_test: $(PROTOBUF_DEP) $(VECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(VECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/vector_test
-
-endif
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/support/vector_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-
-deps_vector_test: $(VECTOR_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(VECTOR_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
 WRITES_PER_RPC_TEST_SRC = \
     test/cpp/performance/writes_per_rpc_test.cc \
 
@@ -18726,6 +18730,26 @@
 endif
 
 
+DUPLICATE_HEADER_BAD_CLIENT_TEST_SRC = \
+    test/core/bad_client/tests/duplicate_header.cc \
+
+DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(DUPLICATE_HEADER_BAD_CLIENT_TEST_SRC))))
+
+
+$(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test: $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test
+
+$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/duplicate_header.o:  $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_duplicate_header_bad_client_test: $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_DEPS),true)
+-include $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS:.o=.dep)
+endif
+
+
 HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_SRC = \
     test/core/bad_client/tests/head_of_line_blocking.cc \
 
diff --git a/build.yaml b/build.yaml
index c9adc9b..2367018 100644
--- a/build.yaml
+++ b/build.yaml
@@ -12,9 +12,9 @@
   '#08': Use "-preN" suffixes to identify pre-release versions
   '#09': Per-language overrides are possible with (eg) ruby_version tag here
   '#10': See the expand_version.py for all the quirks here
-  core_version: 5.0.0-dev
+  core_version: 5.0.0
   g_stands_for: glossy
-  version: 1.9.0-dev
+  version: 1.9.0
 filegroups:
 - name: census
   public_headers:
@@ -26,50 +26,50 @@
   - nanopb
 - name: gpr_base
   src:
+  - src/core/lib/gpr/alloc.cc
+  - src/core/lib/gpr/arena.cc
+  - src/core/lib/gpr/atm.cc
+  - src/core/lib/gpr/avl.cc
+  - src/core/lib/gpr/cmdline.cc
+  - src/core/lib/gpr/cpu_iphone.cc
+  - src/core/lib/gpr/cpu_linux.cc
+  - src/core/lib/gpr/cpu_posix.cc
+  - src/core/lib/gpr/cpu_windows.cc
+  - src/core/lib/gpr/env_linux.cc
+  - src/core/lib/gpr/env_posix.cc
+  - src/core/lib/gpr/env_windows.cc
+  - src/core/lib/gpr/fork.cc
+  - src/core/lib/gpr/host_port.cc
+  - src/core/lib/gpr/log.cc
+  - src/core/lib/gpr/log_android.cc
+  - src/core/lib/gpr/log_linux.cc
+  - src/core/lib/gpr/log_posix.cc
+  - src/core/lib/gpr/log_windows.cc
+  - src/core/lib/gpr/mpscq.cc
+  - src/core/lib/gpr/murmur_hash.cc
+  - src/core/lib/gpr/string.cc
+  - src/core/lib/gpr/string_posix.cc
+  - src/core/lib/gpr/string_util_windows.cc
+  - src/core/lib/gpr/string_windows.cc
+  - src/core/lib/gpr/subprocess_posix.cc
+  - src/core/lib/gpr/subprocess_windows.cc
+  - src/core/lib/gpr/sync.cc
+  - src/core/lib/gpr/sync_posix.cc
+  - src/core/lib/gpr/sync_windows.cc
+  - src/core/lib/gpr/thd.cc
+  - src/core/lib/gpr/thd_posix.cc
+  - src/core/lib/gpr/thd_windows.cc
+  - src/core/lib/gpr/time.cc
+  - src/core/lib/gpr/time_posix.cc
+  - src/core/lib/gpr/time_precise.cc
+  - src/core/lib/gpr/time_windows.cc
+  - src/core/lib/gpr/tls_pthread.cc
+  - src/core/lib/gpr/tmpfile_msys.cc
+  - src/core/lib/gpr/tmpfile_posix.cc
+  - src/core/lib/gpr/tmpfile_windows.cc
+  - src/core/lib/gpr/wrap_memcpy.cc
   - src/core/lib/profiling/basic_timers.cc
   - src/core/lib/profiling/stap_timers.cc
-  - src/core/lib/support/alloc.cc
-  - src/core/lib/support/arena.cc
-  - src/core/lib/support/atm.cc
-  - src/core/lib/support/avl.cc
-  - src/core/lib/support/cmdline.cc
-  - src/core/lib/support/cpu_iphone.cc
-  - src/core/lib/support/cpu_linux.cc
-  - src/core/lib/support/cpu_posix.cc
-  - src/core/lib/support/cpu_windows.cc
-  - src/core/lib/support/env_linux.cc
-  - src/core/lib/support/env_posix.cc
-  - src/core/lib/support/env_windows.cc
-  - src/core/lib/support/fork.cc
-  - src/core/lib/support/host_port.cc
-  - src/core/lib/support/log.cc
-  - src/core/lib/support/log_android.cc
-  - src/core/lib/support/log_linux.cc
-  - src/core/lib/support/log_posix.cc
-  - src/core/lib/support/log_windows.cc
-  - src/core/lib/support/mpscq.cc
-  - src/core/lib/support/murmur_hash.cc
-  - src/core/lib/support/string.cc
-  - src/core/lib/support/string_posix.cc
-  - src/core/lib/support/string_util_windows.cc
-  - src/core/lib/support/string_windows.cc
-  - src/core/lib/support/subprocess_posix.cc
-  - src/core/lib/support/subprocess_windows.cc
-  - src/core/lib/support/sync.cc
-  - src/core/lib/support/sync_posix.cc
-  - src/core/lib/support/sync_windows.cc
-  - src/core/lib/support/thd.cc
-  - src/core/lib/support/thd_posix.cc
-  - src/core/lib/support/thd_windows.cc
-  - src/core/lib/support/time.cc
-  - src/core/lib/support/time_posix.cc
-  - src/core/lib/support/time_precise.cc
-  - src/core/lib/support/time_windows.cc
-  - src/core/lib/support/tls_pthread.cc
-  - src/core/lib/support/tmpfile_msys.cc
-  - src/core/lib/support/tmpfile_posix.cc
-  - src/core/lib/support/tmpfile_windows.cc
-  - src/core/lib/support/wrap_memcpy.cc
   uses:
   - gpr_base_headers
 - name: gpr_base_headers
@@ -101,24 +101,24 @@
   - include/grpc/support/tls_pthread.h
   - include/grpc/support/useful.h
   headers:
+  - src/core/lib/gpr++/abstract.h
+  - src/core/lib/gpr++/atomic.h
+  - src/core/lib/gpr++/atomic_with_atm.h
+  - src/core/lib/gpr++/atomic_with_std.h
+  - src/core/lib/gpr++/manual_constructor.h
+  - src/core/lib/gpr++/memory.h
+  - src/core/lib/gpr/arena.h
+  - src/core/lib/gpr/env.h
+  - src/core/lib/gpr/fork.h
+  - src/core/lib/gpr/mpscq.h
+  - src/core/lib/gpr/murmur_hash.h
+  - src/core/lib/gpr/spinlock.h
+  - src/core/lib/gpr/string.h
+  - src/core/lib/gpr/string_windows.h
+  - src/core/lib/gpr/thd_internal.h
+  - src/core/lib/gpr/time_precise.h
+  - src/core/lib/gpr/tmpfile.h
   - src/core/lib/profiling/timers.h
-  - src/core/lib/support/abstract.h
-  - src/core/lib/support/arena.h
-  - src/core/lib/support/atomic.h
-  - src/core/lib/support/atomic_with_atm.h
-  - src/core/lib/support/atomic_with_std.h
-  - src/core/lib/support/env.h
-  - src/core/lib/support/fork.h
-  - src/core/lib/support/manual_constructor.h
-  - src/core/lib/support/memory.h
-  - src/core/lib/support/mpscq.h
-  - src/core/lib/support/murmur_hash.h
-  - src/core/lib/support/spinlock.h
-  - src/core/lib/support/string.h
-  - src/core/lib/support/string_windows.h
-  - src/core/lib/support/thd_internal.h
-  - src/core/lib/support/time_precise.h
-  - src/core/lib/support/tmpfile.h
   uses:
   - gpr_codegen
 - name: gpr_codegen
@@ -321,6 +321,11 @@
   - src/core/lib/compression/stream_compression_identity.h
   - src/core/lib/debug/stats.h
   - src/core/lib/debug/stats_data.h
+  - src/core/lib/gpr++/debug_location.h
+  - src/core/lib/gpr++/inlined_vector.h
+  - src/core/lib/gpr++/orphanable.h
+  - src/core/lib/gpr++/ref_counted.h
+  - src/core/lib/gpr++/ref_counted_ptr.h
   - src/core/lib/http/format_request.h
   - src/core/lib/http/httpcli.h
   - src/core/lib/http/parser.h
@@ -396,11 +401,6 @@
   - src/core/lib/slice/slice_hash_table.h
   - src/core/lib/slice/slice_internal.h
   - src/core/lib/slice/slice_string_helpers.h
-  - src/core/lib/support/debug_location.h
-  - src/core/lib/support/orphanable.h
-  - src/core/lib/support/ref_counted.h
-  - src/core/lib/support/ref_counted_ptr.h
-  - src/core/lib/support/vector.h
   - src/core/lib/surface/alarm_internal.h
   - src/core/lib/surface/api_trace.h
   - src/core/lib/surface/call.h
@@ -1732,7 +1732,7 @@
   build: test
   language: c
   src:
-  - test/core/support/alloc_test.cc
+  - test/core/gpr/alloc_test.cc
   deps:
   - gpr_test_util
   - gpr
@@ -1765,7 +1765,7 @@
   build: test
   language: c
   src:
-  - test/core/support/arena_test.cc
+  - test/core/gpr/arena_test.cc
   deps:
   - gpr_test_util
   - gpr
@@ -2132,7 +2132,7 @@
   build: test
   language: c
   src:
-  - test/core/support/avl_test.cc
+  - test/core/gpr/avl_test.cc
   deps:
   - gpr_test_util
   - gpr
@@ -2141,7 +2141,7 @@
   build: test
   language: c
   src:
-  - test/core/support/cmdline_test.cc
+  - test/core/gpr/cmdline_test.cc
   deps:
   - gpr_test_util
   - gpr
@@ -2151,7 +2151,7 @@
   build: test
   language: c
   src:
-  - test/core/support/cpu_test.cc
+  - test/core/gpr/cpu_test.cc
   deps:
   - gpr_test_util
   - gpr
@@ -2160,7 +2160,7 @@
   build: test
   language: c
   src:
-  - test/core/support/env_test.cc
+  - test/core/gpr/env_test.cc
   deps:
   - gpr_test_util
   - gpr
@@ -2169,7 +2169,7 @@
   build: test
   language: c
   src:
-  - test/core/support/host_port_test.cc
+  - test/core/gpr/host_port_test.cc
   deps:
   - gpr_test_util
   - gpr
@@ -2178,7 +2178,7 @@
   build: test
   language: c
   src:
-  - test/core/support/log_test.cc
+  - test/core/gpr/log_test.cc
   deps:
   - gpr_test_util
   - gpr
@@ -2188,7 +2188,7 @@
   build: test
   language: c
   src:
-  - test/core/support/manual_constructor_test.cc
+  - test/core/gpr++/manual_constructor_test.cc
   deps:
   - gpr_test_util
   - gpr
@@ -2198,7 +2198,7 @@
   build: test
   language: c
   src:
-  - test/core/support/mpscq_test.cc
+  - test/core/gpr/mpscq_test.cc
   deps:
   - gpr_test_util
   - gpr
@@ -2208,7 +2208,7 @@
   build: test
   language: c
   src:
-  - test/core/support/spinlock_test.cc
+  - test/core/gpr/spinlock_test.cc
   deps:
   - gpr_test_util
   - gpr
@@ -2217,7 +2217,7 @@
   build: test
   language: c
   src:
-  - test/core/support/string_test.cc
+  - test/core/gpr/string_test.cc
   deps:
   - gpr_test_util
   - gpr
@@ -2227,7 +2227,7 @@
   build: test
   language: c
   src:
-  - test/core/support/sync_test.cc
+  - test/core/gpr/sync_test.cc
   deps:
   - gpr_test_util
   - gpr
@@ -2237,7 +2237,7 @@
   build: test
   language: c
   src:
-  - test/core/support/thd_test.cc
+  - test/core/gpr/thd_test.cc
   deps:
   - gpr_test_util
   - gpr
@@ -2246,7 +2246,7 @@
   build: test
   language: c
   src:
-  - test/core/support/time_test.cc
+  - test/core/gpr/time_test.cc
   deps:
   - gpr_test_util
   - gpr
@@ -2255,7 +2255,7 @@
   build: test
   language: c
   src:
-  - test/core/support/tls_test.cc
+  - test/core/gpr/tls_test.cc
   deps:
   - gpr_test_util
   - gpr
@@ -2264,7 +2264,7 @@
   build: test
   language: c
   src:
-  - test/core/support/useful_test.cc
+  - test/core/gpr/useful_test.cc
   deps:
   - gpr_test_util
   - gpr
@@ -2833,7 +2833,7 @@
   build: test
   language: c
   src:
-  - test/core/support/murmur_hash_test.cc
+  - test/core/gpr/murmur_hash_test.cc
   deps:
   - gpr_test_util
   - gpr
@@ -4260,6 +4260,20 @@
   - grpc
   - gpr_test_util
   - gpr
+- name: inlined_vector_test
+  gtest: true
+  build: test
+  language: c++
+  src:
+  - test/core/gpr++/inlined_vector_test.cc
+  deps:
+  - grpc_test_util
+  - grpc++
+  - grpc
+  - gpr_test_util
+  - gpr
+  uses:
+  - grpc++_test
 - name: inproc_sync_unary_ping_pong_test
   build: test
   language: c++
@@ -4357,7 +4371,7 @@
   build: test
   language: c++
   src:
-  - test/core/support/memory_test.cc
+  - test/core/gpr++/memory_test.cc
   deps:
   - grpc_test_util
   - grpc++
@@ -4409,7 +4423,7 @@
   build: test
   language: c++
   src:
-  - test/core/support/orphanable_test.cc
+  - test/core/gpr++/orphanable_test.cc
   deps:
   - grpc_test_util
   - grpc++
@@ -4562,7 +4576,7 @@
   build: test
   language: c++
   src:
-  - test/core/support/ref_counted_ptr_test.cc
+  - test/core/gpr++/ref_counted_ptr_test.cc
   deps:
   - grpc_test_util
   - grpc++
@@ -4576,7 +4590,7 @@
   build: test
   language: c++
   src:
-  - test/core/support/ref_counted_test.cc
+  - test/core/gpr++/ref_counted_test.cc
   deps:
   - grpc_test_util
   - grpc++
@@ -4826,20 +4840,6 @@
   - grpc
   - gpr_test_util
   - gpr
-- name: vector_test
-  gtest: true
-  build: test
-  language: c++
-  src:
-  - test/core/support/vector_test.cc
-  deps:
-  - grpc_test_util
-  - grpc++
-  - grpc
-  - gpr_test_util
-  - gpr
-  uses:
-  - grpc++_test
 - name: writes_per_rpc_test
   gtest: true
   cpu_cost: 0.5
diff --git a/cmake/protobuf.cmake b/cmake/protobuf.cmake
index fccabd4..cb799b5 100644
--- a/cmake/protobuf.cmake
+++ b/cmake/protobuf.cmake
@@ -53,6 +53,11 @@
   endif()
 elseif("${gRPC_PROTOBUF_PROVIDER}" STREQUAL "package")
   find_package(Protobuf REQUIRED ${gRPC_PROTOBUF_PACKAGE_TYPE})
+
+  # {Protobuf,PROTOBUF}_FOUND is defined based on find_package type ("MODULE" vs "CONFIG").
+  # For "MODULE", the case has also changed between cmake 3.5 and 3.6.
+  # We use the legacy uppercase version for *_LIBRARIES AND *_INCLUDE_DIRS variables
+  # as newer cmake versions provide them too for backward compatibility.
   if(Protobuf_FOUND OR PROTOBUF_FOUND)
     if(TARGET protobuf::${_gRPC_PROTOBUF_LIBRARY_NAME})
       set(_gRPC_PROTOBUF_LIBRARIES protobuf::${_gRPC_PROTOBUF_LIBRARY_NAME})
diff --git a/config.m4 b/config.m4
index c026b83..54e29cc 100644
--- a/config.m4
+++ b/config.m4
@@ -39,50 +39,50 @@
     src/php/ext/grpc/server.c \
     src/php/ext/grpc/server_credentials.c \
     src/php/ext/grpc/timeval.c \
+    src/core/lib/gpr/alloc.cc \
+    src/core/lib/gpr/arena.cc \
+    src/core/lib/gpr/atm.cc \
+    src/core/lib/gpr/avl.cc \
+    src/core/lib/gpr/cmdline.cc \
+    src/core/lib/gpr/cpu_iphone.cc \
+    src/core/lib/gpr/cpu_linux.cc \
+    src/core/lib/gpr/cpu_posix.cc \
+    src/core/lib/gpr/cpu_windows.cc \
+    src/core/lib/gpr/env_linux.cc \
+    src/core/lib/gpr/env_posix.cc \
+    src/core/lib/gpr/env_windows.cc \
+    src/core/lib/gpr/fork.cc \
+    src/core/lib/gpr/host_port.cc \
+    src/core/lib/gpr/log.cc \
+    src/core/lib/gpr/log_android.cc \
+    src/core/lib/gpr/log_linux.cc \
+    src/core/lib/gpr/log_posix.cc \
+    src/core/lib/gpr/log_windows.cc \
+    src/core/lib/gpr/mpscq.cc \
+    src/core/lib/gpr/murmur_hash.cc \
+    src/core/lib/gpr/string.cc \
+    src/core/lib/gpr/string_posix.cc \
+    src/core/lib/gpr/string_util_windows.cc \
+    src/core/lib/gpr/string_windows.cc \
+    src/core/lib/gpr/subprocess_posix.cc \
+    src/core/lib/gpr/subprocess_windows.cc \
+    src/core/lib/gpr/sync.cc \
+    src/core/lib/gpr/sync_posix.cc \
+    src/core/lib/gpr/sync_windows.cc \
+    src/core/lib/gpr/thd.cc \
+    src/core/lib/gpr/thd_posix.cc \
+    src/core/lib/gpr/thd_windows.cc \
+    src/core/lib/gpr/time.cc \
+    src/core/lib/gpr/time_posix.cc \
+    src/core/lib/gpr/time_precise.cc \
+    src/core/lib/gpr/time_windows.cc \
+    src/core/lib/gpr/tls_pthread.cc \
+    src/core/lib/gpr/tmpfile_msys.cc \
+    src/core/lib/gpr/tmpfile_posix.cc \
+    src/core/lib/gpr/tmpfile_windows.cc \
+    src/core/lib/gpr/wrap_memcpy.cc \
     src/core/lib/profiling/basic_timers.cc \
     src/core/lib/profiling/stap_timers.cc \
-    src/core/lib/support/alloc.cc \
-    src/core/lib/support/arena.cc \
-    src/core/lib/support/atm.cc \
-    src/core/lib/support/avl.cc \
-    src/core/lib/support/cmdline.cc \
-    src/core/lib/support/cpu_iphone.cc \
-    src/core/lib/support/cpu_linux.cc \
-    src/core/lib/support/cpu_posix.cc \
-    src/core/lib/support/cpu_windows.cc \
-    src/core/lib/support/env_linux.cc \
-    src/core/lib/support/env_posix.cc \
-    src/core/lib/support/env_windows.cc \
-    src/core/lib/support/fork.cc \
-    src/core/lib/support/host_port.cc \
-    src/core/lib/support/log.cc \
-    src/core/lib/support/log_android.cc \
-    src/core/lib/support/log_linux.cc \
-    src/core/lib/support/log_posix.cc \
-    src/core/lib/support/log_windows.cc \
-    src/core/lib/support/mpscq.cc \
-    src/core/lib/support/murmur_hash.cc \
-    src/core/lib/support/string.cc \
-    src/core/lib/support/string_posix.cc \
-    src/core/lib/support/string_util_windows.cc \
-    src/core/lib/support/string_windows.cc \
-    src/core/lib/support/subprocess_posix.cc \
-    src/core/lib/support/subprocess_windows.cc \
-    src/core/lib/support/sync.cc \
-    src/core/lib/support/sync_posix.cc \
-    src/core/lib/support/sync_windows.cc \
-    src/core/lib/support/thd.cc \
-    src/core/lib/support/thd_posix.cc \
-    src/core/lib/support/thd_windows.cc \
-    src/core/lib/support/time.cc \
-    src/core/lib/support/time_posix.cc \
-    src/core/lib/support/time_precise.cc \
-    src/core/lib/support/time_windows.cc \
-    src/core/lib/support/tls_pthread.cc \
-    src/core/lib/support/tmpfile_msys.cc \
-    src/core/lib/support/tmpfile_posix.cc \
-    src/core/lib/support/tmpfile_windows.cc \
-    src/core/lib/support/wrap_memcpy.cc \
     src/core/lib/surface/init.cc \
     src/core/lib/backoff/backoff.cc \
     src/core/lib/channel/channel_args.cc \
@@ -678,6 +678,7 @@
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/channel)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/compression)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/debug)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/gpr)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/http)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/iomgr)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/json)
@@ -695,7 +696,6 @@
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/transport)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/util)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/slice)
-  PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/support)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/surface)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/transport)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/plugin_registry)
diff --git a/config.w32 b/config.w32
index cd3a16a..c800314 100644
--- a/config.w32
+++ b/config.w32
@@ -16,50 +16,50 @@
     "src\\php\\ext\\grpc\\server.c " +
     "src\\php\\ext\\grpc\\server_credentials.c " +
     "src\\php\\ext\\grpc\\timeval.c " +
+    "src\\core\\lib\\gpr\\alloc.cc " +
+    "src\\core\\lib\\gpr\\arena.cc " +
+    "src\\core\\lib\\gpr\\atm.cc " +
+    "src\\core\\lib\\gpr\\avl.cc " +
+    "src\\core\\lib\\gpr\\cmdline.cc " +
+    "src\\core\\lib\\gpr\\cpu_iphone.cc " +
+    "src\\core\\lib\\gpr\\cpu_linux.cc " +
+    "src\\core\\lib\\gpr\\cpu_posix.cc " +
+    "src\\core\\lib\\gpr\\cpu_windows.cc " +
+    "src\\core\\lib\\gpr\\env_linux.cc " +
+    "src\\core\\lib\\gpr\\env_posix.cc " +
+    "src\\core\\lib\\gpr\\env_windows.cc " +
+    "src\\core\\lib\\gpr\\fork.cc " +
+    "src\\core\\lib\\gpr\\host_port.cc " +
+    "src\\core\\lib\\gpr\\log.cc " +
+    "src\\core\\lib\\gpr\\log_android.cc " +
+    "src\\core\\lib\\gpr\\log_linux.cc " +
+    "src\\core\\lib\\gpr\\log_posix.cc " +
+    "src\\core\\lib\\gpr\\log_windows.cc " +
+    "src\\core\\lib\\gpr\\mpscq.cc " +
+    "src\\core\\lib\\gpr\\murmur_hash.cc " +
+    "src\\core\\lib\\gpr\\string.cc " +
+    "src\\core\\lib\\gpr\\string_posix.cc " +
+    "src\\core\\lib\\gpr\\string_util_windows.cc " +
+    "src\\core\\lib\\gpr\\string_windows.cc " +
+    "src\\core\\lib\\gpr\\subprocess_posix.cc " +
+    "src\\core\\lib\\gpr\\subprocess_windows.cc " +
+    "src\\core\\lib\\gpr\\sync.cc " +
+    "src\\core\\lib\\gpr\\sync_posix.cc " +
+    "src\\core\\lib\\gpr\\sync_windows.cc " +
+    "src\\core\\lib\\gpr\\thd.cc " +
+    "src\\core\\lib\\gpr\\thd_posix.cc " +
+    "src\\core\\lib\\gpr\\thd_windows.cc " +
+    "src\\core\\lib\\gpr\\time.cc " +
+    "src\\core\\lib\\gpr\\time_posix.cc " +
+    "src\\core\\lib\\gpr\\time_precise.cc " +
+    "src\\core\\lib\\gpr\\time_windows.cc " +
+    "src\\core\\lib\\gpr\\tls_pthread.cc " +
+    "src\\core\\lib\\gpr\\tmpfile_msys.cc " +
+    "src\\core\\lib\\gpr\\tmpfile_posix.cc " +
+    "src\\core\\lib\\gpr\\tmpfile_windows.cc " +
+    "src\\core\\lib\\gpr\\wrap_memcpy.cc " +
     "src\\core\\lib\\profiling\\basic_timers.cc " +
     "src\\core\\lib\\profiling\\stap_timers.cc " +
-    "src\\core\\lib\\support\\alloc.cc " +
-    "src\\core\\lib\\support\\arena.cc " +
-    "src\\core\\lib\\support\\atm.cc " +
-    "src\\core\\lib\\support\\avl.cc " +
-    "src\\core\\lib\\support\\cmdline.cc " +
-    "src\\core\\lib\\support\\cpu_iphone.cc " +
-    "src\\core\\lib\\support\\cpu_linux.cc " +
-    "src\\core\\lib\\support\\cpu_posix.cc " +
-    "src\\core\\lib\\support\\cpu_windows.cc " +
-    "src\\core\\lib\\support\\env_linux.cc " +
-    "src\\core\\lib\\support\\env_posix.cc " +
-    "src\\core\\lib\\support\\env_windows.cc " +
-    "src\\core\\lib\\support\\fork.cc " +
-    "src\\core\\lib\\support\\host_port.cc " +
-    "src\\core\\lib\\support\\log.cc " +
-    "src\\core\\lib\\support\\log_android.cc " +
-    "src\\core\\lib\\support\\log_linux.cc " +
-    "src\\core\\lib\\support\\log_posix.cc " +
-    "src\\core\\lib\\support\\log_windows.cc " +
-    "src\\core\\lib\\support\\mpscq.cc " +
-    "src\\core\\lib\\support\\murmur_hash.cc " +
-    "src\\core\\lib\\support\\string.cc " +
-    "src\\core\\lib\\support\\string_posix.cc " +
-    "src\\core\\lib\\support\\string_util_windows.cc " +
-    "src\\core\\lib\\support\\string_windows.cc " +
-    "src\\core\\lib\\support\\subprocess_posix.cc " +
-    "src\\core\\lib\\support\\subprocess_windows.cc " +
-    "src\\core\\lib\\support\\sync.cc " +
-    "src\\core\\lib\\support\\sync_posix.cc " +
-    "src\\core\\lib\\support\\sync_windows.cc " +
-    "src\\core\\lib\\support\\thd.cc " +
-    "src\\core\\lib\\support\\thd_posix.cc " +
-    "src\\core\\lib\\support\\thd_windows.cc " +
-    "src\\core\\lib\\support\\time.cc " +
-    "src\\core\\lib\\support\\time_posix.cc " +
-    "src\\core\\lib\\support\\time_precise.cc " +
-    "src\\core\\lib\\support\\time_windows.cc " +
-    "src\\core\\lib\\support\\tls_pthread.cc " +
-    "src\\core\\lib\\support\\tmpfile_msys.cc " +
-    "src\\core\\lib\\support\\tmpfile_posix.cc " +
-    "src\\core\\lib\\support\\tmpfile_windows.cc " +
-    "src\\core\\lib\\support\\wrap_memcpy.cc " +
     "src\\core\\lib\\surface\\init.cc " +
     "src\\core\\lib\\backoff\\backoff.cc " +
     "src\\core\\lib\\channel\\channel_args.cc " +
@@ -690,6 +690,7 @@
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\channel");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\compression");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\debug");
+  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\gpr");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\http");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\iomgr");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\json");
@@ -708,7 +709,6 @@
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\transport");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\util");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\slice");
-  FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\support");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\surface");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\transport");
   FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\plugin_registry");
diff --git a/examples/cpp/helloworld/CMakeLists.txt b/examples/cpp/helloworld/CMakeLists.txt
index 49684a1..c3ce4d5 100644
--- a/examples/cpp/helloworld/CMakeLists.txt
+++ b/examples/cpp/helloworld/CMakeLists.txt
@@ -16,15 +16,22 @@
 find_package(Protobuf REQUIRED)

 message(STATUS "Using protobuf ${protobuf_VERSION}")

 

-if(Protobuf_FOUND)

-  # Protobuf_FOUND is set for package type "CONFIG"

-  set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf)

-  set(_PROTOBUF_PROTOC protobuf::protoc)

-elseif(PROTOBUF_FOUND)

-  # PROTOBUF_FOUND is set for package type "MODULE"

-  set(_PROTOBUF_LIBPROTOBUF ${PROTOBUF_LIBRARIES})

-  set(_PROTOBUF_PROTOC ${PROTOBUF_PROTOC_EXECUTABLE})

-  include_directories(${PROTOBUF_INCLUDE_DIRS})

+# {Protobuf,PROTOBUF}_FOUND is defined based on find_package type ("MODULE" vs "CONFIG").

+# For "MODULE", the case has also changed between cmake 3.5 and 3.6.

+# We use the legacy uppercase version for *_LIBRARIES AND *_INCLUDE_DIRS variables

+# as newer cmake versions provide them too for backward compatibility.

+if(Protobuf_FOUND OR PROTOBUF_FOUND)

+  if(TARGET protobuf::libprotobuf)

+    set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf)

+  else()

+    set(_PROTOBUF_LIBPROTOBUF ${PROTOBUF_LIBRARIES})

+    include_directories(${PROTOBUF_INCLUDE_DIRS})

+  endif()

+  if(TARGET protobuf::protoc)

+    set(_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>)

+  else()

+    set(_PROTOBUF_PROTOC ${PROTOBUF_PROTOC_EXECUTABLE})

+  endif()

 else()

   message(WARNING "Failed to locate libprotobuf and protoc!")

 endif()

diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index df5a411..42b0c0e 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -22,7 +22,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC-Core'
-  version = '1.9.0-dev'
+  version = '1.9.0'
   s.version  = version
   s.summary  = 'Core cross-platform gRPC library, written in C'
   s.homepage = 'https://grpc.io'
@@ -84,7 +84,7 @@
     'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"',
     'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"',
     # If we don't set these two settings, `include/grpc/support/time.h` and
-    # `src/core/lib/support/string.h` shadow the system `<time.h>` and `<string.h>`, breaking the
+    # `src/core/lib/gpr/string.h` shadow the system `<time.h>` and `<string.h>`, breaking the
     # build.
     'USE_HEADERMAP' => 'NO',
     'ALWAYS_SEARCH_USER_PATHS' => 'NO',
@@ -192,68 +192,68 @@
     ss.dependency 'nanopb', '~> 0.3'
 
     # To save you from scrolling, this is the last part of the podspec.
-    ss.source_files = 'src/core/lib/profiling/timers.h',
-                      'src/core/lib/support/abstract.h',
-                      'src/core/lib/support/arena.h',
-                      'src/core/lib/support/atomic.h',
-                      'src/core/lib/support/atomic_with_atm.h',
-                      'src/core/lib/support/atomic_with_std.h',
-                      'src/core/lib/support/env.h',
-                      'src/core/lib/support/fork.h',
-                      'src/core/lib/support/manual_constructor.h',
-                      'src/core/lib/support/memory.h',
-                      'src/core/lib/support/mpscq.h',
-                      'src/core/lib/support/murmur_hash.h',
-                      'src/core/lib/support/spinlock.h',
-                      'src/core/lib/support/string.h',
-                      'src/core/lib/support/string_windows.h',
-                      'src/core/lib/support/thd_internal.h',
-                      'src/core/lib/support/time_precise.h',
-                      'src/core/lib/support/tmpfile.h',
+    ss.source_files = 'src/core/lib/gpr++/abstract.h',
+                      'src/core/lib/gpr++/atomic.h',
+                      'src/core/lib/gpr++/atomic_with_atm.h',
+                      'src/core/lib/gpr++/atomic_with_std.h',
+                      'src/core/lib/gpr++/manual_constructor.h',
+                      'src/core/lib/gpr++/memory.h',
+                      'src/core/lib/gpr/arena.h',
+                      'src/core/lib/gpr/env.h',
+                      'src/core/lib/gpr/fork.h',
+                      'src/core/lib/gpr/mpscq.h',
+                      'src/core/lib/gpr/murmur_hash.h',
+                      'src/core/lib/gpr/spinlock.h',
+                      'src/core/lib/gpr/string.h',
+                      'src/core/lib/gpr/string_windows.h',
+                      'src/core/lib/gpr/thd_internal.h',
+                      'src/core/lib/gpr/time_precise.h',
+                      'src/core/lib/gpr/tmpfile.h',
+                      'src/core/lib/profiling/timers.h',
+                      'src/core/lib/gpr/alloc.cc',
+                      'src/core/lib/gpr/arena.cc',
+                      'src/core/lib/gpr/atm.cc',
+                      'src/core/lib/gpr/avl.cc',
+                      'src/core/lib/gpr/cmdline.cc',
+                      'src/core/lib/gpr/cpu_iphone.cc',
+                      'src/core/lib/gpr/cpu_linux.cc',
+                      'src/core/lib/gpr/cpu_posix.cc',
+                      'src/core/lib/gpr/cpu_windows.cc',
+                      'src/core/lib/gpr/env_linux.cc',
+                      'src/core/lib/gpr/env_posix.cc',
+                      'src/core/lib/gpr/env_windows.cc',
+                      'src/core/lib/gpr/fork.cc',
+                      'src/core/lib/gpr/host_port.cc',
+                      'src/core/lib/gpr/log.cc',
+                      'src/core/lib/gpr/log_android.cc',
+                      'src/core/lib/gpr/log_linux.cc',
+                      'src/core/lib/gpr/log_posix.cc',
+                      'src/core/lib/gpr/log_windows.cc',
+                      'src/core/lib/gpr/mpscq.cc',
+                      'src/core/lib/gpr/murmur_hash.cc',
+                      'src/core/lib/gpr/string.cc',
+                      'src/core/lib/gpr/string_posix.cc',
+                      'src/core/lib/gpr/string_util_windows.cc',
+                      'src/core/lib/gpr/string_windows.cc',
+                      'src/core/lib/gpr/subprocess_posix.cc',
+                      'src/core/lib/gpr/subprocess_windows.cc',
+                      'src/core/lib/gpr/sync.cc',
+                      'src/core/lib/gpr/sync_posix.cc',
+                      'src/core/lib/gpr/sync_windows.cc',
+                      'src/core/lib/gpr/thd.cc',
+                      'src/core/lib/gpr/thd_posix.cc',
+                      'src/core/lib/gpr/thd_windows.cc',
+                      'src/core/lib/gpr/time.cc',
+                      'src/core/lib/gpr/time_posix.cc',
+                      'src/core/lib/gpr/time_precise.cc',
+                      'src/core/lib/gpr/time_windows.cc',
+                      'src/core/lib/gpr/tls_pthread.cc',
+                      'src/core/lib/gpr/tmpfile_msys.cc',
+                      'src/core/lib/gpr/tmpfile_posix.cc',
+                      'src/core/lib/gpr/tmpfile_windows.cc',
+                      'src/core/lib/gpr/wrap_memcpy.cc',
                       'src/core/lib/profiling/basic_timers.cc',
                       'src/core/lib/profiling/stap_timers.cc',
-                      'src/core/lib/support/alloc.cc',
-                      'src/core/lib/support/arena.cc',
-                      'src/core/lib/support/atm.cc',
-                      'src/core/lib/support/avl.cc',
-                      'src/core/lib/support/cmdline.cc',
-                      'src/core/lib/support/cpu_iphone.cc',
-                      'src/core/lib/support/cpu_linux.cc',
-                      'src/core/lib/support/cpu_posix.cc',
-                      'src/core/lib/support/cpu_windows.cc',
-                      'src/core/lib/support/env_linux.cc',
-                      'src/core/lib/support/env_posix.cc',
-                      'src/core/lib/support/env_windows.cc',
-                      'src/core/lib/support/fork.cc',
-                      'src/core/lib/support/host_port.cc',
-                      'src/core/lib/support/log.cc',
-                      'src/core/lib/support/log_android.cc',
-                      'src/core/lib/support/log_linux.cc',
-                      'src/core/lib/support/log_posix.cc',
-                      'src/core/lib/support/log_windows.cc',
-                      'src/core/lib/support/mpscq.cc',
-                      'src/core/lib/support/murmur_hash.cc',
-                      'src/core/lib/support/string.cc',
-                      'src/core/lib/support/string_posix.cc',
-                      'src/core/lib/support/string_util_windows.cc',
-                      'src/core/lib/support/string_windows.cc',
-                      'src/core/lib/support/subprocess_posix.cc',
-                      'src/core/lib/support/subprocess_windows.cc',
-                      'src/core/lib/support/sync.cc',
-                      'src/core/lib/support/sync_posix.cc',
-                      'src/core/lib/support/sync_windows.cc',
-                      'src/core/lib/support/thd.cc',
-                      'src/core/lib/support/thd_posix.cc',
-                      'src/core/lib/support/thd_windows.cc',
-                      'src/core/lib/support/time.cc',
-                      'src/core/lib/support/time_posix.cc',
-                      'src/core/lib/support/time_precise.cc',
-                      'src/core/lib/support/time_windows.cc',
-                      'src/core/lib/support/tls_pthread.cc',
-                      'src/core/lib/support/tmpfile_msys.cc',
-                      'src/core/lib/support/tmpfile_posix.cc',
-                      'src/core/lib/support/tmpfile_windows.cc',
-                      'src/core/lib/support/wrap_memcpy.cc',
                       'src/core/ext/transport/chttp2/transport/bin_decoder.h',
                       'src/core/ext/transport/chttp2/transport/bin_encoder.h',
                       'src/core/ext/transport/chttp2/transport/chttp2_transport.h',
@@ -344,6 +344,11 @@
                       'src/core/lib/compression/stream_compression_identity.h',
                       'src/core/lib/debug/stats.h',
                       'src/core/lib/debug/stats_data.h',
+                      'src/core/lib/gpr++/debug_location.h',
+                      'src/core/lib/gpr++/inlined_vector.h',
+                      'src/core/lib/gpr++/orphanable.h',
+                      'src/core/lib/gpr++/ref_counted.h',
+                      'src/core/lib/gpr++/ref_counted_ptr.h',
                       'src/core/lib/http/format_request.h',
                       'src/core/lib/http/httpcli.h',
                       'src/core/lib/http/parser.h',
@@ -419,11 +424,6 @@
                       'src/core/lib/slice/slice_hash_table.h',
                       'src/core/lib/slice/slice_internal.h',
                       'src/core/lib/slice/slice_string_helpers.h',
-                      'src/core/lib/support/debug_location.h',
-                      'src/core/lib/support/orphanable.h',
-                      'src/core/lib/support/ref_counted.h',
-                      'src/core/lib/support/ref_counted_ptr.h',
-                      'src/core/lib/support/vector.h',
                       'src/core/lib/surface/alarm_internal.h',
                       'src/core/lib/surface/api_trace.h',
                       'src/core/lib/surface/call.h',
@@ -718,24 +718,24 @@
                       'src/core/ext/filters/workarounds/workaround_utils.cc',
                       'src/core/plugin_registry/grpc_plugin_registry.cc'
 
-    ss.private_header_files = 'src/core/lib/profiling/timers.h',
-                              'src/core/lib/support/abstract.h',
-                              'src/core/lib/support/arena.h',
-                              'src/core/lib/support/atomic.h',
-                              'src/core/lib/support/atomic_with_atm.h',
-                              'src/core/lib/support/atomic_with_std.h',
-                              'src/core/lib/support/env.h',
-                              'src/core/lib/support/fork.h',
-                              'src/core/lib/support/manual_constructor.h',
-                              'src/core/lib/support/memory.h',
-                              'src/core/lib/support/mpscq.h',
-                              'src/core/lib/support/murmur_hash.h',
-                              'src/core/lib/support/spinlock.h',
-                              'src/core/lib/support/string.h',
-                              'src/core/lib/support/string_windows.h',
-                              'src/core/lib/support/thd_internal.h',
-                              'src/core/lib/support/time_precise.h',
-                              'src/core/lib/support/tmpfile.h',
+    ss.private_header_files = 'src/core/lib/gpr++/abstract.h',
+                              'src/core/lib/gpr++/atomic.h',
+                              'src/core/lib/gpr++/atomic_with_atm.h',
+                              'src/core/lib/gpr++/atomic_with_std.h',
+                              'src/core/lib/gpr++/manual_constructor.h',
+                              'src/core/lib/gpr++/memory.h',
+                              'src/core/lib/gpr/arena.h',
+                              'src/core/lib/gpr/env.h',
+                              'src/core/lib/gpr/fork.h',
+                              'src/core/lib/gpr/mpscq.h',
+                              'src/core/lib/gpr/murmur_hash.h',
+                              'src/core/lib/gpr/spinlock.h',
+                              'src/core/lib/gpr/string.h',
+                              'src/core/lib/gpr/string_windows.h',
+                              'src/core/lib/gpr/thd_internal.h',
+                              'src/core/lib/gpr/time_precise.h',
+                              'src/core/lib/gpr/tmpfile.h',
+                              'src/core/lib/profiling/timers.h',
                               'src/core/ext/transport/chttp2/transport/bin_decoder.h',
                               'src/core/ext/transport/chttp2/transport/bin_encoder.h',
                               'src/core/ext/transport/chttp2/transport/chttp2_transport.h',
@@ -826,6 +826,11 @@
                               'src/core/lib/compression/stream_compression_identity.h',
                               'src/core/lib/debug/stats.h',
                               'src/core/lib/debug/stats_data.h',
+                              'src/core/lib/gpr++/debug_location.h',
+                              'src/core/lib/gpr++/inlined_vector.h',
+                              'src/core/lib/gpr++/orphanable.h',
+                              'src/core/lib/gpr++/ref_counted.h',
+                              'src/core/lib/gpr++/ref_counted_ptr.h',
                               'src/core/lib/http/format_request.h',
                               'src/core/lib/http/httpcli.h',
                               'src/core/lib/http/parser.h',
@@ -901,11 +906,6 @@
                               'src/core/lib/slice/slice_hash_table.h',
                               'src/core/lib/slice/slice_internal.h',
                               'src/core/lib/slice/slice_string_helpers.h',
-                              'src/core/lib/support/debug_location.h',
-                              'src/core/lib/support/orphanable.h',
-                              'src/core/lib/support/ref_counted.h',
-                              'src/core/lib/support/ref_counted_ptr.h',
-                              'src/core/lib/support/vector.h',
                               'src/core/lib/surface/alarm_internal.h',
                               'src/core/lib/surface/api_trace.h',
                               'src/core/lib/surface/call.h',
diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec
index cb1c548..1f021d1 100644
--- a/gRPC-ProtoRPC.podspec
+++ b/gRPC-ProtoRPC.podspec
@@ -21,7 +21,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC-ProtoRPC'
-  version = '1.9.0-dev'
+  version = '1.9.0'
   s.version  = version
   s.summary  = 'RPC library for Protocol Buffers, based on gRPC'
   s.homepage = 'https://grpc.io'
diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec
index 0f9abb6..524e1e3 100644
--- a/gRPC-RxLibrary.podspec
+++ b/gRPC-RxLibrary.podspec
@@ -21,7 +21,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC-RxLibrary'
-  version = '1.9.0-dev'
+  version = '1.9.0'
   s.version  = version
   s.summary  = 'Reactive Extensions library for iOS/OSX.'
   s.homepage = 'https://grpc.io'
diff --git a/gRPC.podspec b/gRPC.podspec
index 1f3a0a9..b52cf43 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -20,7 +20,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC'
-  version = '1.9.0-dev'
+  version = '1.9.0'
   s.version  = version
   s.summary  = 'gRPC client library for iOS/OSX'
   s.homepage = 'https://grpc.io'
diff --git a/grpc.gemspec b/grpc.gemspec
index f8afaa5..5b1aebe 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -83,68 +83,68 @@
   s.files += %w( include/grpc/impl/codegen/sync_generic.h )
   s.files += %w( include/grpc/impl/codegen/sync_posix.h )
   s.files += %w( include/grpc/impl/codegen/sync_windows.h )
+  s.files += %w( src/core/lib/gpr++/abstract.h )
+  s.files += %w( src/core/lib/gpr++/atomic.h )
+  s.files += %w( src/core/lib/gpr++/atomic_with_atm.h )
+  s.files += %w( src/core/lib/gpr++/atomic_with_std.h )
+  s.files += %w( src/core/lib/gpr++/manual_constructor.h )
+  s.files += %w( src/core/lib/gpr++/memory.h )
+  s.files += %w( src/core/lib/gpr/arena.h )
+  s.files += %w( src/core/lib/gpr/env.h )
+  s.files += %w( src/core/lib/gpr/fork.h )
+  s.files += %w( src/core/lib/gpr/mpscq.h )
+  s.files += %w( src/core/lib/gpr/murmur_hash.h )
+  s.files += %w( src/core/lib/gpr/spinlock.h )
+  s.files += %w( src/core/lib/gpr/string.h )
+  s.files += %w( src/core/lib/gpr/string_windows.h )
+  s.files += %w( src/core/lib/gpr/thd_internal.h )
+  s.files += %w( src/core/lib/gpr/time_precise.h )
+  s.files += %w( src/core/lib/gpr/tmpfile.h )
   s.files += %w( src/core/lib/profiling/timers.h )
-  s.files += %w( src/core/lib/support/abstract.h )
-  s.files += %w( src/core/lib/support/arena.h )
-  s.files += %w( src/core/lib/support/atomic.h )
-  s.files += %w( src/core/lib/support/atomic_with_atm.h )
-  s.files += %w( src/core/lib/support/atomic_with_std.h )
-  s.files += %w( src/core/lib/support/env.h )
-  s.files += %w( src/core/lib/support/fork.h )
-  s.files += %w( src/core/lib/support/manual_constructor.h )
-  s.files += %w( src/core/lib/support/memory.h )
-  s.files += %w( src/core/lib/support/mpscq.h )
-  s.files += %w( src/core/lib/support/murmur_hash.h )
-  s.files += %w( src/core/lib/support/spinlock.h )
-  s.files += %w( src/core/lib/support/string.h )
-  s.files += %w( src/core/lib/support/string_windows.h )
-  s.files += %w( src/core/lib/support/thd_internal.h )
-  s.files += %w( src/core/lib/support/time_precise.h )
-  s.files += %w( src/core/lib/support/tmpfile.h )
+  s.files += %w( src/core/lib/gpr/alloc.cc )
+  s.files += %w( src/core/lib/gpr/arena.cc )
+  s.files += %w( src/core/lib/gpr/atm.cc )
+  s.files += %w( src/core/lib/gpr/avl.cc )
+  s.files += %w( src/core/lib/gpr/cmdline.cc )
+  s.files += %w( src/core/lib/gpr/cpu_iphone.cc )
+  s.files += %w( src/core/lib/gpr/cpu_linux.cc )
+  s.files += %w( src/core/lib/gpr/cpu_posix.cc )
+  s.files += %w( src/core/lib/gpr/cpu_windows.cc )
+  s.files += %w( src/core/lib/gpr/env_linux.cc )
+  s.files += %w( src/core/lib/gpr/env_posix.cc )
+  s.files += %w( src/core/lib/gpr/env_windows.cc )
+  s.files += %w( src/core/lib/gpr/fork.cc )
+  s.files += %w( src/core/lib/gpr/host_port.cc )
+  s.files += %w( src/core/lib/gpr/log.cc )
+  s.files += %w( src/core/lib/gpr/log_android.cc )
+  s.files += %w( src/core/lib/gpr/log_linux.cc )
+  s.files += %w( src/core/lib/gpr/log_posix.cc )
+  s.files += %w( src/core/lib/gpr/log_windows.cc )
+  s.files += %w( src/core/lib/gpr/mpscq.cc )
+  s.files += %w( src/core/lib/gpr/murmur_hash.cc )
+  s.files += %w( src/core/lib/gpr/string.cc )
+  s.files += %w( src/core/lib/gpr/string_posix.cc )
+  s.files += %w( src/core/lib/gpr/string_util_windows.cc )
+  s.files += %w( src/core/lib/gpr/string_windows.cc )
+  s.files += %w( src/core/lib/gpr/subprocess_posix.cc )
+  s.files += %w( src/core/lib/gpr/subprocess_windows.cc )
+  s.files += %w( src/core/lib/gpr/sync.cc )
+  s.files += %w( src/core/lib/gpr/sync_posix.cc )
+  s.files += %w( src/core/lib/gpr/sync_windows.cc )
+  s.files += %w( src/core/lib/gpr/thd.cc )
+  s.files += %w( src/core/lib/gpr/thd_posix.cc )
+  s.files += %w( src/core/lib/gpr/thd_windows.cc )
+  s.files += %w( src/core/lib/gpr/time.cc )
+  s.files += %w( src/core/lib/gpr/time_posix.cc )
+  s.files += %w( src/core/lib/gpr/time_precise.cc )
+  s.files += %w( src/core/lib/gpr/time_windows.cc )
+  s.files += %w( src/core/lib/gpr/tls_pthread.cc )
+  s.files += %w( src/core/lib/gpr/tmpfile_msys.cc )
+  s.files += %w( src/core/lib/gpr/tmpfile_posix.cc )
+  s.files += %w( src/core/lib/gpr/tmpfile_windows.cc )
+  s.files += %w( src/core/lib/gpr/wrap_memcpy.cc )
   s.files += %w( src/core/lib/profiling/basic_timers.cc )
   s.files += %w( src/core/lib/profiling/stap_timers.cc )
-  s.files += %w( src/core/lib/support/alloc.cc )
-  s.files += %w( src/core/lib/support/arena.cc )
-  s.files += %w( src/core/lib/support/atm.cc )
-  s.files += %w( src/core/lib/support/avl.cc )
-  s.files += %w( src/core/lib/support/cmdline.cc )
-  s.files += %w( src/core/lib/support/cpu_iphone.cc )
-  s.files += %w( src/core/lib/support/cpu_linux.cc )
-  s.files += %w( src/core/lib/support/cpu_posix.cc )
-  s.files += %w( src/core/lib/support/cpu_windows.cc )
-  s.files += %w( src/core/lib/support/env_linux.cc )
-  s.files += %w( src/core/lib/support/env_posix.cc )
-  s.files += %w( src/core/lib/support/env_windows.cc )
-  s.files += %w( src/core/lib/support/fork.cc )
-  s.files += %w( src/core/lib/support/host_port.cc )
-  s.files += %w( src/core/lib/support/log.cc )
-  s.files += %w( src/core/lib/support/log_android.cc )
-  s.files += %w( src/core/lib/support/log_linux.cc )
-  s.files += %w( src/core/lib/support/log_posix.cc )
-  s.files += %w( src/core/lib/support/log_windows.cc )
-  s.files += %w( src/core/lib/support/mpscq.cc )
-  s.files += %w( src/core/lib/support/murmur_hash.cc )
-  s.files += %w( src/core/lib/support/string.cc )
-  s.files += %w( src/core/lib/support/string_posix.cc )
-  s.files += %w( src/core/lib/support/string_util_windows.cc )
-  s.files += %w( src/core/lib/support/string_windows.cc )
-  s.files += %w( src/core/lib/support/subprocess_posix.cc )
-  s.files += %w( src/core/lib/support/subprocess_windows.cc )
-  s.files += %w( src/core/lib/support/sync.cc )
-  s.files += %w( src/core/lib/support/sync_posix.cc )
-  s.files += %w( src/core/lib/support/sync_windows.cc )
-  s.files += %w( src/core/lib/support/thd.cc )
-  s.files += %w( src/core/lib/support/thd_posix.cc )
-  s.files += %w( src/core/lib/support/thd_windows.cc )
-  s.files += %w( src/core/lib/support/time.cc )
-  s.files += %w( src/core/lib/support/time_posix.cc )
-  s.files += %w( src/core/lib/support/time_precise.cc )
-  s.files += %w( src/core/lib/support/time_windows.cc )
-  s.files += %w( src/core/lib/support/tls_pthread.cc )
-  s.files += %w( src/core/lib/support/tmpfile_msys.cc )
-  s.files += %w( src/core/lib/support/tmpfile_posix.cc )
-  s.files += %w( src/core/lib/support/tmpfile_windows.cc )
-  s.files += %w( src/core/lib/support/wrap_memcpy.cc )
   s.files += %w( include/grpc/impl/codegen/byte_buffer.h )
   s.files += %w( include/grpc/impl/codegen/byte_buffer_reader.h )
   s.files += %w( include/grpc/impl/codegen/compression_types.h )
@@ -270,6 +270,11 @@
   s.files += %w( src/core/lib/compression/stream_compression_identity.h )
   s.files += %w( src/core/lib/debug/stats.h )
   s.files += %w( src/core/lib/debug/stats_data.h )
+  s.files += %w( src/core/lib/gpr++/debug_location.h )
+  s.files += %w( src/core/lib/gpr++/inlined_vector.h )
+  s.files += %w( src/core/lib/gpr++/orphanable.h )
+  s.files += %w( src/core/lib/gpr++/ref_counted.h )
+  s.files += %w( src/core/lib/gpr++/ref_counted_ptr.h )
   s.files += %w( src/core/lib/http/format_request.h )
   s.files += %w( src/core/lib/http/httpcli.h )
   s.files += %w( src/core/lib/http/parser.h )
@@ -345,11 +350,6 @@
   s.files += %w( src/core/lib/slice/slice_hash_table.h )
   s.files += %w( src/core/lib/slice/slice_internal.h )
   s.files += %w( src/core/lib/slice/slice_string_helpers.h )
-  s.files += %w( src/core/lib/support/debug_location.h )
-  s.files += %w( src/core/lib/support/orphanable.h )
-  s.files += %w( src/core/lib/support/ref_counted.h )
-  s.files += %w( src/core/lib/support/ref_counted_ptr.h )
-  s.files += %w( src/core/lib/support/vector.h )
   s.files += %w( src/core/lib/surface/alarm_internal.h )
   s.files += %w( src/core/lib/surface/api_trace.h )
   s.files += %w( src/core/lib/surface/call.h )
diff --git a/grpc.gyp b/grpc.gyp
index 281fbfa..49dcdf9 100644
--- a/grpc.gyp
+++ b/grpc.gyp
@@ -161,50 +161,50 @@
       'dependencies': [
       ],
       'sources': [
+        'src/core/lib/gpr/alloc.cc',
+        'src/core/lib/gpr/arena.cc',
+        'src/core/lib/gpr/atm.cc',
+        'src/core/lib/gpr/avl.cc',
+        'src/core/lib/gpr/cmdline.cc',
+        'src/core/lib/gpr/cpu_iphone.cc',
+        'src/core/lib/gpr/cpu_linux.cc',
+        'src/core/lib/gpr/cpu_posix.cc',
+        'src/core/lib/gpr/cpu_windows.cc',
+        'src/core/lib/gpr/env_linux.cc',
+        'src/core/lib/gpr/env_posix.cc',
+        'src/core/lib/gpr/env_windows.cc',
+        'src/core/lib/gpr/fork.cc',
+        'src/core/lib/gpr/host_port.cc',
+        'src/core/lib/gpr/log.cc',
+        'src/core/lib/gpr/log_android.cc',
+        'src/core/lib/gpr/log_linux.cc',
+        'src/core/lib/gpr/log_posix.cc',
+        'src/core/lib/gpr/log_windows.cc',
+        'src/core/lib/gpr/mpscq.cc',
+        'src/core/lib/gpr/murmur_hash.cc',
+        'src/core/lib/gpr/string.cc',
+        'src/core/lib/gpr/string_posix.cc',
+        'src/core/lib/gpr/string_util_windows.cc',
+        'src/core/lib/gpr/string_windows.cc',
+        'src/core/lib/gpr/subprocess_posix.cc',
+        'src/core/lib/gpr/subprocess_windows.cc',
+        'src/core/lib/gpr/sync.cc',
+        'src/core/lib/gpr/sync_posix.cc',
+        'src/core/lib/gpr/sync_windows.cc',
+        'src/core/lib/gpr/thd.cc',
+        'src/core/lib/gpr/thd_posix.cc',
+        'src/core/lib/gpr/thd_windows.cc',
+        'src/core/lib/gpr/time.cc',
+        'src/core/lib/gpr/time_posix.cc',
+        'src/core/lib/gpr/time_precise.cc',
+        'src/core/lib/gpr/time_windows.cc',
+        'src/core/lib/gpr/tls_pthread.cc',
+        'src/core/lib/gpr/tmpfile_msys.cc',
+        'src/core/lib/gpr/tmpfile_posix.cc',
+        'src/core/lib/gpr/tmpfile_windows.cc',
+        'src/core/lib/gpr/wrap_memcpy.cc',
         'src/core/lib/profiling/basic_timers.cc',
         'src/core/lib/profiling/stap_timers.cc',
-        'src/core/lib/support/alloc.cc',
-        'src/core/lib/support/arena.cc',
-        'src/core/lib/support/atm.cc',
-        'src/core/lib/support/avl.cc',
-        'src/core/lib/support/cmdline.cc',
-        'src/core/lib/support/cpu_iphone.cc',
-        'src/core/lib/support/cpu_linux.cc',
-        'src/core/lib/support/cpu_posix.cc',
-        'src/core/lib/support/cpu_windows.cc',
-        'src/core/lib/support/env_linux.cc',
-        'src/core/lib/support/env_posix.cc',
-        'src/core/lib/support/env_windows.cc',
-        'src/core/lib/support/fork.cc',
-        'src/core/lib/support/host_port.cc',
-        'src/core/lib/support/log.cc',
-        'src/core/lib/support/log_android.cc',
-        'src/core/lib/support/log_linux.cc',
-        'src/core/lib/support/log_posix.cc',
-        'src/core/lib/support/log_windows.cc',
-        'src/core/lib/support/mpscq.cc',
-        'src/core/lib/support/murmur_hash.cc',
-        'src/core/lib/support/string.cc',
-        'src/core/lib/support/string_posix.cc',
-        'src/core/lib/support/string_util_windows.cc',
-        'src/core/lib/support/string_windows.cc',
-        'src/core/lib/support/subprocess_posix.cc',
-        'src/core/lib/support/subprocess_windows.cc',
-        'src/core/lib/support/sync.cc',
-        'src/core/lib/support/sync_posix.cc',
-        'src/core/lib/support/sync_windows.cc',
-        'src/core/lib/support/thd.cc',
-        'src/core/lib/support/thd_posix.cc',
-        'src/core/lib/support/thd_windows.cc',
-        'src/core/lib/support/time.cc',
-        'src/core/lib/support/time_posix.cc',
-        'src/core/lib/support/time_precise.cc',
-        'src/core/lib/support/time_windows.cc',
-        'src/core/lib/support/tls_pthread.cc',
-        'src/core/lib/support/tmpfile_msys.cc',
-        'src/core/lib/support/tmpfile_posix.cc',
-        'src/core/lib/support/tmpfile_windows.cc',
-        'src/core/lib/support/wrap_memcpy.cc',
       ],
     },
     {
diff --git a/package.xml b/package.xml
index 8c59034..ac2c597 100644
--- a/package.xml
+++ b/package.xml
@@ -10,24 +10,22 @@
   <email>grpc-packages@google.com</email>
   <active>yes</active>
  </lead>
- <date>2017-08-24</date>
+ <date>2018-01-23</date>
  <time>16:06:07</time>
  <version>
-  <release>1.9.0dev</release>
-  <api>1.9.0dev</api>
+  <release>1.9.0</release>
+  <api>1.9.0</api>
  </version>
  <stability>
-  <release>beta</release>
-  <api>beta</api>
+  <release>stable</release>
+  <api>stable</api>
  </stability>
  <license>Apache 2.0</license>
  <notes>
-- Channel are now by default persistent #11878
-- Some bug fixes from 1.4 branch #12109, #12123
-- Fixed hang bug when fork() was used #11814
-- License changed to Apache 2.0
-- Added support for php_namespace option in codegen plugin #11886
-- Updated gRPC C Core library version 1.6
+- Updated gRPC C Core library version 1.9
+- Report grpc extension version in phpinfo() #13687
+- Fixed memory leak when handling metadata array #13660
+- Fixed memory involing persistent channels #14125 - #14130
  </notes>
  <contents>
   <dir baseinstalldir="/" name="/">
@@ -95,68 +93,68 @@
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_generic.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_posix.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_windows.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr++/abstract.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr++/atomic.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr++/atomic_with_atm.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr++/atomic_with_std.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr++/manual_constructor.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr++/memory.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/arena.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/env.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/fork.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/mpscq.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/murmur_hash.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/spinlock.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/string.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/string_windows.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/thd_internal.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/time_precise.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/tmpfile.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/profiling/timers.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/abstract.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/arena.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/atomic.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/atomic_with_atm.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/atomic_with_std.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/env.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/fork.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/manual_constructor.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/memory.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/mpscq.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/murmur_hash.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/spinlock.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/string.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/string_windows.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/thd_internal.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/time_precise.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/tmpfile.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/alloc.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/arena.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/atm.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/avl.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/cmdline.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/cpu_iphone.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/cpu_linux.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/cpu_posix.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/cpu_windows.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/env_linux.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/env_posix.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/env_windows.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/fork.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/host_port.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/log.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/log_android.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/log_linux.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/log_posix.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/log_windows.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/mpscq.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/murmur_hash.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/string.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/string_posix.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/string_util_windows.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/string_windows.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/subprocess_posix.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/subprocess_windows.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/sync.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/sync_posix.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/sync_windows.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/thd.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/thd_posix.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/thd_windows.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/time.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/time_posix.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/time_precise.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/time_windows.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/tls_pthread.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/tmpfile_msys.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/tmpfile_posix.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/tmpfile_windows.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr/wrap_memcpy.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/profiling/basic_timers.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/profiling/stap_timers.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/alloc.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/arena.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/atm.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/avl.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/cmdline.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/cpu_iphone.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/cpu_linux.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/cpu_posix.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/cpu_windows.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/env_linux.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/env_posix.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/env_windows.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/fork.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/host_port.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/log.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/log_android.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/log_linux.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/log_posix.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/log_windows.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/mpscq.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/murmur_hash.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/string.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/string_posix.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/string_util_windows.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/string_windows.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/subprocess_posix.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/subprocess_windows.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/sync.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/sync_posix.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/sync_windows.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/thd.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/thd_posix.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/thd_windows.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/time.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/time_posix.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/time_precise.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/time_windows.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/tls_pthread.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/tmpfile_msys.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/tmpfile_posix.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/tmpfile_windows.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/wrap_memcpy.cc" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/byte_buffer.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/byte_buffer_reader.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/compression_types.h" role="src" />
@@ -282,6 +280,11 @@
     <file baseinstalldir="/" name="src/core/lib/compression/stream_compression_identity.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/debug/stats.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/debug/stats_data.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr++/debug_location.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr++/inlined_vector.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr++/orphanable.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr++/ref_counted.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gpr++/ref_counted_ptr.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/http/format_request.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/http/httpcli.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/http/parser.h" role="src" />
@@ -357,11 +360,6 @@
     <file baseinstalldir="/" name="src/core/lib/slice/slice_hash_table.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/slice/slice_internal.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/slice/slice_string_helpers.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/debug_location.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/orphanable.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/ref_counted.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/ref_counted_ptr.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/vector.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/alarm_internal.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/api_trace.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/call.h" role="src" />
diff --git a/requirements.txt b/requirements.txt
index c976cef..53768c6 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,6 +1,6 @@
 # GRPC Python setup requirements
 coverage>=4.0
-cython>=0.23
+cython>=0.27
 enum34>=1.0.4
 futures>=2.2.0
 protobuf>=3.5.0.post1
diff --git a/src/core/ext/filters/client_channel/backup_poller.cc b/src/core/ext/filters/client_channel/backup_poller.cc
index 4ee5e9c..906a72b 100644
--- a/src/core/ext/filters/client_channel/backup_poller.cc
+++ b/src/core/ext/filters/client_channel/backup_poller.cc
@@ -23,11 +23,11 @@
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 #include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/error.h"
 #include "src/core/lib/iomgr/pollset.h"
 #include "src/core/lib/iomgr/timer.h"
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/completion_queue.h"
 
diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc
index 8c15488..25ef3be 100644
--- a/src/core/ext/filters/client_channel/client_channel.cc
+++ b/src/core/ext/filters/client_channel/client_channel.cc
@@ -41,12 +41,12 @@
 #include "src/core/ext/filters/deadline/deadline_filter.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/connected_channel.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/combiner.h"
 #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"
 #include "src/core/lib/transport/metadata.h"
@@ -1003,7 +1003,7 @@
                                           grpc_error* error) {
   channel_data* chand = (channel_data*)elem->channel_data;
   call_data* calld = (call_data*)elem->call_data;
-  const grpc_core::ConnectedSubchannel::CallArgs call_args = {
+  const grpc_connected_subchannel_call_args call_args = {
       calld->pollent,                       // pollent
       calld->path,                          // path
       calld->call_start_time,               // start_time
@@ -1012,8 +1012,8 @@
       calld->pick.subchannel_call_context,  // context
       calld->call_combiner                  // call_combiner
   };
-  grpc_error* new_error = calld->pick.connected_subchannel->CreateCall(
-      call_args, &calld->subchannel_call);
+  grpc_error* new_error = grpc_connected_subchannel_create_call(
+      calld->pick.connected_subchannel, &call_args, &calld->subchannel_call);
   if (grpc_client_channel_trace.enabled()) {
     gpr_log(GPR_DEBUG, "chand=%p calld=%p: create subchannel_call=%p: error=%s",
             chand, calld, calld->subchannel_call, grpc_error_string(new_error));
@@ -1466,7 +1466,7 @@
   }
   GPR_ASSERT(calld->waiting_for_pick_batches_count == 0);
   if (calld->pick.connected_subchannel != nullptr) {
-    calld->pick.connected_subchannel.reset();
+    GRPC_CONNECTED_SUBCHANNEL_UNREF(calld->pick.connected_subchannel, "picked");
   }
   for (size_t i = 0; i < GRPC_CONTEXT_COUNT; ++i) {
     if (calld->pick.subchannel_call_context[i].value != nullptr) {
diff --git a/src/core/ext/filters/client_channel/http_connect_handshaker.cc b/src/core/ext/filters/client_channel/http_connect_handshaker.cc
index 556a3bc..6bfd038 100644
--- a/src/core/ext/filters/client_channel/http_connect_handshaker.cc
+++ b/src/core/ext/filters/client_channel/http_connect_handshaker.cc
@@ -30,11 +30,11 @@
 #include "src/core/ext/filters/client_channel/uri_parser.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/handshaker_registry.h"
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/http/format_request.h"
 #include "src/core/lib/http/parser.h"
 #include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
 
 typedef struct http_connect_handshaker {
   // Base class.  Must be first.
diff --git a/src/core/ext/filters/client_channel/http_proxy.cc b/src/core/ext/filters/client_channel/http_proxy.cc
index 2eafeee..037c658 100644
--- a/src/core/ext/filters/client_channel/http_proxy.cc
+++ b/src/core/ext/filters/client_channel/http_proxy.cc
@@ -30,9 +30,9 @@
 #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
 #include "src/core/ext/filters/client_channel/uri_parser.h"
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/slice/b64.h"
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
 
 /**
  * Parses the 'http_proxy' env var and returns the proxy hostname to resolve or
diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h
index 0cc0cb5..ea70de0 100644
--- a/src/core/ext/filters/client_channel/lb_policy.h
+++ b/src/core/ext/filters/client_channel/lb_policy.h
@@ -20,8 +20,8 @@
 #define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_H
 
 #include "src/core/ext/filters/client_channel/subchannel.h"
+#include "src/core/lib/gpr++/ref_counted_ptr.h"
 #include "src/core/lib/iomgr/polling_entity.h"
-#include "src/core/lib/support/ref_counted_ptr.h"
 #include "src/core/lib/transport/connectivity_state.h"
 
 /** A load balancing policy: specified by a vtable and a struct (which
@@ -55,9 +55,9 @@
   grpc_linked_mdelem lb_token_mdelem_storage;
   /// Closure to run when pick is complete, if not completed synchronously.
   grpc_closure* on_complete;
-  /// Will be set to the selected subchannel, or nullptr on failure or when
+  /// Will be set to the selected subchannel, or NULL on failure or when
   /// the LB policy decides to drop the call.
-  grpc_core::RefCountedPtr<grpc_core::ConnectedSubchannel> connected_subchannel;
+  grpc_connected_subchannel* connected_subchannel;
   /// Will be populated with context to pass to the subchannel call, if needed.
   grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT];
   /// Upon success, \a *user_data will be set to whatever opaque information
@@ -153,8 +153,7 @@
 int grpc_lb_policy_pick_locked(grpc_lb_policy* policy,
                                grpc_lb_policy_pick_state* pick);
 
-/** Perform a connected subchannel ping (see \a
-   grpc_core::ConnectedSubchannel::Ping)
+/** Perform a connected subchannel ping (see \a grpc_connected_subchannel_ping)
     against one of the connected subchannels managed by \a policy. */
 void grpc_lb_policy_ping_one_locked(grpc_lb_policy* policy,
                                     grpc_closure* on_initiate,
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
index a8c5fb9..629f8ac 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
@@ -106,6 +106,8 @@
 #include "src/core/lib/backoff/backoff.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/channel_stack.h"
+#include "src/core/lib/gpr++/manual_constructor.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/combiner.h"
 #include "src/core/lib/iomgr/sockaddr.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
@@ -113,8 +115,6 @@
 #include "src/core/lib/slice/slice_hash_table.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/manual_constructor.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/call.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/channel_init.h"
@@ -939,7 +939,7 @@
       }
       gpr_free(pp);
     } else {
-      pp->pick->connected_subchannel.reset();
+      pp->pick->connected_subchannel = nullptr;
       GRPC_CLOSURE_SCHED(&pp->on_complete, GRPC_ERROR_REF(error));
     }
     pp = next;
@@ -976,7 +976,7 @@
   while (pp != nullptr) {
     pending_pick* next = pp->next;
     if (pp->pick == pick) {
-      pick->connected_subchannel.reset();
+      pick->connected_subchannel = nullptr;
       GRPC_CLOSURE_SCHED(&pp->on_complete,
                          GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
                              "Pick Cancelled", &error, 1));
@@ -1158,7 +1158,7 @@
     glb_policy->updating_lb_call = false;
   } else if (!glb_policy->shutting_down) {
     /* if we aren't shutting down, restart the LB client call after some time */
-    grpc_millis next_try = glb_policy->lb_call_backoff->Step();
+    grpc_millis next_try = glb_policy->lb_call_backoff->NextAttemptTime();
     if (grpc_lb_glb_trace.enabled()) {
       gpr_log(GPR_DEBUG, "[grpclb %p] Connection to LB server lost...",
               glb_policy);
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc
index a8ecea4..1e7f34b 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc
@@ -22,8 +22,8 @@
 #include "src/core/ext/filters/client_channel/client_channel.h"
 #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h"
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
-#include "src/core/lib/support/string.h"
 
 grpc_channel* grpc_lb_policy_grpclb_create_lb_channel(
     const char* lb_service_target_addresses,
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
index 76bcddf..15233d3 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
@@ -22,11 +22,11 @@
 #include "src/core/ext/filters/client_channel/client_channel.h"
 #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h"
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
 #include "src/core/lib/security/credentials/credentials.h"
 #include "src/core/lib/security/transport/lb_targets_info.h"
 #include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/support/string.h"
 
 grpc_channel* grpc_lb_policy_grpclb_create_lb_channel(
     const char* lb_service_target_addresses,
diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
index 725b78d..6038527 100644
--- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
@@ -81,7 +81,7 @@
         GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE);
       }
     } else {
-      pick->connected_subchannel.reset();
+      pick->connected_subchannel = nullptr;
       GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_REF(error));
     }
   }
@@ -111,7 +111,7 @@
   while (pp != nullptr) {
     grpc_lb_policy_pick_state* next = pp->next;
     if (pp == pick) {
-      pick->connected_subchannel.reset();
+      pick->connected_subchannel = nullptr;
       GRPC_CLOSURE_SCHED(pick->on_complete,
                          GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
                              "Pick Cancelled", &error, 1));
@@ -176,7 +176,8 @@
   pick_first_lb_policy* p = (pick_first_lb_policy*)pol;
   // If we have a selected subchannel already, return synchronously.
   if (p->selected != nullptr) {
-    pick->connected_subchannel = p->selected->connected_subchannel;
+    pick->connected_subchannel = GRPC_CONNECTED_SUBCHANNEL_REF(
+        p->selected->connected_subchannel, "picked");
     return 1;
   }
   // No subchannel selected yet, so handle asynchronously.
@@ -216,7 +217,8 @@
                                grpc_closure* on_ack) {
   pick_first_lb_policy* p = (pick_first_lb_policy*)pol;
   if (p->selected) {
-    p->selected->connected_subchannel->Ping(on_initiate, on_ack);
+    grpc_connected_subchannel_ping(p->selected->connected_subchannel,
+                                   on_initiate, on_ack);
   } else {
     GRPC_CLOSURE_SCHED(on_initiate,
                        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Not connected"));
@@ -295,7 +297,8 @@
                   subchannel_list->num_subchannels);
         }
         if (p->selected->connected_subchannel != nullptr) {
-          sd->connected_subchannel = p->selected->connected_subchannel;
+          sd->connected_subchannel = GRPC_CONNECTED_SUBCHANNEL_REF(
+              p->selected->connected_subchannel, "pf_update_includes_selected");
         }
         p->selected = sd;
         if (p->subchannel_list != nullptr) {
@@ -407,8 +410,8 @@
       // re-resolution is introduced. But we need to investigate whether we
       // really want to take any action instead of waiting for the selected
       // subchannel reconnecting.
-      GPR_ASSERT(sd->curr_connectivity_state != GRPC_CHANNEL_SHUTDOWN);
-      if (sd->curr_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
+      if (sd->curr_connectivity_state == GRPC_CHANNEL_SHUTDOWN ||
+          sd->curr_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
         // If the selected channel goes bad, request a re-resolution.
         grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_IDLE,
                                     GRPC_ERROR_NONE,
@@ -416,19 +419,20 @@
         p->started_picking = false;
         grpc_lb_policy_try_reresolve(&p->base, &grpc_lb_pick_first_trace,
                                      GRPC_ERROR_NONE);
-        // in transient failure. Rely on re-resolution to recover.
-        p->selected = nullptr;
-        grpc_lb_subchannel_data_stop_connectivity_watch(sd);
-        grpc_lb_subchannel_list_unref_for_connectivity_watch(
-            sd->subchannel_list, "pf_selected_shutdown");
-        grpc_lb_subchannel_data_unref_subchannel(
-            sd, "pf_selected_shutdown");  // Unrefs connected subchannel
       } else {
         grpc_connectivity_state_set(&p->state_tracker,
                                     sd->curr_connectivity_state,
                                     GRPC_ERROR_REF(error), "selected_changed");
+      }
+      if (sd->curr_connectivity_state != GRPC_CHANNEL_SHUTDOWN) {
         // Renew notification.
         grpc_lb_subchannel_data_start_connectivity_watch(sd);
+      } else {
+        p->selected = nullptr;
+        grpc_lb_subchannel_data_stop_connectivity_watch(sd);
+        grpc_lb_subchannel_list_unref_for_connectivity_watch(
+            sd->subchannel_list, "pf_selected_shutdown");
+        grpc_lb_subchannel_data_unref_subchannel(sd, "pf_selected_shutdown");
       }
     }
     return;
@@ -446,8 +450,6 @@
     case GRPC_CHANNEL_READY: {
       // Case 2.  Promote p->latest_pending_subchannel_list to
       // p->subchannel_list.
-      sd->connected_subchannel =
-          grpc_subchannel_get_connected_subchannel(sd->subchannel);
       if (sd->subchannel_list == p->latest_pending_subchannel_list) {
         GPR_ASSERT(p->subchannel_list != nullptr);
         grpc_lb_subchannel_list_shutdown_and_unref(p->subchannel_list,
@@ -458,6 +460,9 @@
       // Cases 1 and 2.
       grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_READY,
                                   GRPC_ERROR_NONE, "connecting_ready");
+      sd->connected_subchannel = GRPC_CONNECTED_SUBCHANNEL_REF(
+          grpc_subchannel_get_connected_subchannel(sd->subchannel),
+          "connected");
       p->selected = sd;
       if (grpc_lb_pick_first_trace.enabled()) {
         gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", (void*)p,
@@ -469,7 +474,8 @@
       grpc_lb_policy_pick_state* pick;
       while ((pick = p->pending_picks)) {
         p->pending_picks = pick->next;
-        pick->connected_subchannel = p->selected->connected_subchannel;
+        pick->connected_subchannel = GRPC_CONNECTED_SUBCHANNEL_REF(
+            p->selected->connected_subchannel, "picked");
         if (grpc_lb_pick_first_trace.enabled()) {
           gpr_log(GPR_INFO,
                   "Servicing pending pick with selected subchannel %p",
@@ -514,8 +520,39 @@
       grpc_lb_subchannel_data_start_connectivity_watch(sd);
       break;
     }
-    case GRPC_CHANNEL_SHUTDOWN:
-      GPR_UNREACHABLE_CODE(break);
+    case GRPC_CHANNEL_SHUTDOWN: {
+      grpc_lb_subchannel_data_stop_connectivity_watch(sd);
+      grpc_lb_subchannel_data_unref_subchannel(sd, "pf_candidate_shutdown");
+      // Advance to next subchannel and check its state.
+      grpc_lb_subchannel_data* original_sd = sd;
+      do {
+        sd->subchannel_list->checking_subchannel =
+            (sd->subchannel_list->checking_subchannel + 1) %
+            sd->subchannel_list->num_subchannels;
+        sd = &sd->subchannel_list
+                  ->subchannels[sd->subchannel_list->checking_subchannel];
+      } while (sd->subchannel == nullptr && sd != original_sd);
+      if (sd == original_sd) {
+        grpc_lb_subchannel_list_unref_for_connectivity_watch(
+            sd->subchannel_list, "pf_exhausted_subchannels");
+        if (sd->subchannel_list == p->subchannel_list) {
+          grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_IDLE,
+                                      GRPC_ERROR_NONE,
+                                      "exhausted_subchannels+reresolve");
+          p->started_picking = false;
+          grpc_lb_policy_try_reresolve(&p->base, &grpc_lb_pick_first_trace,
+                                       GRPC_ERROR_NONE);
+        }
+      } else {
+        if (sd->subchannel_list == p->subchannel_list) {
+          grpc_connectivity_state_set(
+              &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
+              GRPC_ERROR_REF(error), "subchannel_failed");
+        }
+        // Reuses the connectivity refs from the previous watch.
+        grpc_lb_subchannel_data_start_connectivity_watch(sd);
+      }
+    }
   }
 }
 
diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
index 5a36aca..c4e9820 100644
--- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
@@ -34,9 +34,9 @@
 #include "src/core/ext/filters/client_channel/subchannel_index.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/debug/trace.h"
+#include "src/core/lib/gpr++/ref_counted_ptr.h"
 #include "src/core/lib/iomgr/combiner.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
-#include "src/core/lib/support/ref_counted_ptr.h"
 #include "src/core/lib/transport/connectivity_state.h"
 #include "src/core/lib/transport/static_metadata.h"
 
@@ -128,7 +128,7 @@
             (void*)p, (unsigned long)last_ready_index,
             (void*)p->subchannel_list->subchannels[last_ready_index].subchannel,
             (void*)p->subchannel_list->subchannels[last_ready_index]
-                .connected_subchannel.get());
+                .connected_subchannel);
   }
 }
 
@@ -163,7 +163,7 @@
         GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE);
       }
     } else {
-      pick->connected_subchannel.reset();
+      pick->connected_subchannel = nullptr;
       GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_REF(error));
     }
   }
@@ -193,7 +193,7 @@
   while (pp != nullptr) {
     grpc_lb_policy_pick_state* next = pp->next;
     if (pp == pick) {
-      pick->connected_subchannel.reset();
+      pick->connected_subchannel = nullptr;
       GRPC_CLOSURE_SCHED(pick->on_complete,
                          GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
                              "Pick cancelled", &error, 1));
@@ -217,7 +217,7 @@
     grpc_lb_policy_pick_state* next = pick->next;
     if ((pick->initial_metadata_flags & initial_metadata_flags_mask) ==
         initial_metadata_flags_eq) {
-      pick->connected_subchannel.reset();
+      pick->connected_subchannel = nullptr;
       GRPC_CLOSURE_SCHED(pick->on_complete,
                          GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
                              "Pick cancelled", &error, 1));
@@ -263,7 +263,8 @@
       /* readily available, report right away */
       grpc_lb_subchannel_data* sd =
           &p->subchannel_list->subchannels[next_ready_index];
-      pick->connected_subchannel = sd->connected_subchannel;
+      pick->connected_subchannel =
+          GRPC_CONNECTED_SUBCHANNEL_REF(sd->connected_subchannel, "rr_picked");
       if (pick->user_data != nullptr) {
         *pick->user_data = sd->user_data;
       }
@@ -272,8 +273,8 @@
             GPR_DEBUG,
             "[RR %p] Picked target <-- Subchannel %p (connected %p) (sl %p, "
             "index %" PRIuPTR ")",
-            p, sd->subchannel, pick->connected_subchannel.get(),
-            sd->subchannel_list, next_ready_index);
+            p, sd->subchannel, pick->connected_subchannel, sd->subchannel_list,
+            next_ready_index);
       }
       /* only advance the last picked pointer if the selection was used */
       update_last_ready_subchannel_index_locked(p, next_ready_index);
@@ -291,14 +292,15 @@
 
 static void update_state_counters_locked(grpc_lb_subchannel_data* sd) {
   grpc_lb_subchannel_list* subchannel_list = sd->subchannel_list;
-  GPR_ASSERT(sd->prev_connectivity_state != GRPC_CHANNEL_SHUTDOWN);
-  GPR_ASSERT(sd->curr_connectivity_state != GRPC_CHANNEL_SHUTDOWN);
   if (sd->prev_connectivity_state == GRPC_CHANNEL_READY) {
     GPR_ASSERT(subchannel_list->num_ready > 0);
     --subchannel_list->num_ready;
   } else if (sd->prev_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
     GPR_ASSERT(subchannel_list->num_transient_failures > 0);
     --subchannel_list->num_transient_failures;
+  } else if (sd->prev_connectivity_state == GRPC_CHANNEL_SHUTDOWN) {
+    GPR_ASSERT(subchannel_list->num_shutdown > 0);
+    --subchannel_list->num_shutdown;
   } else if (sd->prev_connectivity_state == GRPC_CHANNEL_IDLE) {
     GPR_ASSERT(subchannel_list->num_idle > 0);
     --subchannel_list->num_idle;
@@ -308,6 +310,8 @@
     ++subchannel_list->num_ready;
   } else if (sd->curr_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
     ++subchannel_list->num_transient_failures;
+  } else if (sd->curr_connectivity_state == GRPC_CHANNEL_SHUTDOWN) {
+    ++subchannel_list->num_shutdown;
   } else if (sd->curr_connectivity_state == GRPC_CHANNEL_IDLE) {
     ++subchannel_list->num_idle;
   }
@@ -407,7 +411,6 @@
   // either the current or latest pending subchannel lists.
   GPR_ASSERT(sd->subchannel_list == p->subchannel_list ||
              sd->subchannel_list == p->latest_pending_subchannel_list);
-  GPR_ASSERT(sd->pending_connectivity_state_unsafe != GRPC_CHANNEL_SHUTDOWN);
   // Now that we're inside the combiner, copy the pending connectivity
   // state (which was set by the connectivity state watcher) to
   // curr_connectivity_state, which is what we use inside of the combiner.
@@ -415,17 +418,18 @@
   // Update state counters and new overall state.
   update_state_counters_locked(sd);
   update_lb_connectivity_status_locked(sd, GRPC_ERROR_REF(error));
-  // If the sd's new state is TRANSIENT_FAILURE, unref the *connected*
-  // subchannel, if any.
-  switch (sd->curr_connectivity_state) {
-    case GRPC_CHANNEL_TRANSIENT_FAILURE: {
-      sd->connected_subchannel.reset();
-      break;
-    }
-    case GRPC_CHANNEL_READY: {
+  // If the sd's new state is SHUTDOWN, unref the subchannel.
+  if (sd->curr_connectivity_state == GRPC_CHANNEL_SHUTDOWN) {
+    grpc_lb_subchannel_data_stop_connectivity_watch(sd);
+    grpc_lb_subchannel_data_unref_subchannel(sd, "rr_connectivity_shutdown");
+    grpc_lb_subchannel_list_unref_for_connectivity_watch(
+        sd->subchannel_list, "rr_connectivity_shutdown");
+  } else {  // sd not in SHUTDOWN
+    if (sd->curr_connectivity_state == GRPC_CHANNEL_READY) {
       if (sd->connected_subchannel == nullptr) {
-        sd->connected_subchannel =
-            grpc_subchannel_get_connected_subchannel(sd->subchannel);
+        sd->connected_subchannel = GRPC_CONNECTED_SUBCHANNEL_REF(
+            grpc_subchannel_get_connected_subchannel(sd->subchannel),
+            "connected");
       }
       if (sd->subchannel_list != p->subchannel_list) {
         // promote sd->subchannel_list to p->subchannel_list.
@@ -468,7 +472,8 @@
       grpc_lb_policy_pick_state* pick;
       while ((pick = p->pending_picks)) {
         p->pending_picks = pick->next;
-        pick->connected_subchannel = selected->connected_subchannel;
+        pick->connected_subchannel = GRPC_CONNECTED_SUBCHANNEL_REF(
+            selected->connected_subchannel, "rr_picked");
         if (pick->user_data != nullptr) {
           *pick->user_data = selected->user_data;
         }
@@ -481,15 +486,10 @@
         }
         GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE);
       }
-      break;
     }
-    case GRPC_CHANNEL_SHUTDOWN:
-      GPR_UNREACHABLE_CODE(return );
-    case GRPC_CHANNEL_CONNECTING:
-    case GRPC_CHANNEL_IDLE:;  // fallthrough
+    // Renew notification.
+    grpc_lb_subchannel_data_start_connectivity_watch(sd);
   }
-  // Renew notification.
-  grpc_lb_subchannel_data_start_connectivity_watch(sd);
 }
 
 static grpc_connectivity_state rr_check_connectivity_locked(
@@ -513,9 +513,10 @@
   if (next_ready_index < p->subchannel_list->num_subchannels) {
     grpc_lb_subchannel_data* selected =
         &p->subchannel_list->subchannels[next_ready_index];
-    grpc_core::RefCountedPtr<grpc_core::ConnectedSubchannel> target =
-        selected->connected_subchannel;
-    target->Ping(on_initiate, on_ack);
+    grpc_connected_subchannel* target = GRPC_CONNECTED_SUBCHANNEL_REF(
+        selected->connected_subchannel, "rr_ping");
+    grpc_connected_subchannel_ping(target, on_initiate, on_ack);
+    GRPC_CONNECTED_SUBCHANNEL_UNREF(target, "rr_ping");
   } else {
     GRPC_CLOSURE_SCHED(on_initiate, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
                                         "Round Robin not connected"));
diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc
index fa2ffcc..5ce1298 100644
--- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc
@@ -42,7 +42,10 @@
     }
     GRPC_SUBCHANNEL_UNREF(sd->subchannel, reason);
     sd->subchannel = nullptr;
-    sd->connected_subchannel.reset();
+    if (sd->connected_subchannel != nullptr) {
+      GRPC_CONNECTED_SUBCHANNEL_UNREF(sd->connected_subchannel, reason);
+      sd->connected_subchannel = nullptr;
+    }
     if (sd->user_data != nullptr) {
       GPR_ASSERT(sd->user_data_vtable != nullptr);
       sd->user_data_vtable->destroy(sd->user_data);
diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
index f146c72..0f8cea9 100644
--- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
+++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
@@ -22,7 +22,6 @@
 #include "src/core/ext/filters/client_channel/lb_policy_registry.h"
 #include "src/core/ext/filters/client_channel/subchannel.h"
 #include "src/core/lib/debug/trace.h"
-#include "src/core/lib/support/ref_counted_ptr.h"
 #include "src/core/lib/transport/connectivity_state.h"
 
 // TODO(roth): This code is intended to be shared between pick_first and
@@ -44,7 +43,7 @@
   grpc_lb_subchannel_list* subchannel_list;
   /** subchannel itself */
   grpc_subchannel* subchannel;
-  grpc_core::RefCountedPtr<grpc_core::ConnectedSubchannel> connected_subchannel;
+  grpc_connected_subchannel* connected_subchannel;
   /** Is a connectivity notification pending? */
   bool connectivity_notification_pending;
   /** notification that connectivity has changed on subchannel */
diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.cc b/src/core/ext/filters/client_channel/lb_policy_registry.cc
index edd0330..8414504 100644
--- a/src/core/ext/filters/client_channel/lb_policy_registry.cc
+++ b/src/core/ext/filters/client_channel/lb_policy_registry.cc
@@ -20,7 +20,7 @@
 
 #include <string.h>
 
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 
 #define MAX_POLICIES 10
 
diff --git a/src/core/ext/filters/client_channel/parse_address.cc b/src/core/ext/filters/client_channel/parse_address.cc
index 39b1237..c3309e3 100644
--- a/src/core/ext/filters/client_channel/parse_address.cc
+++ b/src/core/ext/filters/client_channel/parse_address.cc
@@ -29,7 +29,7 @@
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 
 #ifdef GRPC_HAVE_UNIX_SOCKET
 
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
index 4659a5f..1efdc26 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
@@ -34,14 +34,14 @@
 #include "src/core/ext/filters/client_channel/resolver_registry.h"
 #include "src/core/lib/backoff/backoff.h"
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr++/manual_constructor.h"
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/combiner.h"
 #include "src/core/lib/iomgr/gethostname.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/json/json.h"
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/manual_constructor.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/service_config.h"
 
 #define GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS 1
@@ -264,7 +264,7 @@
   } else {
     const char* msg = grpc_error_string(error);
     gpr_log(GPR_DEBUG, "dns resolution failed: %s", msg);
-    grpc_millis next_try = r->backoff->Step();
+    grpc_millis next_try = r->backoff->NextAttemptTime();
     grpc_millis timeout = next_try - grpc_core::ExecCtx::Get()->Now();
     gpr_log(GPR_INFO, "dns resolution failed (will retry): %s",
             grpc_error_string(error));
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
index 40e2645..2eb2a9b 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
@@ -30,10 +30,10 @@
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
 #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/ev_posix.h"
 #include "src/core/lib/iomgr/iomgr_internal.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
-#include "src/core/lib/support/string.h"
 
 typedef struct fd_node {
   /** the owner of this fd node */
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
index 3a870b2..2b35bdb 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
@@ -36,12 +36,12 @@
 
 #include "src/core/ext/filters/client_channel/parse_address.h"
 #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/error.h"
 #include "src/core/lib/iomgr/executor.h"
 #include "src/core/lib/iomgr/iomgr_internal.h"
 #include "src/core/lib/iomgr/nameser.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
-#include "src/core/lib/support/string.h"
 
 static gpr_once g_basic_init = GPR_ONCE_INIT;
 static gpr_mu g_init_mu;
diff --git a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
index 1c2cfc0..66a03c5 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
@@ -29,12 +29,12 @@
 #include "src/core/ext/filters/client_channel/resolver_registry.h"
 #include "src/core/lib/backoff/backoff.h"
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr++/manual_constructor.h"
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/combiner.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/timer.h"
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/manual_constructor.h"
-#include "src/core/lib/support/string.h"
 
 #define GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS 1
 #define GRPC_DNS_RECONNECT_BACKOFF_MULTIPLIER 1.6
@@ -161,7 +161,7 @@
     grpc_resolved_addresses_destroy(r->addresses);
     grpc_lb_addresses_destroy(addresses);
   } else {
-    grpc_millis next_try = r->backoff->Step();
+    grpc_millis next_try = r->backoff->NextAttemptTime();
     grpc_millis timeout = next_try - grpc_core::ExecCtx::Get()->Now();
     gpr_log(GPR_INFO, "dns resolution failed (will retry): %s",
             grpc_error_string(error));
diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
index fe3ad14..eaa5e6a 100644
--- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
+++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
@@ -32,13 +32,13 @@
 #include "src/core/ext/filters/client_channel/parse_address.h"
 #include "src/core/ext/filters/client_channel/resolver_registry.h"
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/closure.h"
 #include "src/core/lib/iomgr/combiner.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/unix_sockets_posix.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 
 #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
 
diff --git a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
index 7d1e283..99ad78e 100644
--- a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
+++ b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
@@ -30,12 +30,12 @@
 #include "src/core/ext/filters/client_channel/parse_address.h"
 #include "src/core/ext/filters/client_channel/resolver_registry.h"
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/combiner.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/unix_sockets_posix.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 
 typedef struct {
   /** base class: must be first */
diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc
index 5b8a14b..83aaa09 100644
--- a/src/core/ext/filters/client_channel/subchannel.cc
+++ b/src/core/ext/filters/client_channel/subchannel.cc
@@ -37,12 +37,12 @@
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/connected_channel.h"
 #include "src/core/lib/debug/stats.h"
+#include "src/core/lib/gpr++/debug_location.h"
+#include "src/core/lib/gpr++/manual_constructor.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
 #include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/support/debug_location.h"
-#include "src/core/lib/support/manual_constructor.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/channel_init.h"
 #include "src/core/lib/transport/connectivity_state.h"
@@ -56,6 +56,10 @@
 #define GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS 120
 #define GRPC_SUBCHANNEL_RECONNECT_JITTER 0.2
 
+#define GET_CONNECTED_SUBCHANNEL(subchannel, barrier)     \
+  ((grpc_connected_subchannel*)(gpr_atm_##barrier##_load( \
+      &(subchannel)->connected_subchannel)))
+
 namespace {
 struct state_watcher {
   grpc_closure closure;
@@ -95,7 +99,7 @@
   grpc_connect_out_args connecting_result;
 
   /** callback for connection finishing */
-  grpc_closure on_connected;
+  grpc_closure connected;
 
   /** callback for our alarm */
   grpc_closure on_alarm;
@@ -104,13 +108,12 @@
       being setup */
   grpc_pollset_set* pollset_set;
 
+  /** active connection, or null; of type grpc_connected_subchannel */
+  gpr_atm connected_subchannel;
+
   /** mutex protecting remaining elements */
   gpr_mu mu;
 
-  /** active connection, or null; of type grpc_core::ConnectedSubchannel
-   */
-  grpc_core::RefCountedPtr<grpc_core::ConnectedSubchannel> connected_subchannel;
-
   /** have we seen a disconnection? */
   bool disconnected;
   /** are we connecting */
@@ -134,15 +137,16 @@
 };
 
 struct grpc_subchannel_call {
-  grpc_core::ConnectedSubchannel* connection;
+  grpc_connected_subchannel* connection;
   grpc_closure* schedule_closure_after_destroy;
 };
 
 #define SUBCHANNEL_CALL_TO_CALL_STACK(call) ((grpc_call_stack*)((call) + 1))
+#define CHANNEL_STACK_FROM_CONNECTION(con) ((grpc_channel_stack*)(con))
 #define CALLSTACK_TO_SUBCHANNEL_CALL(callstack) \
   (((grpc_subchannel_call*)(callstack)) - 1)
 
-static void on_subchannel_connected(void* subchannel, grpc_error* error);
+static void subchannel_connected(void* subchannel, grpc_error* error);
 
 #ifndef NDEBUG
 #define REF_REASON reason
@@ -160,9 +164,20 @@
  */
 
 static void connection_destroy(void* arg, grpc_error* error) {
-  grpc_channel_stack* stk = (grpc_channel_stack*)arg;
-  grpc_channel_stack_destroy(stk);
-  gpr_free(stk);
+  grpc_connected_subchannel* c = (grpc_connected_subchannel*)arg;
+  grpc_channel_stack_destroy(CHANNEL_STACK_FROM_CONNECTION(c));
+  gpr_free(c);
+}
+
+grpc_connected_subchannel* grpc_connected_subchannel_ref(
+    grpc_connected_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
+  GRPC_CHANNEL_STACK_REF(CHANNEL_STACK_FROM_CONNECTION(c), REF_REASON);
+  return c;
+}
+
+void grpc_connected_subchannel_unref(
+    grpc_connected_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
+  GRPC_CHANNEL_STACK_UNREF(CHANNEL_STACK_FROM_CONNECTION(c), REF_REASON);
 }
 
 /*
@@ -229,13 +244,18 @@
 }
 
 static void disconnect(grpc_subchannel* c) {
+  grpc_connected_subchannel* con;
   grpc_subchannel_index_unregister(c->key, c);
   gpr_mu_lock(&c->mu);
   GPR_ASSERT(!c->disconnected);
   c->disconnected = true;
   grpc_connector_shutdown(c->connector, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
                                             "Subchannel disconnected"));
-  c->connected_subchannel.reset();
+  con = GET_CONNECTED_SUBCHANNEL(c, no_barrier);
+  if (con != nullptr) {
+    GRPC_CONNECTED_SUBCHANNEL_UNREF(con, "connection");
+    gpr_atm_no_barrier_store(&c->connected_subchannel, (gpr_atm)0xdeadbeef);
+  }
   gpr_mu_unlock(&c->mu);
 }
 
@@ -355,7 +375,7 @@
   if (new_args != nullptr) grpc_channel_args_destroy(new_args);
   c->root_external_state_watcher.next = c->root_external_state_watcher.prev =
       &c->root_external_state_watcher;
-  GRPC_CLOSURE_INIT(&c->on_connected, on_subchannel_connected, c,
+  GRPC_CLOSURE_INIT(&c->connected, subchannel_connected, c,
                     grpc_schedule_on_exec_ctx);
   grpc_connectivity_state_init(&c->state_tracker, GRPC_CHANNEL_IDLE,
                                "subchannel");
@@ -373,12 +393,13 @@
   args.interested_parties = c->pollset_set;
   const grpc_millis min_deadline =
       c->min_connect_timeout_ms + grpc_core::ExecCtx::Get()->Now();
+  c->next_attempt_deadline = c->backoff->NextAttemptTime();
   args.deadline = std::max(c->next_attempt_deadline, min_deadline);
   args.channel_args = c->args;
   grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_CONNECTING,
                               GRPC_ERROR_NONE, "state_change");
   grpc_connector_connect(c->connector, &args, &c->connecting_result,
-                         &c->on_connected);
+                         &c->connected);
 }
 
 grpc_connectivity_state grpc_subchannel_check_connectivity(grpc_subchannel* c,
@@ -418,7 +439,6 @@
   }
   if (error == GRPC_ERROR_NONE) {
     gpr_log(GPR_INFO, "Failed to connect to channel, retrying");
-    c->next_attempt_deadline = c->backoff->Step();
     continue_connect_locked(c);
     gpr_mu_unlock(&c->mu);
   } else {
@@ -439,7 +459,7 @@
     return;
   }
 
-  if (c->connected_subchannel != nullptr) {
+  if (GET_CONNECTED_SUBCHANNEL(c, no_barrier) != nullptr) {
     /* Already connected: don't restart */
     return;
   }
@@ -454,7 +474,6 @@
 
   if (!c->backoff_begun) {
     c->backoff_begun = true;
-    c->next_attempt_deadline = c->backoff->Begin();
     continue_connect_locked(c);
   } else {
     GPR_ASSERT(!c->have_alarm);
@@ -462,10 +481,9 @@
     const grpc_millis time_til_next =
         c->next_attempt_deadline - grpc_core::ExecCtx::Get()->Now();
     if (time_til_next <= 0) {
-      gpr_log(GPR_INFO, "Subchannel %p: Retry immediately", c);
+      gpr_log(GPR_INFO, "Retry immediately");
     } else {
-      gpr_log(GPR_INFO, "Subchannel %p: Retry in %" PRIdPTR " milliseconds", c,
-              time_til_next);
+      gpr_log(GPR_INFO, "Retry in %" PRIdPTR " milliseconds", time_til_next);
     }
     GRPC_CLOSURE_INIT(&c->on_alarm, on_alarm, c, grpc_schedule_on_exec_ctx);
     grpc_timer_init(&c->alarm, c->next_attempt_deadline, &c->on_alarm);
@@ -509,56 +527,75 @@
   }
 }
 
-static void on_connected_subchannel_connectivity_changed(void* p,
-                                                         grpc_error* error) {
-  state_watcher* connected_subchannel_watcher = (state_watcher*)p;
-  grpc_subchannel* c = connected_subchannel_watcher->subchannel;
+void grpc_connected_subchannel_process_transport_op(
+    grpc_connected_subchannel* con, grpc_transport_op* op) {
+  grpc_channel_stack* channel_stack = CHANNEL_STACK_FROM_CONNECTION(con);
+  grpc_channel_element* top_elem = grpc_channel_stack_element(channel_stack, 0);
+  top_elem->filter->start_transport_op(top_elem, op);
+}
+
+static void subchannel_on_child_state_changed(void* p, grpc_error* error) {
+  state_watcher* sw = (state_watcher*)p;
+  grpc_subchannel* c = sw->subchannel;
   gpr_mu* mu = &c->mu;
 
   gpr_mu_lock(mu);
 
-  switch (connected_subchannel_watcher->connectivity_state) {
-    case GRPC_CHANNEL_TRANSIENT_FAILURE:
-    case GRPC_CHANNEL_SHUTDOWN: {
-      if (!c->disconnected && c->connected_subchannel != nullptr) {
-        if (grpc_trace_stream_refcount.enabled()) {
-          gpr_log(GPR_INFO,
-                  "Connected subchannel %p of subchannel %p has gone into %s. "
-                  "Attempting to reconnect.",
-                  c->connected_subchannel.get(), c,
-                  grpc_connectivity_state_name(
-                      connected_subchannel_watcher->connectivity_state));
-        }
-        c->connected_subchannel.reset();
-        grpc_connectivity_state_set(&c->state_tracker,
-                                    GRPC_CHANNEL_TRANSIENT_FAILURE,
-                                    GRPC_ERROR_REF(error), "reflect_child");
-        c->backoff_begun = false;
-        c->backoff->Reset();
-        maybe_start_connecting_locked(c);
-      } else {
-        connected_subchannel_watcher->connectivity_state =
-            GRPC_CHANNEL_SHUTDOWN;
-      }
-      break;
-    }
-    default: {
-      grpc_connectivity_state_set(
-          &c->state_tracker, connected_subchannel_watcher->connectivity_state,
-          GRPC_ERROR_REF(error), "reflect_child");
-      GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher");
-      c->connected_subchannel->NotifyOnStateChange(
-          nullptr, &connected_subchannel_watcher->connectivity_state,
-          &connected_subchannel_watcher->closure);
-      connected_subchannel_watcher = nullptr;
-    }
+  /* if we failed just leave this closure */
+  if (sw->connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
+    /* any errors on a subchannel ==> we're done, create a new one */
+    sw->connectivity_state = GRPC_CHANNEL_SHUTDOWN;
   }
+  grpc_connectivity_state_set(&c->state_tracker, sw->connectivity_state,
+                              GRPC_ERROR_REF(error), "reflect_child");
+  if (sw->connectivity_state != GRPC_CHANNEL_SHUTDOWN) {
+    grpc_connected_subchannel_notify_on_state_change(
+        GET_CONNECTED_SUBCHANNEL(c, no_barrier), nullptr,
+        &sw->connectivity_state, &sw->closure);
+    GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher");
+    sw = nullptr;
+  }
+
   gpr_mu_unlock(mu);
   GRPC_SUBCHANNEL_WEAK_UNREF(c, "state_watcher");
-  gpr_free(connected_subchannel_watcher);
+  gpr_free(sw);
+}
+
+static void connected_subchannel_state_op(grpc_connected_subchannel* con,
+                                          grpc_pollset_set* interested_parties,
+                                          grpc_connectivity_state* state,
+                                          grpc_closure* closure) {
+  grpc_transport_op* op = grpc_make_transport_op(nullptr);
+  grpc_channel_element* elem;
+  op->connectivity_state = state;
+  op->on_connectivity_state_change = closure;
+  op->bind_pollset_set = interested_parties;
+  elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CONNECTION(con), 0);
+  elem->filter->start_transport_op(elem, op);
+}
+
+void grpc_connected_subchannel_notify_on_state_change(
+    grpc_connected_subchannel* con, grpc_pollset_set* interested_parties,
+    grpc_connectivity_state* state, grpc_closure* closure) {
+  connected_subchannel_state_op(con, interested_parties, state, closure);
+}
+
+void grpc_connected_subchannel_ping(grpc_connected_subchannel* con,
+                                    grpc_closure* on_initiate,
+                                    grpc_closure* on_ack) {
+  grpc_transport_op* op = grpc_make_transport_op(nullptr);
+  grpc_channel_element* elem;
+  op->send_ping.on_initiate = on_initiate;
+  op->send_ping.on_ack = on_ack;
+  elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CONNECTION(con), 0);
+  elem->filter->start_transport_op(elem, op);
 }
 
 static bool publish_transport_locked(grpc_subchannel* c) {
+  grpc_connected_subchannel* con;
+  grpc_channel_stack* stk;
+  state_watcher* sw_subchannel;
+
   /* construct channel stack */
   grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create();
   grpc_channel_stack_builder_set_channel_arguments(
@@ -570,9 +607,8 @@
     grpc_channel_stack_builder_destroy(builder);
     return false;
   }
-  grpc_channel_stack* stk;
   grpc_error* error = grpc_channel_stack_builder_finish(
-      builder, 0, 1, connection_destroy, nullptr, (void**)&stk);
+      builder, 0, 1, connection_destroy, nullptr, (void**)&con);
   if (error != GRPC_ERROR_NONE) {
     grpc_transport_destroy(c->connecting_result.transport);
     gpr_log(GPR_ERROR, "error initializing subchannel stack: %s",
@@ -580,37 +616,38 @@
     GRPC_ERROR_UNREF(error);
     return false;
   }
+  stk = CHANNEL_STACK_FROM_CONNECTION(con);
   memset(&c->connecting_result, 0, sizeof(c->connecting_result));
 
   /* initialize state watcher */
-  state_watcher* connected_subchannel_watcher =
-      (state_watcher*)gpr_zalloc(sizeof(*connected_subchannel_watcher));
-  connected_subchannel_watcher->subchannel = c;
-  connected_subchannel_watcher->connectivity_state = GRPC_CHANNEL_READY;
-  GRPC_CLOSURE_INIT(&connected_subchannel_watcher->closure,
-                    on_connected_subchannel_connectivity_changed,
-                    connected_subchannel_watcher, grpc_schedule_on_exec_ctx);
+  sw_subchannel = (state_watcher*)gpr_malloc(sizeof(*sw_subchannel));
+  sw_subchannel->subchannel = c;
+  sw_subchannel->connectivity_state = GRPC_CHANNEL_READY;
+  GRPC_CLOSURE_INIT(&sw_subchannel->closure, subchannel_on_child_state_changed,
+                    sw_subchannel, grpc_schedule_on_exec_ctx);
 
   if (c->disconnected) {
-    gpr_free(connected_subchannel_watcher);
+    gpr_free(sw_subchannel);
     grpc_channel_stack_destroy(stk);
-    gpr_free(stk);
+    gpr_free(con);
     return false;
   }
 
   /* publish */
-  c->connected_subchannel.reset(
-      grpc_core::New<grpc_core::ConnectedSubchannel>(stk));
-  gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p",
-          c->connected_subchannel.get(), c);
+  /* TODO(ctiller): this full barrier seems to clear up a TSAN failure.
+                    I'd have expected the rel_cas below to be enough, but
+                    seemingly it's not.
+                    Re-evaluate if we really need this. */
+  gpr_atm_full_barrier();
+  GPR_ASSERT(gpr_atm_rel_cas(&c->connected_subchannel, 0, (gpr_atm)con));
 
   /* setup subchannel watching connected subchannel for changes; subchannel
      ref for connecting is donated to the state watcher */
   GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher");
   GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting");
-  c->connected_subchannel->NotifyOnStateChange(
-      c->pollset_set, &connected_subchannel_watcher->connectivity_state,
-      &connected_subchannel_watcher->closure);
+  grpc_connected_subchannel_notify_on_state_change(
+      con, c->pollset_set, &sw_subchannel->connectivity_state,
+      &sw_subchannel->closure);
 
   /* signal completion */
   grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_READY,
@@ -618,11 +655,11 @@
   return true;
 }
 
-static void on_subchannel_connected(void* arg, grpc_error* error) {
+static void subchannel_connected(void* arg, grpc_error* error) {
   grpc_subchannel* c = (grpc_subchannel*)arg;
   grpc_channel_args* delete_channel_args = c->connecting_result.channel_args;
 
-  GRPC_SUBCHANNEL_WEAK_REF(c, "on_subchannel_connected");
+  GRPC_SUBCHANNEL_WEAK_REF(c, "connected");
   gpr_mu_lock(&c->mu);
   c->connecting = false;
   if (c->connecting_result.transport != nullptr &&
@@ -657,10 +694,10 @@
   grpc_subchannel_call* c = (grpc_subchannel_call*)call;
   GPR_ASSERT(c->schedule_closure_after_destroy != nullptr);
   GPR_TIMER_BEGIN("grpc_subchannel_call_unref.destroy", 0);
-  grpc_core::ConnectedSubchannel* connection = c->connection;
+  grpc_connected_subchannel* connection = c->connection;
   grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(c), nullptr,
                           c->schedule_closure_after_destroy);
-  connection->Unref(DEBUG_LOCATION, "subchannel_call");
+  GRPC_CONNECTED_SUBCHANNEL_UNREF(connection, "subchannel_call");
   GPR_TIMER_END("grpc_subchannel_call_unref.destroy", 0);
 }
 
@@ -691,12 +728,9 @@
   GPR_TIMER_END("grpc_subchannel_call_process_op", 0);
 }
 
-grpc_core::RefCountedPtr<grpc_core::ConnectedSubchannel>
-grpc_subchannel_get_connected_subchannel(grpc_subchannel* c) {
-  gpr_mu_lock(&c->mu);
-  auto copy = c->connected_subchannel;
-  gpr_mu_unlock(&c->mu);
-  return copy;
+grpc_connected_subchannel* grpc_subchannel_get_connected_subchannel(
+    grpc_subchannel* c) {
+  return GET_CONNECTED_SUBCHANNEL(c, acq);
 }
 
 const grpc_subchannel_key* grpc_subchannel_get_key(
@@ -704,6 +738,36 @@
   return subchannel->key;
 }
 
+grpc_error* grpc_connected_subchannel_create_call(
+    grpc_connected_subchannel* con,
+    const grpc_connected_subchannel_call_args* args,
+    grpc_subchannel_call** call) {
+  grpc_channel_stack* chanstk = CHANNEL_STACK_FROM_CONNECTION(con);
+  *call = (grpc_subchannel_call*)gpr_arena_alloc(
+      args->arena, sizeof(grpc_subchannel_call) + chanstk->call_stack_size);
+  grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call);
+  (*call)->connection = GRPC_CONNECTED_SUBCHANNEL_REF(con, "subchannel_call");
+  const grpc_call_element_args call_args = {
+      callstk,            /* call_stack */
+      nullptr,            /* server_transport_data */
+      args->context,      /* context */
+      args->path,         /* path */
+      args->start_time,   /* start_time */
+      args->deadline,     /* deadline */
+      args->arena,        /* arena */
+      args->call_combiner /* call_combiner */
+  };
+  grpc_error* error = grpc_call_stack_init(chanstk, 1, subchannel_call_destroy,
+                                           *call, &call_args);
+  if (error != GRPC_ERROR_NONE) {
+    const char* error_string = grpc_error_string(error);
+    gpr_log(GPR_ERROR, "error: %s", error_string);
+    return error;
+  }
+  grpc_call_stack_set_pollset_or_pollset_set(callstk, args->pollent);
+  return GRPC_ERROR_NONE;
+}
+
 grpc_call_stack* grpc_subchannel_call_get_call_stack(
     grpc_subchannel_call* subchannel_call) {
   return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call);
@@ -739,64 +803,3 @@
       (char*)GRPC_ARG_SUBCHANNEL_ADDRESS,
       addr->len > 0 ? grpc_sockaddr_to_uri(addr) : gpr_strdup(""));
 }
-
-namespace grpc_core {
-ConnectedSubchannel::ConnectedSubchannel(grpc_channel_stack* channel_stack)
-    : grpc_core::RefCountedWithTracing(&grpc_trace_stream_refcount),
-      channel_stack_(channel_stack) {}
-
-ConnectedSubchannel::~ConnectedSubchannel() {
-  GRPC_CHANNEL_STACK_UNREF(channel_stack_, "connected_subchannel_dtor");
-}
-
-void ConnectedSubchannel::NotifyOnStateChange(
-    grpc_pollset_set* interested_parties, grpc_connectivity_state* state,
-    grpc_closure* closure) {
-  grpc_transport_op* op = grpc_make_transport_op(nullptr);
-  grpc_channel_element* elem;
-  op->connectivity_state = state;
-  op->on_connectivity_state_change = closure;
-  op->bind_pollset_set = interested_parties;
-  elem = grpc_channel_stack_element(channel_stack_, 0);
-  elem->filter->start_transport_op(elem, op);
-}
-
-void ConnectedSubchannel::Ping(grpc_closure* on_initiate,
-                               grpc_closure* on_ack) {
-  grpc_transport_op* op = grpc_make_transport_op(nullptr);
-  grpc_channel_element* elem;
-  op->send_ping.on_initiate = on_initiate;
-  op->send_ping.on_ack = on_ack;
-  elem = grpc_channel_stack_element(channel_stack_, 0);
-  elem->filter->start_transport_op(elem, op);
-}
-
-grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args,
-                                            grpc_subchannel_call** call) {
-  *call = (grpc_subchannel_call*)gpr_arena_alloc(
-      args.arena,
-      sizeof(grpc_subchannel_call) + channel_stack_->call_stack_size);
-  grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call);
-  Ref(DEBUG_LOCATION, "subchannel_call");
-  (*call)->connection = this;
-  const grpc_call_element_args call_args = {
-      callstk,           /* call_stack */
-      nullptr,           /* server_transport_data */
-      args.context,      /* context */
-      args.path,         /* path */
-      args.start_time,   /* start_time */
-      args.deadline,     /* deadline */
-      args.arena,        /* arena */
-      args.call_combiner /* call_combiner */
-  };
-  grpc_error* error = grpc_call_stack_init(
-      channel_stack_, 1, subchannel_call_destroy, *call, &call_args);
-  if (error != GRPC_ERROR_NONE) {
-    const char* error_string = grpc_error_string(error);
-    gpr_log(GPR_ERROR, "error: %s", error_string);
-    return error;
-  }
-  grpc_call_stack_set_pollset_or_pollset_set(callstk, args.pollent);
-  return GRPC_ERROR_NONE;
-}
-}  // namespace grpc_core
diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h
index 3bcc5c2..65d7825 100644
--- a/src/core/ext/filters/client_channel/subchannel.h
+++ b/src/core/ext/filters/client_channel/subchannel.h
@@ -21,10 +21,10 @@
 
 #include "src/core/ext/filters/client_channel/connector.h"
 #include "src/core/lib/channel/channel_stack.h"
+#include "src/core/lib/gpr++/ref_counted.h"
+#include "src/core/lib/gpr++/ref_counted_ptr.h"
+#include "src/core/lib/gpr/arena.h"
 #include "src/core/lib/iomgr/polling_entity.h"
-#include "src/core/lib/support/arena.h"
-#include "src/core/lib/support/ref_counted.h"
-#include "src/core/lib/support/ref_counted_ptr.h"
 #include "src/core/lib/transport/connectivity_state.h"
 #include "src/core/lib/transport/metadata.h"
 
@@ -34,6 +34,7 @@
 /** A (sub-)channel that knows how to connect to exactly one target
     address. Provides a target for load balancing. */
 typedef struct grpc_subchannel grpc_subchannel;
+typedef struct grpc_connected_subchannel grpc_connected_subchannel;
 typedef struct grpc_subchannel_call grpc_subchannel_call;
 typedef struct grpc_subchannel_args grpc_subchannel_args;
 typedef struct grpc_subchannel_key grpc_subchannel_key;
@@ -49,6 +50,10 @@
   grpc_subchannel_weak_ref((p), __FILE__, __LINE__, (r))
 #define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) \
   grpc_subchannel_weak_unref((p), __FILE__, __LINE__, (r))
+#define GRPC_CONNECTED_SUBCHANNEL_REF(p, r) \
+  grpc_connected_subchannel_ref((p), __FILE__, __LINE__, (r))
+#define GRPC_CONNECTED_SUBCHANNEL_UNREF(p, r) \
+  grpc_connected_subchannel_unref((p), __FILE__, __LINE__, (r))
 #define GRPC_SUBCHANNEL_CALL_REF(p, r) \
   grpc_subchannel_call_ref((p), __FILE__, __LINE__, (r))
 #define GRPC_SUBCHANNEL_CALL_UNREF(p, r) \
@@ -62,39 +67,14 @@
 #define GRPC_SUBCHANNEL_UNREF(p, r) grpc_subchannel_unref((p))
 #define GRPC_SUBCHANNEL_WEAK_REF(p, r) grpc_subchannel_weak_ref((p))
 #define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) grpc_subchannel_weak_unref((p))
+#define GRPC_CONNECTED_SUBCHANNEL_REF(p, r) grpc_connected_subchannel_ref((p))
+#define GRPC_CONNECTED_SUBCHANNEL_UNREF(p, r) \
+  grpc_connected_subchannel_unref((p))
 #define GRPC_SUBCHANNEL_CALL_REF(p, r) grpc_subchannel_call_ref((p))
 #define GRPC_SUBCHANNEL_CALL_UNREF(p, r) grpc_subchannel_call_unref((p))
 #define GRPC_SUBCHANNEL_REF_EXTRA_ARGS
 #endif
 
-namespace grpc_core {
-class ConnectedSubchannel : public grpc_core::RefCountedWithTracing {
- public:
-  struct CallArgs {
-    grpc_polling_entity* pollent;
-    grpc_slice path;
-    gpr_timespec start_time;
-    grpc_millis deadline;
-    gpr_arena* arena;
-    grpc_call_context_element* context;
-    grpc_call_combiner* call_combiner;
-  };
-
-  explicit ConnectedSubchannel(grpc_channel_stack* channel_stack);
-  ~ConnectedSubchannel();
-
-  grpc_channel_stack* channel_stack() { return channel_stack_; }
-  void NotifyOnStateChange(grpc_pollset_set* interested_parties,
-                           grpc_connectivity_state* state,
-                           grpc_closure* closure);
-  void Ping(grpc_closure* on_initiate, grpc_closure* on_ack);
-  grpc_error* CreateCall(const CallArgs& args, grpc_subchannel_call** call);
-
- private:
-  grpc_channel_stack* channel_stack_;
-};
-}  // namespace grpc_core
-
 grpc_subchannel* grpc_subchannel_ref(
     grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
 grpc_subchannel* grpc_subchannel_ref_from_weak_ref(
@@ -105,11 +85,35 @@
     grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
 void grpc_subchannel_weak_unref(
     grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
+grpc_connected_subchannel* grpc_connected_subchannel_ref(
+    grpc_connected_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
+void grpc_connected_subchannel_unref(
+    grpc_connected_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
 void grpc_subchannel_call_ref(
     grpc_subchannel_call* call GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
 void grpc_subchannel_call_unref(
     grpc_subchannel_call* call GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
 
+/** construct a subchannel call */
+typedef struct {
+  grpc_polling_entity* pollent;
+  grpc_slice path;
+  gpr_timespec start_time;
+  grpc_millis deadline;
+  gpr_arena* arena;
+  grpc_call_context_element* context;
+  grpc_call_combiner* call_combiner;
+} grpc_connected_subchannel_call_args;
+
+grpc_error* grpc_connected_subchannel_create_call(
+    grpc_connected_subchannel* connected_subchannel,
+    const grpc_connected_subchannel_call_args* args,
+    grpc_subchannel_call** subchannel_call);
+
+/** process a transport level op */
+void grpc_connected_subchannel_process_transport_op(
+    grpc_connected_subchannel* subchannel, grpc_transport_op* op);
+
 /** poll the current connectivity state of a channel */
 grpc_connectivity_state grpc_subchannel_check_connectivity(
     grpc_subchannel* channel, grpc_error** error);
@@ -119,12 +123,17 @@
 void grpc_subchannel_notify_on_state_change(
     grpc_subchannel* channel, grpc_pollset_set* interested_parties,
     grpc_connectivity_state* state, grpc_closure* notify);
+void grpc_connected_subchannel_notify_on_state_change(
+    grpc_connected_subchannel* channel, grpc_pollset_set* interested_parties,
+    grpc_connectivity_state* state, grpc_closure* notify);
+void grpc_connected_subchannel_ping(grpc_connected_subchannel* channel,
+                                    grpc_closure* on_initiate,
+                                    grpc_closure* on_ack);
 
-/** retrieve the grpc_core::ConnectedSubchannel - or nullptr if not connected
- * (which may happen before it initially connects or during transient failures)
- * */
-grpc_core::RefCountedPtr<grpc_core::ConnectedSubchannel>
-grpc_subchannel_get_connected_subchannel(grpc_subchannel* c);
+/** retrieve the grpc_connected_subchannel - or NULL if called before
+    the subchannel becomes connected */
+grpc_connected_subchannel* grpc_subchannel_get_connected_subchannel(
+    grpc_subchannel* subchannel);
 
 /** return the subchannel index key for \a subchannel */
 const grpc_subchannel_key* grpc_subchannel_get_key(
diff --git a/src/core/ext/filters/client_channel/uri_parser.cc b/src/core/ext/filters/client_channel/uri_parser.cc
index 3428f4b..c5f2d68 100644
--- a/src/core/ext/filters/client_channel/uri_parser.cc
+++ b/src/core/ext/filters/client_channel/uri_parser.cc
@@ -26,10 +26,10 @@
 #include <grpc/support/port_platform.h>
 #include <grpc/support/string_util.h>
 
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/slice/percent_encoding.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 
 /** a size_t default value... maps to all 1's */
 #define NOT_SET (~(size_t)0)
diff --git a/src/core/ext/filters/http/client/http_client_filter.cc b/src/core/ext/filters/http/client/http_client_filter.cc
index 6dbd8c2..5584d50 100644
--- a/src/core/ext/filters/http/client/http_client_filter.cc
+++ b/src/core/ext/filters/http/client/http_client_filter.cc
@@ -20,12 +20,12 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include <string.h>
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/slice/b64.h"
 #include "src/core/lib/slice/percent_encoding.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/static_metadata.h"
 #include "src/core/lib/transport/transport_impl.h"
 
diff --git a/src/core/ext/filters/http/message_compress/message_compress_filter.cc b/src/core/ext/filters/http/message_compress/message_compress_filter.cc
index 92d1716..d0b9750 100644
--- a/src/core/ext/filters/http/message_compress/message_compress_filter.cc
+++ b/src/core/ext/filters/http/message_compress/message_compress_filter.cc
@@ -28,10 +28,10 @@
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/compression/algorithm_metadata.h"
 #include "src/core/lib/compression/message_compress.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/call.h"
 #include "src/core/lib/transport/static_metadata.h"
 
diff --git a/src/core/ext/filters/max_age/max_age_filter.cc b/src/core/ext/filters/max_age/max_age_filter.cc
index 7b86e4c..a3f9780 100644
--- a/src/core/ext/filters/max_age/max_age_filter.cc
+++ b/src/core/ext/filters/max_age/max_age_filter.cc
@@ -37,6 +37,12 @@
 #define MAX_CONNECTION_IDLE_INTEGER_OPTIONS \
   { DEFAULT_MAX_CONNECTION_IDLE_MS, 1, INT_MAX }
 
+/* States for idle_state in channel_data */
+#define MAX_IDLE_STATE_INIT ((gpr_atm)0)
+#define MAX_IDLE_STATE_SEEN_EXIT_IDLE ((gpr_atm)1)
+#define MAX_IDLE_STATE_SEEN_ENTER_IDLE ((gpr_atm)2)
+#define MAX_IDLE_STATE_TIMER_SET ((gpr_atm)3)
+
 namespace {
 struct channel_data {
   /* We take a reference to the channel stack for the timer callback */
@@ -64,7 +70,7 @@
   grpc_millis max_connection_age_grace;
   /* Closure to run when the channel's idle duration reaches max_connection_idle
      and should be closed gracefully */
-  grpc_closure close_max_idle_channel;
+  grpc_closure max_idle_timer_cb;
   /* Closure to run when the channel reaches its max age and should be closed
      gracefully */
   grpc_closure close_max_age_channel;
@@ -85,26 +91,117 @@
   grpc_connectivity_state connectivity_state;
   /* Number of active calls */
   gpr_atm call_count;
+  /* TODO(zyc): C++lize this state machine */
+  /* 'idle_state' holds the states of max_idle_timer and channel idleness.
+      It can contain one of the following values:
+     +--------------------------------+----------------+---------+
+     |           idle_state           | max_idle_timer | channel |
+     +--------------------------------+----------------+---------+
+     | MAX_IDLE_STATE_INIT            | unset          | busy    |
+     | MAX_IDLE_STATE_TIMER_SET       | set, valid     | idle    |
+     | MAX_IDLE_STATE_SEEN_EXIT_IDLE  | set, invalid   | busy    |
+     | MAX_IDLE_STATE_SEEN_ENTER_IDLE | set, invalid   | idle    |
+     +--------------------------------+----------------+---------+
+
+     MAX_IDLE_STATE_INIT: The initial and final state of 'idle_state'. The
+     channel has 1 or 1+ active calls, and the the timer is not set. Note that
+     we may put a virtual call to hold this state at channel initialization or
+     shutdown, so that the channel won't enter other states.
+
+     MAX_IDLE_STATE_TIMER_SET: The state after the timer is set and no calls
+     have arrived after the timer is set. The channel must have 0 active call in
+     this state. If the timer is fired in this state, we will close the channel
+     due to idleness.
+
+     MAX_IDLE_STATE_SEEN_EXIT_IDLE: The state after the timer is set and at
+     least one call has arrived after the timer is set. The channel must have 1
+     or 1+ active calls in this state. If the timer is fired in this state, we
+     won't reschudle it.
+
+     MAX_IDLE_STATE_SEEN_ENTER_IDLE: The state after the timer is set and the at
+     least one call has arrived after the timer is set, BUT the channel
+     currently has 1 or 1+ active calls. If the timer is fired in this state, we
+     will reschudle it.
+
+     max_idle_timer will not be cancelled (unless the channel is shutting down).
+     If the timer callback is called when the max_idle_timer is valid (i.e.
+     idle_state is MAX_IDLE_STATE_TIMER_SET), the channel will be closed due to
+     idleness, otherwise the channel won't be changed.
+
+     State transitions:
+         MAX_IDLE_STATE_INIT <-------3------ MAX_IDLE_STATE_SEEN_EXIT_IDLE
+              ^    |                              ^     ^    |
+              |    |                              |     |    |
+              1    2     +-----------4------------+     6    7
+              |    |     |                              |    |
+              |    v     |                              |    v
+       MAX_IDLE_STATE_TIMER_SET <----5------ MAX_IDLE_STATE_SEEN_ENTER_IDLE
+
+     For 1, 3, 5 :  See max_idle_timer_cb() function
+     For 2, 7    :  See decrease_call_count() function
+     For 4, 6    :  See increase_call_count() function */
+  gpr_atm idle_state;
+  /* Time when the channel finished its last outstanding call, in grpc_millis */
+  gpr_atm last_enter_idle_time_millis;
 };
 }  // namespace
 
 /* Increase the nubmer of active calls. Before the increasement, if there are no
    calls, the max_idle_timer should be cancelled. */
 static void increase_call_count(channel_data* chand) {
+  /* Exit idle */
   if (gpr_atm_full_fetch_add(&chand->call_count, 1) == 0) {
-    grpc_timer_cancel(&chand->max_idle_timer);
+    while (true) {
+      gpr_atm idle_state = gpr_atm_acq_load(&chand->idle_state);
+      switch (idle_state) {
+        case MAX_IDLE_STATE_TIMER_SET:
+          /* max_idle_timer_cb may have already set idle_state to
+             MAX_IDLE_STATE_INIT, in this case, we don't need to set it to
+             MAX_IDLE_STATE_SEEN_EXIT_IDLE */
+          gpr_atm_rel_cas(&chand->idle_state, MAX_IDLE_STATE_TIMER_SET,
+                          MAX_IDLE_STATE_SEEN_EXIT_IDLE);
+          return;
+        case MAX_IDLE_STATE_SEEN_ENTER_IDLE:
+          gpr_atm_rel_store(&chand->idle_state, MAX_IDLE_STATE_SEEN_EXIT_IDLE);
+          return;
+        default:
+          /* try again */
+          break;
+      }
+    }
   }
 }
 
 /* Decrease the nubmer of active calls. After the decrement, if there are no
    calls, the max_idle_timer should be started. */
 static void decrease_call_count(channel_data* chand) {
+  /* Enter idle */
   if (gpr_atm_full_fetch_add(&chand->call_count, -1) == 1) {
-    GRPC_CHANNEL_STACK_REF(chand->channel_stack, "max_age max_idle_timer");
-    grpc_timer_init(
-        &chand->max_idle_timer,
-        grpc_core::ExecCtx::Get()->Now() + chand->max_connection_idle,
-        &chand->close_max_idle_channel);
+    gpr_atm_no_barrier_store(&chand->last_enter_idle_time_millis,
+                             (gpr_atm)grpc_core::ExecCtx::Get()->Now());
+    while (true) {
+      gpr_atm idle_state = gpr_atm_acq_load(&chand->idle_state);
+      switch (idle_state) {
+        case MAX_IDLE_STATE_INIT:
+          GRPC_CHANNEL_STACK_REF(chand->channel_stack,
+                                 "max_age max_idle_timer");
+          grpc_timer_init(
+              &chand->max_idle_timer,
+              grpc_core::ExecCtx::Get()->Now() + chand->max_connection_idle,
+              &chand->max_idle_timer_cb);
+          gpr_atm_rel_store(&chand->idle_state, MAX_IDLE_STATE_TIMER_SET);
+          return;
+        case MAX_IDLE_STATE_SEEN_EXIT_IDLE:
+          if (gpr_atm_rel_cas(&chand->idle_state, MAX_IDLE_STATE_SEEN_EXIT_IDLE,
+                              MAX_IDLE_STATE_SEEN_ENTER_IDLE)) {
+            return;
+          }
+          break;
+        default:
+          /* try again */
+          break;
+      }
+    }
   }
 }
 
@@ -152,20 +249,58 @@
                            "max_age start_max_age_grace_timer_after_goaway_op");
 }
 
-static void close_max_idle_channel(void* arg, grpc_error* error) {
+static void close_max_idle_channel(channel_data* chand) {
+  /* Prevent the max idle timer from being set again */
+  gpr_atm_no_barrier_fetch_add(&chand->call_count, 1);
+  grpc_transport_op* op = grpc_make_transport_op(nullptr);
+  op->goaway_error =
+      grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("max_idle"),
+                         GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_NO_ERROR);
+  grpc_channel_element* elem =
+      grpc_channel_stack_element(chand->channel_stack, 0);
+  elem->filter->start_transport_op(elem, op);
+}
+
+static void max_idle_timer_cb(void* arg, grpc_error* error) {
   channel_data* chand = (channel_data*)arg;
   if (error == GRPC_ERROR_NONE) {
-    /* Prevent the max idle timer from being set again */
-    gpr_atm_no_barrier_fetch_add(&chand->call_count, 1);
-    grpc_transport_op* op = grpc_make_transport_op(nullptr);
-    op->goaway_error =
-        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("max_idle"),
-                           GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_NO_ERROR);
-    grpc_channel_element* elem =
-        grpc_channel_stack_element(chand->channel_stack, 0);
-    elem->filter->start_transport_op(elem, op);
-  } else if (error != GRPC_ERROR_CANCELLED) {
-    GRPC_LOG_IF_ERROR("close_max_idle_channel", error);
+    bool try_again = true;
+    while (try_again) {
+      gpr_atm idle_state = gpr_atm_acq_load(&chand->idle_state);
+      switch (idle_state) {
+        case MAX_IDLE_STATE_TIMER_SET:
+          close_max_idle_channel(chand);
+          /* This MAX_IDLE_STATE_INIT is a final state, we don't have to check
+           * if idle_state has been changed */
+          gpr_atm_rel_store(&chand->idle_state, MAX_IDLE_STATE_INIT);
+          try_again = false;
+          break;
+        case MAX_IDLE_STATE_SEEN_EXIT_IDLE:
+          if (gpr_atm_rel_cas(&chand->idle_state, MAX_IDLE_STATE_SEEN_EXIT_IDLE,
+                              MAX_IDLE_STATE_INIT)) {
+            try_again = false;
+          }
+          break;
+        case MAX_IDLE_STATE_SEEN_ENTER_IDLE:
+          GRPC_CHANNEL_STACK_REF(chand->channel_stack,
+                                 "max_age max_idle_timer");
+          grpc_timer_init(&chand->max_idle_timer,
+                          (grpc_millis)gpr_atm_no_barrier_load(
+                              &chand->last_enter_idle_time_millis) +
+                              chand->max_connection_idle,
+                          &chand->max_idle_timer_cb);
+          /* idle_state may have already been set to
+             MAX_IDLE_STATE_SEEN_EXIT_IDLE by increase_call_count(), in this
+             case, we don't need to set it to MAX_IDLE_STATE_TIMER_SET */
+          gpr_atm_rel_cas(&chand->idle_state, MAX_IDLE_STATE_SEEN_ENTER_IDLE,
+                          MAX_IDLE_STATE_TIMER_SET);
+          try_again = false;
+          break;
+        default:
+          /* try again */
+          break;
+      }
+    }
   }
   GRPC_CHANNEL_STACK_UNREF(chand->channel_stack, "max_age max_idle_timer");
 }
@@ -288,6 +423,9 @@
   chand->max_connection_idle = DEFAULT_MAX_CONNECTION_IDLE_MS == INT_MAX
                                    ? GRPC_MILLIS_INF_FUTURE
                                    : DEFAULT_MAX_CONNECTION_IDLE_MS;
+  chand->idle_state = MAX_IDLE_STATE_INIT;
+  gpr_atm_no_barrier_store(&chand->last_enter_idle_time_millis,
+                           GRPC_MILLIS_INF_PAST);
   for (size_t i = 0; i < args->channel_args->num_args; ++i) {
     if (0 == strcmp(args->channel_args->args[i].key,
                     GRPC_ARG_MAX_CONNECTION_AGE_MS)) {
@@ -311,8 +449,8 @@
           value == INT_MAX ? GRPC_MILLIS_INF_FUTURE : value;
     }
   }
-  GRPC_CLOSURE_INIT(&chand->close_max_idle_channel, close_max_idle_channel,
-                    chand, grpc_schedule_on_exec_ctx);
+  GRPC_CLOSURE_INIT(&chand->max_idle_timer_cb, max_idle_timer_cb, chand,
+                    grpc_schedule_on_exec_ctx);
   GRPC_CLOSURE_INIT(&chand->close_max_age_channel, close_max_age_channel, chand,
                     grpc_schedule_on_exec_ctx);
   GRPC_CLOSURE_INIT(&chand->force_close_max_age_channel,
diff --git a/src/core/ext/filters/message_size/message_size_filter.cc b/src/core/ext/filters/message_size/message_size_filter.cc
index 3cb7b13..8d76c4a 100644
--- a/src/core/ext/filters/message_size/message_size_filter.cc
+++ b/src/core/ext/filters/message_size/message_size_filter.cc
@@ -26,7 +26,7 @@
 
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/channel_stack_builder.h"
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/surface/channel_init.h"
 #include "src/core/lib/transport/service_config.h"
 
diff --git a/src/core/ext/transport/chttp2/transport/bin_decoder.cc b/src/core/ext/transport/chttp2/transport/bin_decoder.cc
index 984cd4c..74778ac 100644
--- a/src/core/ext/transport/chttp2/transport/bin_decoder.cc
+++ b/src/core/ext/transport/chttp2/transport/bin_decoder.cc
@@ -19,9 +19,9 @@
 #include "src/core/ext/transport/chttp2/transport/bin_decoder.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 
 static uint8_t decode_table[] = {
     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc b/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
index 3aca61f..a699081 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
+++ b/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
@@ -18,7 +18,7 @@
 
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/debug/trace.h"
-#include "src/core/lib/support/env.h"
+#include "src/core/lib/gpr/env.h"
 #include "src/core/lib/transport/metadata.h"
 
 void grpc_chttp2_plugin_init(void) {
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
index 835de6a..e067b69 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
@@ -38,14 +38,14 @@
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/compression/stream_compression.h"
 #include "src/core/lib/debug/stats.h"
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/http/parser.h"
 #include "src/core/lib/iomgr/executor.h"
 #include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/error_utils.h"
 #include "src/core/lib/transport/http2_errors.h"
 #include "src/core/lib/transport/static_metadata.h"
diff --git a/src/core/ext/transport/chttp2/transport/flow_control.cc b/src/core/ext/transport/chttp2/transport/flow_control.cc
index 3013db2..581241d 100644
--- a/src/core/ext/transport/chttp2/transport/flow_control.cc
+++ b/src/core/ext/transport/chttp2/transport/flow_control.cc
@@ -29,7 +29,7 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/ext/transport/chttp2/transport/internal.h"
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 
 grpc_core::TraceFlag grpc_flowctl_trace(false, "flowctl");
 
diff --git a/src/core/ext/transport/chttp2/transport/flow_control.h b/src/core/ext/transport/chttp2/transport/flow_control.h
index 38b9f50..7e83ea0 100644
--- a/src/core/ext/transport/chttp2/transport/flow_control.h
+++ b/src/core/ext/transport/chttp2/transport/flow_control.h
@@ -24,8 +24,8 @@
 
 #include <grpc/support/useful.h>
 #include "src/core/ext/transport/chttp2/transport/http2_settings.h"
-#include "src/core/lib/support/abstract.h"
-#include "src/core/lib/support/manual_constructor.h"
+#include "src/core/lib/gpr++/abstract.h"
+#include "src/core/lib/gpr++/manual_constructor.h"
 #include "src/core/lib/transport/bdp_estimator.h"
 #include "src/core/lib/transport/pid_controller.h"
 
diff --git a/src/core/ext/transport/chttp2/transport/frame_data.cc b/src/core/ext/transport/chttp2/transport/frame_data.cc
index 9b3a6ac..043b80a 100644
--- a/src/core/ext/transport/chttp2/transport/frame_data.cc
+++ b/src/core/ext/transport/chttp2/transport/frame_data.cc
@@ -25,9 +25,9 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
 #include "src/core/ext/transport/chttp2/transport/internal.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/transport.h"
 
 grpc_error* grpc_chttp2_data_parser_init(grpc_chttp2_data_parser* parser) {
diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.cc b/src/core/ext/transport/chttp2/transport/hpack_parser.cc
index a395ab2..ebee591 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_parser.cc
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser.cc
@@ -31,10 +31,10 @@
 
 #include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
 #include "src/core/lib/debug/stats.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/http2_errors.h"
 
 typedef enum {
diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.cc b/src/core/ext/transport/chttp2/transport/hpack_table.cc
index c325465..9fad158 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_table.cc
+++ b/src/core/ext/transport/chttp2/transport/hpack_table.cc
@@ -26,7 +26,7 @@
 #include <grpc/support/string_util.h>
 
 #include "src/core/lib/debug/trace.h"
-#include "src/core/lib/support/murmur_hash.h"
+#include "src/core/lib/gpr/murmur_hash.h"
 
 extern grpc_core::TraceFlag grpc_http_trace;
 
diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h
index 8852d9e..de901f0 100644
--- a/src/core/ext/transport/chttp2/transport/internal.h
+++ b/src/core/ext/transport/chttp2/transport/internal.h
@@ -35,10 +35,10 @@
 #include "src/core/ext/transport/chttp2/transport/incoming_metadata.h"
 #include "src/core/ext/transport/chttp2/transport/stream_map.h"
 #include "src/core/lib/compression/stream_compression.h"
+#include "src/core/lib/gpr++/manual_constructor.h"
 #include "src/core/lib/iomgr/combiner.h"
 #include "src/core/lib/iomgr/endpoint.h"
 #include "src/core/lib/iomgr/timer.h"
-#include "src/core/lib/support/manual_constructor.h"
 #include "src/core/lib/transport/connectivity_state.h"
 #include "src/core/lib/transport/transport_impl.h"
 
diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc
index 5723da5..5b1c6ab 100644
--- a/src/core/ext/transport/cronet/transport/cronet_transport.cc
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc
@@ -28,11 +28,11 @@
 
 #include "src/core/ext/transport/chttp2/transport/incoming_metadata.h"
 #include "src/core/ext/transport/cronet/transport/cronet_transport.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/endpoint.h"
 #include "src/core/lib/iomgr/exec_ctx.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/transport/metadata_batch.h"
 #include "src/core/lib/transport/static_metadata.h"
diff --git a/src/core/lib/backoff/backoff.cc b/src/core/lib/backoff/backoff.cc
index 41f625a..d561fc7 100644
--- a/src/core/lib/backoff/backoff.cc
+++ b/src/core/lib/backoff/backoff.cc
@@ -41,18 +41,20 @@
   const double range = b - a;
   return a + generate_uniform_random_number(rng_state) * range;
 }
+
 }  // namespace
 
-BackOff::BackOff(const Options& options) : options_(options) {
-  rng_state_ = static_cast<uint32_t>(gpr_now(GPR_CLOCK_REALTIME).tv_nsec);
+BackOff::BackOff(const Options& options)
+    : options_(options),
+      rng_state_(static_cast<uint32_t>(gpr_now(GPR_CLOCK_REALTIME).tv_nsec)) {
+  Reset();
 }
 
-grpc_millis BackOff::Begin() {
-  current_backoff_ = options_.initial_backoff();
-  return current_backoff_ + grpc_core::ExecCtx::Get()->Now();
-}
-
-grpc_millis BackOff::Step() {
+grpc_millis BackOff::NextAttemptTime() {
+  if (initial_) {
+    initial_ = false;
+    return current_backoff_ + grpc_core::ExecCtx::Get()->Now();
+  }
   current_backoff_ =
       (grpc_millis)(std::min(current_backoff_ * options_.multiplier(),
                              (double)options_.max_backoff()));
@@ -63,7 +65,10 @@
   return next_timeout + grpc_core::ExecCtx::Get()->Now();
 }
 
-void BackOff::Reset() { current_backoff_ = options_.initial_backoff(); }
+void BackOff::Reset() {
+  current_backoff_ = options_.initial_backoff();
+  initial_ = true;
+}
 
 void BackOff::SetRandomSeed(uint32_t seed) { rng_state_ = seed; }
 
diff --git a/src/core/lib/backoff/backoff.h b/src/core/lib/backoff/backoff.h
index 84ef9b8..de30e52 100644
--- a/src/core/lib/backoff/backoff.h
+++ b/src/core/lib/backoff/backoff.h
@@ -32,14 +32,11 @@
   /// Initialize backoff machinery - does not need to be destroyed
   explicit BackOff(const Options& options);
 
-  /// Begin retry loop: returns the deadline to be used for the next attempt,
-  /// following the backoff strategy.
-  grpc_millis Begin();
-  /// Step a retry loop: returns the deadline to be used for the next attempt,
-  /// following the backoff strategy.
-  grpc_millis Step();
-  /// Reset the backoff, so the next grpc_backoff_step will be a
-  /// grpc_backoff_begin.
+  /// Returns the time at which the next attempt should start.
+  grpc_millis NextAttemptTime();
+
+  /// Reset the backoff, so the next value returned by NextAttemptTime()
+  /// will be the time of the second attempt (rather than the Nth).
   void Reset();
 
   void SetRandomSeed(unsigned int seed);
@@ -80,9 +77,10 @@
 
  private:
   const Options options_;
+  uint32_t rng_state_;
+  bool initial_;
   /// current delay before retries
   grpc_millis current_backoff_;
-  uint32_t rng_state_;
 };
 
 }  // namespace grpc_core
diff --git a/src/core/lib/channel/channel_args.cc b/src/core/lib/channel/channel_args.cc
index 578475b..634286d 100644
--- a/src/core/lib/channel/channel_args.cc
+++ b/src/core/lib/channel/channel_args.cc
@@ -29,7 +29,7 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 
 static grpc_arg copy_arg(const grpc_arg* src) {
   grpc_arg dst;
diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h
index 716866b..b9f9748 100644
--- a/src/core/lib/channel/channel_stack.h
+++ b/src/core/lib/channel/channel_stack.h
@@ -40,9 +40,9 @@
 #include <grpc/support/time.h>
 
 #include "src/core/lib/debug/trace.h"
+#include "src/core/lib/gpr/arena.h"
 #include "src/core/lib/iomgr/call_combiner.h"
 #include "src/core/lib/iomgr/polling_entity.h"
-#include "src/core/lib/support/arena.h"
 #include "src/core/lib/transport/transport.h"
 
 typedef struct grpc_channel_element grpc_channel_element;
diff --git a/src/core/lib/channel/connected_channel.cc b/src/core/lib/channel/connected_channel.cc
index 9d07cff..fb26bdf 100644
--- a/src/core/lib/channel/connected_channel.cc
+++ b/src/core/lib/channel/connected_channel.cc
@@ -26,8 +26,8 @@
 #include <grpc/slice_buffer.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/profiling/timers.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/transport.h"
 
 #define MAX_BUFFER_LENGTH 8192
diff --git a/src/core/lib/debug/stats.cc b/src/core/lib/debug/stats.cc
index 0b39b2b..465c761 100644
--- a/src/core/lib/debug/stats.cc
+++ b/src/core/lib/debug/stats.cc
@@ -25,7 +25,7 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
 
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 
 grpc_stats_data* grpc_stats_per_cpu_storage = nullptr;
 static size_t g_num_cores;
diff --git a/src/core/lib/debug/trace.cc b/src/core/lib/debug/trace.cc
index a76c1af..d870bbc 100644
--- a/src/core/lib/debug/trace.cc
+++ b/src/core/lib/debug/trace.cc
@@ -23,7 +23,7 @@
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
-#include "src/core/lib/support/env.h"
+#include "src/core/lib/gpr/env.h"
 
 int grpc_tracer_set_enabled(const char* name, int enabled);
 
diff --git a/src/core/lib/gpr++/README.md b/src/core/lib/gpr++/README.md
new file mode 100644
index 0000000..eab018b
--- /dev/null
+++ b/src/core/lib/gpr++/README.md
@@ -0,0 +1,16 @@
+# GPR++ - Google Portable Runtime for C++
+
+The files in this directory contain various utility code for C++ code.
+None of this code is gRPC-specific; anything here may also be useful
+for other open source projects written in C++.
+
+Note that this is one of the few places in src/core where we allow
+the use of portability macros.
+
+Note that this is the only place in src/core where we allow
+use of the C++ standard library (i.e., anything in the `std::`
+namespace).  And for now, we require that any use of the
+standard library is build-time-only -- i.e., we do not allow
+run-time dependencies on libstdc++.  For more details, see
+[gRFC L6](/grpc/proposal/blob/master/L6-allow-c%2B%2B-in-grpc-core.md) and
+[Moving gRPC core to C++](/grpc/grpc/blob/master/doc/core/moving-to-c%2B%2B.md).
diff --git a/src/core/lib/support/abstract.h b/src/core/lib/gpr++/abstract.h
similarity index 89%
rename from src/core/lib/support/abstract.h
rename to src/core/lib/gpr++/abstract.h
index 1dffa30..51d7572 100644
--- a/src/core/lib/support/abstract.h
+++ b/src/core/lib/gpr++/abstract.h
@@ -16,8 +16,8 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_ABSTRACT_H
-#define GRPC_CORE_LIB_SUPPORT_ABSTRACT_H
+#ifndef GRPC_CORE_LIB_GPRXX_ABSTRACT_H
+#define GRPC_CORE_LIB_GPRXX_ABSTRACT_H
 
 // This is needed to support abstract base classes in the c core. Since gRPC
 // doesn't have a c++ runtime, it will hit a linker error on delete unless
@@ -31,4 +31,4 @@
 #define GRPC_ABSTRACT \
   { GPR_ASSERT(false); }
 
-#endif /* GRPC_CORE_LIB_SUPPORT_ABSTRACT_H */
+#endif /* GRPC_CORE_LIB_GPRXX_ABSTRACT_H */
diff --git a/src/core/lib/support/atomic.h b/src/core/lib/gpr++/atomic.h
similarity index 75%
rename from src/core/lib/support/atomic.h
rename to src/core/lib/gpr++/atomic.h
index 73c59ae..d68ccea 100644
--- a/src/core/lib/support/atomic.h
+++ b/src/core/lib/gpr++/atomic.h
@@ -16,15 +16,15 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_ATOMIC_H
-#define GRPC_CORE_LIB_SUPPORT_ATOMIC_H
+#ifndef GRPC_CORE_LIB_GPRXX_ATOMIC_H
+#define GRPC_CORE_LIB_GPRXX_ATOMIC_H
 
 #include <grpc/support/port_platform.h>
 
 #ifdef GPR_HAS_CXX11_ATOMIC
-#include "src/core/lib/support/atomic_with_std.h"
+#include "src/core/lib/gpr++/atomic_with_std.h"
 #else
-#include "src/core/lib/support/atomic_with_atm.h"
+#include "src/core/lib/gpr++/atomic_with_atm.h"
 #endif
 
-#endif /* GRPC_CORE_LIB_SUPPORT_ATOMIC_H */
+#endif /* GRPC_CORE_LIB_GPRXX_ATOMIC_H */
diff --git a/src/core/lib/support/atomic_with_atm.h b/src/core/lib/gpr++/atomic_with_atm.h
similarity index 89%
rename from src/core/lib/support/atomic_with_atm.h
rename to src/core/lib/gpr++/atomic_with_atm.h
index fe00e9b..09490e8 100644
--- a/src/core/lib/support/atomic_with_atm.h
+++ b/src/core/lib/gpr++/atomic_with_atm.h
@@ -16,8 +16,8 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_ATM_H
-#define GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_ATM_H
+#ifndef GRPC_CORE_LIB_GPRXX_ATOMIC_WITH_ATM_H
+#define GRPC_CORE_LIB_GPRXX_ATOMIC_WITH_ATM_H
 
 #include <grpc/support/atm.h>
 
@@ -52,4 +52,4 @@
 
 }  // namespace grpc_core
 
-#endif /* GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_ATM_H */
+#endif /* GRPC_CORE_LIB_GPRXX_ATOMIC_WITH_ATM_H */
diff --git a/src/core/lib/support/atomic_with_std.h b/src/core/lib/gpr++/atomic_with_std.h
similarity index 83%
rename from src/core/lib/support/atomic_with_std.h
rename to src/core/lib/gpr++/atomic_with_std.h
index c7a92f7..b6ff906 100644
--- a/src/core/lib/support/atomic_with_std.h
+++ b/src/core/lib/gpr++/atomic_with_std.h
@@ -16,8 +16,8 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_STD_H
-#define GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_STD_H
+#ifndef GRPC_CORE_LIB_GPRXX_ATOMIC_WITH_STD_H
+#define GRPC_CORE_LIB_GPRXX_ATOMIC_WITH_STD_H
 
 #include <atomic>
 
@@ -30,4 +30,4 @@
 
 }  // namespace grpc_core
 
-#endif /* GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_STD_H */
+#endif /* GRPC_CORE_LIB_GPRXX_ATOMIC_WITH_STD_H */
diff --git a/src/core/lib/support/debug_location.h b/src/core/lib/gpr++/debug_location.h
similarity index 90%
rename from src/core/lib/support/debug_location.h
rename to src/core/lib/gpr++/debug_location.h
index 9b3f922..5a8665c 100644
--- a/src/core/lib/support/debug_location.h
+++ b/src/core/lib/gpr++/debug_location.h
@@ -16,8 +16,8 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_DEBUG_LOCATION_H
-#define GRPC_CORE_LIB_SUPPORT_DEBUG_LOCATION_H
+#ifndef GRPC_CORE_LIB_GPRXX_DEBUG_LOCATION_H
+#define GRPC_CORE_LIB_GPRXX_DEBUG_LOCATION_H
 
 namespace grpc_core {
 
@@ -49,4 +49,4 @@
 
 }  // namespace grpc_core
 
-#endif /* GRPC_CORE_LIB_SUPPORT_DEBUG_LOCATION_H */
+#endif /* GRPC_CORE_LIB_GPRXX_DEBUG_LOCATION_H */
diff --git a/src/core/lib/support/vector.h b/src/core/lib/gpr++/inlined_vector.h
similarity index 94%
rename from src/core/lib/support/vector.h
rename to src/core/lib/gpr++/inlined_vector.h
index 2f249a5..17ee9e1 100644
--- a/src/core/lib/support/vector.h
+++ b/src/core/lib/gpr++/inlined_vector.h
@@ -16,12 +16,12 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_VECTOR_H
-#define GRPC_CORE_LIB_SUPPORT_VECTOR_H
+#ifndef GRPC_CORE_LIB_GPRXX_INLINED_VECTOR_H
+#define GRPC_CORE_LIB_GPRXX_INLINED_VECTOR_H
 
 #include <cassert>
 
-#include "src/core/lib/support/memory.h"
+#include "src/core/lib/gpr++/memory.h"
 
 namespace grpc_core {
 
@@ -109,4 +109,4 @@
 
 }  // namespace grpc_core
 
-#endif
+#endif /* GRPC_CORE_LIB_GPRXX_INLINED_VECTOR_H */
diff --git a/src/core/lib/support/manual_constructor.h b/src/core/lib/gpr++/manual_constructor.h
similarity index 98%
rename from src/core/lib/support/manual_constructor.h
rename to src/core/lib/gpr++/manual_constructor.h
index fda7653..a3f006d 100644
--- a/src/core/lib/support/manual_constructor.h
+++ b/src/core/lib/gpr++/manual_constructor.h
@@ -16,8 +16,8 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_MANUAL_CONSTRUCTOR_H
-#define GRPC_CORE_LIB_SUPPORT_MANUAL_CONSTRUCTOR_H
+#ifndef GRPC_CORE_LIB_GPRXX_MANUAL_CONSTRUCTOR_H
+#define GRPC_CORE_LIB_GPRXX_MANUAL_CONSTRUCTOR_H
 
 // manually construct a region of memory with some type
 
diff --git a/src/core/lib/support/memory.h b/src/core/lib/gpr++/memory.h
similarity index 95%
rename from src/core/lib/support/memory.h
rename to src/core/lib/gpr++/memory.h
index 695418e..75ed3d6 100644
--- a/src/core/lib/support/memory.h
+++ b/src/core/lib/gpr++/memory.h
@@ -16,8 +16,8 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_MEMORY_H
-#define GRPC_CORE_LIB_SUPPORT_MEMORY_H
+#ifndef GRPC_CORE_LIB_GPRXX_MEMORY_H
+#define GRPC_CORE_LIB_GPRXX_MEMORY_H
 
 #include <grpc/support/alloc.h>
 
@@ -97,4 +97,4 @@
 
 }  // namespace grpc_core
 
-#endif /* GRPC_CORE_LIB_SUPPORT_MEMORY_H */
+#endif /* GRPC_CORE_LIB_GPRXX_MEMORY_H */
diff --git a/src/core/lib/support/orphanable.h b/src/core/lib/gpr++/orphanable.h
similarity index 94%
rename from src/core/lib/support/orphanable.h
rename to src/core/lib/gpr++/orphanable.h
index 2f53757..f106e74 100644
--- a/src/core/lib/support/orphanable.h
+++ b/src/core/lib/gpr++/orphanable.h
@@ -16,8 +16,8 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_ORPHANABLE_H
-#define GRPC_CORE_LIB_SUPPORT_ORPHANABLE_H
+#ifndef GRPC_CORE_LIB_GPRXX_ORPHANABLE_H
+#define GRPC_CORE_LIB_GPRXX_ORPHANABLE_H
 
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
@@ -25,9 +25,9 @@
 #include <memory>
 
 #include "src/core/lib/debug/trace.h"
-#include "src/core/lib/support/abstract.h"
-#include "src/core/lib/support/debug_location.h"
-#include "src/core/lib/support/memory.h"
+#include "src/core/lib/gpr++/abstract.h"
+#include "src/core/lib/gpr++/debug_location.h"
+#include "src/core/lib/gpr++/memory.h"
 
 namespace grpc_core {
 
@@ -168,4 +168,4 @@
 
 }  // namespace grpc_core
 
-#endif /* GRPC_CORE_LIB_SUPPORT_ORPHANABLE_H */
+#endif /* GRPC_CORE_LIB_GPRXX_ORPHANABLE_H */
diff --git a/src/core/lib/support/ref_counted.h b/src/core/lib/gpr++/ref_counted.h
similarity index 92%
rename from src/core/lib/support/ref_counted.h
rename to src/core/lib/gpr++/ref_counted.h
index 48c11f7..c2ae76c 100644
--- a/src/core/lib/support/ref_counted.h
+++ b/src/core/lib/gpr++/ref_counted.h
@@ -16,16 +16,16 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_REF_COUNTED_H
-#define GRPC_CORE_LIB_SUPPORT_REF_COUNTED_H
+#ifndef GRPC_CORE_LIB_GPRXX_REF_COUNTED_H
+#define GRPC_CORE_LIB_GPRXX_REF_COUNTED_H
 
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 
 #include "src/core/lib/debug/trace.h"
-#include "src/core/lib/support/abstract.h"
-#include "src/core/lib/support/debug_location.h"
-#include "src/core/lib/support/memory.h"
+#include "src/core/lib/gpr++/abstract.h"
+#include "src/core/lib/gpr++/debug_location.h"
+#include "src/core/lib/gpr++/memory.h"
 
 namespace grpc_core {
 
@@ -130,4 +130,4 @@
 
 }  // namespace grpc_core
 
-#endif /* GRPC_CORE_LIB_SUPPORT_REF_COUNTED_H */
+#endif /* GRPC_CORE_LIB_GPRXX_REF_COUNTED_H */
diff --git a/src/core/lib/support/ref_counted_ptr.h b/src/core/lib/gpr++/ref_counted_ptr.h
similarity index 93%
rename from src/core/lib/support/ref_counted_ptr.h
rename to src/core/lib/gpr++/ref_counted_ptr.h
index 76ff0bb..862294d 100644
--- a/src/core/lib/support/ref_counted_ptr.h
+++ b/src/core/lib/gpr++/ref_counted_ptr.h
@@ -16,12 +16,12 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_REF_COUNTED_PTR_H
-#define GRPC_CORE_LIB_SUPPORT_REF_COUNTED_PTR_H
+#ifndef GRPC_CORE_LIB_GPRXX_REF_COUNTED_PTR_H
+#define GRPC_CORE_LIB_GPRXX_REF_COUNTED_PTR_H
 
 #include <utility>
 
-#include "src/core/lib/support/memory.h"
+#include "src/core/lib/gpr++/memory.h"
 
 namespace grpc_core {
 
@@ -96,4 +96,4 @@
 
 }  // namespace grpc_core
 
-#endif /* GRPC_CORE_LIB_SUPPORT_REF_COUNTED_PTR_H */
+#endif /* GRPC_CORE_LIB_GPRXX_REF_COUNTED_PTR_H */
diff --git a/src/core/lib/gpr/README.md b/src/core/lib/gpr/README.md
new file mode 100644
index 0000000..21fb0c7
--- /dev/null
+++ b/src/core/lib/gpr/README.md
@@ -0,0 +1,8 @@
+# GPR - Google Portable Runtime for C
+
+The files in this directory contain basic utility code and platform
+abstractions for C code.  None of this code is gRPC-specific; anything
+here may also be useful for other open source projects written in C.
+
+Note that this is one of the few places in src/core where we allow
+the use of portability macros.
diff --git a/src/core/lib/support/alloc.cc b/src/core/lib/gpr/alloc.cc
similarity index 100%
rename from src/core/lib/support/alloc.cc
rename to src/core/lib/gpr/alloc.cc
diff --git a/src/core/lib/support/arena.cc b/src/core/lib/gpr/arena.cc
similarity index 98%
rename from src/core/lib/support/arena.cc
rename to src/core/lib/gpr/arena.cc
index 5b9dd37..177c176 100644
--- a/src/core/lib/support/arena.cc
+++ b/src/core/lib/gpr/arena.cc
@@ -16,7 +16,7 @@
  *
  */
 
-#include "src/core/lib/support/arena.h"
+#include "src/core/lib/gpr/arena.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/atm.h>
 #include <grpc/support/log.h>
diff --git a/src/core/lib/support/arena.h b/src/core/lib/gpr/arena.h
similarity index 91%
rename from src/core/lib/support/arena.h
rename to src/core/lib/gpr/arena.h
index cfe973a..339771c 100644
--- a/src/core/lib/support/arena.h
+++ b/src/core/lib/gpr/arena.h
@@ -22,8 +22,8 @@
 // Tracks the total memory allocated against it, so that future arenas can
 // pre-allocate the right amount of memory
 
-#ifndef GRPC_CORE_LIB_SUPPORT_ARENA_H
-#define GRPC_CORE_LIB_SUPPORT_ARENA_H
+#ifndef GRPC_CORE_LIB_GPR_ARENA_H
+#define GRPC_CORE_LIB_GPR_ARENA_H
 
 #include <stddef.h>
 
@@ -36,4 +36,4 @@
 // Destroy an arena, returning the total number of bytes allocated
 size_t gpr_arena_destroy(gpr_arena* arena);
 
-#endif /* GRPC_CORE_LIB_SUPPORT_ARENA_H */
+#endif /* GRPC_CORE_LIB_GPR_ARENA_H */
diff --git a/src/core/lib/support/atm.cc b/src/core/lib/gpr/atm.cc
similarity index 100%
rename from src/core/lib/support/atm.cc
rename to src/core/lib/gpr/atm.cc
diff --git a/src/core/lib/support/avl.cc b/src/core/lib/gpr/avl.cc
similarity index 100%
rename from src/core/lib/support/avl.cc
rename to src/core/lib/gpr/avl.cc
diff --git a/src/core/lib/support/cmdline.cc b/src/core/lib/gpr/cmdline.cc
similarity index 99%
rename from src/core/lib/support/cmdline.cc
rename to src/core/lib/gpr/cmdline.cc
index da9f10a..4118f9a 100644
--- a/src/core/lib/support/cmdline.cc
+++ b/src/core/lib/gpr/cmdline.cc
@@ -25,7 +25,7 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 
 typedef enum { ARGTYPE_INT, ARGTYPE_BOOL, ARGTYPE_STRING } argtype;
 
diff --git a/src/core/lib/support/cpu_iphone.cc b/src/core/lib/gpr/cpu_iphone.cc
similarity index 100%
rename from src/core/lib/support/cpu_iphone.cc
rename to src/core/lib/gpr/cpu_iphone.cc
diff --git a/src/core/lib/support/cpu_linux.cc b/src/core/lib/gpr/cpu_linux.cc
similarity index 100%
rename from src/core/lib/support/cpu_linux.cc
rename to src/core/lib/gpr/cpu_linux.cc
diff --git a/src/core/lib/support/cpu_posix.cc b/src/core/lib/gpr/cpu_posix.cc
similarity index 100%
rename from src/core/lib/support/cpu_posix.cc
rename to src/core/lib/gpr/cpu_posix.cc
diff --git a/src/core/lib/support/cpu_windows.cc b/src/core/lib/gpr/cpu_windows.cc
similarity index 100%
rename from src/core/lib/support/cpu_windows.cc
rename to src/core/lib/gpr/cpu_windows.cc
diff --git a/src/core/lib/support/env.h b/src/core/lib/gpr/env.h
similarity index 92%
rename from src/core/lib/support/env.h
rename to src/core/lib/gpr/env.h
index 2452fd3..7f35104 100644
--- a/src/core/lib/support/env.h
+++ b/src/core/lib/gpr/env.h
@@ -16,8 +16,8 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_ENV_H
-#define GRPC_CORE_LIB_SUPPORT_ENV_H
+#ifndef GRPC_CORE_LIB_GPR_ENV_H
+#define GRPC_CORE_LIB_GPR_ENV_H
 
 #include <stdio.h>
 
@@ -38,4 +38,4 @@
    level of logging. So DO NOT USE THIS. */
 const char* gpr_getenv_silent(const char* name, char** dst);
 
-#endif /* GRPC_CORE_LIB_SUPPORT_ENV_H */
+#endif /* GRPC_CORE_LIB_GPR_ENV_H */
diff --git a/src/core/lib/support/env_linux.cc b/src/core/lib/gpr/env_linux.cc
similarity index 96%
rename from src/core/lib/support/env_linux.cc
rename to src/core/lib/gpr/env_linux.cc
index 0af2de9..17902c3 100644
--- a/src/core/lib/support/env_linux.cc
+++ b/src/core/lib/gpr/env_linux.cc
@@ -25,7 +25,7 @@
 
 #ifdef GPR_LINUX_ENV
 
-#include "src/core/lib/support/env.h"
+#include "src/core/lib/gpr/env.h"
 
 #include <dlfcn.h>
 #include <features.h>
@@ -36,7 +36,7 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
 
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 
 const char* gpr_getenv_silent(const char* name, char** dst) {
   const char* insecure_func_used = nullptr;
diff --git a/src/core/lib/support/env_posix.cc b/src/core/lib/gpr/env_posix.cc
similarity index 93%
rename from src/core/lib/support/env_posix.cc
rename to src/core/lib/gpr/env_posix.cc
index 8146330..599f85a 100644
--- a/src/core/lib/support/env_posix.cc
+++ b/src/core/lib/gpr/env_posix.cc
@@ -20,14 +20,14 @@
 
 #ifdef GPR_POSIX_ENV
 
-#include "src/core/lib/support/env.h"
+#include "src/core/lib/gpr/env.h"
 
 #include <stdlib.h>
 
 #include <grpc/support/log.h>
 
 #include <grpc/support/string_util.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 
 const char* gpr_getenv_silent(const char* name, char** dst) {
   *dst = gpr_getenv(name);
diff --git a/src/core/lib/support/env_windows.cc b/src/core/lib/gpr/env_windows.cc
similarity index 92%
rename from src/core/lib/support/env_windows.cc
rename to src/core/lib/gpr/env_windows.cc
index cdb1d58..9ca1e02 100644
--- a/src/core/lib/support/env_windows.cc
+++ b/src/core/lib/gpr/env_windows.cc
@@ -22,9 +22,9 @@
 
 #include <windows.h>
 
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
-#include "src/core/lib/support/string_windows.h"
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/string_windows.h"
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
diff --git a/src/core/lib/support/fork.cc b/src/core/lib/gpr/fork.cc
similarity index 95%
rename from src/core/lib/support/fork.cc
rename to src/core/lib/gpr/fork.cc
index dc291c4..c47e686 100644
--- a/src/core/lib/support/fork.cc
+++ b/src/core/lib/gpr/fork.cc
@@ -16,14 +16,14 @@
  *
  */
 
-#include "src/core/lib/support/fork.h"
+#include "src/core/lib/gpr/fork.h"
 
 #include <string.h>
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/useful.h>
 
-#include "src/core/lib/support/env.h"
+#include "src/core/lib/gpr/env.h"
 
 /*
  * NOTE: FORKING IS NOT GENERALLY SUPPORTED, THIS IS ONLY INTENDED TO WORK
diff --git a/src/core/lib/support/fork.h b/src/core/lib/gpr/fork.h
similarity index 88%
rename from src/core/lib/support/fork.h
rename to src/core/lib/gpr/fork.h
index 215d4214..94c61bb 100644
--- a/src/core/lib/support/fork.h
+++ b/src/core/lib/gpr/fork.h
@@ -16,8 +16,8 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_FORK_H
-#define GRPC_CORE_LIB_SUPPORT_FORK_H
+#ifndef GRPC_CORE_LIB_GPR_FORK_H
+#define GRPC_CORE_LIB_GPR_FORK_H
 
 /*
  * NOTE: FORKING IS NOT GENERALLY SUPPORTED, THIS IS ONLY INTENDED TO WORK
@@ -32,4 +32,4 @@
 // environment variables/compile flags
 void grpc_enable_fork_support(int enable);
 
-#endif /* GRPC_CORE_LIB_SUPPORT_FORK_H */
+#endif /* GRPC_CORE_LIB_GPR_FORK_H */
diff --git a/src/core/lib/support/host_port.cc b/src/core/lib/gpr/host_port.cc
similarity index 98%
rename from src/core/lib/support/host_port.cc
rename to src/core/lib/gpr/host_port.cc
index cb8e3d4..2917827 100644
--- a/src/core/lib/support/host_port.cc
+++ b/src/core/lib/gpr/host_port.cc
@@ -23,7 +23,7 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 
 int gpr_join_host_port(char** out, const char* host, int port) {
   if (host[0] != '[' && strchr(host, ':') != nullptr) {
diff --git a/src/core/lib/support/log.cc b/src/core/lib/gpr/log.cc
similarity index 97%
rename from src/core/lib/support/log.cc
rename to src/core/lib/gpr/log.cc
index 2a40745..19c0f6c 100644
--- a/src/core/lib/support/log.cc
+++ b/src/core/lib/gpr/log.cc
@@ -21,8 +21,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/port_platform.h>
 
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
 
 #include <stdio.h>
 #include <string.h>
diff --git a/src/core/lib/support/log_android.cc b/src/core/lib/gpr/log_android.cc
similarity index 100%
rename from src/core/lib/support/log_android.cc
rename to src/core/lib/gpr/log_android.cc
diff --git a/src/core/lib/support/log_linux.cc b/src/core/lib/gpr/log_linux.cc
similarity index 100%
rename from src/core/lib/support/log_linux.cc
rename to src/core/lib/gpr/log_linux.cc
diff --git a/src/core/lib/support/log_posix.cc b/src/core/lib/gpr/log_posix.cc
similarity index 100%
rename from src/core/lib/support/log_posix.cc
rename to src/core/lib/gpr/log_posix.cc
diff --git a/src/core/lib/support/log_windows.cc b/src/core/lib/gpr/log_windows.cc
similarity index 96%
rename from src/core/lib/support/log_windows.cc
rename to src/core/lib/gpr/log_windows.cc
index 0013bf4..caaa973 100644
--- a/src/core/lib/support/log_windows.cc
+++ b/src/core/lib/gpr/log_windows.cc
@@ -29,8 +29,8 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/time.h>
 
-#include "src/core/lib/support/string.h"
-#include "src/core/lib/support/string_windows.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/string_windows.h"
 
 void gpr_log(const char* file, int line, gpr_log_severity severity,
              const char* format, ...) {
diff --git a/src/core/lib/support/mpscq.cc b/src/core/lib/gpr/mpscq.cc
similarity index 98%
rename from src/core/lib/support/mpscq.cc
rename to src/core/lib/gpr/mpscq.cc
index 47e896d..34fc050 100644
--- a/src/core/lib/support/mpscq.cc
+++ b/src/core/lib/gpr/mpscq.cc
@@ -16,7 +16,7 @@
  *
  */
 
-#include "src/core/lib/support/mpscq.h"
+#include "src/core/lib/gpr/mpscq.h"
 
 #include <grpc/support/log.h>
 
diff --git a/src/core/lib/support/mpscq.h b/src/core/lib/gpr/mpscq.h
similarity index 95%
rename from src/core/lib/support/mpscq.h
rename to src/core/lib/gpr/mpscq.h
index 648ead1..4409c5c 100644
--- a/src/core/lib/support/mpscq.h
+++ b/src/core/lib/gpr/mpscq.h
@@ -16,8 +16,8 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_MPSCQ_H
-#define GRPC_CORE_LIB_SUPPORT_MPSCQ_H
+#ifndef GRPC_CORE_LIB_GPR_MPSCQ_H
+#define GRPC_CORE_LIB_GPR_MPSCQ_H
 
 #include <grpc/support/atm.h>
 #include <grpc/support/sync.h>
@@ -81,4 +81,4 @@
 // calling this function
 gpr_mpscq_node* gpr_locked_mpscq_pop(gpr_locked_mpscq* q);
 
-#endif /* GRPC_CORE_LIB_SUPPORT_MPSCQ_H */
+#endif /* GRPC_CORE_LIB_GPR_MPSCQ_H */
diff --git a/src/core/lib/support/murmur_hash.cc b/src/core/lib/gpr/murmur_hash.cc
similarity index 97%
rename from src/core/lib/support/murmur_hash.cc
rename to src/core/lib/gpr/murmur_hash.cc
index 2f0e71a..3f5e04d 100644
--- a/src/core/lib/support/murmur_hash.cc
+++ b/src/core/lib/gpr/murmur_hash.cc
@@ -16,7 +16,7 @@
  *
  */
 
-#include "src/core/lib/support/murmur_hash.h"
+#include "src/core/lib/gpr/murmur_hash.h"
 
 #include <string.h>
 
diff --git a/src/core/lib/support/murmur_hash.h b/src/core/lib/gpr/murmur_hash.h
similarity index 84%
rename from src/core/lib/support/murmur_hash.h
rename to src/core/lib/gpr/murmur_hash.h
index 422770f..8004889 100644
--- a/src/core/lib/support/murmur_hash.h
+++ b/src/core/lib/gpr/murmur_hash.h
@@ -16,8 +16,8 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_MURMUR_HASH_H
-#define GRPC_CORE_LIB_SUPPORT_MURMUR_HASH_H
+#ifndef GRPC_CORE_LIB_GPR_MURMUR_HASH_H
+#define GRPC_CORE_LIB_GPR_MURMUR_HASH_H
 
 #include <grpc/support/port_platform.h>
 
@@ -26,4 +26,4 @@
 /* compute the hash of key (length len) */
 uint32_t gpr_murmur_hash3(const void* key, size_t len, uint32_t seed);
 
-#endif /* GRPC_CORE_LIB_SUPPORT_MURMUR_HASH_H */
+#endif /* GRPC_CORE_LIB_GPR_MURMUR_HASH_H */
diff --git a/src/core/lib/support/spinlock.h b/src/core/lib/gpr/spinlock.h
similarity index 90%
rename from src/core/lib/support/spinlock.h
rename to src/core/lib/gpr/spinlock.h
index 8b43964..f03be1d 100644
--- a/src/core/lib/support/spinlock.h
+++ b/src/core/lib/gpr/spinlock.h
@@ -16,8 +16,8 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_SPINLOCK_H
-#define GRPC_CORE_LIB_SUPPORT_SPINLOCK_H
+#ifndef GRPC_CORE_LIB_GPR_SPINLOCK_H
+#define GRPC_CORE_LIB_GPR_SPINLOCK_H
 
 #include <grpc/support/atm.h>
 
@@ -41,4 +41,4 @@
   do {                          \
   } while (!gpr_spinlock_trylock((lock)))
 
-#endif /* GRPC_CORE_LIB_SUPPORT_SPINLOCK_H */
+#endif /* GRPC_CORE_LIB_GPR_SPINLOCK_H */
diff --git a/src/core/lib/support/string.cc b/src/core/lib/gpr/string.cc
similarity index 99%
rename from src/core/lib/support/string.cc
rename to src/core/lib/gpr/string.cc
index e31ad72..919d957 100644
--- a/src/core/lib/support/string.cc
+++ b/src/core/lib/gpr/string.cc
@@ -16,7 +16,7 @@
  *
  */
 
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 
 #include <ctype.h>
 #include <limits.h>
diff --git a/src/core/lib/support/string.h b/src/core/lib/gpr/string.h
similarity index 96%
rename from src/core/lib/support/string.h
rename to src/core/lib/gpr/string.h
index dd37f0b..ef3a8c6 100644
--- a/src/core/lib/support/string.h
+++ b/src/core/lib/gpr/string.h
@@ -16,8 +16,8 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_STRING_H
-#define GRPC_CORE_LIB_SUPPORT_STRING_H
+#ifndef GRPC_CORE_LIB_GPR_STRING_H
+#define GRPC_CORE_LIB_GPR_STRING_H
 
 #include <stdbool.h>
 #include <stddef.h>
@@ -106,4 +106,4 @@
 /** Return true if lower(s) equals "true", "yes" or "1", otherwise false. */
 bool gpr_is_true(const char* s);
 
-#endif /* GRPC_CORE_LIB_SUPPORT_STRING_H */
+#endif /* GRPC_CORE_LIB_GPR_STRING_H */
diff --git a/src/core/lib/support/string_posix.cc b/src/core/lib/gpr/string_posix.cc
similarity index 100%
rename from src/core/lib/support/string_posix.cc
rename to src/core/lib/gpr/string_posix.cc
diff --git a/src/core/lib/support/string_util_windows.cc b/src/core/lib/gpr/string_util_windows.cc
similarity index 96%
rename from src/core/lib/support/string_util_windows.cc
rename to src/core/lib/gpr/string_util_windows.cc
index e2b386b..8c8c99c 100644
--- a/src/core/lib/support/string_util_windows.cc
+++ b/src/core/lib/gpr/string_util_windows.cc
@@ -36,8 +36,8 @@
 #include <grpc/support/log_windows.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/lib/support/string.h"
-#include "src/core/lib/support/string_windows.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/string_windows.h"
 
 #if defined UNICODE || defined _UNICODE
 LPTSTR
diff --git a/src/core/lib/support/string_windows.cc b/src/core/lib/gpr/string_windows.cc
similarity index 97%
rename from src/core/lib/support/string_windows.cc
rename to src/core/lib/gpr/string_windows.cc
index ceb78f0..25bfd41 100644
--- a/src/core/lib/support/string_windows.cc
+++ b/src/core/lib/gpr/string_windows.cc
@@ -29,7 +29,7 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 
 int gpr_asprintf(char** strp, const char* format, ...) {
   va_list args;
diff --git a/src/core/lib/support/string_windows.h b/src/core/lib/gpr/string_windows.h
similarity index 85%
rename from src/core/lib/support/string_windows.h
rename to src/core/lib/gpr/string_windows.h
index 7c7f31e..e370f80 100644
--- a/src/core/lib/support/string_windows.h
+++ b/src/core/lib/gpr/string_windows.h
@@ -16,8 +16,8 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_STRING_WINDOWS_H
-#define GRPC_CORE_LIB_SUPPORT_STRING_WINDOWS_H
+#ifndef GRPC_CORE_LIB_GPR_STRING_WINDOWS_H
+#define GRPC_CORE_LIB_GPR_STRING_WINDOWS_H
 
 #include <grpc/support/port_platform.h>
 
@@ -29,4 +29,4 @@
 
 #endif /* GPR_WINDOWS */
 
-#endif /* GRPC_CORE_LIB_SUPPORT_STRING_WINDOWS_H */
+#endif /* GRPC_CORE_LIB_GPR_STRING_WINDOWS_H */
diff --git a/src/core/lib/support/subprocess_posix.cc b/src/core/lib/gpr/subprocess_posix.cc
similarity index 100%
rename from src/core/lib/support/subprocess_posix.cc
rename to src/core/lib/gpr/subprocess_posix.cc
diff --git a/src/core/lib/support/subprocess_windows.cc b/src/core/lib/gpr/subprocess_windows.cc
similarity index 96%
rename from src/core/lib/support/subprocess_windows.cc
rename to src/core/lib/gpr/subprocess_windows.cc
index dcdafb5..1947d47 100644
--- a/src/core/lib/support/subprocess_windows.cc
+++ b/src/core/lib/gpr/subprocess_windows.cc
@@ -27,8 +27,8 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/subprocess.h>
-#include "src/core/lib/support/string.h"
-#include "src/core/lib/support/string_windows.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/string_windows.h"
 
 struct gpr_subprocess {
   PROCESS_INFORMATION pi;
diff --git a/src/core/lib/support/sync.cc b/src/core/lib/gpr/sync.cc
similarity index 100%
rename from src/core/lib/support/sync.cc
rename to src/core/lib/gpr/sync.cc
diff --git a/src/core/lib/support/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc
similarity index 100%
rename from src/core/lib/support/sync_posix.cc
rename to src/core/lib/gpr/sync_posix.cc
diff --git a/src/core/lib/support/sync_windows.cc b/src/core/lib/gpr/sync_windows.cc
similarity index 100%
rename from src/core/lib/support/sync_windows.cc
rename to src/core/lib/gpr/sync_windows.cc
diff --git a/src/core/lib/support/thd.cc b/src/core/lib/gpr/thd.cc
similarity index 100%
rename from src/core/lib/support/thd.cc
rename to src/core/lib/gpr/thd.cc
diff --git a/src/core/lib/support/thd_internal.h b/src/core/lib/gpr/thd_internal.h
similarity index 85%
rename from src/core/lib/support/thd_internal.h
rename to src/core/lib/gpr/thd_internal.h
index 38bffc8..692c00c 100644
--- a/src/core/lib/support/thd_internal.h
+++ b/src/core/lib/gpr/thd_internal.h
@@ -16,8 +16,8 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_THD_INTERNAL_H
-#define GRPC_CORE_LIB_SUPPORT_THD_INTERNAL_H
+#ifndef GRPC_CORE_LIB_GPR_THD_INTERNAL_H
+#define GRPC_CORE_LIB_GPR_THD_INTERNAL_H
 
 #include <grpc/support/time.h>
 
@@ -27,4 +27,4 @@
 /* Wait for all outstanding threads to finish, up to deadline */
 int gpr_await_threads(gpr_timespec deadline);
 
-#endif /* GRPC_CORE_LIB_SUPPORT_THD_INTERNAL_H */
+#endif /* GRPC_CORE_LIB_GPR_THD_INTERNAL_H */
diff --git a/src/core/lib/support/thd_posix.cc b/src/core/lib/gpr/thd_posix.cc
similarity index 98%
rename from src/core/lib/support/thd_posix.cc
rename to src/core/lib/gpr/thd_posix.cc
index f0ed48d..cfff0df 100644
--- a/src/core/lib/support/thd_posix.cc
+++ b/src/core/lib/gpr/thd_posix.cc
@@ -31,7 +31,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "src/core/lib/support/fork.h"
+#include "src/core/lib/gpr/fork.h"
 
 static gpr_mu g_mu;
 static gpr_cv g_cv;
diff --git a/src/core/lib/support/thd_windows.cc b/src/core/lib/gpr/thd_windows.cc
similarity index 100%
rename from src/core/lib/support/thd_windows.cc
rename to src/core/lib/gpr/thd_windows.cc
diff --git a/src/core/lib/support/time.cc b/src/core/lib/gpr/time.cc
similarity index 100%
rename from src/core/lib/support/time.cc
rename to src/core/lib/gpr/time.cc
diff --git a/src/core/lib/support/time_posix.cc b/src/core/lib/gpr/time_posix.cc
similarity index 98%
rename from src/core/lib/support/time_posix.cc
rename to src/core/lib/gpr/time_posix.cc
index b2087c9..9c7e86b 100644
--- a/src/core/lib/support/time_posix.cc
+++ b/src/core/lib/gpr/time_posix.cc
@@ -17,7 +17,7 @@
  */
 
 #include <grpc/support/port_platform.h>
-#include "src/core/lib/support/time_precise.h"
+#include "src/core/lib/gpr/time_precise.h"
 
 #ifdef GPR_POSIX_TIME
 
diff --git a/src/core/lib/support/time_precise.cc b/src/core/lib/gpr/time_precise.cc
similarity index 97%
rename from src/core/lib/support/time_precise.cc
rename to src/core/lib/gpr/time_precise.cc
index b7372df..3c7aaab 100644
--- a/src/core/lib/support/time_precise.cc
+++ b/src/core/lib/gpr/time_precise.cc
@@ -20,7 +20,7 @@
 #include <grpc/support/time.h>
 #include <stdio.h>
 
-#include "src/core/lib/support/time_precise.h"
+#include "src/core/lib/gpr/time_precise.h"
 
 #ifdef GRPC_TIMERS_RDTSC
 #if defined(__i386__)
diff --git a/src/core/lib/support/time_precise.h b/src/core/lib/gpr/time_precise.h
similarity index 83%
rename from src/core/lib/support/time_precise.h
rename to src/core/lib/gpr/time_precise.h
index 35cd154..acc4ee3 100644
--- a/src/core/lib/support/time_precise.h
+++ b/src/core/lib/gpr/time_precise.h
@@ -16,12 +16,12 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_TIME_PRECISE_H
-#define GRPC_CORE_LIB_SUPPORT_TIME_PRECISE_H
+#ifndef GRPC_CORE_LIB_GPR_TIME_PRECISE_H
+#define GRPC_CORE_LIB_GPR_TIME_PRECISE_H
 
 #include <grpc/support/time.h>
 
 void gpr_precise_clock_init(void);
 void gpr_precise_clock_now(gpr_timespec* clk);
 
-#endif /* GRPC_CORE_LIB_SUPPORT_TIME_PRECISE_H */
+#endif /* GRPC_CORE_LIB_GPR_TIME_PRECISE_H */
diff --git a/src/core/lib/support/time_windows.cc b/src/core/lib/gpr/time_windows.cc
similarity index 97%
rename from src/core/lib/support/time_windows.cc
rename to src/core/lib/gpr/time_windows.cc
index fb17e5c..247cc16 100644
--- a/src/core/lib/support/time_windows.cc
+++ b/src/core/lib/gpr/time_windows.cc
@@ -28,7 +28,7 @@
 #include <process.h>
 #include <sys/timeb.h>
 
-#include "src/core/lib/support/time_precise.h"
+#include "src/core/lib/gpr/time_precise.h"
 
 static LARGE_INTEGER g_start_time;
 static double g_time_scale;
diff --git a/src/core/lib/support/tls_pthread.cc b/src/core/lib/gpr/tls_pthread.cc
similarity index 100%
rename from src/core/lib/support/tls_pthread.cc
rename to src/core/lib/gpr/tls_pthread.cc
diff --git a/src/core/lib/support/tmpfile.h b/src/core/lib/gpr/tmpfile.h
similarity index 88%
rename from src/core/lib/support/tmpfile.h
rename to src/core/lib/gpr/tmpfile.h
index c5ceda8..f47ec7a 100644
--- a/src/core/lib/support/tmpfile.h
+++ b/src/core/lib/gpr/tmpfile.h
@@ -16,8 +16,8 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_TMPFILE_H
-#define GRPC_CORE_LIB_SUPPORT_TMPFILE_H
+#ifndef GRPC_CORE_LIB_GPR_TMPFILE_H
+#define GRPC_CORE_LIB_GPR_TMPFILE_H
 
 #include <stdio.h>
 
@@ -27,4 +27,4 @@
    unless an error occurs in which case it will be set to NULL. */
 FILE* gpr_tmpfile(const char* prefix, char** tmp_filename);
 
-#endif /* GRPC_CORE_LIB_SUPPORT_TMPFILE_H */
+#endif /* GRPC_CORE_LIB_GPR_TMPFILE_H */
diff --git a/src/core/lib/support/tmpfile_msys.cc b/src/core/lib/gpr/tmpfile_msys.cc
similarity index 94%
rename from src/core/lib/support/tmpfile_msys.cc
rename to src/core/lib/gpr/tmpfile_msys.cc
index 430e866..76cd886 100644
--- a/src/core/lib/support/tmpfile_msys.cc
+++ b/src/core/lib/gpr/tmpfile_msys.cc
@@ -29,8 +29,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/lib/support/string_windows.h"
-#include "src/core/lib/support/tmpfile.h"
+#include "src/core/lib/gpr/string_windows.h"
+#include "src/core/lib/gpr/tmpfile.h"
 
 FILE* gpr_tmpfile(const char* prefix, char** tmp_filename_out) {
   FILE* result = NULL;
diff --git a/src/core/lib/support/tmpfile_posix.cc b/src/core/lib/gpr/tmpfile_posix.cc
similarity index 95%
rename from src/core/lib/support/tmpfile_posix.cc
rename to src/core/lib/gpr/tmpfile_posix.cc
index 79c5c68..ffdad33 100644
--- a/src/core/lib/support/tmpfile_posix.cc
+++ b/src/core/lib/gpr/tmpfile_posix.cc
@@ -20,7 +20,7 @@
 
 #ifdef GPR_POSIX_TMPFILE
 
-#include "src/core/lib/support/tmpfile.h"
+#include "src/core/lib/gpr/tmpfile.h"
 
 #include <errno.h>
 #include <stdlib.h>
@@ -31,7 +31,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 
 FILE* gpr_tmpfile(const char* prefix, char** tmp_filename) {
   FILE* result = nullptr;
diff --git a/src/core/lib/support/tmpfile_windows.cc b/src/core/lib/gpr/tmpfile_windows.cc
similarity index 95%
rename from src/core/lib/support/tmpfile_windows.cc
rename to src/core/lib/gpr/tmpfile_windows.cc
index 2b10bcd..d486808 100644
--- a/src/core/lib/support/tmpfile_windows.cc
+++ b/src/core/lib/gpr/tmpfile_windows.cc
@@ -29,8 +29,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/lib/support/string_windows.h"
-#include "src/core/lib/support/tmpfile.h"
+#include "src/core/lib/gpr/string_windows.h"
+#include "src/core/lib/gpr/tmpfile.h"
 
 FILE* gpr_tmpfile(const char* prefix, char** tmp_filename_out) {
   FILE* result = NULL;
diff --git a/src/core/lib/support/wrap_memcpy.cc b/src/core/lib/gpr/wrap_memcpy.cc
similarity index 100%
rename from src/core/lib/support/wrap_memcpy.cc
rename to src/core/lib/gpr/wrap_memcpy.cc
diff --git a/src/core/lib/http/format_request.cc b/src/core/lib/http/format_request.cc
index f3f3cbd..473fa71 100644
--- a/src/core/lib/http/format_request.cc
+++ b/src/core/lib/http/format_request.cc
@@ -26,7 +26,7 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 
 static void fill_common_header(const grpc_httpcli_request* request,
                                gpr_strvec* buf, bool connection_close) {
diff --git a/src/core/lib/http/httpcli.cc b/src/core/lib/http/httpcli.cc
index ed874c4..c43c92b 100644
--- a/src/core/lib/http/httpcli.cc
+++ b/src/core/lib/http/httpcli.cc
@@ -26,6 +26,7 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/http/format_request.h"
 #include "src/core/lib/http/parser.h"
 #include "src/core/lib/iomgr/endpoint.h"
@@ -34,7 +35,6 @@
 #include "src/core/lib/iomgr/sockaddr_utils.h"
 #include "src/core/lib/iomgr/tcp_client.h"
 #include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/support/string.h"
 
 typedef struct {
   grpc_slice request_text;
diff --git a/src/core/lib/http/httpcli_security_connector.cc b/src/core/lib/http/httpcli_security_connector.cc
index bfb536a..8664418 100644
--- a/src/core/lib/http/httpcli_security_connector.cc
+++ b/src/core/lib/http/httpcli_security_connector.cc
@@ -26,9 +26,9 @@
 
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/handshaker_registry.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/security/transport/security_handshaker.h"
 #include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/tsi/ssl_transport_security.h"
 #include "src/core/tsi/transport_security_adapter.h"
 
diff --git a/src/core/lib/iomgr/call_combiner.h b/src/core/lib/iomgr/call_combiner.h
index 9f7e6ce..4814dbf 100644
--- a/src/core/lib/iomgr/call_combiner.h
+++ b/src/core/lib/iomgr/call_combiner.h
@@ -23,9 +23,9 @@
 
 #include <grpc/support/atm.h>
 
+#include "src/core/lib/gpr/mpscq.h"
 #include "src/core/lib/iomgr/closure.h"
 #include "src/core/lib/iomgr/exec_ctx.h"
-#include "src/core/lib/support/mpscq.h"
 
 // A simple, lock-free mechanism for serializing activity related to a
 // single call.  This is similar to a combiner but is more lightweight.
diff --git a/src/core/lib/iomgr/closure.h b/src/core/lib/iomgr/closure.h
index 4c58c0e..249fca6 100644
--- a/src/core/lib/iomgr/closure.h
+++ b/src/core/lib/iomgr/closure.h
@@ -25,9 +25,9 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <stdbool.h>
+#include "src/core/lib/gpr/mpscq.h"
 #include "src/core/lib/iomgr/error.h"
 #include "src/core/lib/profiling/timers.h"
-#include "src/core/lib/support/mpscq.h"
 
 struct grpc_closure;
 typedef struct grpc_closure grpc_closure;
diff --git a/src/core/lib/iomgr/combiner.h b/src/core/lib/iomgr/combiner.h
index 46b9ac5..c62d21a 100644
--- a/src/core/lib/iomgr/combiner.h
+++ b/src/core/lib/iomgr/combiner.h
@@ -23,8 +23,8 @@
 
 #include <grpc/support/atm.h>
 #include "src/core/lib/debug/trace.h"
+#include "src/core/lib/gpr/mpscq.h"
 #include "src/core/lib/iomgr/exec_ctx.h"
-#include "src/core/lib/support/mpscq.h"
 
 // Provides serialized access to some resource.
 // Each action queued on a combiner is executed serially in a borrowed thread.
diff --git a/src/core/lib/iomgr/endpoint_pair_posix.cc b/src/core/lib/iomgr/endpoint_pair_posix.cc
index 0b4aefd..3ad6b47 100644
--- a/src/core/lib/iomgr/endpoint_pair_posix.cc
+++ b/src/core/lib/iomgr/endpoint_pair_posix.cc
@@ -33,8 +33,8 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/tcp_posix.h"
-#include "src/core/lib/support/string.h"
 
 static void create_sockets(int sv[2]) {
   int flags;
diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc
index aa14d59..1cb0150 100644
--- a/src/core/lib/iomgr/ev_epoll1_linux.cc
+++ b/src/core/lib/iomgr/ev_epoll1_linux.cc
@@ -43,14 +43,14 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/lib/debug/stats.h"
+#include "src/core/lib/gpr++/manual_constructor.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/block_annotate.h"
 #include "src/core/lib/iomgr/ev_posix.h"
 #include "src/core/lib/iomgr/iomgr_internal.h"
 #include "src/core/lib/iomgr/lockfree_event.h"
 #include "src/core/lib/iomgr/wakeup_fd_posix.h"
 #include "src/core/lib/profiling/timers.h"
-#include "src/core/lib/support/manual_constructor.h"
-#include "src/core/lib/support/string.h"
 
 static grpc_wakeup_fd global_wakeup_fd;
 
diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc
index e4a2d67..b81c00c 100644
--- a/src/core/lib/iomgr/ev_epollex_linux.cc
+++ b/src/core/lib/iomgr/ev_epollex_linux.cc
@@ -41,6 +41,8 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/lib/debug/stats.h"
+#include "src/core/lib/gpr++/manual_constructor.h"
+#include "src/core/lib/gpr/spinlock.h"
 #include "src/core/lib/iomgr/block_annotate.h"
 #include "src/core/lib/iomgr/iomgr_internal.h"
 #include "src/core/lib/iomgr/is_epollexclusive_available.h"
@@ -49,8 +51,6 @@
 #include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/iomgr/wakeup_fd_posix.h"
 #include "src/core/lib/profiling/timers.h"
-#include "src/core/lib/support/manual_constructor.h"
-#include "src/core/lib/support/spinlock.h"
 
 // debug aid: create workers on the heap (allows asan to spot
 // use-after-destruction)
diff --git a/src/core/lib/iomgr/ev_epollsig_linux.cc b/src/core/lib/iomgr/ev_epollsig_linux.cc
index 3544d4f..11c64d0 100644
--- a/src/core/lib/iomgr/ev_epollsig_linux.cc
+++ b/src/core/lib/iomgr/ev_epollsig_linux.cc
@@ -43,6 +43,7 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/lib/debug/stats.h"
+#include "src/core/lib/gpr++/manual_constructor.h"
 #include "src/core/lib/iomgr/block_annotate.h"
 #include "src/core/lib/iomgr/ev_posix.h"
 #include "src/core/lib/iomgr/iomgr_internal.h"
@@ -50,7 +51,6 @@
 #include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/iomgr/wakeup_fd_posix.h"
 #include "src/core/lib/profiling/timers.h"
-#include "src/core/lib/support/manual_constructor.h"
 
 #define GRPC_POLLSET_KICK_BROADCAST ((grpc_pollset_worker*)1)
 
diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc
index 08edff5..3b79728 100644
--- a/src/core/lib/iomgr/ev_poll_posix.cc
+++ b/src/core/lib/iomgr/ev_poll_posix.cc
@@ -38,12 +38,12 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/lib/debug/stats.h"
+#include "src/core/lib/gpr/murmur_hash.h"
 #include "src/core/lib/iomgr/block_annotate.h"
 #include "src/core/lib/iomgr/iomgr_internal.h"
 #include "src/core/lib/iomgr/wakeup_fd_cv.h"
 #include "src/core/lib/iomgr/wakeup_fd_posix.h"
 #include "src/core/lib/profiling/timers.h"
-#include "src/core/lib/support/murmur_hash.h"
 
 #define GRPC_POLLSET_KICK_BROADCAST ((grpc_pollset_worker*)1)
 
diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc
index b516f93..3a57141 100644
--- a/src/core/lib/iomgr/ev_posix.cc
+++ b/src/core/lib/iomgr/ev_posix.cc
@@ -30,11 +30,11 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/lib/debug/trace.h"
+#include "src/core/lib/gpr/env.h"
 #include "src/core/lib/iomgr/ev_epoll1_linux.h"
 #include "src/core/lib/iomgr/ev_epollex_linux.h"
 #include "src/core/lib/iomgr/ev_epollsig_linux.h"
 #include "src/core/lib/iomgr/ev_poll_posix.h"
-#include "src/core/lib/support/env.h"
 
 grpc_core::TraceFlag grpc_polling_trace(false,
                                         "polling"); /* Disabled by default */
diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h
index 5c6007c..2e71482 100644
--- a/src/core/lib/iomgr/exec_ctx.h
+++ b/src/core/lib/iomgr/exec_ctx.h
@@ -158,10 +158,6 @@
     now_is_valid_ = true;
   }
 
-  /** Finish any pending work for a grpc_exec_ctx. Must be called before
-   *  the instance is destroyed, or work may be lost. */
-  void Finish();
-
   /** Global initialization for ExecCtx. Called by iomgr */
   static void GlobalInit(void);
 
diff --git a/src/core/lib/iomgr/executor.cc b/src/core/lib/iomgr/executor.cc
index 67a0412..835dc9d 100644
--- a/src/core/lib/iomgr/executor.cc
+++ b/src/core/lib/iomgr/executor.cc
@@ -29,8 +29,8 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/lib/debug/stats.h"
+#include "src/core/lib/gpr/spinlock.h"
 #include "src/core/lib/iomgr/exec_ctx.h"
-#include "src/core/lib/support/spinlock.h"
 
 #define MAX_DEPTH 2
 
diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc
index cc13140..9bfa792 100644
--- a/src/core/lib/iomgr/fork_posix.cc
+++ b/src/core/lib/iomgr/fork_posix.cc
@@ -27,13 +27,13 @@
 #include <grpc/support/thd.h>
 #include <grpc/support/useful.h>
 
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/fork.h"
+#include "src/core/lib/gpr/thd_internal.h"
 #include "src/core/lib/iomgr/ev_posix.h"
 #include "src/core/lib/iomgr/executor.h"
 #include "src/core/lib/iomgr/timer_manager.h"
 #include "src/core/lib/iomgr/wakeup_fd_posix.h"
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/fork.h"
-#include "src/core/lib/support/thd_internal.h"
 #include "src/core/lib/surface/init.h"
 
 /*
diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc
index 70807c4..4cd0a4f 100644
--- a/src/core/lib/iomgr/iomgr.cc
+++ b/src/core/lib/iomgr/iomgr.cc
@@ -31,14 +31,14 @@
 #include <grpc/support/thd.h>
 #include <grpc/support/useful.h>
 
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/exec_ctx.h"
 #include "src/core/lib/iomgr/executor.h"
 #include "src/core/lib/iomgr/iomgr_internal.h"
 #include "src/core/lib/iomgr/network_status_tracker.h"
 #include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/iomgr/timer_manager.h"
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
 
 static gpr_mu g_mu;
 static gpr_cv g_rcv;
diff --git a/src/core/lib/iomgr/load_file.cc b/src/core/lib/iomgr/load_file.cc
index 4a05de1..b6586fb 100644
--- a/src/core/lib/iomgr/load_file.cc
+++ b/src/core/lib/iomgr/load_file.cc
@@ -25,8 +25,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/block_annotate.h"
-#include "src/core/lib/support/string.h"
 
 grpc_error* grpc_load_file(const char* filename, int add_null_terminator,
                            grpc_slice* output) {
diff --git a/src/core/lib/iomgr/resolve_address_posix.cc b/src/core/lib/iomgr/resolve_address_posix.cc
index cc3d4fd..176caee 100644
--- a/src/core/lib/iomgr/resolve_address_posix.cc
+++ b/src/core/lib/iomgr/resolve_address_posix.cc
@@ -33,11 +33,11 @@
 #include <grpc/support/thd.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/block_annotate.h"
 #include "src/core/lib/iomgr/executor.h"
 #include "src/core/lib/iomgr/iomgr_internal.h"
 #include "src/core/lib/iomgr/unix_sockets_posix.h"
-#include "src/core/lib/support/string.h"
 
 static grpc_error* blocking_resolve_address_impl(
     const char* name, const char* default_port,
diff --git a/src/core/lib/iomgr/resolve_address_windows.cc b/src/core/lib/iomgr/resolve_address_windows.cc
index ccb1dae..e44ab39 100644
--- a/src/core/lib/iomgr/resolve_address_windows.cc
+++ b/src/core/lib/iomgr/resolve_address_windows.cc
@@ -34,11 +34,11 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/time.h>
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/block_annotate.h"
 #include "src/core/lib/iomgr/executor.h"
 #include "src/core/lib/iomgr/iomgr_internal.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
-#include "src/core/lib/support/string.h"
 
 typedef struct {
   char* name;
diff --git a/src/core/lib/iomgr/sockaddr_utils.cc b/src/core/lib/iomgr/sockaddr_utils.cc
index 0c0a2fe..71e3e38 100644
--- a/src/core/lib/iomgr/sockaddr_utils.cc
+++ b/src/core/lib/iomgr/sockaddr_utils.cc
@@ -28,10 +28,10 @@
 #include <grpc/support/port_platform.h>
 #include <grpc/support/string_util.h>
 
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/sockaddr.h"
 #include "src/core/lib/iomgr/socket_utils.h"
 #include "src/core/lib/iomgr/unix_sockets_posix.h"
-#include "src/core/lib/support/string.h"
 
 static const uint8_t kV4MappedPrefix[] = {0, 0, 0, 0, 0,    0,
                                           0, 0, 0, 0, 0xff, 0xff};
diff --git a/src/core/lib/iomgr/socket_mutator.h b/src/core/lib/iomgr/socket_mutator.h
index 0a97cf6..f8fd21d 100644
--- a/src/core/lib/iomgr/socket_mutator.h
+++ b/src/core/lib/iomgr/socket_mutator.h
@@ -26,7 +26,7 @@
 
 /** The virtual table of grpc_socket_mutator */
 typedef struct {
-  /** Mutates the socket opitons of \a fd */
+  /** Mutates the socket options of \a fd */
   bool (*mutate_fd)(int fd, grpc_socket_mutator* mutator);
   /** Compare socket mutator \a a and \a b */
   int (*compare)(grpc_socket_mutator* a, grpc_socket_mutator* b);
diff --git a/src/core/lib/iomgr/socket_utils_common_posix.cc b/src/core/lib/iomgr/socket_utils_common_posix.cc
index 2d4b8f0..5068a80 100644
--- a/src/core/lib/iomgr/socket_utils_common_posix.cc
+++ b/src/core/lib/iomgr/socket_utils_common_posix.cc
@@ -40,8 +40,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/port_platform.h>
 #include <grpc/support/sync.h>
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
-#include "src/core/lib/support/string.h"
 
 /* set a socket to non blocking mode */
 grpc_error* grpc_set_socket_nonblocking(int fd, int non_blocking) {
diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc
index 8cd5f8d..3dff624 100644
--- a/src/core/lib/iomgr/tcp_client_posix.cc
+++ b/src/core/lib/iomgr/tcp_client_posix.cc
@@ -33,6 +33,7 @@
 #include <grpc/support/time.h>
 
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/ev_posix.h"
 #include "src/core/lib/iomgr/iomgr_posix.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
@@ -41,7 +42,6 @@
 #include "src/core/lib/iomgr/tcp_posix.h"
 #include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/iomgr/unix_sockets_posix.h"
-#include "src/core/lib/support/string.h"
 
 extern grpc_core::TraceFlag grpc_tcp_trace;
 
diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc
index d47a077..0ec5926 100644
--- a/src/core/lib/iomgr/tcp_posix.cc
+++ b/src/core/lib/iomgr/tcp_posix.cc
@@ -42,12 +42,12 @@
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/debug/stats.h"
 #include "src/core/lib/debug/trace.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/ev_posix.h"
 #include "src/core/lib/iomgr/executor.h"
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 
 #ifdef GRPC_HAVE_MSG_NOSIGNAL
 #define SENDMSG_FLAGS MSG_NOSIGNAL
diff --git a/src/core/lib/iomgr/tcp_server_posix.cc b/src/core/lib/iomgr/tcp_server_posix.cc
index 99e1c6c..2fa00a8 100644
--- a/src/core/lib/iomgr/tcp_server_posix.cc
+++ b/src/core/lib/iomgr/tcp_server_posix.cc
@@ -45,6 +45,7 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/sockaddr.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
@@ -52,7 +53,6 @@
 #include "src/core/lib/iomgr/tcp_posix.h"
 #include "src/core/lib/iomgr/tcp_server_utils_posix.h"
 #include "src/core/lib/iomgr/unix_sockets_posix.h"
-#include "src/core/lib/support/string.h"
 
 static gpr_once check_init = GPR_ONCE_INIT;
 static bool has_so_reuseport = false;
diff --git a/src/core/lib/iomgr/tcp_uv.cc b/src/core/lib/iomgr/tcp_uv.cc
index baa49d5..b384623 100644
--- a/src/core/lib/iomgr/tcp_uv.cc
+++ b/src/core/lib/iomgr/tcp_uv.cc
@@ -29,6 +29,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/error.h"
 #include "src/core/lib/iomgr/iomgr_uv.h"
 #include "src/core/lib/iomgr/network_status_tracker.h"
@@ -36,7 +37,6 @@
 #include "src/core/lib/iomgr/tcp_uv.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 
 grpc_core::TraceFlag grpc_tcp_trace(false, "tcp");
 
diff --git a/src/core/lib/iomgr/timer_generic.cc b/src/core/lib/iomgr/timer_generic.cc
index 103144e..177bdec 100644
--- a/src/core/lib/iomgr/timer_generic.cc
+++ b/src/core/lib/iomgr/timer_generic.cc
@@ -32,9 +32,9 @@
 #include <grpc/support/tls.h>
 #include <grpc/support/useful.h>
 #include "src/core/lib/debug/trace.h"
+#include "src/core/lib/gpr/spinlock.h"
 #include "src/core/lib/iomgr/time_averaged_stats.h"
 #include "src/core/lib/iomgr/timer_heap.h"
-#include "src/core/lib/support/spinlock.h"
 
 #define INVALID_HEAP_INDEX 0xffffffffu
 
diff --git a/src/core/lib/iomgr/udp_server.cc b/src/core/lib/iomgr/udp_server.cc
index 946846a..27d32c5 100644
--- a/src/core/lib/iomgr/udp_server.cc
+++ b/src/core/lib/iomgr/udp_server.cc
@@ -49,6 +49,7 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/time.h>
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/error.h"
 #include "src/core/lib/iomgr/ev_posix.h"
 #include "src/core/lib/iomgr/executor.h"
@@ -58,7 +59,6 @@
 #include "src/core/lib/iomgr/socket_factory_posix.h"
 #include "src/core/lib/iomgr/socket_utils_posix.h"
 #include "src/core/lib/iomgr/unix_sockets_posix.h"
-#include "src/core/lib/support/string.h"
 
 /* one listening port */
 typedef struct grpc_udp_listener grpc_udp_listener;
diff --git a/src/core/lib/profiling/basic_timers.cc b/src/core/lib/profiling/basic_timers.cc
index 87dd4ab..d1c9fd7 100644
--- a/src/core/lib/profiling/basic_timers.cc
+++ b/src/core/lib/profiling/basic_timers.cc
@@ -30,7 +30,7 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "src/core/lib/support/env.h"
+#include "src/core/lib/gpr/env.h"
 
 typedef enum { BEGIN = '{', END = '}', MARK = '.' } marker_type;
 
diff --git a/src/core/lib/security/context/security_context.cc b/src/core/lib/security/context/security_context.cc
index 0371027..63ec42c 100644
--- a/src/core/lib/security/context/security_context.cc
+++ b/src/core/lib/security/context/security_context.cc
@@ -19,8 +19,8 @@
 #include <string.h>
 
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/security/context/security_context.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/api_trace.h"
 #include "src/core/lib/surface/call.h"
 
diff --git a/src/core/lib/security/credentials/credentials.cc b/src/core/lib/security/credentials/credentials.cc
index 48b459e..009a5ce 100644
--- a/src/core/lib/security/credentials/credentials.cc
+++ b/src/core/lib/security/credentials/credentials.cc
@@ -22,11 +22,11 @@
 #include <string.h>
 
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/http/httpcli.h"
 #include "src/core/lib/http/parser.h"
 #include "src/core/lib/iomgr/executor.h"
 #include "src/core/lib/json/json.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/api_trace.h"
 
 #include <grpc/support/alloc.h>
diff --git a/src/core/lib/security/credentials/fake/fake_credentials.cc b/src/core/lib/security/credentials/fake/fake_credentials.cc
index 99b1214..9065325 100644
--- a/src/core/lib/security/credentials/fake/fake_credentials.cc
+++ b/src/core/lib/security/credentials/fake/fake_credentials.cc
@@ -25,8 +25,8 @@
 #include <grpc/support/string_util.h>
 
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/executor.h"
-#include "src/core/lib/support/string.h"
 
 /* -- Fake transport security credentials. -- */
 
diff --git a/src/core/lib/security/credentials/google_default/credentials_generic.cc b/src/core/lib/security/credentials/google_default/credentials_generic.cc
index af103f5..15ae9d6 100644
--- a/src/core/lib/security/credentials/google_default/credentials_generic.cc
+++ b/src/core/lib/security/credentials/google_default/credentials_generic.cc
@@ -22,8 +22,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
 
 char* grpc_get_well_known_google_credentials_file_path_impl(void) {
   char* result = nullptr;
diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.cc b/src/core/lib/security/credentials/google_default/google_default_credentials.cc
index 03d5285..dc19202 100644
--- a/src/core/lib/security/credentials/google_default/google_default_credentials.cc
+++ b/src/core/lib/security/credentials/google_default/google_default_credentials.cc
@@ -24,6 +24,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/http/httpcli.h"
 #include "src/core/lib/http/parser.h"
 #include "src/core/lib/iomgr/load_file.h"
@@ -33,8 +35,6 @@
 #include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/api_trace.h"
 
 /* -- Constants. -- */
diff --git a/src/core/lib/security/credentials/jwt/json_token.cc b/src/core/lib/security/credentials/jwt/json_token.cc
index a152ddc..078f04e 100644
--- a/src/core/lib/security/credentials/jwt/json_token.cc
+++ b/src/core/lib/security/credentials/jwt/json_token.cc
@@ -26,9 +26,9 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/time.h>
 
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/security/util/json_util.h"
 #include "src/core/lib/slice/b64.h"
-#include "src/core/lib/support/string.h"
 
 extern "C" {
 #include <openssl/bio.h>
diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.cc b/src/core/lib/security/credentials/jwt/jwt_verifier.cc
index 39339f0..860506d 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.cc
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.cc
@@ -31,11 +31,11 @@
 #include <openssl/pem.h>
 }
 
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/http/httpcli.h"
 #include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/slice/b64.h"
 #include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/tsi/ssl_types.h"
 
 /* --- Utils. --- */
diff --git a/src/core/lib/security/transport/client_auth_filter.cc b/src/core/lib/security/transport/client_auth_filter.cc
index 948775b..5ca7870 100644
--- a/src/core/lib/security/transport/client_auth_filter.cc
+++ b/src/core/lib/security/transport/client_auth_filter.cc
@@ -25,13 +25,13 @@
 #include <grpc/support/string_util.h>
 
 #include "src/core/lib/channel/channel_stack.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/security/context/security_context.h"
 #include "src/core/lib/security/credentials/credentials.h"
 #include "src/core/lib/security/transport/security_connector.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/call.h"
 #include "src/core/lib/transport/static_metadata.h"
 
diff --git a/src/core/lib/security/transport/secure_endpoint.cc b/src/core/lib/security/transport/secure_endpoint.cc
index e5c089d..bd8a6cd 100644
--- a/src/core/lib/security/transport/secure_endpoint.cc
+++ b/src/core/lib/security/transport/secure_endpoint.cc
@@ -28,12 +28,12 @@
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 #include "src/core/lib/debug/trace.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/security/transport/secure_endpoint.h"
 #include "src/core/lib/security/transport/tsi_error.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/tsi/transport_security_grpc.h"
 
 #define STAGING_BUFFER_SIZE 8192
diff --git a/src/core/lib/security/transport/security_connector.cc b/src/core/lib/security/transport/security_connector.cc
index fd13971..1d962f9 100644
--- a/src/core/lib/security/transport/security_connector.cc
+++ b/src/core/lib/security/transport/security_connector.cc
@@ -30,6 +30,8 @@
 #include "src/core/ext/transport/chttp2/alpn/alpn.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/handshaker.h"
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/load_file.h"
 #include "src/core/lib/security/context/security_context.h"
 #include "src/core/lib/security/credentials/credentials.h"
@@ -38,8 +40,6 @@
 #include "src/core/lib/security/transport/lb_targets_info.h"
 #include "src/core/lib/security/transport/secure_endpoint.h"
 #include "src/core/lib/security/transport/security_handshaker.h"
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/tsi/fake_transport_security.h"
 #include "src/core/tsi/ssl_transport_security.h"
 #include "src/core/tsi/transport_security_adapter.h"
diff --git a/src/core/lib/slice/slice_intern.cc b/src/core/lib/slice/slice_intern.cc
index c578c6d..fe1770b 100644
--- a/src/core/lib/slice/slice_intern.cc
+++ b/src/core/lib/slice/slice_intern.cc
@@ -24,10 +24,10 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
+#include "src/core/lib/gpr/murmur_hash.h"
 #include "src/core/lib/iomgr/iomgr_internal.h" /* for iomgr_abort_on_leaks() */
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/murmur_hash.h"
 #include "src/core/lib/transport/static_metadata.h"
 
 #define LOG2_SHARD_COUNT 5
diff --git a/src/core/lib/slice/slice_string_helpers.cc b/src/core/lib/slice/slice_string_helpers.cc
index 5385be9..be0db09 100644
--- a/src/core/lib/slice/slice_string_helpers.cc
+++ b/src/core/lib/slice/slice_string_helpers.cc
@@ -22,8 +22,8 @@
 
 #include <grpc/support/log.h>
 
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/support/string.h"
 
 char* grpc_dump_slice(grpc_slice s, uint32_t flags) {
   return gpr_dump((const char*)GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s),
diff --git a/src/core/lib/slice/slice_string_helpers.h b/src/core/lib/slice/slice_string_helpers.h
index 7f51b11..109084b 100644
--- a/src/core/lib/slice/slice_string_helpers.h
+++ b/src/core/lib/slice/slice_string_helpers.h
@@ -26,7 +26,7 @@
 #include <grpc/slice_buffer.h>
 #include <grpc/support/port_platform.h>
 
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 
 /* Calls gpr_dump on a slice. */
 char* grpc_dump_slice(grpc_slice slice, uint32_t flags);
diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc
index d677576..a337c32 100644
--- a/src/core/lib/surface/call.cc
+++ b/src/core/lib/surface/call.cc
@@ -33,12 +33,12 @@
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/compression/algorithm_metadata.h"
 #include "src/core/lib/debug/stats.h"
+#include "src/core/lib/gpr/arena.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/arena.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/api_trace.h"
 #include "src/core/lib/surface/call.h"
 #include "src/core/lib/surface/call_test_only.h"
@@ -1081,6 +1081,7 @@
 static void publish_app_metadata(grpc_call* call, grpc_metadata_batch* b,
                                  int is_trailing) {
   if (b->list.count == 0) return;
+  if (is_trailing && call->buffered_metadata[1] == nullptr) return;
   GPR_TIMER_BEGIN("publish_app_metadata", 0);
   grpc_metadata_array* dest;
   grpc_metadata* mdusr;
diff --git a/src/core/lib/surface/call_log_batch.cc b/src/core/lib/surface/call_log_batch.cc
index 535a3d3..d56ea2a 100644
--- a/src/core/lib/surface/call_log_batch.cc
+++ b/src/core/lib/surface/call_log_batch.cc
@@ -22,8 +22,8 @@
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/string_util.h>
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 
 static void add_metadata(gpr_strvec* b, const grpc_metadata* md, size_t count) {
   size_t i;
diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc
index cf5e8c2..62db82a 100644
--- a/src/core/lib/surface/channel.cc
+++ b/src/core/lib/surface/channel.cc
@@ -29,9 +29,9 @@
 
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/debug/stats.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/iomgr.h"
 #include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/api_trace.h"
 #include "src/core/lib/surface/call.h"
 #include "src/core/lib/surface/channel_init.h"
diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc
index aa5808d..e731e21 100644
--- a/src/core/lib/surface/completion_queue.cc
+++ b/src/core/lib/surface/completion_queue.cc
@@ -31,11 +31,11 @@
 #include <grpc/support/tls.h>
 
 #include "src/core/lib/debug/stats.h"
+#include "src/core/lib/gpr/spinlock.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/pollset.h"
 #include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/profiling/timers.h"
-#include "src/core/lib/support/spinlock.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/api_trace.h"
 #include "src/core/lib/surface/call.h"
 #include "src/core/lib/surface/event_string.h"
diff --git a/src/core/lib/surface/event_string.cc b/src/core/lib/surface/event_string.cc
index 5168edc..7f40bb2 100644
--- a/src/core/lib/surface/event_string.cc
+++ b/src/core/lib/surface/event_string.cc
@@ -22,7 +22,7 @@
 
 #include <grpc/byte_buffer.h>
 #include <grpc/support/string_util.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 
 static void addhdr(gpr_strvec* buf, grpc_event* ev) {
   char* tmp;
diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc
index 0f40965..70329b0 100644
--- a/src/core/lib/surface/init.cc
+++ b/src/core/lib/surface/init.cc
@@ -31,6 +31,8 @@
 #include "src/core/lib/channel/handshaker_registry.h"
 #include "src/core/lib/debug/stats.h"
 #include "src/core/lib/debug/trace.h"
+#include "src/core/lib/gpr/fork.h"
+#include "src/core/lib/gpr/thd_internal.h"
 #include "src/core/lib/http/parser.h"
 #include "src/core/lib/iomgr/call_combiner.h"
 #include "src/core/lib/iomgr/combiner.h"
@@ -40,8 +42,6 @@
 #include "src/core/lib/iomgr/timer_manager.h"
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/support/fork.h"
-#include "src/core/lib/support/thd_internal.h"
 #include "src/core/lib/surface/alarm_internal.h"
 #include "src/core/lib/surface/api_trace.h"
 #include "src/core/lib/surface/call.h"
diff --git a/src/core/lib/surface/lame_client.cc b/src/core/lib/surface/lame_client.cc
index 08611ff..27a2a4e 100644
--- a/src/core/lib/surface/lame_client.cc
+++ b/src/core/lib/surface/lame_client.cc
@@ -23,10 +23,10 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
-#include "src/core/lib/support/atomic.h"
+#include "src/core/lib/gpr++/atomic.h"
 
 #include "src/core/lib/channel/channel_stack.h"
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/surface/api_trace.h"
 #include "src/core/lib/surface/call.h"
 #include "src/core/lib/surface/channel.h"
diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc
index ee98cf2..c8c1db3 100644
--- a/src/core/lib/surface/server.cc
+++ b/src/core/lib/surface/server.cc
@@ -30,12 +30,12 @@
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/connected_channel.h"
 #include "src/core/lib/debug/stats.h"
+#include "src/core/lib/gpr/mpscq.h"
+#include "src/core/lib/gpr/spinlock.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/executor.h"
 #include "src/core/lib/iomgr/iomgr.h"
 #include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/support/mpscq.h"
-#include "src/core/lib/support/spinlock.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/api_trace.h"
 #include "src/core/lib/surface/call.h"
 #include "src/core/lib/surface/channel.h"
diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc
index 7d36c6c..fc66d02 100644
--- a/src/core/lib/surface/version.cc
+++ b/src/core/lib/surface/version.cc
@@ -21,6 +21,6 @@
 
 #include <grpc/grpc.h>
 
-const char* grpc_version_string(void) { return "5.0.0-dev"; }
+const char* grpc_version_string(void) { return "5.0.0"; }
 
 const char* grpc_g_stands_for(void) { return "glossy"; }
diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc
index 5f0673e..652222b 100644
--- a/src/core/lib/transport/metadata.cc
+++ b/src/core/lib/transport/metadata.cc
@@ -31,12 +31,12 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/time.h>
 
+#include "src/core/lib/gpr/murmur_hash.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/iomgr_internal.h"
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/murmur_hash.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/static_metadata.h"
 
 /* There are two kinds of mdelem and mdstr instances.
diff --git a/src/core/lib/transport/service_config.cc b/src/core/lib/transport/service_config.cc
index cbafc33..5c9930a 100644
--- a/src/core/lib/transport/service_config.cc
+++ b/src/core/lib/transport/service_config.cc
@@ -23,11 +23,11 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/json/json.h"
 #include "src/core/lib/slice/slice_hash_table.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 
 // The main purpose of the code here is to parse the service config in
 // JSON form, which will look like this:
diff --git a/src/core/lib/transport/timeout_encoding.cc b/src/core/lib/transport/timeout_encoding.cc
index 86db6c8..47f964a 100644
--- a/src/core/lib/transport/timeout_encoding.cc
+++ b/src/core/lib/transport/timeout_encoding.cc
@@ -22,7 +22,7 @@
 #include <string.h>
 
 #include <grpc/support/port_platform.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 
 static int64_t round_up(int64_t x, int64_t divisor) {
   return (x / divisor + (x % divisor != 0)) * divisor;
diff --git a/src/core/lib/transport/timeout_encoding.h b/src/core/lib/transport/timeout_encoding.h
index 8611f49..4e92682 100644
--- a/src/core/lib/transport/timeout_encoding.h
+++ b/src/core/lib/transport/timeout_encoding.h
@@ -22,8 +22,8 @@
 #include <grpc/slice.h>
 #include <grpc/support/time.h>
 
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/exec_ctx.h"
-#include "src/core/lib/support/string.h"
 
 #define GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE (GPR_LTOA_MIN_BUFSIZE + 1)
 
diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc
index 08aee04..ea0380e 100644
--- a/src/core/lib/transport/transport.cc
+++ b/src/core/lib/transport/transport.cc
@@ -25,10 +25,10 @@
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/executor.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/transport_impl.h"
 
 grpc_core::DebugOnlyTraceFlag grpc_trace_stream_refcount(false,
diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h
index 80a7ff9..b392c69 100644
--- a/src/core/lib/transport/transport.h
+++ b/src/core/lib/transport/transport.h
@@ -22,12 +22,12 @@
 #include <stddef.h>
 
 #include "src/core/lib/channel/context.h"
+#include "src/core/lib/gpr/arena.h"
 #include "src/core/lib/iomgr/call_combiner.h"
 #include "src/core/lib/iomgr/endpoint.h"
 #include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/iomgr/pollset.h"
 #include "src/core/lib/iomgr/pollset_set.h"
-#include "src/core/lib/support/arena.h"
 #include "src/core/lib/transport/byte_stream.h"
 #include "src/core/lib/transport/metadata_batch.h"
 
diff --git a/src/core/lib/transport/transport_op_string.cc b/src/core/lib/transport/transport_op_string.cc
index c0f82fe..58a21e9 100644
--- a/src/core/lib/transport/transport_op_string.cc
+++ b/src/core/lib/transport/transport_op_string.cc
@@ -28,8 +28,8 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/connectivity_state.h"
 
 /* These routines are here to facilitate debugging - they produce string
diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc
index 0842081..362dff6 100644
--- a/src/cpp/client/channel_cc.cc
+++ b/src/cpp/client/channel_cc.cc
@@ -42,9 +42,9 @@
 #include <grpc/support/thd.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/profiling/timers.h"
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
 
 namespace grpc {
 
diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc
index 7f01a66..185172b 100644
--- a/src/cpp/common/version_cc.cc
+++ b/src/cpp/common/version_cc.cc
@@ -22,5 +22,5 @@
 #include <grpc++/grpc++.h>
 
 namespace grpc {
-grpc::string Version() { return "1.9.0-dev"; }
+grpc::string Version() { return "1.9.0"; }
 }  // namespace grpc
diff --git a/src/csharp/Grpc.Core.Tests/Internal/DefaultObjectPoolTest.cs b/src/csharp/Grpc.Core.Tests/Internal/DefaultObjectPoolTest.cs
index b6bb0a9..9c6f8a2 100644
--- a/src/csharp/Grpc.Core.Tests/Internal/DefaultObjectPoolTest.cs
+++ b/src/csharp/Grpc.Core.Tests/Internal/DefaultObjectPoolTest.cs
@@ -60,6 +60,16 @@
         }
 
         [Test]
+        public void LeaseSetsReturnAction()
+        {
+            var pool = new DefaultObjectPool<TestPooledObject>(() => new TestPooledObject(), 10, 0);
+            var origLeased = pool.Lease();
+            origLeased.ReturnAction(origLeased);
+            pool.Dispose();
+            Assert.AreNotSame(origLeased, pool.Lease());
+        }
+
+        [Test]
         public void Constructor()
         {
             Assert.Throws<ArgumentNullException>(() => new DefaultObjectPool<TestPooledObject>(null, 10, 2));
@@ -67,8 +77,14 @@
             Assert.Throws<ArgumentException>(() => new DefaultObjectPool<TestPooledObject>(() => new TestPooledObject(), 10, -1));
         }
 
-        class TestPooledObject : IDisposable
+        class TestPooledObject : IPooledObject<TestPooledObject>
         {
+            public Action<TestPooledObject> ReturnAction;
+
+            public void SetReturnToPoolAction(Action<TestPooledObject> returnAction)
+            {
+                this.ReturnAction = returnAction;
+            }
 
             public void Dispose()
             {
diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs
index 7b4342b..6bb2f6c 100644
--- a/src/csharp/Grpc.Core/GrpcEnvironment.cs
+++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs
@@ -299,8 +299,8 @@
         private GrpcEnvironment()
         {
             GrpcNativeInit();
-            batchContextPool = new DefaultObjectPool<BatchContextSafeHandle>(() => BatchContextSafeHandle.Create(this.batchContextPool), batchContextPoolSharedCapacity, batchContextPoolThreadLocalCapacity);
-            requestCallContextPool = new DefaultObjectPool<RequestCallContextSafeHandle>(() => RequestCallContextSafeHandle.Create(this.requestCallContextPool), requestCallContextPoolSharedCapacity, requestCallContextPoolThreadLocalCapacity);
+            batchContextPool = new DefaultObjectPool<BatchContextSafeHandle>(() => BatchContextSafeHandle.Create(), batchContextPoolSharedCapacity, batchContextPoolThreadLocalCapacity);
+            requestCallContextPool = new DefaultObjectPool<RequestCallContextSafeHandle>(() => RequestCallContextSafeHandle.Create(), requestCallContextPoolSharedCapacity, requestCallContextPoolThreadLocalCapacity);
             threadPool = new GrpcThreadPool(this, GetThreadPoolSizeOrDefault(), GetCompletionQueueCountOrDefault(), inlineHandlers);
             threadPool.Start();
         }
@@ -381,6 +381,7 @@
             await Task.Run(() => ShuttingDown?.Invoke(this, null)).ConfigureAwait(false);
 
             await threadPool.StopAsync().ConfigureAwait(false);
+            requestCallContextPool.Dispose();
             batchContextPool.Dispose();
             GrpcNativeShutdown();
             isShutdown = true;
diff --git a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
index 83385ad..53a859d 100644
--- a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
@@ -33,22 +33,21 @@
     /// <summary>
     /// grpcsharp_batch_context
     /// </summary>
-    internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid, IOpCompletionCallback
+    internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid, IOpCompletionCallback, IPooledObject<BatchContextSafeHandle>
     {
         static readonly NativeMethods Native = NativeMethods.Get();
         static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<BatchContextSafeHandle>();
 
-        IObjectPool<BatchContextSafeHandle> ownedByPool;
+        Action<BatchContextSafeHandle> returnToPoolAction;
         CompletionCallbackData completionCallbackData;
 
         private BatchContextSafeHandle()
         {
         }
 
-        public static BatchContextSafeHandle Create(IObjectPool<BatchContextSafeHandle> ownedByPool = null)
+        public static BatchContextSafeHandle Create()
         {
             var ctx = Native.grpcsharp_batch_context_create();
-            ctx.ownedByPool = ownedByPool;
             return ctx;
         }
 
@@ -60,6 +59,12 @@
             }
         }
 
+        public void SetReturnToPoolAction(Action<BatchContextSafeHandle> returnAction)
+        {
+            GrpcPreconditions.CheckState(returnToPoolAction == null);
+            returnToPoolAction = returnAction;
+        }
+
         public void SetCompletionCallback(BatchCompletionDelegate callback, object state)
         {
             GrpcPreconditions.CheckState(completionCallbackData.Callback == null);
@@ -109,10 +114,15 @@
 
         public void Recycle()
         {
-            if (ownedByPool != null)
+            if (returnToPoolAction != null)
             {
                 Native.grpcsharp_batch_context_reset(this);
-                ownedByPool.Return(this);
+
+                var origReturnAction = returnToPoolAction;
+                // Not clearing all the references to the pool could prevent garbage collection of the pool object
+                // and thus cause memory leaks.
+                returnToPoolAction = null;
+                origReturnAction(this);
             }
             else
             {
diff --git a/src/csharp/Grpc.Core/Internal/DefaultObjectPool.cs b/src/csharp/Grpc.Core/Internal/DefaultObjectPool.cs
index 2f030f3..0e1dc4d 100644
--- a/src/csharp/Grpc.Core/Internal/DefaultObjectPool.cs
+++ b/src/csharp/Grpc.Core/Internal/DefaultObjectPool.cs
@@ -27,9 +27,10 @@
     /// Pool of objects that combines a shared pool and a thread local pool.
     /// </summary>
     internal class DefaultObjectPool<T> : IObjectPool<T>
-        where T : class, IDisposable
+        where T : class, IPooledObject<T>
     {
         readonly object myLock = new object();
+        readonly Action<T> returnAction;
         readonly Func<T> itemFactory;
 
         // Queue shared between threads, access needs to be synchronized.
@@ -54,6 +55,7 @@
         {
             GrpcPreconditions.CheckArgument(sharedCapacity >= 0);
             GrpcPreconditions.CheckArgument(threadLocalCapacity >= 0);
+            this.returnAction = Return;
             this.itemFactory = GrpcPreconditions.CheckNotNull(itemFactory, nameof(itemFactory));
             this.sharedQueue = new Queue<T>(sharedCapacity);
             this.sharedCapacity = sharedCapacity;
@@ -74,6 +76,13 @@
         /// </summary>
         public T Lease()
         {
+            var item = LeaseInternal();
+            item.SetReturnToPoolAction(returnAction);
+            return item;
+        }
+
+        private T LeaseInternal()
+        {
             var localData = threadLocalData.Value;
             if (localData.Queue.Count > 0)
             {
diff --git a/src/csharp/Grpc.Core/Internal/IPooledObject.cs b/src/csharp/Grpc.Core/Internal/IPooledObject.cs
new file mode 100644
index 0000000..e20bd51
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/IPooledObject.cs
@@ -0,0 +1,34 @@
+#region Copyright notice and license
+
+// Copyright 2018 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using System;
+
+namespace Grpc.Core.Internal
+{
+    /// <summary>
+    /// An object that can be pooled in <c>IObjectPool</c>.
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+    internal interface IPooledObject<T> : IDisposable
+    {
+        /// <summary>
+        /// Set the action that will be invoked to return a leased object to the pool.
+        /// </summary>
+        void SetReturnToPoolAction(Action<T> returnAction);
+    }
+}
diff --git a/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs
index 59e9d9b..ebc2d6d 100644
--- a/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs
@@ -20,26 +20,26 @@
 using System.Runtime.InteropServices;
 using Grpc.Core;
 using Grpc.Core.Logging;
+using Grpc.Core.Utils;
 
 namespace Grpc.Core.Internal
 {
     /// <summary>
     /// grpcsharp_request_call_context
     /// </summary>
-    internal class RequestCallContextSafeHandle : SafeHandleZeroIsInvalid, IOpCompletionCallback
+    internal class RequestCallContextSafeHandle : SafeHandleZeroIsInvalid, IOpCompletionCallback, IPooledObject<RequestCallContextSafeHandle>
     {
         static readonly NativeMethods Native = NativeMethods.Get();
         static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<RequestCallContextSafeHandle>();
-        IObjectPool<RequestCallContextSafeHandle> ownedByPool;
+        Action<RequestCallContextSafeHandle> returnToPoolAction;
 
         private RequestCallContextSafeHandle()
         {
         }
 
-        public static RequestCallContextSafeHandle Create(IObjectPool<RequestCallContextSafeHandle> ownedByPool = null)
+        public static RequestCallContextSafeHandle Create()
         {
             var ctx = Native.grpcsharp_request_call_context_create();
-            ctx.ownedByPool = ownedByPool;
             return ctx;
         }
 
@@ -51,6 +51,12 @@
             }
         }
 
+        public void SetReturnToPoolAction(Action<RequestCallContextSafeHandle> returnAction)
+        {
+            GrpcPreconditions.CheckState(returnToPoolAction == null);
+            returnToPoolAction = returnAction;
+        }
+
         public RequestCallCompletionDelegate CompletionCallback { get; set; }
 
         // Gets data of server_rpc_new completion.
@@ -76,10 +82,15 @@
 
         public void Recycle()
         {
-            if (ownedByPool != null)
+            if (returnToPoolAction != null)
             {
                 Native.grpcsharp_request_call_context_reset(this);
-                ownedByPool.Return(this);
+
+                var origReturnAction = returnToPoolAction;
+                // Not clearing all the references to the pool could prevent garbage collection of the pool object
+                // and thus cause memory leaks.
+                returnToPoolAction = null;
+                origReturnAction(this);
             }
             else
             {
diff --git a/src/csharp/Grpc.Core/SourceLink.csproj.include b/src/csharp/Grpc.Core/SourceLink.csproj.include
index 02ae79f..0ec273f 100755
--- a/src/csharp/Grpc.Core/SourceLink.csproj.include
+++ b/src/csharp/Grpc.Core/SourceLink.csproj.include
@@ -13,7 +13,7 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="SourceLink.Embed.AllSourceFiles" Version="2.7.3" PrivateAssets="all" />
+    <PackageReference Include="SourceLink.Create.CommandLine" Version="2.7.6" PrivateAssets="all" />
   </ItemGroup>
 
 </Project>
diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include
index 2d9e4ba..8e906ed 100755
--- a/src/csharp/Grpc.Core/Version.csproj.include
+++ b/src/csharp/Grpc.Core/Version.csproj.include
@@ -1,7 +1,7 @@
 <!-- This file is generated -->
 <Project>
   <PropertyGroup>
-    <GrpcCsharpVersion>1.9.0-dev</GrpcCsharpVersion>
+    <GrpcCsharpVersion>1.9.0</GrpcCsharpVersion>
     <GoogleProtobufVersion>3.3.0</GoogleProtobufVersion>
   </PropertyGroup>
 </Project>
diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs
index 9b5da1c..e320bd3 100644
--- a/src/csharp/Grpc.Core/VersionInfo.cs
+++ b/src/csharp/Grpc.Core/VersionInfo.cs
@@ -38,6 +38,6 @@
         /// <summary>
         /// Current version of gRPC C#
         /// </summary>
-        public const string CurrentVersion = "1.9.0-dev";
+        public const string CurrentVersion = "1.9.0";
     }
 }
diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat
index 8f89e28..ab43d3c 100755
--- a/src/csharp/build_packages_dotnetcli.bat
+++ b/src/csharp/build_packages_dotnetcli.bat
@@ -13,7 +13,7 @@
 @rem limitations under the License.
 
 @rem Current package versions
-set VERSION=1.9.0-dev
+set VERSION=1.9.0
 
 @rem Adjust the location of nuget.exe
 set NUGET=C:\nuget\nuget.exe
diff --git a/src/csharp/build_packages_dotnetcli.sh b/src/csharp/build_packages_dotnetcli.sh
index 6a6cafe..82335c8 100755
--- a/src/csharp/build_packages_dotnetcli.sh
+++ b/src/csharp/build_packages_dotnetcli.sh
@@ -39,7 +39,7 @@
 dotnet pack --configuration Release Grpc.HealthCheck --output ../../../artifacts
 dotnet pack --configuration Release Grpc.Reflection --output ../../../artifacts
 
-nuget pack Grpc.nuspec -Version "1.9.0-dev" -OutputDirectory ../../artifacts
-nuget pack Grpc.Tools.nuspec -Version "1.9.0-dev" -OutputDirectory ../../artifacts
+nuget pack Grpc.nuspec -Version "1.9.0" -OutputDirectory ../../artifacts
+nuget pack Grpc.Tools.nuspec -Version "1.9.0" -OutputDirectory ../../artifacts
 
 (cd ../../artifacts && zip csharp_nugets_dotnetcli.zip *.nupkg)
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index 6875d40..eb69b58 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -16,7 +16,7 @@
  *
  */
 
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 
 #include <grpc/byte_buffer_reader.h>
 #include <grpc/grpc.h>
diff --git "a/src/objective-c/\041ProtoCompiler-gRPCPlugin.podspec" "b/src/objective-c/\041ProtoCompiler-gRPCPlugin.podspec"
index 2250176..8e075f6 100644
--- "a/src/objective-c/\041ProtoCompiler-gRPCPlugin.podspec"
+++ "b/src/objective-c/\041ProtoCompiler-gRPCPlugin.podspec"
@@ -42,7 +42,7 @@
   # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
   # before them.
   s.name     = '!ProtoCompiler-gRPCPlugin'
-  v = '1.9.0-dev'
+  v = '1.9.0'
   s.version  = v
   s.summary  = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.'
   s.description = <<-DESC
diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h
index 69dd626..b00dd02 100644
--- a/src/objective-c/GRPCClient/private/version.h
+++ b/src/objective-c/GRPCClient/private/version.h
@@ -23,4 +23,4 @@
 // `tools/buildgen/generate_projects.sh`.
 
 
-#define GRPC_OBJC_VERSION_STRING @"1.9.0-dev"
+#define GRPC_OBJC_VERSION_STRING @"1.9.0"
diff --git a/src/objective-c/examples/Sample/Podfile b/src/objective-c/examples/Sample/Podfile
index f6f0c00..9ea2f61 100644
--- a/src/objective-c/examples/Sample/Podfile
+++ b/src/objective-c/examples/Sample/Podfile
@@ -40,7 +40,7 @@
     'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"',
     'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"',
     # If we don't set these two settings, `include/grpc/support/time.h` and
-    # `src/core/lib/support/string.h` shadow the system `<time.h>` and `<string.h>`, breaking the
+    # `src/core/lib/gpr/string.h` shadow the system `<time.h>` and `<string.h>`, breaking the
     # build.
     'USE_HEADERMAP' => 'NO',
     'ALWAYS_SEARCH_USER_PATHS' => 'NO',
diff --git a/src/objective-c/examples/SwiftSample/Podfile b/src/objective-c/examples/SwiftSample/Podfile
index b08a346..a2c2b82 100644
--- a/src/objective-c/examples/SwiftSample/Podfile
+++ b/src/objective-c/examples/SwiftSample/Podfile
@@ -40,7 +40,7 @@
     'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"',
     'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"',
     # If we don't set these two settings, `include/grpc/support/time.h` and
-    # `src/core/lib/support/string.h` shadow the system `<time.h>` and `<string.h>`, breaking the
+    # `src/core/lib/gpr/string.h` shadow the system `<time.h>` and `<string.h>`, breaking the
     # build.
     'USE_HEADERMAP' => 'NO',
     'ALWAYS_SEARCH_USER_PATHS' => 'NO',
diff --git a/src/objective-c/tests/Connectivity/Podfile b/src/objective-c/tests/Connectivity/Podfile
index 27ff935..cdbc6dd 100644
--- a/src/objective-c/tests/Connectivity/Podfile
+++ b/src/objective-c/tests/Connectivity/Podfile
@@ -24,7 +24,7 @@
     'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"',
     'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"',
     # If we don't set these two settings, `include/grpc/support/time.h` and
-    # `src/core/lib/support/string.h` shadow the system `<time.h>` and `<string.h>`, breaking the
+    # `src/core/lib/gpr/string.h` shadow the system `<time.h>` and `<string.h>`, breaking the
     # build.
     'USE_HEADERMAP' => 'NO',
     'ALWAYS_SEARCH_USER_PATHS' => 'NO',
diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm
index d130971..16940a4 100644
--- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm
+++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm
@@ -39,9 +39,9 @@
 
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/security/credentials/credentials.h"
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
-#include "src/core/lib/support/tmpfile.h"
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/tmpfile.h"
 #include "test/core/end2end/data/ssl_test_data.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
diff --git a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m
index 92bc20e..09ee062 100644
--- a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m
+++ b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m
@@ -31,9 +31,9 @@
 #import <grpc/support/log.h>
 
 #import "src/core/lib/channel/channel_args.h"
-#import "src/core/lib/support/env.h"
-#import "src/core/lib/support/string.h"
-#import "src/core/lib/support/tmpfile.h"
+#import "src/core/lib/gpr/env.h"
+#import "src/core/lib/gpr/string.h"
+#import "src/core/lib/gpr/tmpfile.h"
 #import "test/core/end2end/data/ssl_test_data.h"
 #import "test/core/util/test_config.h"
 
diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile
index 8f1cb04..9e9db1f 100644
--- a/src/objective-c/tests/Podfile
+++ b/src/objective-c/tests/Podfile
@@ -75,7 +75,7 @@
     'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"',
     'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"',
     # If we don't set these two settings, `include/grpc/support/time.h` and
-    # `src/core/lib/support/string.h` shadow the system `<time.h>` and `<string.h>`, breaking the
+    # `src/core/lib/gpr/string.h` shadow the system `<time.h>` and `<string.h>`, breaking the
     # build.
     'USE_HEADERMAP' => 'NO',
     'ALWAYS_SEARCH_USER_PATHS' => 'NO',
diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h
index 6e3a073..9a117c3 100644
--- a/src/objective-c/tests/version.h
+++ b/src/objective-c/tests/version.h
@@ -23,5 +23,5 @@
 // `tools/buildgen/generate_projects.sh`.
 
 
-#define GRPC_OBJC_VERSION_STRING @"1.9.0-dev"
-#define GRPC_C_VERSION_STRING @"5.0.0-dev"
+#define GRPC_OBJC_VERSION_STRING @"1.9.0"
+#define GRPC_C_VERSION_STRING @"5.0.0"
diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c
index c4997f7..ff55c3c 100644
--- a/src/php/ext/grpc/call.c
+++ b/src/php/ext/grpc/call.c
@@ -99,6 +99,7 @@
                              1 TSRMLS_CC);
         efree(str_key);
         efree(str_val);
+        PHP_GRPC_FREE_STD_ZVAL(array);
         return NULL;
       }
       php_grpc_add_next_index_stringl(data, str_val,
@@ -127,10 +128,12 @@
   HashTable *inner_array_hash;
   zval *value;
   zval *inner_array;
+  grpc_metadata_array_init(metadata);
+  metadata->count = 0;
+  metadata->metadata = NULL;
   if (Z_TYPE_P(array) != IS_ARRAY) {
     return false;
   }
-  grpc_metadata_array_init(metadata);
   array_hash = Z_ARRVAL_P(array);
 
   char *key;
@@ -174,6 +177,18 @@
   return true;
 }
 
+void grpc_php_metadata_array_destroy_including_entries(
+    grpc_metadata_array* array) {
+  size_t i;
+  if (array->metadata) {
+    for (i = 0; i < array->count; i++) {
+      grpc_slice_unref(array->metadata[i].key);
+      grpc_slice_unref(array->metadata[i].value);
+    }
+  }
+  grpc_metadata_array_destroy(array);
+}
+
 /* Wraps a grpc_call struct in a PHP object. Owned indicates whether the
    struct should be destroyed at the end of the object's lifecycle */
 zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned TSRMLS_DC) {
@@ -502,8 +517,8 @@
   }
 
 cleanup:
-  grpc_metadata_array_destroy(&metadata);
-  grpc_metadata_array_destroy(&trailing_metadata);
+  grpc_php_metadata_array_destroy_including_entries(&metadata);
+  grpc_php_metadata_array_destroy_including_entries(&trailing_metadata);
   grpc_metadata_array_destroy(&recv_metadata);
   grpc_metadata_array_destroy(&recv_trailing_metadata);
   grpc_slice_unref(recv_status_details);
@@ -526,7 +541,9 @@
  */
 PHP_METHOD(Call, getPeer) {
   wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(getThis());
-  PHP_GRPC_RETURN_STRING(grpc_call_get_peer(call->wrapped), 1);
+  char *peer = grpc_call_get_peer(call->wrapped);
+  PHP_GRPC_RETVAL_STRING(peer, 1);
+  gpr_free(peer);
 }
 
 /**
diff --git a/src/php/ext/grpc/call.h b/src/php/ext/grpc/call.h
index 5bde5d5..104ac30 100644
--- a/src/php/ext/grpc/call.h
+++ b/src/php/ext/grpc/call.h
@@ -69,5 +69,6 @@
 /* Populates a grpc_metadata_array with the data in a PHP array object.
    Returns true on success and false on failure */
 bool create_metadata_array(zval *array, grpc_metadata_array *metadata);
-
+void grpc_php_metadata_array_destroy_including_entries(
+    grpc_metadata_array* array);
 #endif /* NET_GRPC_PHP_GRPC_CHANNEL_H_ */
diff --git a/src/php/ext/grpc/call_credentials.c b/src/php/ext/grpc/call_credentials.c
index a395d53..41c488a 100644
--- a/src/php/ext/grpc/call_credentials.c
+++ b/src/php/ext/grpc/call_credentials.c
@@ -120,6 +120,8 @@
                             fci->params, fci->param_count) == FAILURE) {
     zend_throw_exception(spl_ce_InvalidArgumentException,
                          "createFromPlugin expects 1 callback", 1 TSRMLS_CC);
+    free(fci);
+    free(fci_cache);
     return;
   }
 
@@ -183,15 +185,17 @@
   *status = GRPC_STATUS_OK;
   *error_details = NULL;
 
+  bool should_return = false;
   grpc_metadata_array metadata;
 
   if (retval == NULL || Z_TYPE_P(retval) != IS_ARRAY) {
     *status = GRPC_STATUS_INVALID_ARGUMENT;
-    return true;  // Synchronous return.
+    should_return = true;  // Synchronous return.
   }
   if (!create_metadata_array(retval, &metadata)) {
     *status = GRPC_STATUS_INVALID_ARGUMENT;
-    return true;  // Synchronous return.
+    should_return = true;  // Synchronous return.
+    grpc_php_metadata_array_destroy_including_entries(&metadata);
   }
 
   if (retval != NULL) {
@@ -204,6 +208,9 @@
     PHP_GRPC_FREE_STD_ZVAL(retval);
 #endif
   }
+  if (should_return) {
+    return true;
+  }
 
   if (metadata.count > GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX) {
     *status = GRPC_STATUS_INTERNAL;
diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c
index db59869..4054723 100644
--- a/src/php/ext/grpc/channel.c
+++ b/src/php/ext/grpc/channel.c
@@ -41,6 +41,7 @@
 
 #include <grpc/grpc.h>
 #include <grpc/grpc_security.h>
+#include <grpc/support/alloc.h>
 
 #include "completion_queue.h"
 #include "channel_credentials.h"
@@ -56,22 +57,63 @@
 
 /* Frees and destroys an instance of wrapped_grpc_channel */
 PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_channel)
+  bool is_last_wrapper = false;
+  // In_persistent_list is used when the user don't close the channel.
+  // In this case, le in the list won't be freed.
+  bool in_persistent_list = true;
   if (p->wrapper != NULL) {
     gpr_mu_lock(&p->wrapper->mu);
     if (p->wrapper->wrapped != NULL) {
-      php_grpc_zend_resource *rsrc;
-      php_grpc_int key_len = strlen(p->wrapper->key);
-      // only destroy the channel here if not found in the persistent list
-      gpr_mu_lock(&global_persistent_list_mu);
-      if (!(PHP_GRPC_PERSISTENT_LIST_FIND(&EG(persistent_list), p->wrapper->key,
-                                          key_len, rsrc))) {
-        grpc_channel_destroy(p->wrapper->wrapped);
-        free(p->wrapper->target);
-        free(p->wrapper->args_hashstr);
+      if (p->wrapper->is_valid) {
+        php_grpc_zend_resource *rsrc;
+        php_grpc_int key_len = strlen(p->wrapper->key);
+        // only destroy the channel here if not found in the persistent list
+        gpr_mu_lock(&global_persistent_list_mu);
+        if (!(PHP_GRPC_PERSISTENT_LIST_FIND(&EG(persistent_list), p->wrapper->key,
+                                            key_len, rsrc))) {
+          in_persistent_list = false;
+          grpc_channel_destroy(p->wrapper->wrapped);
+          free(p->wrapper->target);
+          free(p->wrapper->args_hashstr);
+          if(p->wrapper->creds_hashstr != NULL){
+            free(p->wrapper->creds_hashstr);
+            p->wrapper->creds_hashstr = NULL;
+          }
+        }
+        gpr_mu_unlock(&global_persistent_list_mu);
       }
-      gpr_mu_unlock(&global_persistent_list_mu);
+    }
+    p->wrapper->ref_count -= 1;
+    if (p->wrapper->ref_count == 0) {
+      is_last_wrapper = true;
     }
     gpr_mu_unlock(&p->wrapper->mu);
+    if (is_last_wrapper) {
+      if (in_persistent_list) {
+        // If ref_count==0 and the key still in the list, it means the user
+        // don't call channel->close().persistent list should free the
+        // allocation in such case, as well as related wrapped channel.
+        if (p->wrapper->wrapped != NULL) {
+          gpr_mu_lock(&p->wrapper->mu);
+          grpc_channel_destroy(p->wrapper->wrapped);
+          free(p->wrapper->target);
+          free(p->wrapper->args_hashstr);
+          if(p->wrapper->creds_hashstr != NULL){
+            free(p->wrapper->creds_hashstr);
+            p->wrapper->creds_hashstr = NULL;
+          }
+          p->wrapper->wrapped = NULL;
+          php_grpc_delete_persistent_list_entry(p->wrapper->key,
+                                                strlen(p->wrapper->key)
+                                                TSRMLS_CC);
+          gpr_mu_unlock(&p->wrapper->mu);
+        }
+      }
+      gpr_mu_destroy(&p->wrapper->mu);
+      free(p->wrapper->key);
+      free(p->wrapper);
+    }
+    p->wrapper = NULL;
   }
 PHP_GRPC_FREE_WRAPPED_FUNC_END()
 
@@ -276,9 +318,16 @@
   channel->wrapper->key = key;
   channel->wrapper->target = strdup(target);
   channel->wrapper->args_hashstr = strdup(sha1str);
+  channel->wrapper->creds_hashstr = NULL;
+  channel->wrapper->ref_count = 1;
+  channel->wrapper->is_valid = true;
   if (creds != NULL && creds->hashstr != NULL) {
-    channel->wrapper->creds_hashstr = creds->hashstr;
+    php_grpc_int creds_hashstr_len = strlen(creds->hashstr);
+    char *channel_creds_hashstr = malloc(creds_hashstr_len + 1);
+    strcpy(channel_creds_hashstr, creds->hashstr);
+    channel->wrapper->creds_hashstr = channel_creds_hashstr;
   }
+
   gpr_mu_init(&channel->wrapper->mu);
   smart_str_free(&buf);
 
@@ -303,7 +352,17 @@
           channel, target, args, creds, key, key_len TSRMLS_CC);
     } else {
       efree(args.args);
+      if (channel->wrapper->creds_hashstr != NULL){
+        free(channel->wrapper->creds_hashstr);
+        channel->wrapper->creds_hashstr = NULL;
+      }
+      free(channel->wrapper->creds_hashstr);
+      free(channel->wrapper->key);
+      free(channel->wrapper->target);
+      free(channel->wrapper->args_hashstr);
+      free(channel->wrapper);
       channel->wrapper = le->channel;
+      channel->wrapper->ref_count += 1;
     }
   }
 }
@@ -323,7 +382,8 @@
   }
   char *target = grpc_channel_get_target(channel->wrapper->wrapped);
   gpr_mu_unlock(&channel->wrapper->mu);
-  PHP_GRPC_RETURN_STRING(target, 1);
+  PHP_GRPC_RETVAL_STRING(target, 1);
+  gpr_free(target);
 }
 
 /**
@@ -411,18 +471,46 @@
  */
 PHP_METHOD(Channel, close) {
   wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis());
-  gpr_mu_lock(&channel->wrapper->mu);
-  if (channel->wrapper->wrapped != NULL) {
-    grpc_channel_destroy(channel->wrapper->wrapped);
-    free(channel->wrapper->target);
-    free(channel->wrapper->args_hashstr);
-    channel->wrapper->wrapped = NULL;
+  bool is_last_wrapper = false;
+  if (channel->wrapper != NULL) {
+    // Channel_wrapper hasn't call close before.
+    gpr_mu_lock(&channel->wrapper->mu);
+    if (channel->wrapper->wrapped != NULL) {
+      if (channel->wrapper->is_valid) {
+        // Wrapped channel hasn't been destoryed by other wrapper.
+        grpc_channel_destroy(channel->wrapper->wrapped);
+        free(channel->wrapper->target);
+        free(channel->wrapper->args_hashstr);
+        if(channel->wrapper->creds_hashstr != NULL){
+          free(channel->wrapper->creds_hashstr);
+          channel->wrapper->creds_hashstr = NULL;
+        }
+        channel->wrapper->wrapped = NULL;
+        channel->wrapper->is_valid = false;
 
-    php_grpc_delete_persistent_list_entry(channel->wrapper->key,
-                                          strlen(channel->wrapper->key)
-                                          TSRMLS_CC);
+        php_grpc_delete_persistent_list_entry(channel->wrapper->key,
+                                              strlen(channel->wrapper->key)
+                                              TSRMLS_CC);
+      }
+    }
+    channel->wrapper->ref_count -= 1;
+    if(channel->wrapper->ref_count == 0){
+      // Mark that the wrapper can be freed because mu should be
+      // destroyed outside the lock.
+      is_last_wrapper = true;
+    }
+    gpr_mu_unlock(&channel->wrapper->mu);
   }
-  gpr_mu_unlock(&channel->wrapper->mu);
+  gpr_mu_lock(&global_persistent_list_mu);
+  if (is_last_wrapper) {
+    gpr_mu_destroy(&channel->wrapper->mu);
+    free(channel->wrapper->key);
+    free(channel->wrapper);
+  }
+  // Set channel->wrapper to NULL to avoid call close twice for the same
+  // channel.
+  channel->wrapper = NULL;
+  gpr_mu_unlock(&global_persistent_list_mu);
 }
 
 // Delete an entry from the persistent list
@@ -437,6 +525,7 @@
     le = (channel_persistent_le_t *)rsrc->ptr;
     le->channel = NULL;
     php_grpc_zend_hash_del(&EG(persistent_list), key, key_len+1);
+    free(le);
   }
   gpr_mu_unlock(&global_persistent_list_mu);
 }
diff --git a/src/php/ext/grpc/channel.h b/src/php/ext/grpc/channel.h
index 69adc47..86bfdea 100755
--- a/src/php/ext/grpc/channel.h
+++ b/src/php/ext/grpc/channel.h
@@ -40,6 +40,11 @@
   char *args_hashstr;
   char *creds_hashstr;
   gpr_mu mu;
+  // is_valid is used to check the wrapped channel has been freed
+  // before to avoid double free.
+  bool is_valid;
+  // ref_count is used to let the last wrapper free related channel and key.
+  size_t ref_count;
 } grpc_channel_wrapper;
 
 /* Wrapper struct for grpc_channel that can be associated with a PHP object */
diff --git a/src/php/ext/grpc/channel_credentials.c b/src/php/ext/grpc/channel_credentials.c
index d120d6e..624d7cc 100644
--- a/src/php/ext/grpc/channel_credentials.c
+++ b/src/php/ext/grpc/channel_credentials.c
@@ -57,8 +57,13 @@
 
 /* Frees and destroys an instance of wrapped_grpc_channel_credentials */
 PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_channel_credentials)
+  if (p->hashstr != NULL) {
+    free(p->hashstr);
+    p->hashstr = NULL;
+  }
   if (p->wrapped != NULL) {
     grpc_channel_credentials_release(p->wrapped);
+    p->wrapped = NULL;
   }
 PHP_GRPC_FREE_WRAPPED_FUNC_END()
 
@@ -152,7 +157,7 @@
   }
 
   php_grpc_int hashkey_len = root_certs_length + cert_chain_length;
-  char *hashkey = emalloc(hashkey_len);
+  char *hashkey = emalloc(hashkey_len + 1);
   if (root_certs_length > 0) {
     strcpy(hashkey, pem_root_certs);
   }
@@ -199,8 +204,13 @@
   grpc_channel_credentials *creds =
       grpc_composite_channel_credentials_create(cred1->wrapped, cred2->wrapped,
                                                 NULL);
+  // wrapped_grpc_channel_credentials object should keeps it's own
+  // allocation. Otherwise it conflicts free hashstr with call.c.
+  php_grpc_int cred1_len = strlen(cred1->hashstr);
+  char *cred1_hashstr = malloc(cred1_len+1);
+  strcpy(cred1_hashstr, cred1->hashstr);
   zval *creds_object =
-      grpc_php_wrap_channel_credentials(creds, cred1->hashstr, true
+      grpc_php_wrap_channel_credentials(creds, cred1_hashstr, true
                                         TSRMLS_CC);
   RETURN_DESTROY_ZVAL(creds_object);
 }
diff --git a/src/php/ext/grpc/php7_wrapper.h b/src/php/ext/grpc/php7_wrapper.h
index 96091f9..2f4a536 100644
--- a/src/php/ext/grpc/php7_wrapper.h
+++ b/src/php/ext/grpc/php7_wrapper.h
@@ -33,6 +33,7 @@
 #define php_grpc_add_next_index_stringl(data, str, len, b) \
   add_next_index_stringl(data, str, len, b)
 
+#define PHP_GRPC_RETVAL_STRING(val, dup) RETVAL_STRING(val, dup)
 #define PHP_GRPC_RETURN_STRING(val, dup) RETURN_STRING(val, dup)
 #define PHP_GRPC_MAKE_STD_ZVAL(pzv) MAKE_STD_ZVAL(pzv)
 #define PHP_GRPC_FREE_STD_ZVAL(pzv)
@@ -145,6 +146,7 @@
 #define php_grpc_add_next_index_stringl(data, str, len, b) \
   add_next_index_stringl(data, str, len)
 
+#define PHP_GRPC_RETVAL_STRING(val, dup) RETVAL_STRING(val)
 #define PHP_GRPC_RETURN_STRING(val, dup) RETURN_STRING(val)
 #define PHP_GRPC_MAKE_STD_ZVAL(pzv) \
   pzv = (zval *)emalloc(sizeof(zval));
diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c
index 0f2c5b8..5971bab 100644
--- a/src/php/ext/grpc/php_grpc.c
+++ b/src/php/ext/grpc/php_grpc.c
@@ -253,7 +253,8 @@
  */
 PHP_MINFO_FUNCTION(grpc) {
   php_info_print_table_start();
-  php_info_print_table_header(2, "grpc support", "enabled");
+  php_info_print_table_row(2, "grpc support", "enabled");
+  php_info_print_table_row(2, "grpc module version", PHP_GRPC_VERSION);
   php_info_print_table_end();
 
   /* Remove comments if you have entries in php.ini
diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h
index 48131d7..e2dfc40 100644
--- a/src/php/ext/grpc/version.h
+++ b/src/php/ext/grpc/version.h
@@ -20,6 +20,6 @@
 #ifndef VERSION_H
 #define VERSION_H
 
-#define PHP_GRPC_VERSION "1.9.0dev"
+#define PHP_GRPC_VERSION "1.9.0"
 
 #endif /* VERSION_H */
diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py
index 993c49d..f7ba466 100644
--- a/src/python/grpcio/grpc/_grpcio_metadata.py
+++ b/src/python/grpcio/grpc/_grpcio_metadata.py
@@ -14,4 +14,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!!
 
-__version__ = """1.9.0.dev0"""
+__version__ = """1.9.0"""
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index aea0786..9debb22 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -15,50 +15,50 @@
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_core_dependencies.py.template`!!!
 
 CORE_SOURCE_FILES = [
+    'src/core/lib/gpr/alloc.cc',
+    'src/core/lib/gpr/arena.cc',
+    'src/core/lib/gpr/atm.cc',
+    'src/core/lib/gpr/avl.cc',
+    'src/core/lib/gpr/cmdline.cc',
+    'src/core/lib/gpr/cpu_iphone.cc',
+    'src/core/lib/gpr/cpu_linux.cc',
+    'src/core/lib/gpr/cpu_posix.cc',
+    'src/core/lib/gpr/cpu_windows.cc',
+    'src/core/lib/gpr/env_linux.cc',
+    'src/core/lib/gpr/env_posix.cc',
+    'src/core/lib/gpr/env_windows.cc',
+    'src/core/lib/gpr/fork.cc',
+    'src/core/lib/gpr/host_port.cc',
+    'src/core/lib/gpr/log.cc',
+    'src/core/lib/gpr/log_android.cc',
+    'src/core/lib/gpr/log_linux.cc',
+    'src/core/lib/gpr/log_posix.cc',
+    'src/core/lib/gpr/log_windows.cc',
+    'src/core/lib/gpr/mpscq.cc',
+    'src/core/lib/gpr/murmur_hash.cc',
+    'src/core/lib/gpr/string.cc',
+    'src/core/lib/gpr/string_posix.cc',
+    'src/core/lib/gpr/string_util_windows.cc',
+    'src/core/lib/gpr/string_windows.cc',
+    'src/core/lib/gpr/subprocess_posix.cc',
+    'src/core/lib/gpr/subprocess_windows.cc',
+    'src/core/lib/gpr/sync.cc',
+    'src/core/lib/gpr/sync_posix.cc',
+    'src/core/lib/gpr/sync_windows.cc',
+    'src/core/lib/gpr/thd.cc',
+    'src/core/lib/gpr/thd_posix.cc',
+    'src/core/lib/gpr/thd_windows.cc',
+    'src/core/lib/gpr/time.cc',
+    'src/core/lib/gpr/time_posix.cc',
+    'src/core/lib/gpr/time_precise.cc',
+    'src/core/lib/gpr/time_windows.cc',
+    'src/core/lib/gpr/tls_pthread.cc',
+    'src/core/lib/gpr/tmpfile_msys.cc',
+    'src/core/lib/gpr/tmpfile_posix.cc',
+    'src/core/lib/gpr/tmpfile_windows.cc',
+    'src/core/lib/gpr/wrap_memcpy.cc',
     'src/core/lib/profiling/basic_timers.cc',
     'src/core/lib/profiling/stap_timers.cc',
-    'src/core/lib/support/alloc.cc',
-    'src/core/lib/support/arena.cc',
-    'src/core/lib/support/atm.cc',
-    'src/core/lib/support/avl.cc',
-    'src/core/lib/support/cmdline.cc',
-    'src/core/lib/support/cpu_iphone.cc',
-    'src/core/lib/support/cpu_linux.cc',
-    'src/core/lib/support/cpu_posix.cc',
-    'src/core/lib/support/cpu_windows.cc',
-    'src/core/lib/support/env_linux.cc',
-    'src/core/lib/support/env_posix.cc',
-    'src/core/lib/support/env_windows.cc',
-    'src/core/lib/support/fork.cc',
-    'src/core/lib/support/host_port.cc',
-    'src/core/lib/support/log.cc',
-    'src/core/lib/support/log_android.cc',
-    'src/core/lib/support/log_linux.cc',
-    'src/core/lib/support/log_posix.cc',
-    'src/core/lib/support/log_windows.cc',
-    'src/core/lib/support/mpscq.cc',
-    'src/core/lib/support/murmur_hash.cc',
-    'src/core/lib/support/string.cc',
-    'src/core/lib/support/string_posix.cc',
-    'src/core/lib/support/string_util_windows.cc',
-    'src/core/lib/support/string_windows.cc',
-    'src/core/lib/support/subprocess_posix.cc',
-    'src/core/lib/support/subprocess_windows.cc',
-    'src/core/lib/support/sync.cc',
-    'src/core/lib/support/sync_posix.cc',
-    'src/core/lib/support/sync_windows.cc',
-    'src/core/lib/support/thd.cc',
-    'src/core/lib/support/thd_posix.cc',
-    'src/core/lib/support/thd_windows.cc',
-    'src/core/lib/support/time.cc',
-    'src/core/lib/support/time_posix.cc',
-    'src/core/lib/support/time_precise.cc',
-    'src/core/lib/support/time_windows.cc',
-    'src/core/lib/support/tls_pthread.cc',
-    'src/core/lib/support/tmpfile_msys.cc',
-    'src/core/lib/support/tmpfile_posix.cc',
-    'src/core/lib/support/tmpfile_windows.cc',
-    'src/core/lib/support/wrap_memcpy.cc',
     'src/core/lib/surface/init.cc',
     'src/core/lib/backoff/backoff.cc',
     'src/core/lib/channel/channel_args.cc',
diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py
index 1fac57b..dfb4906 100644
--- a/src/python/grpcio/grpc_version.py
+++ b/src/python/grpcio/grpc_version.py
@@ -14,4 +14,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!!
 
-VERSION = '1.9.0.dev0'
+VERSION = '1.9.0'
diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py
index 5b7e585..b29f5c7 100644
--- a/src/python/grpcio_health_checking/grpc_version.py
+++ b/src/python/grpcio_health_checking/grpc_version.py
@@ -14,4 +14,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!!
 
-VERSION = '1.9.0.dev0'
+VERSION = '1.9.0'
diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py
index 0ad9621..5969131 100644
--- a/src/python/grpcio_reflection/grpc_version.py
+++ b/src/python/grpcio_reflection/grpc_version.py
@@ -14,4 +14,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!!
 
-VERSION = '1.9.0.dev0'
+VERSION = '1.9.0'
diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py
index 0eb5fbf..7bf045d 100644
--- a/src/python/grpcio_testing/grpc_version.py
+++ b/src/python/grpcio_testing/grpc_version.py
@@ -14,4 +14,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!!
 
-VERSION = '1.9.0.dev0'
+VERSION = '1.9.0'
diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py
index b1b4d7e..997f182 100644
--- a/src/python/grpcio_tests/grpc_version.py
+++ b/src/python/grpcio_tests/grpc_version.py
@@ -14,4 +14,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!!
 
-VERSION = '1.9.0.dev0'
+VERSION = '1.9.0'
diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb
index be14125..4348b79 100644
--- a/src/ruby/lib/grpc/version.rb
+++ b/src/ruby/lib/grpc/version.rb
@@ -14,5 +14,5 @@
 
 # GRPC contains the General RPC module.
 module GRPC
-  VERSION = '1.9.0.dev'
+  VERSION = '1.9.0'
 end
diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb
index 48aad39..0b899eb 100644
--- a/src/ruby/tools/version.rb
+++ b/src/ruby/tools/version.rb
@@ -14,6 +14,6 @@
 
 module GRPC
   module Tools
-    VERSION = '1.9.0.dev'
+    VERSION = '1.9.0'
   end
 end
diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template
index da404e2..2be7692 100644
--- a/templates/gRPC-Core.podspec.template
+++ b/templates/gRPC-Core.podspec.template
@@ -135,7 +135,7 @@
       'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"',
       'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"',
       # If we don't set these two settings, `include/grpc/support/time.h` and
-      # `src/core/lib/support/string.h` shadow the system `<time.h>` and `<string.h>`, breaking the
+      # `src/core/lib/gpr/string.h` shadow the system `<time.h>` and `<string.h>`, breaking the
       # build.
       'USE_HEADERMAP' => 'NO',
       'ALWAYS_SEARCH_USER_PATHS' => 'NO',
diff --git a/templates/package.xml.template b/templates/package.xml.template
index f10f75b..1232179 100644
--- a/templates/package.xml.template
+++ b/templates/package.xml.template
@@ -12,24 +12,22 @@
     <email>grpc-packages@google.com</email>
     <active>yes</active>
    </lead>
-   <date>2017-08-24</date>
+   <date>2018-01-23</date>
    <time>16:06:07</time>
    <version>
     <release>${settings.php_version.php()}</release>
     <api>${settings.php_version.php()}</api>
    </version>
    <stability>
-    <release>beta</release>
-    <api>beta</api>
+    <release>${settings.php_version.php_stability()}</release>
+    <api>${settings.php_version.php_stability()}</api>
    </stability>
    <license>Apache 2.0</license>
    <notes>
-  - Channel are now by default persistent #11878
-  - Some bug fixes from 1.4 branch #12109, #12123
-  - Fixed hang bug when fork() was used #11814
-  - License changed to Apache 2.0
-  - Added support for php_namespace option in codegen plugin #11886
-  - Updated gRPC C Core library version 1.6
+  - Updated gRPC C Core library version 1.9
+  - Report grpc extension version in phpinfo() #13687
+  - Fixed memory leak when handling metadata array #13660
+  - Fixed memory involing persistent channels #14125 - #14130
    </notes>
    <contents>
     <dir baseinstalldir="/" name="/">
diff --git a/test/core/backoff/backoff_test.cc b/test/core/backoff/backoff_test.cc
index 7bc4d14..2e61243 100644
--- a/test/core/backoff/backoff_test.cc
+++ b/test/core/backoff/backoff_test.cc
@@ -45,11 +45,11 @@
       .set_max_backoff(max_backoff);
   BackOff backoff(options);
 
-  grpc_millis next_attempt_start_time = backoff.Begin();
+  grpc_millis next_attempt_start_time = backoff.NextAttemptTime();
   EXPECT_EQ(next_attempt_start_time - grpc_core::ExecCtx::Get()->Now(),
             initial_backoff);
   for (int i = 0; i < 10000; i++) {
-    next_attempt_start_time = backoff.Step();
+    next_attempt_start_time = backoff.NextAttemptTime();
     EXPECT_EQ(next_attempt_start_time - grpc_core::ExecCtx::Get()->Now(),
               initial_backoff);
   }
@@ -67,7 +67,7 @@
       .set_jitter(jitter)
       .set_max_backoff(max_backoff);
   BackOff backoff(options);
-  grpc_millis next = backoff.Begin();
+  grpc_millis next = backoff.NextAttemptTime();
   EXPECT_EQ(next - grpc_core::ExecCtx::Get()->Now(), initial_backoff);
 }
 
@@ -86,42 +86,42 @@
   // x_n = 2**i + x_{i-1} ( = 2**(n+1) - 2 )
   grpc_core::ExecCtx exec_ctx;
   grpc_core::ExecCtx::Get()->TestOnlySetNow(0);
-  grpc_millis next = backoff.Begin();
+  grpc_millis next = backoff.NextAttemptTime();
   EXPECT_EQ(next, 2);
   grpc_core::ExecCtx::Get()->TestOnlySetNow(next);
-  next = backoff.Step();
+  next = backoff.NextAttemptTime();
   EXPECT_EQ(next, 6);
   grpc_core::ExecCtx::Get()->TestOnlySetNow(next);
-  next = backoff.Step();
+  next = backoff.NextAttemptTime();
   EXPECT_EQ(next, 14);
   grpc_core::ExecCtx::Get()->TestOnlySetNow(next);
-  next = backoff.Step();
+  next = backoff.NextAttemptTime();
   EXPECT_EQ(next, 30);
   grpc_core::ExecCtx::Get()->TestOnlySetNow(next);
-  next = backoff.Step();
+  next = backoff.NextAttemptTime();
   EXPECT_EQ(next, 62);
   grpc_core::ExecCtx::Get()->TestOnlySetNow(next);
-  next = backoff.Step();
+  next = backoff.NextAttemptTime();
   EXPECT_EQ(next, 126);
   grpc_core::ExecCtx::Get()->TestOnlySetNow(next);
-  next = backoff.Step();
+  next = backoff.NextAttemptTime();
   EXPECT_EQ(next, 254);
   grpc_core::ExecCtx::Get()->TestOnlySetNow(next);
-  next = backoff.Step();
+  next = backoff.NextAttemptTime();
   EXPECT_EQ(next, 510);
   grpc_core::ExecCtx::Get()->TestOnlySetNow(next);
-  next = backoff.Step();
+  next = backoff.NextAttemptTime();
   EXPECT_EQ(next, 1022);
   grpc_core::ExecCtx::Get()->TestOnlySetNow(next);
-  next = backoff.Step();
+  next = backoff.NextAttemptTime();
   // Hit the maximum timeout. From this point onwards, retries will increase
   // only by max timeout.
   EXPECT_EQ(next, 1535);
   grpc_core::ExecCtx::Get()->TestOnlySetNow(next);
-  next = backoff.Step();
+  next = backoff.NextAttemptTime();
   EXPECT_EQ(next, 2048);
   grpc_core::ExecCtx::Get()->TestOnlySetNow(next);
-  next = backoff.Step();
+  next = backoff.NextAttemptTime();
   EXPECT_EQ(next, 2561);
 }
 
@@ -141,7 +141,7 @@
   backoff.SetRandomSeed(0);  // force consistent PRNG
 
   grpc_core::ExecCtx exec_ctx;
-  grpc_millis next = backoff.Begin();
+  grpc_millis next = backoff.NextAttemptTime();
   EXPECT_EQ(next - grpc_core::ExecCtx::Get()->Now(), initial_backoff);
 
   grpc_millis expected_next_lower_bound =
@@ -150,7 +150,7 @@
       (grpc_millis)((double)current_backoff * (1 + jitter));
 
   for (int i = 0; i < 10000; i++) {
-    next = backoff.Step();
+    next = backoff.NextAttemptTime();
     // next-now must be within (jitter*100)% of the current backoff (which
     // increases by * multiplier up to max_backoff).
     const grpc_millis timeout_millis = next - grpc_core::ExecCtx::Get()->Now();
diff --git a/test/core/bad_client/bad_client.cc b/test/core/bad_client/bad_client.cc
index 4c1642a..dd8d881 100644
--- a/test/core/bad_client/bad_client.cc
+++ b/test/core/bad_client/bad_client.cc
@@ -28,10 +28,10 @@
 #include "src/core/ext/filters/http/server/http_server_filter.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/channel_stack.h"
+#include "src/core/lib/gpr/murmur_hash.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/endpoint_pair.h"
 #include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/support/murmur_hash.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/completion_queue.h"
 #include "src/core/lib/surface/server.h"
 
diff --git a/test/core/bad_client/gen_build_yaml.py b/test/core/bad_client/gen_build_yaml.py
index 14c8a27..c0922fc 100755
--- a/test/core/bad_client/gen_build_yaml.py
+++ b/test/core/bad_client/gen_build_yaml.py
@@ -27,6 +27,7 @@
 BAD_CLIENT_TESTS = {
     'badreq': default_test_options,
     'connection_prefix': default_test_options._replace(cpu_cost=0.2),
+    'duplicate_header': default_test_options,
     'headers': default_test_options._replace(cpu_cost=0.2),
     'initial_settings_frame': default_test_options._replace(cpu_cost=0.2),
     'head_of_line_blocking': default_test_options,
diff --git a/test/core/bad_client/generate_tests.bzl b/test/core/bad_client/generate_tests.bzl
index 022edf3..0dbf501 100755
--- a/test/core/bad_client/generate_tests.bzl
+++ b/test/core/bad_client/generate_tests.bzl
@@ -25,6 +25,7 @@
 BAD_CLIENT_TESTS = {
     'badreq': test_options(),
     'connection_prefix': test_options(),
+    'duplicate_header': test_options(),
     'headers': test_options(),
     'initial_settings_frame': test_options(),
     'head_of_line_blocking': test_options(),
diff --git a/test/core/bad_client/tests/duplicate_header.cc b/test/core/bad_client/tests/duplicate_header.cc
new file mode 100644
index 0000000..0d689bb
--- /dev/null
+++ b/test/core/bad_client/tests/duplicate_header.cc
@@ -0,0 +1,134 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test/core/bad_client/bad_client.h"
+
+#include <string.h>
+
+#include <grpc/grpc.h>
+
+#include "src/core/lib/surface/server.h"
+#include "test/core/end2end/cq_verifier.h"
+
+#define PFX_STR                      \
+  "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" \
+  "\x00\x00\x00\x04\x00\x00\x00\x00\x00" /* settings frame */
+
+#define HEADER_STR                                                         \
+  "\x00\x00\xc9\x01\x04\x00\x00\x00\x01" /* headers: generated from        \
+                                            simple_request.headers in this \
+                                            directory */                   \
+  "\x10\x05:path\x08/foo/bar"                                              \
+  "\x10\x07:scheme\x04http"                                                \
+  "\x10\x07:method\x04POST"                                                \
+  "\x10\x0a:authority\x09localhost"                                        \
+  "\x10\x0c"                                                               \
+  "content-type\x10"                                                       \
+  "application/grpc"                                                       \
+  "\x10\x14grpc-accept-encoding\x15"                                       \
+  "deflate,identity,gzip"                                                  \
+  "\x10\x02te\x08trailers"                                                 \
+  "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)"
+
+#define PAYLOAD_STR                      \
+  "\x00\x00\x20\x00\x00\x00\x00\x00\x01" \
+  "\x00\x00\x00\x00"
+
+static void* tag(intptr_t t) { return (void*)t; }
+
+static void verifier(grpc_server* server, grpc_completion_queue* cq,
+                     void* registered_method) {
+  grpc_call_error error;
+  grpc_call* s;
+  grpc_call_details call_details;
+  grpc_byte_buffer* request_payload_recv = nullptr;
+  grpc_op* op;
+  grpc_op ops[6];
+  cq_verifier* cqv = cq_verifier_create(cq);
+  grpc_metadata_array request_metadata_recv;
+  int was_cancelled = 2;
+
+  grpc_call_details_init(&call_details);
+  grpc_metadata_array_init(&request_metadata_recv);
+
+  error = grpc_server_request_call(server, &s, &call_details,
+                                   &request_metadata_recv, cq, cq, tag(101));
+  GPR_ASSERT(GRPC_CALL_OK == error);
+  CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
+  cq_verify(cqv);
+
+  GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.host, "localhost"));
+  GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo/bar"));
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op->flags = 0;
+  op->reserved = nullptr;
+  op++;
+  op->op = GRPC_OP_RECV_MESSAGE;
+  op->data.recv_message.recv_message = &request_payload_recv;
+  op->flags = 0;
+  op->reserved = nullptr;
+  op++;
+  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  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;
+  op->flags = 0;
+  op->reserved = nullptr;
+  op++;
+  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_UNIMPLEMENTED;
+  grpc_slice status_details = grpc_slice_from_static_string("xyz");
+  op->data.send_status_from_server.status_details = &status_details;
+  op->flags = 0;
+  op->reserved = nullptr;
+  op++;
+  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  CQ_EXPECT_COMPLETION(cqv, tag(103), 1);
+
+  grpc_metadata_array_destroy(&request_metadata_recv);
+  grpc_call_details_destroy(&call_details);
+  grpc_call_unref(s);
+  cq_verifier_destroy(cqv);
+}
+
+int main(int argc, char** argv) {
+  grpc_test_init(argc, argv);
+  grpc_init();
+
+  /* Verify that sending multiple headers doesn't segfault */
+  GRPC_RUN_BAD_CLIENT_TEST(verifier, nullptr,
+                           PFX_STR HEADER_STR HEADER_STR PAYLOAD_STR, 0);
+  GRPC_RUN_BAD_CLIENT_TEST(verifier, nullptr,
+                           PFX_STR HEADER_STR HEADER_STR HEADER_STR PAYLOAD_STR,
+                           0);
+  grpc_shutdown();
+  return 0;
+}
diff --git a/test/core/bad_client/tests/large_metadata.cc b/test/core/bad_client/tests/large_metadata.cc
index 1ce0f28..ff3e9eb 100644
--- a/test/core/bad_client/tests/large_metadata.cc
+++ b/test/core/bad_client/tests/large_metadata.cc
@@ -22,7 +22,7 @@
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/string_util.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/surface/server.h"
 #include "test/core/end2end/cq_verifier.h"
 
diff --git a/test/core/bad_ssl/bad_ssl_test.cc b/test/core/bad_ssl/bad_ssl_test.cc
index 0e74a62..8a7960b 100644
--- a/test/core/bad_ssl/bad_ssl_test.cc
+++ b/test/core/bad_ssl/bad_ssl_test.cc
@@ -26,8 +26,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/subprocess.h>
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
diff --git a/test/core/channel/minimal_stack_is_minimal_test.cc b/test/core/channel/minimal_stack_is_minimal_test.cc
index 3495f60..f02c818 100644
--- a/test/core/channel/minimal_stack_is_minimal_test.cc
+++ b/test/core/channel/minimal_stack_is_minimal_test.cc
@@ -35,7 +35,7 @@
 #include <string.h>
 
 #include "src/core/lib/channel/channel_stack_builder.h"
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/surface/channel_init.h"
 #include "src/core/lib/surface/channel_stack_type.h"
 #include "src/core/lib/transport/transport_impl.h"
diff --git a/test/core/client_channel/lb_policies_test.cc b/test/core/client_channel/lb_policies_test.cc
index 847ea00..716c63b 100644
--- a/test/core/client_channel/lb_policies_test.cc
+++ b/test/core/client_channel/lb_policies_test.cc
@@ -30,7 +30,7 @@
 #include "src/core/ext/filters/client_channel/lb_policy_registry.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/channel_stack.h"
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/server.h"
 #include "test/core/end2end/cq_verifier.h"
diff --git a/test/core/client_channel/resolvers/sockaddr_resolver_test.cc b/test/core/client_channel/resolvers/sockaddr_resolver_test.cc
index 4d16a77..07ee133 100644
--- a/test/core/client_channel/resolvers/sockaddr_resolver_test.cc
+++ b/test/core/client_channel/resolvers/sockaddr_resolver_test.cc
@@ -63,8 +63,10 @@
   grpc_resolver_next_locked(resolver, &on_res_arg.resolver_result,
                             on_resolution);
   GRPC_RESOLVER_UNREF(resolver, "test_succeeds");
-
   grpc_uri_destroy(uri);
+  /* Flush ExecCtx to avoid stack-use-after-scope on on_res_arg which is
+   * accessed in the closure on_resolution_cb */
+  grpc_core::ExecCtx::Get()->Flush();
 }
 
 static void test_fails(grpc_resolver_factory* factory, const char* string) {
diff --git a/test/core/compression/message_compress_test.cc b/test/core/compression/message_compress_test.cc
index 6ca07b7..b03ca4c 100644
--- a/test/core/compression/message_compress_test.cc
+++ b/test/core/compression/message_compress_test.cc
@@ -25,8 +25,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/useful.h>
 
+#include "src/core/lib/gpr/murmur_hash.h"
 #include "src/core/lib/iomgr/exec_ctx.h"
-#include "src/core/lib/support/murmur_hash.h"
 #include "test/core/util/slice_splitter.h"
 #include "test/core/util/test_config.h"
 
diff --git a/test/core/end2end/bad_server_response_test.cc b/test/core/end2end/bad_server_response_test.cc
index 93809ac..a8e5e29 100644
--- a/test/core/end2end/bad_server_response_test.cc
+++ b/test/core/end2end/bad_server_response_test.cc
@@ -31,10 +31,10 @@
 #include <grpc/support/log.h>
 #include <grpc/support/thd.h>
 
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/sockaddr.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
diff --git a/test/core/end2end/cq_verifier.cc b/test/core/end2end/cq_verifier.cc
index 8686f4e..7bf8ae0 100644
--- a/test/core/end2end/cq_verifier.cc
+++ b/test/core/end2end/cq_verifier.cc
@@ -29,7 +29,7 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/surface/event_string.h"
 
 #define ROOT_EXPECTATION 1000
diff --git a/test/core/end2end/dualstack_socket_test.cc b/test/core/end2end/dualstack_socket_test.cc
index 04c727e..bb30547 100644
--- a/test/core/end2end/dualstack_socket_test.cc
+++ b/test/core/end2end/dualstack_socket_test.cc
@@ -29,12 +29,12 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/error.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
 #include "src/core/lib/iomgr/socket_utils_posix.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
diff --git a/test/core/end2end/fixtures/h2_full+trace.cc b/test/core/end2end/fixtures/h2_full+trace.cc
index a49de96..7104fbc 100644
--- a/test/core/end2end/fixtures/h2_full+trace.cc
+++ b/test/core/end2end/fixtures/h2_full+trace.cc
@@ -35,7 +35,7 @@
 #include "src/core/ext/filters/http/server/http_server_filter.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/support/env.h"
+#include "src/core/lib/gpr/env.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/server.h"
 #include "test/core/util/port.h"
diff --git a/test/core/end2end/fixtures/h2_http_proxy.cc b/test/core/end2end/fixtures/h2_http_proxy.cc
index 099367d..e8e81f0 100644
--- a/test/core/end2end/fixtures/h2_http_proxy.cc
+++ b/test/core/end2end/fixtures/h2_http_proxy.cc
@@ -31,7 +31,7 @@
 #include "src/core/ext/filters/http/server/http_server_filter.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/support/env.h"
+#include "src/core/lib/gpr/env.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/server.h"
 #include "test/core/end2end/fixtures/http_proxy_fixture.h"
diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.cc b/test/core/end2end/fixtures/h2_sockpair+trace.cc
index 9807e92..236780b 100644
--- a/test/core/end2end/fixtures/h2_sockpair+trace.cc
+++ b/test/core/end2end/fixtures/h2_sockpair+trace.cc
@@ -36,9 +36,9 @@
 #include "src/core/ext/filters/http/server/http_server_filter.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/connected_channel.h"
+#include "src/core/lib/gpr/env.h"
 #include "src/core/lib/iomgr/endpoint_pair.h"
 #include "src/core/lib/iomgr/iomgr.h"
-#include "src/core/lib/support/env.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/completion_queue.h"
 #include "src/core/lib/surface/server.h"
diff --git a/test/core/end2end/fixtures/h2_ssl.cc b/test/core/end2end/fixtures/h2_ssl.cc
index 9a0680c..8c5c8a2 100644
--- a/test/core/end2end/fixtures/h2_ssl.cc
+++ b/test/core/end2end/fixtures/h2_ssl.cc
@@ -26,10 +26,10 @@
 #include <grpc/support/log.h>
 
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/tmpfile.h"
 #include "src/core/lib/security/credentials/credentials.h"
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
-#include "src/core/lib/support/tmpfile.h"
 #include "test/core/end2end/data/ssl_test_data.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.cc b/test/core/end2end/fixtures/h2_ssl_proxy.cc
index 5ddbdef..3f0646c 100644
--- a/test/core/end2end/fixtures/h2_ssl_proxy.cc
+++ b/test/core/end2end/fixtures/h2_ssl_proxy.cc
@@ -26,10 +26,10 @@
 #include <grpc/support/log.h>
 
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/tmpfile.h"
 #include "src/core/lib/security/credentials/credentials.h"
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
-#include "src/core/lib/support/tmpfile.h"
 #include "test/core/end2end/data/ssl_test_data.h"
 #include "test/core/end2end/fixtures/proxy.h"
 #include "test/core/util/port.h"
diff --git a/test/core/end2end/fixtures/h2_uds.cc b/test/core/end2end/fixtures/h2_uds.cc
index 28f0a50..1944dd8 100644
--- a/test/core/end2end/fixtures/h2_uds.cc
+++ b/test/core/end2end/fixtures/h2_uds.cc
@@ -33,7 +33,7 @@
 #include "src/core/ext/filters/http/server/http_server_filter.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/server.h"
 #include "test/core/util/port.h"
diff --git a/test/core/end2end/fixtures/http_proxy_fixture.cc b/test/core/end2end/fixtures/http_proxy_fixture.cc
index 137f7c9..8ec97df 100644
--- a/test/core/end2end/fixtures/http_proxy_fixture.cc
+++ b/test/core/end2end/fixtures/http_proxy_fixture.cc
@@ -34,6 +34,7 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/http/parser.h"
 #include "src/core/lib/iomgr/closure.h"
 #include "src/core/lib/iomgr/combiner.h"
@@ -49,7 +50,6 @@
 #include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/slice/b64.h"
 #include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/support/string.h"
 #include "test/core/util/port.h"
 
 struct grpc_end2end_http_proxy {
diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc
index 43c9fa1..14c1555 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.cc
+++ b/test/core/end2end/fuzzers/api_fuzzer.cc
@@ -28,13 +28,13 @@
 #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/env.h"
 #include "src/core/lib/iomgr/executor.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/tcp_client.h"
 #include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/iomgr/timer_manager.h"
 #include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/support/env.h"
 #include "src/core/lib/surface/server.h"
 #include "src/core/lib/transport/metadata.h"
 #include "test/core/end2end/data/ssl_test_data.h"
diff --git a/test/core/end2end/h2_ssl_cert_test.cc b/test/core/end2end/h2_ssl_cert_test.cc
index d50d1f4..3383d6d 100644
--- a/test/core/end2end/h2_ssl_cert_test.cc
+++ b/test/core/end2end/h2_ssl_cert_test.cc
@@ -26,10 +26,10 @@
 #include <grpc/support/log.h>
 
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/tmpfile.h"
 #include "src/core/lib/security/credentials/credentials.h"
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
-#include "src/core/lib/support/tmpfile.h"
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/data/ssl_test_data.h"
 #include "test/core/util/port.h"
diff --git a/test/core/end2end/tests/bad_hostname.cc b/test/core/end2end/tests/bad_hostname.cc
index 97ef62b..85e9ba1 100644
--- a/test/core/end2end/tests/bad_hostname.cc
+++ b/test/core/end2end/tests/bad_hostname.cc
@@ -27,7 +27,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
 static void* tag(intptr_t t) { return (void*)t; }
diff --git a/test/core/end2end/tests/call_creds.cc b/test/core/end2end/tests/call_creds.cc
index e1c8682..c5ea101 100644
--- a/test/core/end2end/tests/call_creds.cc
+++ b/test/core/end2end/tests/call_creds.cc
@@ -27,8 +27,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/security/credentials/credentials.h"
-#include "src/core/lib/support/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
 static const char iam_token[] = "token";
diff --git a/test/core/end2end/tests/cancel_with_status.cc b/test/core/end2end/tests/cancel_with_status.cc
index c867751..7937fd1 100644
--- a/test/core/end2end/tests/cancel_with_status.cc
+++ b/test/core/end2end/tests/cancel_with_status.cc
@@ -28,7 +28,7 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
 static void* tag(intptr_t t) { return (void*)t; }
diff --git a/test/core/end2end/tests/default_host.cc b/test/core/end2end/tests/default_host.cc
index 85f92b0..7c94420 100644
--- a/test/core/end2end/tests/default_host.cc
+++ b/test/core/end2end/tests/default_host.cc
@@ -27,7 +27,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
 static void* tag(intptr_t t) { return (void*)t; }
diff --git a/test/core/end2end/tests/empty_batch.cc b/test/core/end2end/tests/empty_batch.cc
index b249c14..c41e65d 100644
--- a/test/core/end2end/tests/empty_batch.cc
+++ b/test/core/end2end/tests/empty_batch.cc
@@ -27,7 +27,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
 static void* tag(intptr_t t) { return (void*)t; }
diff --git a/test/core/end2end/tests/high_initial_seqno.cc b/test/core/end2end/tests/high_initial_seqno.cc
index d390a95..d4d4f5a 100644
--- a/test/core/end2end/tests/high_initial_seqno.cc
+++ b/test/core/end2end/tests/high_initial_seqno.cc
@@ -29,7 +29,7 @@
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
 
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
 static void* tag(intptr_t t) { return (void*)t; }
diff --git a/test/core/end2end/tests/hpack_size.cc b/test/core/end2end/tests/hpack_size.cc
index 7ac5fef..0d6ec01 100644
--- a/test/core/end2end/tests/hpack_size.cc
+++ b/test/core/end2end/tests/hpack_size.cc
@@ -29,7 +29,7 @@
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
 
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
 static void* tag(intptr_t t) { return (void*)t; }
diff --git a/test/core/end2end/tests/idempotent_request.cc b/test/core/end2end/tests/idempotent_request.cc
index e399753..7487e4d 100644
--- a/test/core/end2end/tests/idempotent_request.cc
+++ b/test/core/end2end/tests/idempotent_request.cc
@@ -27,7 +27,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
 static void* tag(intptr_t t) { return (void*)t; }
diff --git a/test/core/end2end/tests/keepalive_timeout.cc b/test/core/end2end/tests/keepalive_timeout.cc
index 8225655..6482b86 100644
--- a/test/core/end2end/tests/keepalive_timeout.cc
+++ b/test/core/end2end/tests/keepalive_timeout.cc
@@ -28,8 +28,8 @@
 #include <grpc/support/useful.h>
 #include "src/core/ext/transport/chttp2/transport/frame_ping.h"
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/env.h"
 #include "src/core/lib/iomgr/exec_ctx.h"
-#include "src/core/lib/support/env.h"
 #include "test/core/end2end/cq_verifier.h"
 
 static void* tag(intptr_t t) { return (void*)t; }
diff --git a/test/core/end2end/tests/negative_deadline.cc b/test/core/end2end/tests/negative_deadline.cc
index b793964..b752bf9 100644
--- a/test/core/end2end/tests/negative_deadline.cc
+++ b/test/core/end2end/tests/negative_deadline.cc
@@ -27,7 +27,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
 static void* tag(intptr_t t) { return (void*)t; }
diff --git a/test/core/end2end/tests/no_logging.cc b/test/core/end2end/tests/no_logging.cc
index bf86512..d89918b 100644
--- a/test/core/end2end/tests/no_logging.cc
+++ b/test/core/end2end/tests/no_logging.cc
@@ -28,8 +28,8 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/error.h"
-#include "src/core/lib/support/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
 enum { TIMEOUT = 200000 };
diff --git a/test/core/end2end/tests/proxy_auth.cc b/test/core/end2end/tests/proxy_auth.cc
index e4b91ab..495151b 100644
--- a/test/core/end2end/tests/proxy_auth.cc
+++ b/test/core/end2end/tests/proxy_auth.cc
@@ -32,7 +32,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
 static void* tag(intptr_t t) { return (void*)t; }
diff --git a/test/core/end2end/tests/registered_call.cc b/test/core/end2end/tests/registered_call.cc
index 440d817..cefa89d 100644
--- a/test/core/end2end/tests/registered_call.cc
+++ b/test/core/end2end/tests/registered_call.cc
@@ -27,7 +27,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
 static void* tag(intptr_t t) { return (void*)t; }
diff --git a/test/core/end2end/tests/server_finishes_request.cc b/test/core/end2end/tests/server_finishes_request.cc
index 46b874b..743b3ae 100644
--- a/test/core/end2end/tests/server_finishes_request.cc
+++ b/test/core/end2end/tests/server_finishes_request.cc
@@ -27,7 +27,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
 static void* tag(intptr_t t) { return (void*)t; }
diff --git a/test/core/end2end/tests/simple_request.cc b/test/core/end2end/tests/simple_request.cc
index 7eb7467..ae93f79 100644
--- a/test/core/end2end/tests/simple_request.cc
+++ b/test/core/end2end/tests/simple_request.cc
@@ -28,7 +28,7 @@
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
 #include "src/core/lib/debug/stats.h"
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
 static void* tag(intptr_t t) { return (void*)t; }
diff --git a/test/core/fling/fling_stream_test.cc b/test/core/fling/fling_stream_test.cc
index b476f2e..b5a5ce81 100644
--- a/test/core/fling/fling_stream_test.cc
+++ b/test/core/fling/fling_stream_test.cc
@@ -23,7 +23,7 @@
 #include <grpc/support/host_port.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/subprocess.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/util/port.h"
 
 int main(int argc, char** argv) {
diff --git a/test/core/fling/fling_test.cc b/test/core/fling/fling_test.cc
index 0e8b3c1..3792e45 100644
--- a/test/core/fling/fling_test.cc
+++ b/test/core/fling/fling_test.cc
@@ -23,7 +23,7 @@
 #include <grpc/support/host_port.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/subprocess.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/util/port.h"
 
 int main(int argc, const char** argv) {
diff --git a/test/core/gpr++/BUILD b/test/core/gpr++/BUILD
new file mode 100644
index 0000000..93324a3
--- /dev/null
+++ b/test/core/gpr++/BUILD
@@ -0,0 +1,95 @@
+# Copyright 2016 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_cc_binary", "grpc_package")
+
+licenses(["notice"])  # Apache v2
+
+grpc_package(name = "test/core/gpr++")
+
+grpc_cc_test(
+    name = "manual_constructor_test",
+    srcs = ["manual_constructor_test.cc"],
+    language = "C++",
+    deps = [
+        "//:gpr",
+        "//test/core/util:gpr_test_util",
+    ],
+)
+
+grpc_cc_test(
+    name = "memory_test",
+    srcs = ["memory_test.cc"],
+    external_deps = [
+        "gtest",
+    ],
+    language = "C++",
+    deps = [
+        "//:grpc",
+        "//test/core/util:gpr_test_util",
+    ],
+)
+
+grpc_cc_test(
+    name = "inlined_vector_test",
+    srcs = ["inlined_vector_test.cc"],
+    external_deps = [
+        "gtest",
+    ],
+    language = "C++",
+    deps = [
+        "//:grpc",
+        "//test/core/util:gpr_test_util",
+    ],
+)
+
+grpc_cc_test(
+    name = "orphanable_test",
+    srcs = ["orphanable_test.cc"],
+    language = "C++",
+    deps = [
+        "//:orphanable",
+        "//test/core/util:gpr_test_util",
+    ],
+    external_deps = [
+        "gtest",
+    ],
+)
+
+grpc_cc_test(
+    name = "ref_counted_test",
+    srcs = ["ref_counted_test.cc"],
+    language = "C++",
+    deps = [
+        "//:ref_counted",
+        "//test/core/util:gpr_test_util",
+    ],
+    external_deps = [
+        "gtest",
+    ],
+)
+
+grpc_cc_test(
+    name = "ref_counted_ptr_test",
+    srcs = ["ref_counted_ptr_test.cc"],
+    language = "C++",
+    deps = [
+        "//:ref_counted",
+        "//:ref_counted_ptr",
+        "//test/core/util:gpr_test_util",
+    ],
+    external_deps = [
+        "gtest",
+    ],
+)
diff --git a/test/core/support/vector_test.cc b/test/core/gpr++/inlined_vector_test.cc
similarity index 95%
rename from test/core/support/vector_test.cc
rename to test/core/gpr++/inlined_vector_test.cc
index 82607a1..09d5453 100644
--- a/test/core/support/vector_test.cc
+++ b/test/core/gpr++/inlined_vector_test.cc
@@ -16,9 +16,9 @@
  *
  */
 
-#include "src/core/lib/support/vector.h"
+#include "src/core/lib/gpr++/inlined_vector.h"
 #include <gtest/gtest.h>
-#include "src/core/lib/support/memory.h"
+#include "src/core/lib/gpr++/memory.h"
 #include "test/core/util/test_config.h"
 
 namespace grpc_core {
diff --git a/test/core/support/manual_constructor_test.cc b/test/core/gpr++/manual_constructor_test.cc
similarity index 95%
rename from test/core/support/manual_constructor_test.cc
rename to test/core/gpr++/manual_constructor_test.cc
index 714f8b2..e049b79 100644
--- a/test/core/support/manual_constructor_test.cc
+++ b/test/core/gpr++/manual_constructor_test.cc
@@ -18,7 +18,7 @@
 
 /* Test of gpr synchronization support. */
 
-#include "src/core/lib/support/manual_constructor.h"
+#include "src/core/lib/gpr++/manual_constructor.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
@@ -26,7 +26,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <cstring>
-#include "src/core/lib/support/abstract.h"
+#include "src/core/lib/gpr++/abstract.h"
 #include "test/core/util/test_config.h"
 
 class A {
diff --git a/test/core/support/memory_test.cc b/test/core/gpr++/memory_test.cc
similarity index 97%
rename from test/core/support/memory_test.cc
rename to test/core/gpr++/memory_test.cc
index 79ab631..3553e11 100644
--- a/test/core/support/memory_test.cc
+++ b/test/core/gpr++/memory_test.cc
@@ -16,7 +16,7 @@
  *
  */
 
-#include "src/core/lib/support/memory.h"
+#include "src/core/lib/gpr++/memory.h"
 #include <gtest/gtest.h>
 #include "test/core/util/test_config.h"
 
diff --git a/test/core/support/orphanable_test.cc b/test/core/gpr++/orphanable_test.cc
similarity index 96%
rename from test/core/support/orphanable_test.cc
rename to test/core/gpr++/orphanable_test.cc
index e07017a..4513d25 100644
--- a/test/core/support/orphanable_test.cc
+++ b/test/core/gpr++/orphanable_test.cc
@@ -16,11 +16,11 @@
  *
  */
 
-#include "src/core/lib/support/orphanable.h"
+#include "src/core/lib/gpr++/orphanable.h"
 
 #include <gtest/gtest.h>
 
-#include "src/core/lib/support/memory.h"
+#include "src/core/lib/gpr++/memory.h"
 #include "test/core/util/test_config.h"
 
 namespace grpc_core {
diff --git a/test/core/support/ref_counted_ptr_test.cc b/test/core/gpr++/ref_counted_ptr_test.cc
similarity index 96%
rename from test/core/support/ref_counted_ptr_test.cc
rename to test/core/gpr++/ref_counted_ptr_test.cc
index ce4975d..e897b28 100644
--- a/test/core/support/ref_counted_ptr_test.cc
+++ b/test/core/gpr++/ref_counted_ptr_test.cc
@@ -16,14 +16,14 @@
  *
  */
 
-#include "src/core/lib/support/ref_counted_ptr.h"
+#include "src/core/lib/gpr++/ref_counted_ptr.h"
 
 #include <gtest/gtest.h>
 
 #include <grpc/support/log.h>
 
-#include "src/core/lib/support/memory.h"
-#include "src/core/lib/support/ref_counted.h"
+#include "src/core/lib/gpr++/memory.h"
+#include "src/core/lib/gpr++/ref_counted.h"
 #include "test/core/util/test_config.h"
 
 namespace grpc_core {
diff --git a/test/core/support/ref_counted_test.cc b/test/core/gpr++/ref_counted_test.cc
similarity index 94%
rename from test/core/support/ref_counted_test.cc
rename to test/core/gpr++/ref_counted_test.cc
index 0629e3f..568ec51 100644
--- a/test/core/support/ref_counted_test.cc
+++ b/test/core/gpr++/ref_counted_test.cc
@@ -16,11 +16,11 @@
  *
  */
 
-#include "src/core/lib/support/ref_counted.h"
+#include "src/core/lib/gpr++/ref_counted.h"
 
 #include <gtest/gtest.h>
 
-#include "src/core/lib/support/memory.h"
+#include "src/core/lib/gpr++/memory.h"
 #include "test/core/util/test_config.h"
 
 namespace grpc_core {
diff --git a/test/core/support/BUILD b/test/core/gpr/BUILD
similarity index 70%
rename from test/core/support/BUILD
rename to test/core/gpr/BUILD
index c8fa046..1be1036 100644
--- a/test/core/support/BUILD
+++ b/test/core/gpr/BUILD
@@ -16,7 +16,7 @@
 
 licenses(["notice"])  # Apache v2
 
-grpc_package(name = "test/core/support")
+grpc_package(name = "test/core/gpr")
 
 grpc_cc_test(
     name = "alloc_test",
@@ -119,16 +119,6 @@
 )
 
 grpc_cc_test(
-    name = "manual_constructor_test",
-    srcs = ["manual_constructor_test.cc"],
-    language = "C++",
-    deps = [
-        "//:gpr",
-        "//test/core/util:gpr_test_util",
-    ],
-)
-
-grpc_cc_test(
     name = "spinlock_test",
     srcs = ["spinlock_test.cc"],
     language = "C++",
@@ -187,69 +177,3 @@
         "//test/core/util:gpr_test_util",
     ],
 )
-
-grpc_cc_test(
-    name = "memory_test",
-    srcs = ["memory_test.cc"],
-    external_deps = [
-        "gtest",
-    ],
-    language = "C++",
-    deps = [
-        "//:grpc",
-        "//test/core/util:gpr_test_util",
-    ],
-)
-
-grpc_cc_test(
-    name = "vector_test",
-    srcs = ["vector_test.cc"],
-    external_deps = [
-        "gtest",
-    ],
-    language = "C++",
-    deps = [
-        "//:grpc",
-        "//test/core/util:gpr_test_util",
-    ],
-)
-
-grpc_cc_test(
-    name = "orphanable_test",
-    srcs = ["orphanable_test.cc"],
-    language = "C++",
-    deps = [
-        "//:orphanable",
-        "//test/core/util:gpr_test_util",
-    ],
-    external_deps = [
-        "gtest",
-    ],
-)
-
-grpc_cc_test(
-    name = "ref_counted_test",
-    srcs = ["ref_counted_test.cc"],
-    language = "C++",
-    deps = [
-        "//:ref_counted",
-        "//test/core/util:gpr_test_util",
-    ],
-    external_deps = [
-        "gtest",
-    ],
-)
-
-grpc_cc_test(
-    name = "ref_counted_ptr_test",
-    srcs = ["ref_counted_ptr_test.cc"],
-    language = "C++",
-    deps = [
-        "//:ref_counted",
-        "//:ref_counted_ptr",
-        "//test/core/util:gpr_test_util",
-    ],
-    external_deps = [
-        "gtest",
-    ],
-)
diff --git a/test/core/support/alloc_test.cc b/test/core/gpr/alloc_test.cc
similarity index 100%
rename from test/core/support/alloc_test.cc
rename to test/core/gpr/alloc_test.cc
diff --git a/test/core/support/arena_test.cc b/test/core/gpr/arena_test.cc
similarity index 97%
rename from test/core/support/arena_test.cc
rename to test/core/gpr/arena_test.cc
index ada0f43..59ea04c 100644
--- a/test/core/support/arena_test.cc
+++ b/test/core/gpr/arena_test.cc
@@ -16,7 +16,7 @@
  *
  */
 
-#include "src/core/lib/support/arena.h"
+#include "src/core/lib/gpr/arena.h"
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
@@ -27,7 +27,7 @@
 #include <inttypes.h>
 #include <string.h>
 
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/util/test_config.h"
 
 static void test_noop(void) { gpr_arena_destroy(gpr_arena_create(1)); }
diff --git a/test/core/support/avl_test.cc b/test/core/gpr/avl_test.cc
similarity index 100%
rename from test/core/support/avl_test.cc
rename to test/core/gpr/avl_test.cc
diff --git a/test/core/support/cmdline_test.cc b/test/core/gpr/cmdline_test.cc
similarity index 100%
rename from test/core/support/cmdline_test.cc
rename to test/core/gpr/cmdline_test.cc
diff --git a/test/core/support/cpu_test.cc b/test/core/gpr/cpu_test.cc
similarity index 100%
rename from test/core/support/cpu_test.cc
rename to test/core/gpr/cpu_test.cc
diff --git a/test/core/support/env_test.cc b/test/core/gpr/env_test.cc
similarity index 93%
rename from test/core/support/env_test.cc
rename to test/core/gpr/env_test.cc
index b12c04d..3f4b493 100644
--- a/test/core/support/env_test.cc
+++ b/test/core/gpr/env_test.cc
@@ -22,8 +22,8 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/util/test_config.h"
 
 #define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x)
diff --git a/test/core/support/host_port_test.cc b/test/core/gpr/host_port_test.cc
similarity index 100%
rename from test/core/support/host_port_test.cc
rename to test/core/gpr/host_port_test.cc
diff --git a/test/core/support/log_test.cc b/test/core/gpr/log_test.cc
similarity index 98%
rename from test/core/support/log_test.cc
rename to test/core/gpr/log_test.cc
index 7dba35c..839ff0a 100644
--- a/test/core/support/log_test.cc
+++ b/test/core/gpr/log_test.cc
@@ -21,7 +21,7 @@
 #include <stdbool.h>
 #include <string.h>
 
-#include "src/core/lib/support/env.h"
+#include "src/core/lib/gpr/env.h"
 #include "test/core/util/test_config.h"
 
 static bool log_func_reached = false;
diff --git a/test/core/support/mpscq_test.cc b/test/core/gpr/mpscq_test.cc
similarity index 98%
rename from test/core/support/mpscq_test.cc
rename to test/core/gpr/mpscq_test.cc
index 1b83f7d..5a81775 100644
--- a/test/core/support/mpscq_test.cc
+++ b/test/core/gpr/mpscq_test.cc
@@ -16,7 +16,7 @@
  *
  */
 
-#include "src/core/lib/support/mpscq.h"
+#include "src/core/lib/gpr/mpscq.h"
 
 #include <stdlib.h>
 
diff --git a/test/core/support/murmur_hash_test.cc b/test/core/gpr/murmur_hash_test.cc
similarity index 97%
rename from test/core/support/murmur_hash_test.cc
rename to test/core/gpr/murmur_hash_test.cc
index 461c728..d920dd3 100644
--- a/test/core/support/murmur_hash_test.cc
+++ b/test/core/gpr/murmur_hash_test.cc
@@ -16,7 +16,7 @@
  *
  */
 
-#include "src/core/lib/support/murmur_hash.h"
+#include "src/core/lib/gpr/murmur_hash.h"
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include "test/core/util/test_config.h"
diff --git a/test/core/support/spinlock_test.cc b/test/core/gpr/spinlock_test.cc
similarity index 98%
rename from test/core/support/spinlock_test.cc
rename to test/core/gpr/spinlock_test.cc
index ea0dbbf..77e3dfb 100644
--- a/test/core/support/spinlock_test.cc
+++ b/test/core/gpr/spinlock_test.cc
@@ -18,7 +18,7 @@
 
 /* Test of gpr synchronization support. */
 
-#include "src/core/lib/support/spinlock.h"
+#include "src/core/lib/gpr/spinlock.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
diff --git a/test/core/support/string_test.cc b/test/core/gpr/string_test.cc
similarity index 99%
rename from test/core/support/string_test.cc
rename to test/core/gpr/string_test.cc
index fd7f7cd..57068eb 100644
--- a/test/core/support/string_test.cc
+++ b/test/core/gpr/string_test.cc
@@ -16,7 +16,7 @@
  *
  */
 
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 
 #include <limits.h>
 #include <stddef.h>
diff --git a/test/core/support/sync_test.cc b/test/core/gpr/sync_test.cc
similarity index 100%
rename from test/core/support/sync_test.cc
rename to test/core/gpr/sync_test.cc
diff --git a/test/core/support/thd_test.cc b/test/core/gpr/thd_test.cc
similarity index 100%
rename from test/core/support/thd_test.cc
rename to test/core/gpr/thd_test.cc
diff --git a/test/core/support/time_test.cc b/test/core/gpr/time_test.cc
similarity index 100%
rename from test/core/support/time_test.cc
rename to test/core/gpr/time_test.cc
diff --git a/test/core/support/tls_test.cc b/test/core/gpr/tls_test.cc
similarity index 100%
rename from test/core/support/tls_test.cc
rename to test/core/gpr/tls_test.cc
diff --git a/test/core/support/useful_test.cc b/test/core/gpr/useful_test.cc
similarity index 100%
rename from test/core/support/useful_test.cc
rename to test/core/gpr/useful_test.cc
diff --git a/test/core/iomgr/load_file_test.cc b/test/core/iomgr/load_file_test.cc
index 797d0ef..38c8710 100644
--- a/test/core/iomgr/load_file_test.cc
+++ b/test/core/iomgr/load_file_test.cc
@@ -24,9 +24,9 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/tmpfile.h"
 #include "src/core/lib/iomgr/load_file.h"
-#include "src/core/lib/support/string.h"
-#include "src/core/lib/support/tmpfile.h"
 #include "test/core/util/test_config.h"
 
 #define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x)
diff --git a/test/core/iomgr/wakeup_fd_cv_test.cc b/test/core/iomgr/wakeup_fd_cv_test.cc
index d4e05bd..c092a8f 100644
--- a/test/core/iomgr/wakeup_fd_cv_test.cc
+++ b/test/core/iomgr/wakeup_fd_cv_test.cc
@@ -27,9 +27,9 @@
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
 
+#include "src/core/lib/gpr/env.h"
 #include "src/core/lib/iomgr/ev_posix.h"
 #include "src/core/lib/iomgr/iomgr_posix.h"
-#include "src/core/lib/support/env.h"
 
 typedef struct poll_args {
   struct pollfd* fds;
diff --git a/test/core/json/json_test.cc b/test/core/json/json_test.cc
index 18b9c55..902f1cd 100644
--- a/test/core/json/json_test.cc
+++ b/test/core/json/json_test.cc
@@ -22,8 +22,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/json/json.h"
-#include "src/core/lib/support/string.h"
 
 #include "test/core/util/test_config.h"
 
diff --git a/test/core/memory_usage/client.cc b/test/core/memory_usage/client.cc
index eb90067..ca84143 100644
--- a/test/core/memory_usage/client.cc
+++ b/test/core/memory_usage/client.cc
@@ -28,8 +28,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/util/memory_counters.h"
 #include "test/core/util/test_config.h"
 
diff --git a/test/core/memory_usage/memory_usage_test.cc b/test/core/memory_usage/memory_usage_test.cc
index 58e31c9..fb6d290 100644
--- a/test/core/memory_usage/memory_usage_test.cc
+++ b/test/core/memory_usage/memory_usage_test.cc
@@ -23,7 +23,7 @@
 #include <grpc/support/host_port.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/subprocess.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/util/port.h"
 
 int main(int argc, char** argv) {
diff --git a/test/core/security/auth_context_test.cc b/test/core/security/auth_context_test.cc
index d8e4132..58f0d8e 100644
--- a/test/core/security/auth_context_test.cc
+++ b/test/core/security/auth_context_test.cc
@@ -18,8 +18,8 @@
 
 #include <string.h>
 
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/security/context/security_context.h"
-#include "src/core/lib/support/string.h"
 #include "test/core/util/test_config.h"
 
 #include <grpc/support/log.h>
diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc
index ecc6192..9031046 100644
--- a/test/core/security/credentials_test.cc
+++ b/test/core/security/credentials_test.cc
@@ -31,6 +31,9 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/time.h>
 
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/tmpfile.h"
 #include "src/core/lib/http/httpcli.h"
 #include "src/core/lib/security/credentials/composite/composite_credentials.h"
 #include "src/core/lib/security/credentials/fake/fake_credentials.h"
@@ -38,9 +41,6 @@
 #include "src/core/lib/security/credentials/jwt/jwt_credentials.h"
 #include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
 #include "src/core/lib/security/transport/auth_filters.h"
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
-#include "src/core/lib/support/tmpfile.h"
 #include "test/core/util/test_config.h"
 
 /* -- Mock channel credentials. -- */
diff --git a/test/core/security/print_google_default_creds_token.cc b/test/core/security/print_google_default_creds_token.cc
index d71116d..a90f997 100644
--- a/test/core/security/print_google_default_creds_token.cc
+++ b/test/core/security/print_google_default_creds_token.cc
@@ -27,10 +27,10 @@
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/security/credentials/composite/composite_credentials.h"
 #include "src/core/lib/security/credentials/credentials.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 
 typedef struct {
   gpr_mu* mu;
diff --git a/test/core/security/security_connector_test.cc b/test/core/security/security_connector_test.cc
index 9a68e17..6eaef2b 100644
--- a/test/core/security/security_connector_test.cc
+++ b/test/core/security/security_connector_test.cc
@@ -25,12 +25,12 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
 
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/tmpfile.h"
 #include "src/core/lib/security/context/security_context.h"
 #include "src/core/lib/security/transport/security_connector.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
-#include "src/core/lib/support/tmpfile.h"
 #include "src/core/tsi/ssl_transport_security.h"
 #include "src/core/tsi/transport_security.h"
 #include "test/core/util/test_config.h"
diff --git a/test/core/slice/percent_encoding_test.cc b/test/core/slice/percent_encoding_test.cc
index 11f3995..e8d04fc 100644
--- a/test/core/slice/percent_encoding_test.cc
+++ b/test/core/slice/percent_encoding_test.cc
@@ -22,8 +22,8 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 #include "test/core/util/test_config.h"
 
 #define TEST_VECTOR(raw, encoded, dict) \
diff --git a/test/core/slice/slice_string_helpers_test.cc b/test/core/slice/slice_string_helpers_test.cc
index f1d4704..a443f17 100644
--- a/test/core/slice/slice_string_helpers_test.cc
+++ b/test/core/slice/slice_string_helpers_test.cc
@@ -29,7 +29,7 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
 
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/util/test_config.h"
 
 #define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x)
diff --git a/test/core/transport/bdp_estimator_test.cc b/test/core/transport/bdp_estimator_test.cc
index 445823b..3afcad7 100644
--- a/test/core/transport/bdp_estimator_test.cc
+++ b/test/core/transport/bdp_estimator_test.cc
@@ -25,8 +25,8 @@
 #include <grpc/support/useful.h>
 #include <gtest/gtest.h>
 #include <limits.h>
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/timer_manager.h"
-#include "src/core/lib/support/string.h"
 #include "test/core/util/test_config.h"
 
 extern gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type);
diff --git a/test/core/transport/chttp2/bin_decoder_test.cc b/test/core/transport/chttp2/bin_decoder_test.cc
index 6d70a42..283eebb 100644
--- a/test/core/transport/chttp2/bin_decoder_test.cc
+++ b/test/core/transport/chttp2/bin_decoder_test.cc
@@ -24,9 +24,9 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 
 static int all_ok = 1;
 
diff --git a/test/core/transport/chttp2/bin_encoder_test.cc b/test/core/transport/chttp2/bin_encoder_test.cc
index 44f5de8..bd62b0e 100644
--- a/test/core/transport/chttp2/bin_encoder_test.cc
+++ b/test/core/transport/chttp2/bin_encoder_test.cc
@@ -26,8 +26,8 @@
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 
 static int all_ok = 1;
 
diff --git a/test/core/transport/chttp2/hpack_encoder_test.cc b/test/core/transport/chttp2/hpack_encoder_test.cc
index d2dbd4a..a40bd64 100644
--- a/test/core/transport/chttp2/hpack_encoder_test.cc
+++ b/test/core/transport/chttp2/hpack_encoder_test.cc
@@ -26,9 +26,9 @@
 #include <grpc/support/string_util.h>
 
 #include "src/core/ext/transport/chttp2/transport/hpack_parser.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/metadata.h"
 #include "test/core/util/parse_hexstring.h"
 #include "test/core/util/slice_splitter.h"
diff --git a/test/core/transport/chttp2/hpack_table_test.cc b/test/core/transport/chttp2/hpack_table_test.cc
index 3f3cb2e..e316cf6 100644
--- a/test/core/transport/chttp2/hpack_table_test.cc
+++ b/test/core/transport/chttp2/hpack_table_test.cc
@@ -26,7 +26,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/util/test_config.h"
 
 #define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x)
diff --git a/test/core/transport/metadata_test.cc b/test/core/transport/metadata_test.cc
index 5c52ae8..7d943fd 100644
--- a/test/core/transport/metadata_test.cc
+++ b/test/core/transport/metadata_test.cc
@@ -27,8 +27,8 @@
 #include <grpc/support/string_util.h>
 
 #include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/static_metadata.h"
 #include "test/core/util/test_config.h"
 
diff --git a/test/core/transport/pid_controller_test.cc b/test/core/transport/pid_controller_test.cc
index 081d034..1a499c2 100644
--- a/test/core/transport/pid_controller_test.cc
+++ b/test/core/transport/pid_controller_test.cc
@@ -26,7 +26,7 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
 #include <gtest/gtest.h>
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/util/test_config.h"
 
 namespace grpc_core {
diff --git a/test/core/transport/timeout_encoding_test.cc b/test/core/transport/timeout_encoding_test.cc
index 0930bc8..e94be13 100644
--- a/test/core/transport/timeout_encoding_test.cc
+++ b/test/core/transport/timeout_encoding_test.cc
@@ -25,8 +25,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
-#include "src/core/lib/support/murmur_hash.h"
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/murmur_hash.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/core/util/test_config.h"
 
 #define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x)
diff --git a/test/core/tsi/transport_security_test.cc b/test/core/tsi/transport_security_test.cc
index c788ad9..42e17df 100644
--- a/test/core/tsi/transport_security_test.cc
+++ b/test/core/tsi/transport_security_test.cc
@@ -27,7 +27,7 @@
 
 #include <openssl/crypto.h>
 
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/tsi/fake_transport_security.h"
 #include "src/core/tsi/ssl_transport_security.h"
 #include "test/core/util/test_config.h"
diff --git a/test/core/util/test_config.cc b/test/core/util/test_config.cc
index 9ebb52d..6b41044 100644
--- a/test/core/util/test_config.cc
+++ b/test/core/util/test_config.cc
@@ -27,8 +27,8 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
 
 int64_t g_fixture_slowdown_factor = 1;
 int64_t g_poller_slowdown_factor = 1;
diff --git a/test/cpp/client/client_channel_stress_test.cc b/test/cpp/client/client_channel_stress_test.cc
index e829d52..80d1583 100644
--- a/test/cpp/client/client_channel_stress_test.cc
+++ b/test/cpp/client/client_channel_stress_test.cc
@@ -19,6 +19,7 @@
 #include <atomic>
 #include <memory>
 #include <mutex>
+#include <random>
 #include <sstream>
 #include <thread>
 
@@ -104,8 +105,8 @@
     for (size_t i = 0; i < num_drop_entry; ++i) {
       random_backend_indices.push_back(-1);
     }
-    std::random_shuffle(random_backend_indices.begin(),
-                        random_backend_indices.end());
+    std::shuffle(random_backend_indices.begin(), random_backend_indices.end(),
+                 std::mt19937(std::random_device()()));
     // Build the response according to the random list generated above.
     LoadBalanceResponse response;
     for (int index : random_backend_indices) {
@@ -149,7 +150,8 @@
           addresses.emplace_back(AddressData{balancer_server.port_, true, ""});
         }
       }
-      std::random_shuffle(addresses.begin(), addresses.end());
+      std::shuffle(addresses.begin(), addresses.end(),
+                   std::mt19937(std::random_device()()));
       SetNextResolution(addresses);
       std::this_thread::sleep_for(wait_duration);
     }
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index 1ea087e..44cd81a 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -34,8 +34,8 @@
 #include <grpc/support/time.h>
 #include <grpc/support/tls.h>
 
+#include "src/core/lib/gpr/env.h"
 #include "src/core/lib/iomgr/port.h"
-#include "src/core/lib/support/env.h"
 #include "src/proto/grpc/health/v1/health.grpc.pb.h"
 #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
 #include "src/proto/grpc/testing/echo.grpc.pb.h"
diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc
index 5a7e52e..7f82330 100644
--- a/test/cpp/end2end/client_lb_end2end_test.cc
+++ b/test/cpp/end2end/client_lb_end2end_test.cc
@@ -19,6 +19,7 @@
 #include <algorithm>
 #include <memory>
 #include <mutex>
+#include <random>
 #include <thread>
 
 #include <grpc++/channel.h>
@@ -37,7 +38,7 @@
 #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
 #include "src/core/ext/filters/client_channel/subchannel_index.h"
 #include "src/core/lib/backoff/backoff.h"
-#include "src/core/lib/support/env.h"
+#include "src/core/lib/gpr/env.h"
 
 #include "src/proto/grpc/testing/echo.grpc.pb.h"
 #include "test/core/util/port.h"
@@ -456,7 +457,8 @@
     grpc_subchannel_index_test_only_set_force_creation(force_creation);
     gpr_log(GPR_INFO, "Force subchannel creation: %d", force_creation);
     for (size_t i = 0; i < 1000; ++i) {
-      std::random_shuffle(ports.begin(), ports.end());
+      std::shuffle(ports.begin(), ports.end(),
+                   std::mt19937(std::random_device()()));
       SetNextResolution(ports);
       if (i % 10 == 0) CheckRpcSendOk();
     }
@@ -621,7 +623,8 @@
     ports.emplace_back(servers_[i]->port_);
   }
   for (size_t i = 0; i < 1000; ++i) {
-    std::random_shuffle(ports.begin(), ports.end());
+    std::shuffle(ports.begin(), ports.end(),
+                 std::mt19937(std::random_device()()));
     SetNextResolution(ports);
     if (i % 10 == 0) CheckRpcSendOk();
   }
@@ -673,42 +676,6 @@
   GPR_ASSERT(gpr_time_cmp(deadline, now) > 0);
 }
 
-TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) {
-  const int kNumServers = 3;
-  StartServers(kNumServers);
-  const auto ports = GetServersPorts();
-  ResetStub(ports, "round_robin");
-  SetNextResolution(ports);
-  for (size_t i = 0; i < kNumServers; ++i) WaitForServer(i);
-  for (size_t i = 0; i < servers_.size(); ++i) {
-    CheckRpcSendOk();
-    EXPECT_EQ(1, servers_[i]->service_.request_count()) << "for backend #" << i;
-  }
-  // One request should have gone to each server.
-  for (size_t i = 0; i < servers_.size(); ++i) {
-    EXPECT_EQ(1, servers_[i]->service_.request_count());
-  }
-  const auto pre_death = servers_[0]->service_.request_count();
-  // Kill the first server.
-  servers_[0]->Shutdown(true);
-  // Client request still succeed. May need retrying if RR had returned a pick
-  // before noticing the change in the server's connectivity.
-  while (!SendRpc())
-    ;  // Retry until success.
-  // Send a bunch of RPCs that should succeed.
-  for (int i = 0; i < 10 * kNumServers; ++i) CheckRpcSendOk();
-  const auto post_death = servers_[0]->service_.request_count();
-  // No requests have gone to the deceased server.
-  EXPECT_EQ(pre_death, post_death);
-  // Bring the first server back up.
-  servers_[0].reset(new ServerData(server_host_, ports[0]));
-  // Requests should start arriving at the first server either right away (if
-  // the server managed to start before the RR policy retried the subchannel) or
-  // after the subchannel retry delay otherwise (RR's subchannel retried before
-  // the server was fully back up).
-  WaitForServer(0);
-}
-
 }  // namespace
 }  // namespace testing
 }  // namespace grpc
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index a6ea5aa..e25de81 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -35,8 +35,8 @@
 #include <grpc/support/thd.h>
 #include <grpc/support/time.h>
 
+#include "src/core/lib/gpr/env.h"
 #include "src/core/lib/security/credentials/credentials.h"
-#include "src/core/lib/support/env.h"
 #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
 #include "src/proto/grpc/testing/echo.grpc.pb.h"
 #include "test/core/util/port.h"
diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc
index d4ee6b4..815dfd0 100644
--- a/test/cpp/end2end/grpclb_end2end_test.cc
+++ b/test/cpp/end2end/grpclb_end2end_test.cc
@@ -34,8 +34,8 @@
 #include <grpc/support/time.h>
 
 #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
+#include "src/core/lib/gpr/env.h"
 #include "src/core/lib/iomgr/sockaddr.h"
-#include "src/core/lib/support/env.h"
 
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
diff --git a/test/cpp/end2end/shutdown_test.cc b/test/cpp/end2end/shutdown_test.cc
index 14ba7c9..9119102 100644
--- a/test/cpp/end2end/shutdown_test.cc
+++ b/test/cpp/end2end/shutdown_test.cc
@@ -28,7 +28,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 
-#include "src/core/lib/support/env.h"
+#include "src/core/lib/gpr/env.h"
 #include "src/proto/grpc/testing/echo.grpc.pb.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
diff --git a/test/cpp/grpclb/grpclb_test.cc b/test/cpp/grpclb/grpclb_test.cc
index 38b65fb..d241594 100644
--- a/test/cpp/grpclb/grpclb_test.cc
+++ b/test/cpp/grpclb/grpclb_test.cc
@@ -40,11 +40,11 @@
 #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/channel_stack.h"
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/tmpfile.h"
 #include "src/core/lib/iomgr/sockaddr.h"
 #include "src/core/lib/security/credentials/fake/fake_credentials.h"
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
-#include "src/core/lib/support/tmpfile.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/server.h"
 #include "test/core/end2end/cq_verifier.h"
diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc
index 716fb96..8958b98 100644
--- a/test/cpp/interop/client.cc
+++ b/test/cpp/interop/client.cc
@@ -27,7 +27,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/useful.h>
 
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/cpp/interop/client_helper.h"
 #include "test/cpp/interop/interop_client.h"
 #include "test/cpp/util/test_config.h"
diff --git a/test/cpp/interop/http2_client.cc b/test/cpp/interop/http2_client.cc
index 2de7abc..7a9e3ce 100644
--- a/test/cpp/interop/http2_client.cc
+++ b/test/cpp/interop/http2_client.cc
@@ -30,7 +30,7 @@
 #include "src/proto/grpc/testing/test.grpc.pb.h"
 #include "test/cpp/interop/http2_client.h"
 
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "test/cpp/util/create_test_channel.h"
 #include "test/cpp/util/test_config.h"
 
diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc
index 30bd8bf..7cfdb2f 100644
--- a/test/cpp/interop/interop_server.cc
+++ b/test/cpp/interop/interop_server.cc
@@ -31,7 +31,7 @@
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
 
-#include "src/core/lib/support/string.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/transport/byte_stream.h"
 #include "src/proto/grpc/testing/empty.pb.h"
 #include "src/proto/grpc/testing/messages.pb.h"
diff --git a/test/cpp/interop/interop_test.cc b/test/cpp/interop/interop_test.cc
index 1bf0d8d..563b7ab 100644
--- a/test/cpp/interop/interop_test.cc
+++ b/test/cpp/interop/interop_test.cc
@@ -37,8 +37,8 @@
 #include "test/core/util/port.h"
 #include "test/cpp/util/test_config.h"
 
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/socket_utils_posix.h"
-#include "src/core/lib/support/string.h"
 
 DEFINE_string(extra_server_flags, "", "Extra flags to pass to server.");
 
diff --git a/test/cpp/microbenchmarks/bm_arena.cc b/test/cpp/microbenchmarks/bm_arena.cc
index 5b7c611..69c8c1c 100644
--- a/test/cpp/microbenchmarks/bm_arena.cc
+++ b/test/cpp/microbenchmarks/bm_arena.cc
@@ -18,7 +18,7 @@
 
 /* Benchmark arenas */
 
-#include "src/core/lib/support/arena.h"
+#include "src/core/lib/gpr/arena.h"
 #include "test/cpp/microbenchmarks/helpers.h"
 #include "third_party/benchmark/include/benchmark/benchmark.h"
 
diff --git a/test/cpp/microbenchmarks/bm_closure.cc b/test/cpp/microbenchmarks/bm_closure.cc
index 4d5a82c..6d88fae 100644
--- a/test/cpp/microbenchmarks/bm_closure.cc
+++ b/test/cpp/microbenchmarks/bm_closure.cc
@@ -22,10 +22,10 @@
 #include <grpc/grpc.h>
 #include <sstream>
 
+#include "src/core/lib/gpr/spinlock.h"
 #include "src/core/lib/iomgr/closure.h"
 #include "src/core/lib/iomgr/combiner.h"
 #include "src/core/lib/iomgr/exec_ctx.h"
-#include "src/core/lib/support/spinlock.h"
 
 #include "test/cpp/microbenchmarks/helpers.h"
 
diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc
index 3481d9d..8b5523f 100644
--- a/test/cpp/naming/resolver_component_test.cc
+++ b/test/cpp/naming/resolver_component_test.cc
@@ -37,13 +37,13 @@
 #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
 #include "src/core/ext/filters/client_channel/resolver_registry.h"
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
 #include "src/core/lib/iomgr/combiner.h"
 #include "src/core/lib/iomgr/executor.h"
 #include "src/core/lib/iomgr/iomgr.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 
diff --git a/test/cpp/naming/resolver_component_tests_runner_invoker.cc b/test/cpp/naming/resolver_component_tests_runner_invoker.cc
index 0beb27d..65f1124 100644
--- a/test/cpp/naming/resolver_component_tests_runner_invoker.cc
+++ b/test/cpp/naming/resolver_component_tests_runner_invoker.cc
@@ -32,7 +32,7 @@
 #include "test/cpp/util/subprocess.h"
 #include "test/cpp/util/test_config.h"
 
-#include "src/core/lib/support/env.h"
+#include "src/core/lib/gpr/env.h"
 #include "test/core/util/port.h"
 
 DEFINE_bool(
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index 22d039d..2f765a6 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -31,8 +31,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
+#include "src/core/lib/gpr/env.h"
 #include "src/core/lib/profiling/timers.h"
-#include "src/core/lib/support/env.h"
 #include "src/proto/grpc/testing/services.grpc.pb.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
diff --git a/test/cpp/qps/json_run_localhost.cc b/test/cpp/qps/json_run_localhost.cc
index db8b2a3..948c308 100644
--- a/test/cpp/qps/json_run_localhost.cc
+++ b/test/cpp/qps/json_run_localhost.cc
@@ -26,7 +26,7 @@
 
 #include <grpc/support/log.h>
 
-#include "src/core/lib/support/env.h"
+#include "src/core/lib/gpr/env.h"
 #include "test/core/util/port.h"
 #include "test/cpp/util/subprocess.h"
 
diff --git a/test/distrib/cpp/run_distrib_test_cmake.bat b/test/distrib/cpp/run_distrib_test_cmake.bat
index 047846b..f920768 100644
--- a/test/distrib/cpp/run_distrib_test_cmake.bat
+++ b/test/distrib/cpp/run_distrib_test_cmake.bat
@@ -58,13 +58,13 @@
 cmake --build . --config Release --target install || goto :error
 cd ../..
 
-# Build helloworld example using cmake
+@rem Build helloworld example using cmake
 cd examples/cpp/helloworld
 mkdir cmake
 cd cmake
 mkdir build
 cd build
-cmake -DCMAKE_INSTALL_PREFIX=%INSTALL_DIR% ../.. || goto :error
+cmake -DCMAKE_INSTALL_PREFIX=%INSTALL_DIR% -DOPENSSL_ROOT_DIR=%OPENSSL_DIR% -DOPENSSL_INCLUDE_DIR=%OPENSSL_DIR%/include ../.. || goto :error
 cmake --build . --config Release || goto :error
 cd ../../../../..
 
diff --git a/tools/buildgen/plugins/expand_version.py b/tools/buildgen/plugins/expand_version.py
index 8f56ce8..facf349 100755
--- a/tools/buildgen/plugins/expand_version.py
+++ b/tools/buildgen/plugins/expand_version.py
@@ -84,6 +84,13 @@
                     % self.tag)
         return s
 
+    def php_stability(self):
+        """stability string for PHP PECL package.xml file"""
+        if self.tag:
+            return 'beta'
+        else:
+            return 'stable'
+
     def php_composer(self):
         """Version string for PHP Composer package"""
         return '%d.%d.%d' % (self.major, self.minor, self.patch)
diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py
index c4ed066..1ef36b1 100644
--- a/tools/distrib/python/grpcio_tools/grpc_version.py
+++ b/tools/distrib/python/grpcio_tools/grpc_version.py
@@ -14,4 +14,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!!
 
-VERSION = '1.9.0.dev0'
+VERSION = '1.9.0'
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 5bdbcd7..afd4a62 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -40,7 +40,7 @@
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 1.9.0-dev
+PROJECT_NUMBER         = 1.9.0
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 85bbeed..a01cf14 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -40,7 +40,7 @@
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 1.9.0-dev
+PROJECT_NUMBER         = 1.9.0
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
@@ -950,6 +950,28 @@
 src/core/lib/debug/stats.h \
 src/core/lib/debug/stats_data.h \
 src/core/lib/debug/trace.h \
+src/core/lib/gpr++/abstract.h \
+src/core/lib/gpr++/atomic.h \
+src/core/lib/gpr++/atomic_with_atm.h \
+src/core/lib/gpr++/atomic_with_std.h \
+src/core/lib/gpr++/debug_location.h \
+src/core/lib/gpr++/inlined_vector.h \
+src/core/lib/gpr++/manual_constructor.h \
+src/core/lib/gpr++/memory.h \
+src/core/lib/gpr++/orphanable.h \
+src/core/lib/gpr++/ref_counted.h \
+src/core/lib/gpr++/ref_counted_ptr.h \
+src/core/lib/gpr/arena.h \
+src/core/lib/gpr/env.h \
+src/core/lib/gpr/fork.h \
+src/core/lib/gpr/mpscq.h \
+src/core/lib/gpr/murmur_hash.h \
+src/core/lib/gpr/spinlock.h \
+src/core/lib/gpr/string.h \
+src/core/lib/gpr/string_windows.h \
+src/core/lib/gpr/thd_internal.h \
+src/core/lib/gpr/time_precise.h \
+src/core/lib/gpr/tmpfile.h \
 src/core/lib/http/format_request.h \
 src/core/lib/http/httpcli.h \
 src/core/lib/http/parser.h \
@@ -1026,28 +1048,6 @@
 src/core/lib/slice/slice_hash_table.h \
 src/core/lib/slice/slice_internal.h \
 src/core/lib/slice/slice_string_helpers.h \
-src/core/lib/support/abstract.h \
-src/core/lib/support/arena.h \
-src/core/lib/support/atomic.h \
-src/core/lib/support/atomic_with_atm.h \
-src/core/lib/support/atomic_with_std.h \
-src/core/lib/support/debug_location.h \
-src/core/lib/support/env.h \
-src/core/lib/support/fork.h \
-src/core/lib/support/manual_constructor.h \
-src/core/lib/support/memory.h \
-src/core/lib/support/mpscq.h \
-src/core/lib/support/murmur_hash.h \
-src/core/lib/support/orphanable.h \
-src/core/lib/support/ref_counted.h \
-src/core/lib/support/ref_counted_ptr.h \
-src/core/lib/support/spinlock.h \
-src/core/lib/support/string.h \
-src/core/lib/support/string_windows.h \
-src/core/lib/support/thd_internal.h \
-src/core/lib/support/time_precise.h \
-src/core/lib/support/tmpfile.h \
-src/core/lib/support/vector.h \
 src/core/lib/surface/alarm_internal.h \
 src/core/lib/surface/api_trace.h \
 src/core/lib/surface/call.h \
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index 916d3b1..060d00a 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -40,7 +40,7 @@
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 5.0.0-dev
+PROJECT_NUMBER         = 5.0.0
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 4bf0fc7..ef91f4f 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -40,7 +40,7 @@
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 5.0.0-dev
+PROJECT_NUMBER         = 5.0.0
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
@@ -1064,6 +1064,72 @@
 src/core/lib/debug/stats_data.h \
 src/core/lib/debug/trace.cc \
 src/core/lib/debug/trace.h \
+src/core/lib/gpr++/README.md \
+src/core/lib/gpr++/abstract.h \
+src/core/lib/gpr++/atomic.h \
+src/core/lib/gpr++/atomic_with_atm.h \
+src/core/lib/gpr++/atomic_with_std.h \
+src/core/lib/gpr++/debug_location.h \
+src/core/lib/gpr++/inlined_vector.h \
+src/core/lib/gpr++/manual_constructor.h \
+src/core/lib/gpr++/memory.h \
+src/core/lib/gpr++/orphanable.h \
+src/core/lib/gpr++/ref_counted.h \
+src/core/lib/gpr++/ref_counted_ptr.h \
+src/core/lib/gpr/README.md \
+src/core/lib/gpr/alloc.cc \
+src/core/lib/gpr/arena.cc \
+src/core/lib/gpr/arena.h \
+src/core/lib/gpr/atm.cc \
+src/core/lib/gpr/avl.cc \
+src/core/lib/gpr/cmdline.cc \
+src/core/lib/gpr/cpu_iphone.cc \
+src/core/lib/gpr/cpu_linux.cc \
+src/core/lib/gpr/cpu_posix.cc \
+src/core/lib/gpr/cpu_windows.cc \
+src/core/lib/gpr/env.h \
+src/core/lib/gpr/env_linux.cc \
+src/core/lib/gpr/env_posix.cc \
+src/core/lib/gpr/env_windows.cc \
+src/core/lib/gpr/fork.cc \
+src/core/lib/gpr/fork.h \
+src/core/lib/gpr/host_port.cc \
+src/core/lib/gpr/log.cc \
+src/core/lib/gpr/log_android.cc \
+src/core/lib/gpr/log_linux.cc \
+src/core/lib/gpr/log_posix.cc \
+src/core/lib/gpr/log_windows.cc \
+src/core/lib/gpr/mpscq.cc \
+src/core/lib/gpr/mpscq.h \
+src/core/lib/gpr/murmur_hash.cc \
+src/core/lib/gpr/murmur_hash.h \
+src/core/lib/gpr/spinlock.h \
+src/core/lib/gpr/string.cc \
+src/core/lib/gpr/string.h \
+src/core/lib/gpr/string_posix.cc \
+src/core/lib/gpr/string_util_windows.cc \
+src/core/lib/gpr/string_windows.cc \
+src/core/lib/gpr/string_windows.h \
+src/core/lib/gpr/subprocess_posix.cc \
+src/core/lib/gpr/subprocess_windows.cc \
+src/core/lib/gpr/sync.cc \
+src/core/lib/gpr/sync_posix.cc \
+src/core/lib/gpr/sync_windows.cc \
+src/core/lib/gpr/thd.cc \
+src/core/lib/gpr/thd_internal.h \
+src/core/lib/gpr/thd_posix.cc \
+src/core/lib/gpr/thd_windows.cc \
+src/core/lib/gpr/time.cc \
+src/core/lib/gpr/time_posix.cc \
+src/core/lib/gpr/time_precise.cc \
+src/core/lib/gpr/time_precise.h \
+src/core/lib/gpr/time_windows.cc \
+src/core/lib/gpr/tls_pthread.cc \
+src/core/lib/gpr/tmpfile.h \
+src/core/lib/gpr/tmpfile_msys.cc \
+src/core/lib/gpr/tmpfile_posix.cc \
+src/core/lib/gpr/tmpfile_windows.cc \
+src/core/lib/gpr/wrap_memcpy.cc \
 src/core/lib/http/format_request.cc \
 src/core/lib/http/format_request.h \
 src/core/lib/http/httpcli.cc \
@@ -1271,70 +1337,6 @@
 src/core/lib/slice/slice_internal.h \
 src/core/lib/slice/slice_string_helpers.cc \
 src/core/lib/slice/slice_string_helpers.h \
-src/core/lib/support/abstract.h \
-src/core/lib/support/alloc.cc \
-src/core/lib/support/arena.cc \
-src/core/lib/support/arena.h \
-src/core/lib/support/atm.cc \
-src/core/lib/support/atomic.h \
-src/core/lib/support/atomic_with_atm.h \
-src/core/lib/support/atomic_with_std.h \
-src/core/lib/support/avl.cc \
-src/core/lib/support/cmdline.cc \
-src/core/lib/support/cpu_iphone.cc \
-src/core/lib/support/cpu_linux.cc \
-src/core/lib/support/cpu_posix.cc \
-src/core/lib/support/cpu_windows.cc \
-src/core/lib/support/debug_location.h \
-src/core/lib/support/env.h \
-src/core/lib/support/env_linux.cc \
-src/core/lib/support/env_posix.cc \
-src/core/lib/support/env_windows.cc \
-src/core/lib/support/fork.cc \
-src/core/lib/support/fork.h \
-src/core/lib/support/host_port.cc \
-src/core/lib/support/log.cc \
-src/core/lib/support/log_android.cc \
-src/core/lib/support/log_linux.cc \
-src/core/lib/support/log_posix.cc \
-src/core/lib/support/log_windows.cc \
-src/core/lib/support/manual_constructor.h \
-src/core/lib/support/memory.h \
-src/core/lib/support/mpscq.cc \
-src/core/lib/support/mpscq.h \
-src/core/lib/support/murmur_hash.cc \
-src/core/lib/support/murmur_hash.h \
-src/core/lib/support/orphanable.h \
-src/core/lib/support/ref_counted.h \
-src/core/lib/support/ref_counted_ptr.h \
-src/core/lib/support/spinlock.h \
-src/core/lib/support/string.cc \
-src/core/lib/support/string.h \
-src/core/lib/support/string_posix.cc \
-src/core/lib/support/string_util_windows.cc \
-src/core/lib/support/string_windows.cc \
-src/core/lib/support/string_windows.h \
-src/core/lib/support/subprocess_posix.cc \
-src/core/lib/support/subprocess_windows.cc \
-src/core/lib/support/sync.cc \
-src/core/lib/support/sync_posix.cc \
-src/core/lib/support/sync_windows.cc \
-src/core/lib/support/thd.cc \
-src/core/lib/support/thd_internal.h \
-src/core/lib/support/thd_posix.cc \
-src/core/lib/support/thd_windows.cc \
-src/core/lib/support/time.cc \
-src/core/lib/support/time_posix.cc \
-src/core/lib/support/time_precise.cc \
-src/core/lib/support/time_precise.h \
-src/core/lib/support/time_windows.cc \
-src/core/lib/support/tls_pthread.cc \
-src/core/lib/support/tmpfile.h \
-src/core/lib/support/tmpfile_msys.cc \
-src/core/lib/support/tmpfile_posix.cc \
-src/core/lib/support/tmpfile_windows.cc \
-src/core/lib/support/vector.h \
-src/core/lib/support/wrap_memcpy.cc \
 src/core/lib/surface/README.md \
 src/core/lib/surface/alarm.cc \
 src/core/lib/surface/alarm_internal.h \
diff --git a/tools/internal_ci/linux/grpc_full_performance_master.sh b/tools/internal_ci/linux/grpc_full_performance_master.sh
index 1846839..4eddc18 100755
--- a/tools/internal_ci/linux/grpc_full_performance_master.sh
+++ b/tools/internal_ci/linux/grpc_full_performance_master.sh
@@ -26,7 +26,7 @@
     --category scalable \
     --remote_worker_host grpc-kokoro-performance-server-8core grpc-kokoro-performance-client-8core grpc-kokoro-performance-client2-8core \
     -u kbuilder \
-    --bq_result_table performance_test.kokoro_performance_experiment \
+    --bq_result_table performance_test.performance_experiment \
     --xml_report reports/8core/sponge_log.xml \
     || EXIT_CODE=1
 
@@ -40,7 +40,7 @@
     --category scalable \
     --remote_worker_host grpc-kokoro-performance-server-32core grpc-kokoro-performance-client-32core grpc-kokoro-performance-client2-32core \
     -u kbuilder \
-    --bq_result_table performance_test.kokoro_performance_experiment_32core \
+    --bq_result_table performance_test.performance_experiment_32core \
     --xml_report reports/32core/sponge_log.xml \
     || EXIT_CODE=1
 
@@ -52,7 +52,7 @@
     -l csharp \
     --category scalable \
     --remote_worker_host grpc-kokoro-performance-windows1 grpc-kokoro-performance-windows2 \
-    --bq_result_table performance_test.kokoro_performance_experiment_windows \
+    --bq_result_table performance_test.performance_experiment_windows \
     --xml_report reports/windows/sponge_log.xml \
     || EXIT_CODE=1
 
diff --git a/tools/internal_ci/linux/grpc_full_performance_release.cfg b/tools/internal_ci/linux/grpc_full_performance_release.cfg
new file mode 100644
index 0000000..e9a4bcd
--- /dev/null
+++ b/tools/internal_ci/linux/grpc_full_performance_release.cfg
@@ -0,0 +1,25 @@
+# Copyright 2017 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Config file for the internal CI (in protobuf text format)
+
+# Location of the continuous shell script in repository.
+build_file: "grpc/tools/internal_ci/linux/grpc_full_performance_release.sh"
+timeout_mins: 600
+action {
+  define_artifacts {
+    regex: "**/*sponge_log.xml"
+    regex: "**/perf_reports/**"
+  }
+}
diff --git a/tools/internal_ci/linux/grpc_full_performance_release.sh b/tools/internal_ci/linux/grpc_full_performance_release.sh
new file mode 100755
index 0000000..a31cea2
--- /dev/null
+++ b/tools/internal_ci/linux/grpc_full_performance_release.sh
@@ -0,0 +1,59 @@
+#!/usr/bin/env bash
+# Copyright 2017 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+set -ex
+
+# Enter the gRPC repo root
+cd $(dirname $0)/../../..
+
+source tools/internal_ci/helper_scripts/prepare_build_linux_perf_multilang_rc
+
+# run 8core client vs 8core server
+tools/run_tests/run_performance_tests.py \
+    -l c++ csharp ruby java python go php7 php7_protobuf_c \
+    --netperf \
+    --category scalable \
+    --remote_worker_host grpc-kokoro-performance-server-8core grpc-kokoro-performance-client-8core grpc-kokoro-performance-client2-8core \
+    -u kbuilder \
+    --bq_result_table performance_released.performance_experiment \
+    --xml_report reports/8core/sponge_log.xml \
+    || EXIT_CODE=1
+
+# prevent pushing leftover build files to remote hosts in the next step.
+git clean -fdxq -e reports
+
+# scalability with 32cores (and upload to a different BQ table)
+tools/run_tests/run_performance_tests.py \
+    -l c++ java csharp go \
+    --netperf \
+    --category scalable \
+    --remote_worker_host grpc-kokoro-performance-server-32core grpc-kokoro-performance-client-32core grpc-kokoro-performance-client2-32core \
+    -u kbuilder \
+    --bq_result_table performance_released.performance_experiment_32core \
+    --xml_report reports/32core/sponge_log.xml \
+    || EXIT_CODE=1
+
+# prevent pushing leftover build files to remote hosts in the next step.
+git clean -fdxq -e reports
+
+# selected scenarios on Windows
+tools/run_tests/run_performance_tests.py \
+    -l csharp \
+    --category scalable \
+    --remote_worker_host grpc-kokoro-performance-windows1 grpc-kokoro-performance-windows2 \
+    --bq_result_table performance_released.performance_experiment_windows \
+    --xml_report reports/windows/sponge_log.xml \
+    || EXIT_CODE=1
+
+exit $EXIT_CODE
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index df45489..dc95ddf 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -45,7 +45,7 @@
     "language": "c", 
     "name": "alloc_test", 
     "src": [
-      "test/core/support/alloc_test.cc"
+      "test/core/gpr/alloc_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -94,7 +94,7 @@
     "language": "c", 
     "name": "arena_test", 
     "src": [
-      "test/core/support/arena_test.cc"
+      "test/core/gpr/arena_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -597,7 +597,7 @@
     "language": "c", 
     "name": "gpr_avl_test", 
     "src": [
-      "test/core/support/avl_test.cc"
+      "test/core/gpr/avl_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -612,7 +612,7 @@
     "language": "c", 
     "name": "gpr_cmdline_test", 
     "src": [
-      "test/core/support/cmdline_test.cc"
+      "test/core/gpr/cmdline_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -627,7 +627,7 @@
     "language": "c", 
     "name": "gpr_cpu_test", 
     "src": [
-      "test/core/support/cpu_test.cc"
+      "test/core/gpr/cpu_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -642,7 +642,7 @@
     "language": "c", 
     "name": "gpr_env_test", 
     "src": [
-      "test/core/support/env_test.cc"
+      "test/core/gpr/env_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -657,7 +657,7 @@
     "language": "c", 
     "name": "gpr_host_port_test", 
     "src": [
-      "test/core/support/host_port_test.cc"
+      "test/core/gpr/host_port_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -672,7 +672,7 @@
     "language": "c", 
     "name": "gpr_log_test", 
     "src": [
-      "test/core/support/log_test.cc"
+      "test/core/gpr/log_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -687,7 +687,7 @@
     "language": "c", 
     "name": "gpr_manual_constructor_test", 
     "src": [
-      "test/core/support/manual_constructor_test.cc"
+      "test/core/gpr++/manual_constructor_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -702,7 +702,7 @@
     "language": "c", 
     "name": "gpr_mpscq_test", 
     "src": [
-      "test/core/support/mpscq_test.cc"
+      "test/core/gpr/mpscq_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -717,7 +717,7 @@
     "language": "c", 
     "name": "gpr_spinlock_test", 
     "src": [
-      "test/core/support/spinlock_test.cc"
+      "test/core/gpr/spinlock_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -732,7 +732,7 @@
     "language": "c", 
     "name": "gpr_string_test", 
     "src": [
-      "test/core/support/string_test.cc"
+      "test/core/gpr/string_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -747,7 +747,7 @@
     "language": "c", 
     "name": "gpr_sync_test", 
     "src": [
-      "test/core/support/sync_test.cc"
+      "test/core/gpr/sync_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -762,7 +762,7 @@
     "language": "c", 
     "name": "gpr_thd_test", 
     "src": [
-      "test/core/support/thd_test.cc"
+      "test/core/gpr/thd_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -777,7 +777,7 @@
     "language": "c", 
     "name": "gpr_time_test", 
     "src": [
-      "test/core/support/time_test.cc"
+      "test/core/gpr/time_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -792,7 +792,7 @@
     "language": "c", 
     "name": "gpr_tls_test", 
     "src": [
-      "test/core/support/tls_test.cc"
+      "test/core/gpr/tls_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -807,7 +807,7 @@
     "language": "c", 
     "name": "gpr_useful_test", 
     "src": [
-      "test/core/support/useful_test.cc"
+      "test/core/gpr/useful_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -1636,7 +1636,7 @@
     "language": "c", 
     "name": "murmur_hash_test", 
     "src": [
-      "test/core/support/murmur_hash_test.cc"
+      "test/core/gpr/murmur_hash_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -3534,6 +3534,25 @@
       "gpr_test_util", 
       "grpc", 
       "grpc++", 
+      "grpc++_test", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c++", 
+    "name": "inlined_vector_test", 
+    "src": [
+      "test/core/gpr++/inlined_vector_test.cc"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc++", 
       "grpc++_core_stats", 
       "grpc++_test_config", 
       "grpc++_test_util", 
@@ -3643,7 +3662,7 @@
     "language": "c++", 
     "name": "memory_test", 
     "src": [
-      "test/core/support/memory_test.cc"
+      "test/core/gpr++/memory_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -3721,7 +3740,7 @@
     "language": "c++", 
     "name": "orphanable_test", 
     "src": [
-      "test/core/support/orphanable_test.cc"
+      "test/core/gpr++/orphanable_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -3932,7 +3951,7 @@
     "language": "c++", 
     "name": "ref_counted_ptr_test", 
     "src": [
-      "test/core/support/ref_counted_ptr_test.cc"
+      "test/core/gpr++/ref_counted_ptr_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -3951,7 +3970,7 @@
     "language": "c++", 
     "name": "ref_counted_test", 
     "src": [
-      "test/core/support/ref_counted_test.cc"
+      "test/core/gpr++/ref_counted_test.cc"
     ], 
     "third_party": false, 
     "type": "target"
@@ -4306,25 +4325,6 @@
       "gpr_test_util", 
       "grpc", 
       "grpc++", 
-      "grpc++_test", 
-      "grpc_test_util"
-    ], 
-    "headers": [], 
-    "is_filegroup": false, 
-    "language": "c++", 
-    "name": "vector_test", 
-    "src": [
-      "test/core/support/vector_test.cc"
-    ], 
-    "third_party": false, 
-    "type": "target"
-  }, 
-  {
-    "deps": [
-      "gpr", 
-      "gpr_test_util", 
-      "grpc", 
-      "grpc++", 
       "grpc++_test_util", 
       "grpc_test_util"
     ], 
@@ -4971,6 +4971,24 @@
     "headers": [], 
     "is_filegroup": false, 
     "language": "c", 
+    "name": "duplicate_header_bad_client_test", 
+    "src": [
+      "test/core/bad_client/tests/duplicate_header.cc"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "bad_client_test", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc_test_util_unsecure", 
+      "grpc_unsecure"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c", 
     "name": "head_of_line_blocking_bad_client_test", 
     "src": [
       "test/core/bad_client/tests/head_of_line_blocking.cc"
@@ -7827,50 +7845,50 @@
     "language": "c", 
     "name": "gpr_base", 
     "src": [
+      "src/core/lib/gpr/alloc.cc", 
+      "src/core/lib/gpr/arena.cc", 
+      "src/core/lib/gpr/atm.cc", 
+      "src/core/lib/gpr/avl.cc", 
+      "src/core/lib/gpr/cmdline.cc", 
+      "src/core/lib/gpr/cpu_iphone.cc", 
+      "src/core/lib/gpr/cpu_linux.cc", 
+      "src/core/lib/gpr/cpu_posix.cc", 
+      "src/core/lib/gpr/cpu_windows.cc", 
+      "src/core/lib/gpr/env_linux.cc", 
+      "src/core/lib/gpr/env_posix.cc", 
+      "src/core/lib/gpr/env_windows.cc", 
+      "src/core/lib/gpr/fork.cc", 
+      "src/core/lib/gpr/host_port.cc", 
+      "src/core/lib/gpr/log.cc", 
+      "src/core/lib/gpr/log_android.cc", 
+      "src/core/lib/gpr/log_linux.cc", 
+      "src/core/lib/gpr/log_posix.cc", 
+      "src/core/lib/gpr/log_windows.cc", 
+      "src/core/lib/gpr/mpscq.cc", 
+      "src/core/lib/gpr/murmur_hash.cc", 
+      "src/core/lib/gpr/string.cc", 
+      "src/core/lib/gpr/string_posix.cc", 
+      "src/core/lib/gpr/string_util_windows.cc", 
+      "src/core/lib/gpr/string_windows.cc", 
+      "src/core/lib/gpr/subprocess_posix.cc", 
+      "src/core/lib/gpr/subprocess_windows.cc", 
+      "src/core/lib/gpr/sync.cc", 
+      "src/core/lib/gpr/sync_posix.cc", 
+      "src/core/lib/gpr/sync_windows.cc", 
+      "src/core/lib/gpr/thd.cc", 
+      "src/core/lib/gpr/thd_posix.cc", 
+      "src/core/lib/gpr/thd_windows.cc", 
+      "src/core/lib/gpr/time.cc", 
+      "src/core/lib/gpr/time_posix.cc", 
+      "src/core/lib/gpr/time_precise.cc", 
+      "src/core/lib/gpr/time_windows.cc", 
+      "src/core/lib/gpr/tls_pthread.cc", 
+      "src/core/lib/gpr/tmpfile_msys.cc", 
+      "src/core/lib/gpr/tmpfile_posix.cc", 
+      "src/core/lib/gpr/tmpfile_windows.cc", 
+      "src/core/lib/gpr/wrap_memcpy.cc", 
       "src/core/lib/profiling/basic_timers.cc", 
-      "src/core/lib/profiling/stap_timers.cc", 
-      "src/core/lib/support/alloc.cc", 
-      "src/core/lib/support/arena.cc", 
-      "src/core/lib/support/atm.cc", 
-      "src/core/lib/support/avl.cc", 
-      "src/core/lib/support/cmdline.cc", 
-      "src/core/lib/support/cpu_iphone.cc", 
-      "src/core/lib/support/cpu_linux.cc", 
-      "src/core/lib/support/cpu_posix.cc", 
-      "src/core/lib/support/cpu_windows.cc", 
-      "src/core/lib/support/env_linux.cc", 
-      "src/core/lib/support/env_posix.cc", 
-      "src/core/lib/support/env_windows.cc", 
-      "src/core/lib/support/fork.cc", 
-      "src/core/lib/support/host_port.cc", 
-      "src/core/lib/support/log.cc", 
-      "src/core/lib/support/log_android.cc", 
-      "src/core/lib/support/log_linux.cc", 
-      "src/core/lib/support/log_posix.cc", 
-      "src/core/lib/support/log_windows.cc", 
-      "src/core/lib/support/mpscq.cc", 
-      "src/core/lib/support/murmur_hash.cc", 
-      "src/core/lib/support/string.cc", 
-      "src/core/lib/support/string_posix.cc", 
-      "src/core/lib/support/string_util_windows.cc", 
-      "src/core/lib/support/string_windows.cc", 
-      "src/core/lib/support/subprocess_posix.cc", 
-      "src/core/lib/support/subprocess_windows.cc", 
-      "src/core/lib/support/sync.cc", 
-      "src/core/lib/support/sync_posix.cc", 
-      "src/core/lib/support/sync_windows.cc", 
-      "src/core/lib/support/thd.cc", 
-      "src/core/lib/support/thd_posix.cc", 
-      "src/core/lib/support/thd_windows.cc", 
-      "src/core/lib/support/time.cc", 
-      "src/core/lib/support/time_posix.cc", 
-      "src/core/lib/support/time_precise.cc", 
-      "src/core/lib/support/time_windows.cc", 
-      "src/core/lib/support/tls_pthread.cc", 
-      "src/core/lib/support/tmpfile_msys.cc", 
-      "src/core/lib/support/tmpfile_posix.cc", 
-      "src/core/lib/support/tmpfile_windows.cc", 
-      "src/core/lib/support/wrap_memcpy.cc"
+      "src/core/lib/profiling/stap_timers.cc"
     ], 
     "third_party": false, 
     "type": "filegroup"
@@ -7906,24 +7924,24 @@
       "include/grpc/support/tls_msvc.h", 
       "include/grpc/support/tls_pthread.h", 
       "include/grpc/support/useful.h", 
-      "src/core/lib/profiling/timers.h", 
-      "src/core/lib/support/abstract.h", 
-      "src/core/lib/support/arena.h", 
-      "src/core/lib/support/atomic.h", 
-      "src/core/lib/support/atomic_with_atm.h", 
-      "src/core/lib/support/atomic_with_std.h", 
-      "src/core/lib/support/env.h", 
-      "src/core/lib/support/fork.h", 
-      "src/core/lib/support/manual_constructor.h", 
-      "src/core/lib/support/memory.h", 
-      "src/core/lib/support/mpscq.h", 
-      "src/core/lib/support/murmur_hash.h", 
-      "src/core/lib/support/spinlock.h", 
-      "src/core/lib/support/string.h", 
-      "src/core/lib/support/string_windows.h", 
-      "src/core/lib/support/thd_internal.h", 
-      "src/core/lib/support/time_precise.h", 
-      "src/core/lib/support/tmpfile.h"
+      "src/core/lib/gpr++/abstract.h", 
+      "src/core/lib/gpr++/atomic.h", 
+      "src/core/lib/gpr++/atomic_with_atm.h", 
+      "src/core/lib/gpr++/atomic_with_std.h", 
+      "src/core/lib/gpr++/manual_constructor.h", 
+      "src/core/lib/gpr++/memory.h", 
+      "src/core/lib/gpr/arena.h", 
+      "src/core/lib/gpr/env.h", 
+      "src/core/lib/gpr/fork.h", 
+      "src/core/lib/gpr/mpscq.h", 
+      "src/core/lib/gpr/murmur_hash.h", 
+      "src/core/lib/gpr/spinlock.h", 
+      "src/core/lib/gpr/string.h", 
+      "src/core/lib/gpr/string_windows.h", 
+      "src/core/lib/gpr/thd_internal.h", 
+      "src/core/lib/gpr/time_precise.h", 
+      "src/core/lib/gpr/tmpfile.h", 
+      "src/core/lib/profiling/timers.h"
     ], 
     "is_filegroup": true, 
     "language": "c", 
@@ -7955,24 +7973,24 @@
       "include/grpc/support/tls_msvc.h", 
       "include/grpc/support/tls_pthread.h", 
       "include/grpc/support/useful.h", 
-      "src/core/lib/profiling/timers.h", 
-      "src/core/lib/support/abstract.h", 
-      "src/core/lib/support/arena.h", 
-      "src/core/lib/support/atomic.h", 
-      "src/core/lib/support/atomic_with_atm.h", 
-      "src/core/lib/support/atomic_with_std.h", 
-      "src/core/lib/support/env.h", 
-      "src/core/lib/support/fork.h", 
-      "src/core/lib/support/manual_constructor.h", 
-      "src/core/lib/support/memory.h", 
-      "src/core/lib/support/mpscq.h", 
-      "src/core/lib/support/murmur_hash.h", 
-      "src/core/lib/support/spinlock.h", 
-      "src/core/lib/support/string.h", 
-      "src/core/lib/support/string_windows.h", 
-      "src/core/lib/support/thd_internal.h", 
-      "src/core/lib/support/time_precise.h", 
-      "src/core/lib/support/tmpfile.h"
+      "src/core/lib/gpr++/abstract.h", 
+      "src/core/lib/gpr++/atomic.h", 
+      "src/core/lib/gpr++/atomic_with_atm.h", 
+      "src/core/lib/gpr++/atomic_with_std.h", 
+      "src/core/lib/gpr++/manual_constructor.h", 
+      "src/core/lib/gpr++/memory.h", 
+      "src/core/lib/gpr/arena.h", 
+      "src/core/lib/gpr/env.h", 
+      "src/core/lib/gpr/fork.h", 
+      "src/core/lib/gpr/mpscq.h", 
+      "src/core/lib/gpr/murmur_hash.h", 
+      "src/core/lib/gpr/spinlock.h", 
+      "src/core/lib/gpr/string.h", 
+      "src/core/lib/gpr/string_windows.h", 
+      "src/core/lib/gpr/thd_internal.h", 
+      "src/core/lib/gpr/time_precise.h", 
+      "src/core/lib/gpr/tmpfile.h", 
+      "src/core/lib/profiling/timers.h"
     ], 
     "third_party": false, 
     "type": "filegroup"
@@ -8229,6 +8247,11 @@
       "src/core/lib/compression/stream_compression_identity.h", 
       "src/core/lib/debug/stats.h", 
       "src/core/lib/debug/stats_data.h", 
+      "src/core/lib/gpr++/debug_location.h", 
+      "src/core/lib/gpr++/inlined_vector.h", 
+      "src/core/lib/gpr++/orphanable.h", 
+      "src/core/lib/gpr++/ref_counted.h", 
+      "src/core/lib/gpr++/ref_counted_ptr.h", 
       "src/core/lib/http/format_request.h", 
       "src/core/lib/http/httpcli.h", 
       "src/core/lib/http/parser.h", 
@@ -8304,11 +8327,6 @@
       "src/core/lib/slice/slice_hash_table.h", 
       "src/core/lib/slice/slice_internal.h", 
       "src/core/lib/slice/slice_string_helpers.h", 
-      "src/core/lib/support/debug_location.h", 
-      "src/core/lib/support/orphanable.h", 
-      "src/core/lib/support/ref_counted.h", 
-      "src/core/lib/support/ref_counted_ptr.h", 
-      "src/core/lib/support/vector.h", 
       "src/core/lib/surface/alarm_internal.h", 
       "src/core/lib/surface/api_trace.h", 
       "src/core/lib/surface/call.h", 
@@ -8370,6 +8388,11 @@
       "src/core/lib/compression/stream_compression_identity.h", 
       "src/core/lib/debug/stats.h", 
       "src/core/lib/debug/stats_data.h", 
+      "src/core/lib/gpr++/debug_location.h", 
+      "src/core/lib/gpr++/inlined_vector.h", 
+      "src/core/lib/gpr++/orphanable.h", 
+      "src/core/lib/gpr++/ref_counted.h", 
+      "src/core/lib/gpr++/ref_counted_ptr.h", 
       "src/core/lib/http/format_request.h", 
       "src/core/lib/http/httpcli.h", 
       "src/core/lib/http/parser.h", 
@@ -8445,11 +8468,6 @@
       "src/core/lib/slice/slice_hash_table.h", 
       "src/core/lib/slice/slice_internal.h", 
       "src/core/lib/slice/slice_string_helpers.h", 
-      "src/core/lib/support/debug_location.h", 
-      "src/core/lib/support/orphanable.h", 
-      "src/core/lib/support/ref_counted.h", 
-      "src/core/lib/support/ref_counted_ptr.h", 
-      "src/core/lib/support/vector.h", 
       "src/core/lib/surface/alarm_internal.h", 
       "src/core/lib/surface/api_trace.h", 
       "src/core/lib/surface/call.h", 
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index dc2b39e..05a3a20 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -3967,6 +3967,30 @@
     "ci_platforms": [
       "linux", 
       "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
+    "name": "inlined_vector_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "uses_polling": true
+  }, 
+  {
+    "args": [], 
+    "benchmark": false, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -4558,30 +4582,6 @@
     "ci_platforms": [
       "linux", 
       "mac", 
-      "posix", 
-      "windows"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": false, 
-    "gtest": true, 
-    "language": "c++", 
-    "name": "vector_test", 
-    "platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ], 
-    "uses_polling": true
-  }, 
-  {
-    "args": [], 
-    "benchmark": false, 
-    "ci_platforms": [
-      "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.5, 
@@ -4691,6 +4691,32 @@
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
+    "name": "duplicate_header_bad_client_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "uses_polling": true
+  }, 
+  {
+    "args": [], 
+    "benchmark": false, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "gtest": false, 
+    "language": "c", 
     "name": "head_of_line_blocking_bad_client_test", 
     "platforms": [
       "linux", 
diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py
index 9ee2896..9899905 100755
--- a/tools/run_tests/sanity/core_banned_functions.py
+++ b/tools/run_tests/sanity/core_banned_functions.py
@@ -42,8 +42,8 @@
     'grpc_closure_run(': ['src/core/lib/iomgr/closure.c'],
     'grpc_closure_list_sched(': ['src/core/lib/iomgr/closure.c'],
     'gpr_getenv_silent(': [
-        'src/core/lib/support/log.c', 'src/core/lib/support/env_linux.c',
-        'src/core/lib/support/env_posix.c', 'src/core/lib/support/env_windows.c'
+        'src/core/lib/gpr/log.c', 'src/core/lib/gpr/env_linux.c',
+        'src/core/lib/gpr/env_posix.c', 'src/core/lib/gpr/env_windows.c'
     ],
 }