Merge github.com:grpc/grpc into sceq
diff --git a/Makefile b/Makefile
index 506ba85..8b7e44d 100644
--- a/Makefile
+++ b/Makefile
@@ -122,8 +122,7 @@
 CXX_asan-noleaks = clang++
 LD_asan-noleaks = clang
 LDXX_asan-noleaks = clang++
-CFLAGS_asan-noleaks = -O0 -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument
-CXXFLAGS_asan-noleaks = -O0 -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument
+CPPFLAGS_asan-noleaks = -O0 -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument
 LDFLAGS_asan-noleaks = -fsanitize=address
 DEFINES_asan-noleaks += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=1.5
 
@@ -133,8 +132,7 @@
 CXX_ubsan = clang++
 LD_ubsan = clang
 LDXX_ubsan = clang++
-CFLAGS_ubsan = -O1 -fsanitize=undefined -fno-omit-frame-pointer -Wno-unused-command-line-argument
-CXXFLAGS_ubsan = -O1 -fsanitize=undefined -fno-omit-frame-pointer -Wno-unused-command-line-argument
+CPPFLAGS_ubsan = -O1 -fsanitize=undefined -fno-omit-frame-pointer -Wno-unused-command-line-argument
 LDFLAGS_ubsan = -fsanitize=undefined
 DEFINES_ubsan = NDEBUG
 DEFINES_ubsan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=1.5
@@ -161,8 +159,7 @@
 CXX_gcov = g++
 LD_gcov = gcc
 LDXX_gcov = g++
-CFLAGS_gcov = -O0 -fprofile-arcs -ftest-coverage -Wno-return-type
-CXXFLAGS_gcov = -O0 -fprofile-arcs -ftest-coverage -Wno-return-type
+CPPFLAGS_gcov = -O0 -fprofile-arcs -ftest-coverage -Wno-return-type
 LDFLAGS_gcov = -fprofile-arcs -ftest-coverage -rdynamic
 DEFINES_gcov = _DEBUG DEBUG GPR_GCOV
 
@@ -182,8 +179,7 @@
 CXX_asan = clang++
 LD_asan = clang
 LDXX_asan = clang++
-CFLAGS_asan = -O0 -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument
-CXXFLAGS_asan = -O0 -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument
+CPPFLAGS_asan = -O0 -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument
 LDFLAGS_asan = -fsanitize=address
 DEFINES_asan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=1.5
 
@@ -193,8 +189,7 @@
 CXX_tsan = clang++
 LD_tsan = clang
 LDXX_tsan = clang++
-CFLAGS_tsan = -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument -fPIE -pie
-CXXFLAGS_tsan = -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument -fPIE -pie
+CPPFLAGS_tsan = -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument -fPIE -pie
 LDFLAGS_tsan = -fsanitize=thread -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,)
 DEFINES_tsan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=2
 
@@ -204,11 +199,10 @@
 CXX_msan = clang++
 LD_msan = clang
 LDXX_msan = clang++
-CFLAGS_msan = -O0 -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -Wno-unused-command-line-argument -fPIE -pie
-CXXFLAGS_msan = -O0 -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -Wno-unused-command-line-argument -fPIE -pie
+CPPFLAGS_msan = -O0 -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -Wno-unused-command-line-argument -fPIE -pie
 LDFLAGS_msan = -fsanitize=memory -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,)
 DEFINES_msan = NDEBUG
-DEFINES_msan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=1.5
+DEFINES_msan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=2
 
 VALID_CONFIG_mutrace = 1
 CC_mutrace = $(DEFAULT_CC)
@@ -226,26 +220,44 @@
 
 prefix ?= /usr/local
 
-PROTOC = protoc
-DTRACE = dtrace
+PROTOC ?= protoc
+DTRACE ?= dtrace
 CONFIG ?= opt
+# Doing X ?= Y is the same as:
+# ifeq ($(origin X), undefined)
+#  X = Y
+# endif
+# but some variables, such as CC, CXX, LD or AR, have defaults.
+# So instead of using ?= on them, we need to check their origin.
+# See:
+#  https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html
+#  https://www.gnu.org/software/make/manual/html_node/Flavors.html#index-_003f_003d
+#  https://www.gnu.org/software/make/manual/html_node/Origin-Function.html
+ifeq ($(origin CC), default)
 CC = $(CC_$(CONFIG))
+endif
+ifeq ($(origin CXX), default)
 CXX = $(CXX_$(CONFIG))
+endif
+ifeq ($(origin LD), default)
 LD = $(LD_$(CONFIG))
-LDXX = $(LDXX_$(CONFIG))
+endif
+LDXX ?= $(LDXX_$(CONFIG))
+ifeq ($(origin AR), default)
 AR = ar
+endif
 ifeq ($(SYSTEM),Linux)
-STRIP = strip --strip-unneeded
+STRIP ?= strip --strip-unneeded
 else
 ifeq ($(SYSTEM),Darwin)
-STRIP = strip -x
+STRIP ?= strip -x
 else
-STRIP = strip
+STRIP ?= strip
 endif
 endif
-INSTALL = install
-RM = rm -f
-PKG_CONFIG = pkg-config
+INSTALL ?= install
+RM ?= rm -f
+PKG_CONFIG ?= pkg-config
 
 ifndef VALID_CONFIG_$(CONFIG)
 $(error Invalid CONFIG value '$(CONFIG)')
@@ -272,10 +284,10 @@
 # cross-compiling, you can override these variables from GNU make's
 # command line: make CC=cross-gcc HOST_CC=gcc
 
-HOST_CC = $(CC)
-HOST_CXX = $(CXX)
-HOST_LD = $(LD)
-HOST_LDXX = $(LDXX)
+HOST_CC ?= $(CC)
+HOST_CXX ?= $(CXX)
+HOST_LD ?= $(LD)
+HOST_LDXX ?= $(LDXX)
 
 ifdef EXTRA_DEFINES
 DEFINES += $(EXTRA_DEFINES)
@@ -287,8 +299,7 @@
 else
 CXXFLAGS += -std=c++0x
 endif
-CFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter
-CXXFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter
+CPPFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter
 LDFLAGS += -g
 
 CPPFLAGS += $(CPPFLAGS_$(CONFIG))
@@ -348,7 +359,7 @@
 Q = @
 endif
 
-VERSION = 0.12.0.0
+VERSION = 0.13.0.0
 
 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
 CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@@ -406,14 +417,6 @@
 IS_GIT_FOLDER = true
 endif
 
-ifeq ($(SYSTEM),Linux)
-OPENSSL_REQUIRES_DL = true
-endif
-
-ifeq ($(SYSTEM),Darwin)
-OPENSSL_REQUIRES_DL = true
-endif
-
 ifeq ($(HAS_PKG_CONFIG),true)
 OPENSSL_ALPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.2 openssl
 OPENSSL_NPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.1 openssl
@@ -427,25 +430,20 @@
 OPENSSL_LIBS = ssl crypto
 endif
 
-OPENSSL_ALPN_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/openssl-alpn.c $(addprefix -l, $(OPENSSL_LIBS)) $(LDFLAGS)
-OPENSSL_NPN_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/openssl-npn.c $(addprefix -l, $(OPENSSL_LIBS)) $(LDFLAGS)
-ZLIB_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/zlib.c -lz $(LDFLAGS)
-PROTOBUF_CHECK_CMD = $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/protobuf.cc -lprotobuf $(LDFLAGS)
-
-ifeq ($(OPENSSL_REQUIRES_DL),true)
-OPENSSL_ALPN_CHECK_CMD += -ldl
-OPENSSL_NPN_CHECK_CMD += -ldl
-endif
+OPENSSL_ALPN_CHECK_CMD = $(CC) $(CPPFLAGS) $(CFLAGS) -o $(TMPOUT) test/build/openssl-alpn.c $(addprefix -l, $(OPENSSL_LIBS)) $(LDFLAGS)
+OPENSSL_NPN_CHECK_CMD = $(CC) $(CPPFLAGS) $(CFLAGS) -o $(TMPOUT) test/build/openssl-npn.c $(addprefix -l, $(OPENSSL_LIBS)) $(LDFLAGS)
+ZLIB_CHECK_CMD = $(CC) $(CPPFLAGS) $(CFLAGS) -o $(TMPOUT) test/build/zlib.c -lz $(LDFLAGS)
+PROTOBUF_CHECK_CMD = $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $(TMPOUT) test/build/protobuf.cc -lprotobuf $(LDFLAGS)
 
 endif # HAS_PKG_CONFIG
 
-PERFTOOLS_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/perftools.c -lprofiler $(LDFLAGS)
+PERFTOOLS_CHECK_CMD = $(CC) $(CPPFLAGS) $(CFLAGS) -o $(TMPOUT) test/build/perftools.c -lprofiler $(LDFLAGS)
 
 PROTOC_CHECK_CMD = which protoc > /dev/null
 PROTOC_CHECK_VERSION_CMD = protoc --version | grep -q libprotoc.3
 DTRACE_CHECK_CMD = which dtrace > /dev/null
-SYSTEMTAP_HEADERS_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/systemtap.c $(LDFLAGS)
-ZOOKEEPER_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/zookeeper.c $(LDFLAGS) -lzookeeper_mt
+SYSTEMTAP_HEADERS_CHECK_CMD = $(CC) $(CPPFLAGS) $(CFLAGS) -o $(TMPOUT) test/build/systemtap.c $(LDFLAGS)
+ZOOKEEPER_CHECK_CMD = $(CC) $(CPPFLAGS) $(CFLAGS) -o $(TMPOUT) test/build/zookeeper.c $(LDFLAGS) -lzookeeper_mt
 
 ifndef REQUIRE_CUSTOM_LIBRARIES_$(CONFIG)
 HAS_SYSTEM_PERFTOOLS ?= $(shell $(PERFTOOLS_CHECK_CMD) 2> /dev/null && echo true || echo false)
@@ -600,9 +598,6 @@
 OPENSSL_MERGE_LIBS += $(LIBDIR)/$(CONFIG)/libboringssl.a
 # need to prefix these to ensure overriding system libraries
 CPPFLAGS := -Ithird_party/boringssl/include $(CPPFLAGS)
-ifeq ($(OPENSSL_REQUIRES_DL),true)
-LIBS_SECURE = dl
-endif # OPENSSL_REQUIRES_DL
 else # EMBED_OPENSSL=false
 ifeq ($(HAS_PKG_CONFIG),true)
 OPENSSL_PKG_CONFIG = true
@@ -622,10 +617,7 @@
 CPPFLAGS += -DTSI_OPENSSL_ALPN_SUPPORT=0
 LIBS_SECURE = $(OPENSSL_LIBS)
 endif # HAS_SYSTEM_OPENSSL_NPN
-ifeq ($(OPENSSL_REQUIRES_DL),true)
-LIBS_SECURE += dl
 PC_LIBS_SECURE = $(addprefix -l, $(LIBS_SECURE))
-endif # OPENSSL_REQUIRES_DL=true
 endif # EMBED_OPENSSL
 endif # NO_SECURE
 
@@ -1943,12 +1935,12 @@
 $(OBJDIR)/$(CONFIG)/%.o : %.c
 	$(E) "[C]       Compiling $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
+	$(Q) $(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
 
 $(OBJDIR)/$(CONFIG)/%.o : $(GENDIR)/%.pb.cc
 	$(E) "[CXX]     Compiling $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
+	$(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
 
 $(OBJDIR)/$(CONFIG)/src/compiler/%.o : src/compiler/%.cc
 	$(E) "[HOSTCXX] Compiling $<"
@@ -1958,7 +1950,7 @@
 $(OBJDIR)/$(CONFIG)/%.o : %.cc
 	$(E) "[CXX]     Compiling $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
+	$(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
 
 install: install_c install_cxx install-plugins install-certs verify-install
 
@@ -2280,7 +2272,7 @@
 LIBGPR_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGPR_SRC))))
 
 
-$(LIBDIR)/$(CONFIG)/libgpr.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(LIBGPR_OBJS)
+$(LIBDIR)/$(CONFIG)/libgpr.a: $(ZLIB_DEP)  $(LIBGPR_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgpr.a
@@ -2321,7 +2313,7 @@
 LIBGPR_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGPR_TEST_UTIL_SRC))))
 
 
-$(LIBDIR)/$(CONFIG)/libgpr_test_util.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(LIBGPR_TEST_UTIL_OBJS)
+$(LIBDIR)/$(CONFIG)/libgpr_test_util.a: $(ZLIB_DEP)  $(LIBGPR_TEST_UTIL_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgpr_test_util.a
@@ -2646,7 +2638,7 @@
 LIBGRPC_TEST_UTIL_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_TEST_UTIL_UNSECURE_SRC))))
 
 
-$(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(LIBGRPC_TEST_UTIL_UNSECURE_OBJS)
+$(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a: $(ZLIB_DEP)  $(LIBGRPC_TEST_UTIL_UNSECURE_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a
@@ -2809,7 +2801,7 @@
 LIBGRPC_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_UNSECURE_SRC))))
 
 
-$(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(LIBGRPC_UNSECURE_OBJS)
+$(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a: $(ZLIB_DEP)  $(LIBGRPC_UNSECURE_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
@@ -2867,7 +2859,7 @@
 LIBGRPC_ZOOKEEPER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_ZOOKEEPER_SRC))))
 
 
-$(LIBDIR)/$(CONFIG)/libgrpc_zookeeper.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(LIBGRPC_ZOOKEEPER_OBJS)
+$(LIBDIR)/$(CONFIG)/libgrpc_zookeeper.a: $(ZLIB_DEP)  $(LIBGRPC_ZOOKEEPER_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_zookeeper.a
@@ -3337,7 +3329,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBGRPC++_UNSECURE_OBJS)
+$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBGRPC++_UNSECURE_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
@@ -3408,7 +3400,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBGRPC_PLUGIN_SUPPORT_OBJS)
+$(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBGRPC_PLUGIN_SUPPORT_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
@@ -4063,14 +4055,10 @@
 
 LIBBORINGSSL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
-$(LIBDIR)/$(CONFIG)/libboringssl.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(LIBBORINGSSL_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl.a: $(ZLIB_DEP)  $(LIBBORINGSSL_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl.a
@@ -4095,12 +4083,8 @@
 
 LIBBORINGSSL_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_TEST_UTIL_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_TEST_UTIL_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_TEST_UTIL_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_TEST_UTIL_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_TEST_UTIL_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_TEST_UTIL_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -4111,7 +4095,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_test_util.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_TEST_UTIL_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_test_util.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_TEST_UTIL_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a
@@ -4136,12 +4120,8 @@
 
 LIBBORINGSSL_AES_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_AES_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_AES_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_AES_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_AES_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_AES_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_AES_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -4152,7 +4132,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_AES_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_AES_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a
@@ -4177,12 +4157,8 @@
 
 LIBBORINGSSL_BASE64_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_BASE64_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_BASE64_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_BASE64_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_BASE64_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_BASE64_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_BASE64_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -4193,7 +4169,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_BASE64_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_BASE64_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a
@@ -4218,12 +4194,8 @@
 
 LIBBORINGSSL_BIO_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_BIO_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_BIO_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_BIO_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_BIO_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_BIO_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_BIO_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -4234,7 +4206,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_BIO_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_BIO_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a
@@ -4259,12 +4231,8 @@
 
 LIBBORINGSSL_BN_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_BN_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_BN_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_BN_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_BN_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_BN_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_BN_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -4275,7 +4243,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_BN_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_BN_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a
@@ -4300,12 +4268,8 @@
 
 LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_BYTESTRING_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -4316,7 +4280,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a
@@ -4341,12 +4305,8 @@
 
 LIBBORINGSSL_AEAD_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_AEAD_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_AEAD_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_AEAD_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_AEAD_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_AEAD_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_AEAD_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -4357,7 +4317,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_AEAD_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_AEAD_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a
@@ -4382,12 +4342,8 @@
 
 LIBBORINGSSL_CIPHER_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_CIPHER_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -4398,7 +4354,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a
@@ -4423,12 +4379,8 @@
 
 LIBBORINGSSL_CMAC_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_CMAC_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_CMAC_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_CMAC_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_CMAC_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_CMAC_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_CMAC_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -4439,7 +4391,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_CMAC_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_CMAC_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a
@@ -4464,14 +4416,10 @@
 
 LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
-$(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a
@@ -4494,12 +4442,8 @@
 
 LIBBORINGSSL_ED25519_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_ED25519_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_ED25519_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_ED25519_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_ED25519_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_ED25519_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_ED25519_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -4510,7 +4454,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_ED25519_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_ED25519_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a
@@ -4535,12 +4479,8 @@
 
 LIBBORINGSSL_X25519_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_X25519_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_X25519_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_X25519_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_X25519_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_X25519_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_X25519_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -4551,7 +4491,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_X25519_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_X25519_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a
@@ -4576,12 +4516,8 @@
 
 LIBBORINGSSL_DH_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_DH_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_DH_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_DH_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_DH_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_DH_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_DH_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -4592,7 +4528,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_DH_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_DH_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a
@@ -4617,12 +4553,8 @@
 
 LIBBORINGSSL_DIGEST_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_DIGEST_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -4633,7 +4565,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a
@@ -4658,14 +4590,10 @@
 
 LIBBORINGSSL_DSA_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_DSA_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_DSA_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_DSA_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_DSA_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_DSA_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_DSA_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
-$(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(LIBBORINGSSL_DSA_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_DSA_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a
@@ -4688,12 +4616,8 @@
 
 LIBBORINGSSL_EC_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_EC_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_EC_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_EC_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_EC_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_EC_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_EC_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -4704,7 +4628,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_EC_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_EC_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a
@@ -4729,14 +4653,10 @@
 
 LIBBORINGSSL_EXAMPLE_MUL_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_EXAMPLE_MUL_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_EXAMPLE_MUL_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_EXAMPLE_MUL_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_EXAMPLE_MUL_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_EXAMPLE_MUL_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_EXAMPLE_MUL_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
-$(LIBDIR)/$(CONFIG)/libboringssl_example_mul_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(LIBBORINGSSL_EXAMPLE_MUL_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_example_mul_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_EXAMPLE_MUL_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_example_mul_lib.a
@@ -4759,12 +4679,8 @@
 
 LIBBORINGSSL_ECDSA_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_ECDSA_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -4775,7 +4691,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a
@@ -4800,12 +4716,8 @@
 
 LIBBORINGSSL_ERR_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_ERR_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_ERR_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_ERR_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_ERR_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_ERR_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_ERR_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -4816,7 +4728,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_ERR_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_ERR_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a
@@ -4841,12 +4753,8 @@
 
 LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -4857,7 +4765,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a
@@ -4882,12 +4790,8 @@
 
 LIBBORINGSSL_EVP_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_EVP_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_EVP_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_EVP_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_EVP_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_EVP_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_EVP_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -4898,7 +4802,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_EVP_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_EVP_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a
@@ -4923,12 +4827,8 @@
 
 LIBBORINGSSL_PBKDF_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_PBKDF_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -4939,7 +4839,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a
@@ -4964,14 +4864,10 @@
 
 LIBBORINGSSL_HKDF_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_HKDF_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_HKDF_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_HKDF_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_HKDF_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_HKDF_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_HKDF_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
-$(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(LIBBORINGSSL_HKDF_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_HKDF_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a
@@ -4994,12 +4890,8 @@
 
 LIBBORINGSSL_HMAC_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_HMAC_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_HMAC_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_HMAC_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_HMAC_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_HMAC_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_HMAC_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -5010,7 +4902,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_HMAC_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_HMAC_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a
@@ -5035,14 +4927,10 @@
 
 LIBBORINGSSL_LHASH_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_LHASH_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_LHASH_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_LHASH_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_LHASH_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_LHASH_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_LHASH_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
-$(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(LIBBORINGSSL_LHASH_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_LHASH_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a
@@ -5065,14 +4953,10 @@
 
 LIBBORINGSSL_GCM_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_GCM_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_GCM_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_GCM_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_GCM_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_GCM_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_GCM_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
-$(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(LIBBORINGSSL_GCM_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_GCM_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a
@@ -5095,12 +4979,8 @@
 
 LIBBORINGSSL_PKCS12_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_PKCS12_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -5111,7 +4991,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a
@@ -5136,12 +5016,8 @@
 
 LIBBORINGSSL_PKCS8_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_PKCS8_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -5152,7 +5028,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a
@@ -5177,12 +5053,8 @@
 
 LIBBORINGSSL_POLY1305_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_POLY1305_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -5193,7 +5065,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a
@@ -5218,14 +5090,10 @@
 
 LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_REFCOUNT_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
-$(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a
@@ -5248,12 +5116,8 @@
 
 LIBBORINGSSL_RSA_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_RSA_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_RSA_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_RSA_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_RSA_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_RSA_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_RSA_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -5264,7 +5128,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_RSA_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_RSA_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a
@@ -5289,14 +5153,10 @@
 
 LIBBORINGSSL_THREAD_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_THREAD_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_THREAD_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_THREAD_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_THREAD_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_THREAD_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_THREAD_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
-$(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(LIBBORINGSSL_THREAD_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_THREAD_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a
@@ -5319,14 +5179,10 @@
 
 LIBBORINGSSL_PKCS7_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_PKCS7_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
-$(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a
@@ -5349,14 +5205,10 @@
 
 LIBBORINGSSL_TAB_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_TAB_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_TAB_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_TAB_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_TAB_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_TAB_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_TAB_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
-$(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(LIBBORINGSSL_TAB_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_TAB_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a
@@ -5379,14 +5231,10 @@
 
 LIBBORINGSSL_V3NAME_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_V3NAME_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
-$(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a
@@ -5409,14 +5257,10 @@
 
 LIBBORINGSSL_PQUEUE_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_PQUEUE_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_PQUEUE_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_PQUEUE_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_PQUEUE_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_PQUEUE_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_PQUEUE_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
-$(LIBDIR)/$(CONFIG)/libboringssl_pqueue_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(LIBBORINGSSL_PQUEUE_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_pqueue_test_lib.a: $(ZLIB_DEP)  $(LIBBORINGSSL_PQUEUE_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pqueue_test_lib.a
@@ -5439,12 +5283,8 @@
 
 LIBBORINGSSL_SSL_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_SSL_TEST_LIB_SRC))))
 
-# boringssl needs an override to ensure that it does not include
-# system openssl headers regardless of other configuration
-# we do so here with a target specific variable assignment
-$(LIBBORINGSSL_SSL_TEST_LIB_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-$(LIBBORINGSSL_SSL_TEST_LIB_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-$(LIBBORINGSSL_SSL_TEST_LIB_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_SSL_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE
+$(LIBBORINGSSL_SSL_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 
 ifeq ($(NO_PROTOBUF),true)
 
@@ -5455,7 +5295,7 @@
 
 else
 
-$(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_SSL_TEST_LIB_OBJS)
+$(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_SSL_TEST_LIB_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a
@@ -5494,9 +5334,9 @@
 
 LIBZ_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBZ_SRC))))
 
-$(LIBZ_OBJS): CFLAGS := $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-implicit-function-declaration $(W_NO_SHIFT_NEGATIVE_VALUE) -fvisibility=hidden
+$(LIBZ_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-implicit-function-declaration $(W_NO_SHIFT_NEGATIVE_VALUE) -fvisibility=hidden
 
-$(LIBDIR)/$(CONFIG)/libz.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(LIBZ_OBJS)
+$(LIBDIR)/$(CONFIG)/libz.a:  $(LIBZ_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libz.a
@@ -5705,7 +5545,7 @@
 LIBEND2END_NOSEC_TESTS_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBEND2END_NOSEC_TESTS_SRC))))
 
 
-$(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a: $(ZLIB_DEP) $(OPENSSL_DEP)  $(LIBEND2END_NOSEC_TESTS_OBJS)
+$(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a: $(ZLIB_DEP)  $(LIBEND2END_NOSEC_TESTS_OBJS)
 	$(E) "[AR]      Creating $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a
@@ -10810,7 +10650,7 @@
 $(OBJDIR)/$(CONFIG)/test/core/surface/public_headers_must_be_c89.o : test/core/surface/public_headers_must_be_c89.c
 	$(E) "[C]       Compiling $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -std=c89 -pedantic -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
+	$(Q) $(CC) $(CPPFLAGS) $(CFLAGS) -std=c89 -pedantic -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
 
 deps_public_headers_must_be_c89: $(PUBLIC_HEADERS_MUST_BE_C89_OBJS:.o=.dep)
 
diff --git a/PYTHON-MANIFEST.in b/PYTHON-MANIFEST.in
index 52ef1ab..2f5700d 100644
--- a/PYTHON-MANIFEST.in
+++ b/PYTHON-MANIFEST.in
@@ -6,6 +6,7 @@
 graft third_party/zlib
 include src/python/grpcio/commands.py
 include src/python/grpcio/grpc_core_dependencies.py
+include src/python/grpcio/support.py
 include src/python/grpcio/README.rst
 include requirements.txt
 include etc/roots.pem
diff --git a/README.md b/README.md
index e0553ec..f894def 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
 [gRPC - An RPC library and framework](http://github.com/grpc/grpc)
 ===================================
 
-Copyright 2015 Google Inc.
+Copyright 2015-2016 Google Inc.
 
 #Documentation
 
diff --git a/binding.gyp b/binding.gyp
index 51c9cda..ad05b17 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -5,7 +5,7 @@
 # This file can be regenerated from the template by running
 # tools/buildgen/generate_projects.sh
 
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -54,12 +54,16 @@
     ],
     'include_dirs': [
       '.',
-      'include',
-      '<(node_root_dir)/deps/openssl/openssl/include',
-      '<(node_root_dir)/deps/zlib'
+      'include'
     ],
     'conditions': [
-      ['OS != "win"', {
+      ['OS == "win"', {
+        "include_dirs": [ "third_party/boringssl/include" ]
+      }, {
+        'include_dirs': [
+          '<(node_root_dir)/deps/openssl/openssl/include',
+          '<(node_root_dir)/deps/zlib'
+        ],
         'conditions': [
           ['config=="gcov"', {
             'cflags': [
@@ -72,20 +76,366 @@
               '-fprofile-arcs'
             ]
           }
-         ]
+         ],
+         ["target_arch=='ia32'", {
+             "include_dirs": [ "<(node_root_dir)/deps/openssl/config/piii" ]
+         }],
+         ["target_arch=='x64'", {
+             "include_dirs": [ "<(node_root_dir)/deps/openssl/config/k8" ]
+         }],
+         ["target_arch=='arm'", {
+             "include_dirs": [ "<(node_root_dir)/deps/openssl/config/arm" ]
+         }]
         ]
-      }],
-      ["target_arch=='ia32'", {
-          "include_dirs": [ "<(node_root_dir)/deps/openssl/config/piii" ]
-      }],
-      ["target_arch=='x64'", {
-          "include_dirs": [ "<(node_root_dir)/deps/openssl/config/k8" ]
-      }],
-      ["target_arch=='arm'", {
-          "include_dirs": [ "<(node_root_dir)/deps/openssl/config/arm" ]
       }]
     ]
   },
+  'conditions': [
+    ['OS == "win"', {
+      'targets': [
+        # Only want to compile BoringSSL and zlib under Windows
+        {
+          'cflags': [
+            '-std=c99',
+            '-Wall',
+            '-Werror'
+          ],
+          'target_name': 'boringssl',
+          'product_prefix': 'lib',
+          'type': 'static_library',
+          'dependencies': [
+          ],
+          'sources': [
+            'src/boringssl/err_data.c',
+            'third_party/boringssl/crypto/aes/aes.c',
+            'third_party/boringssl/crypto/aes/mode_wrappers.c',
+            'third_party/boringssl/crypto/asn1/a_bitstr.c',
+            'third_party/boringssl/crypto/asn1/a_bool.c',
+            'third_party/boringssl/crypto/asn1/a_bytes.c',
+            'third_party/boringssl/crypto/asn1/a_d2i_fp.c',
+            'third_party/boringssl/crypto/asn1/a_dup.c',
+            'third_party/boringssl/crypto/asn1/a_enum.c',
+            'third_party/boringssl/crypto/asn1/a_gentm.c',
+            'third_party/boringssl/crypto/asn1/a_i2d_fp.c',
+            'third_party/boringssl/crypto/asn1/a_int.c',
+            'third_party/boringssl/crypto/asn1/a_mbstr.c',
+            'third_party/boringssl/crypto/asn1/a_object.c',
+            'third_party/boringssl/crypto/asn1/a_octet.c',
+            'third_party/boringssl/crypto/asn1/a_print.c',
+            'third_party/boringssl/crypto/asn1/a_strnid.c',
+            'third_party/boringssl/crypto/asn1/a_time.c',
+            'third_party/boringssl/crypto/asn1/a_type.c',
+            'third_party/boringssl/crypto/asn1/a_utctm.c',
+            'third_party/boringssl/crypto/asn1/a_utf8.c',
+            'third_party/boringssl/crypto/asn1/asn1_lib.c',
+            'third_party/boringssl/crypto/asn1/asn1_par.c',
+            'third_party/boringssl/crypto/asn1/asn_pack.c',
+            'third_party/boringssl/crypto/asn1/bio_asn1.c',
+            'third_party/boringssl/crypto/asn1/bio_ndef.c',
+            'third_party/boringssl/crypto/asn1/f_enum.c',
+            'third_party/boringssl/crypto/asn1/f_int.c',
+            'third_party/boringssl/crypto/asn1/f_string.c',
+            'third_party/boringssl/crypto/asn1/t_bitst.c',
+            'third_party/boringssl/crypto/asn1/t_pkey.c',
+            'third_party/boringssl/crypto/asn1/tasn_dec.c',
+            'third_party/boringssl/crypto/asn1/tasn_enc.c',
+            'third_party/boringssl/crypto/asn1/tasn_fre.c',
+            'third_party/boringssl/crypto/asn1/tasn_new.c',
+            'third_party/boringssl/crypto/asn1/tasn_prn.c',
+            'third_party/boringssl/crypto/asn1/tasn_typ.c',
+            'third_party/boringssl/crypto/asn1/tasn_utl.c',
+            'third_party/boringssl/crypto/asn1/x_bignum.c',
+            'third_party/boringssl/crypto/asn1/x_long.c',
+            'third_party/boringssl/crypto/base64/base64.c',
+            'third_party/boringssl/crypto/bio/bio.c',
+            'third_party/boringssl/crypto/bio/bio_mem.c',
+            'third_party/boringssl/crypto/bio/buffer.c',
+            'third_party/boringssl/crypto/bio/connect.c',
+            'third_party/boringssl/crypto/bio/fd.c',
+            'third_party/boringssl/crypto/bio/file.c',
+            'third_party/boringssl/crypto/bio/hexdump.c',
+            'third_party/boringssl/crypto/bio/pair.c',
+            'third_party/boringssl/crypto/bio/printf.c',
+            'third_party/boringssl/crypto/bio/socket.c',
+            'third_party/boringssl/crypto/bio/socket_helper.c',
+            'third_party/boringssl/crypto/bn/add.c',
+            'third_party/boringssl/crypto/bn/asm/x86_64-gcc.c',
+            'third_party/boringssl/crypto/bn/bn.c',
+            'third_party/boringssl/crypto/bn/bn_asn1.c',
+            'third_party/boringssl/crypto/bn/cmp.c',
+            'third_party/boringssl/crypto/bn/convert.c',
+            'third_party/boringssl/crypto/bn/ctx.c',
+            'third_party/boringssl/crypto/bn/div.c',
+            'third_party/boringssl/crypto/bn/exponentiation.c',
+            'third_party/boringssl/crypto/bn/gcd.c',
+            'third_party/boringssl/crypto/bn/generic.c',
+            'third_party/boringssl/crypto/bn/kronecker.c',
+            'third_party/boringssl/crypto/bn/montgomery.c',
+            'third_party/boringssl/crypto/bn/mul.c',
+            'third_party/boringssl/crypto/bn/prime.c',
+            'third_party/boringssl/crypto/bn/random.c',
+            'third_party/boringssl/crypto/bn/rsaz_exp.c',
+            'third_party/boringssl/crypto/bn/shift.c',
+            'third_party/boringssl/crypto/bn/sqrt.c',
+            'third_party/boringssl/crypto/buf/buf.c',
+            'third_party/boringssl/crypto/bytestring/ber.c',
+            'third_party/boringssl/crypto/bytestring/cbb.c',
+            'third_party/boringssl/crypto/bytestring/cbs.c',
+            'third_party/boringssl/crypto/chacha/chacha_generic.c',
+            'third_party/boringssl/crypto/chacha/chacha_vec.c',
+            'third_party/boringssl/crypto/cipher/aead.c',
+            'third_party/boringssl/crypto/cipher/cipher.c',
+            'third_party/boringssl/crypto/cipher/derive_key.c',
+            'third_party/boringssl/crypto/cipher/e_aes.c',
+            'third_party/boringssl/crypto/cipher/e_chacha20poly1305.c',
+            'third_party/boringssl/crypto/cipher/e_des.c',
+            'third_party/boringssl/crypto/cipher/e_null.c',
+            'third_party/boringssl/crypto/cipher/e_rc2.c',
+            'third_party/boringssl/crypto/cipher/e_rc4.c',
+            'third_party/boringssl/crypto/cipher/e_ssl3.c',
+            'third_party/boringssl/crypto/cipher/e_tls.c',
+            'third_party/boringssl/crypto/cipher/tls_cbc.c',
+            'third_party/boringssl/crypto/cmac/cmac.c',
+            'third_party/boringssl/crypto/conf/conf.c',
+            'third_party/boringssl/crypto/cpu-arm.c',
+            'third_party/boringssl/crypto/cpu-intel.c',
+            'third_party/boringssl/crypto/crypto.c',
+            'third_party/boringssl/crypto/curve25519/curve25519.c',
+            'third_party/boringssl/crypto/des/des.c',
+            'third_party/boringssl/crypto/dh/check.c',
+            'third_party/boringssl/crypto/dh/dh.c',
+            'third_party/boringssl/crypto/dh/dh_asn1.c',
+            'third_party/boringssl/crypto/dh/params.c',
+            'third_party/boringssl/crypto/digest/digest.c',
+            'third_party/boringssl/crypto/digest/digests.c',
+            'third_party/boringssl/crypto/directory_posix.c',
+            'third_party/boringssl/crypto/directory_win.c',
+            'third_party/boringssl/crypto/dsa/dsa.c',
+            'third_party/boringssl/crypto/dsa/dsa_asn1.c',
+            'third_party/boringssl/crypto/ec/ec.c',
+            'third_party/boringssl/crypto/ec/ec_asn1.c',
+            'third_party/boringssl/crypto/ec/ec_key.c',
+            'third_party/boringssl/crypto/ec/ec_montgomery.c',
+            'third_party/boringssl/crypto/ec/oct.c',
+            'third_party/boringssl/crypto/ec/p224-64.c',
+            'third_party/boringssl/crypto/ec/p256-64.c',
+            'third_party/boringssl/crypto/ec/p256-x86_64.c',
+            'third_party/boringssl/crypto/ec/simple.c',
+            'third_party/boringssl/crypto/ec/util-64.c',
+            'third_party/boringssl/crypto/ec/wnaf.c',
+            'third_party/boringssl/crypto/ecdh/ecdh.c',
+            'third_party/boringssl/crypto/ecdsa/ecdsa.c',
+            'third_party/boringssl/crypto/ecdsa/ecdsa_asn1.c',
+            'third_party/boringssl/crypto/engine/engine.c',
+            'third_party/boringssl/crypto/err/err.c',
+            'third_party/boringssl/crypto/evp/algorithm.c',
+            'third_party/boringssl/crypto/evp/digestsign.c',
+            'third_party/boringssl/crypto/evp/evp.c',
+            'third_party/boringssl/crypto/evp/evp_asn1.c',
+            'third_party/boringssl/crypto/evp/evp_ctx.c',
+            'third_party/boringssl/crypto/evp/p_dsa_asn1.c',
+            'third_party/boringssl/crypto/evp/p_ec.c',
+            'third_party/boringssl/crypto/evp/p_ec_asn1.c',
+            'third_party/boringssl/crypto/evp/p_rsa.c',
+            'third_party/boringssl/crypto/evp/p_rsa_asn1.c',
+            'third_party/boringssl/crypto/evp/pbkdf.c',
+            'third_party/boringssl/crypto/evp/sign.c',
+            'third_party/boringssl/crypto/ex_data.c',
+            'third_party/boringssl/crypto/hkdf/hkdf.c',
+            'third_party/boringssl/crypto/hmac/hmac.c',
+            'third_party/boringssl/crypto/lhash/lhash.c',
+            'third_party/boringssl/crypto/md4/md4.c',
+            'third_party/boringssl/crypto/md5/md5.c',
+            'third_party/boringssl/crypto/mem.c',
+            'third_party/boringssl/crypto/modes/cbc.c',
+            'third_party/boringssl/crypto/modes/cfb.c',
+            'third_party/boringssl/crypto/modes/ctr.c',
+            'third_party/boringssl/crypto/modes/gcm.c',
+            'third_party/boringssl/crypto/modes/ofb.c',
+            'third_party/boringssl/crypto/obj/obj.c',
+            'third_party/boringssl/crypto/obj/obj_xref.c',
+            'third_party/boringssl/crypto/pem/pem_all.c',
+            'third_party/boringssl/crypto/pem/pem_info.c',
+            'third_party/boringssl/crypto/pem/pem_lib.c',
+            'third_party/boringssl/crypto/pem/pem_oth.c',
+            'third_party/boringssl/crypto/pem/pem_pk8.c',
+            'third_party/boringssl/crypto/pem/pem_pkey.c',
+            'third_party/boringssl/crypto/pem/pem_x509.c',
+            'third_party/boringssl/crypto/pem/pem_xaux.c',
+            'third_party/boringssl/crypto/pkcs8/p5_pbe.c',
+            'third_party/boringssl/crypto/pkcs8/p5_pbev2.c',
+            'third_party/boringssl/crypto/pkcs8/p8_pkey.c',
+            'third_party/boringssl/crypto/pkcs8/pkcs8.c',
+            'third_party/boringssl/crypto/poly1305/poly1305.c',
+            'third_party/boringssl/crypto/poly1305/poly1305_arm.c',
+            'third_party/boringssl/crypto/poly1305/poly1305_vec.c',
+            'third_party/boringssl/crypto/rand/rand.c',
+            'third_party/boringssl/crypto/rand/urandom.c',
+            'third_party/boringssl/crypto/rand/windows.c',
+            'third_party/boringssl/crypto/rc4/rc4.c',
+            'third_party/boringssl/crypto/refcount_c11.c',
+            'third_party/boringssl/crypto/refcount_lock.c',
+            'third_party/boringssl/crypto/rsa/blinding.c',
+            'third_party/boringssl/crypto/rsa/padding.c',
+            'third_party/boringssl/crypto/rsa/rsa.c',
+            'third_party/boringssl/crypto/rsa/rsa_asn1.c',
+            'third_party/boringssl/crypto/rsa/rsa_impl.c',
+            'third_party/boringssl/crypto/sha/sha1.c',
+            'third_party/boringssl/crypto/sha/sha256.c',
+            'third_party/boringssl/crypto/sha/sha512.c',
+            'third_party/boringssl/crypto/stack/stack.c',
+            'third_party/boringssl/crypto/thread.c',
+            'third_party/boringssl/crypto/thread_none.c',
+            'third_party/boringssl/crypto/thread_pthread.c',
+            'third_party/boringssl/crypto/thread_win.c',
+            'third_party/boringssl/crypto/time_support.c',
+            'third_party/boringssl/crypto/x509/a_digest.c',
+            'third_party/boringssl/crypto/x509/a_sign.c',
+            'third_party/boringssl/crypto/x509/a_strex.c',
+            'third_party/boringssl/crypto/x509/a_verify.c',
+            'third_party/boringssl/crypto/x509/asn1_gen.c',
+            'third_party/boringssl/crypto/x509/by_dir.c',
+            'third_party/boringssl/crypto/x509/by_file.c',
+            'third_party/boringssl/crypto/x509/i2d_pr.c',
+            'third_party/boringssl/crypto/x509/pkcs7.c',
+            'third_party/boringssl/crypto/x509/t_crl.c',
+            'third_party/boringssl/crypto/x509/t_req.c',
+            'third_party/boringssl/crypto/x509/t_x509.c',
+            'third_party/boringssl/crypto/x509/t_x509a.c',
+            'third_party/boringssl/crypto/x509/x509.c',
+            'third_party/boringssl/crypto/x509/x509_att.c',
+            'third_party/boringssl/crypto/x509/x509_cmp.c',
+            'third_party/boringssl/crypto/x509/x509_d2.c',
+            'third_party/boringssl/crypto/x509/x509_def.c',
+            'third_party/boringssl/crypto/x509/x509_ext.c',
+            'third_party/boringssl/crypto/x509/x509_lu.c',
+            'third_party/boringssl/crypto/x509/x509_obj.c',
+            'third_party/boringssl/crypto/x509/x509_r2x.c',
+            'third_party/boringssl/crypto/x509/x509_req.c',
+            'third_party/boringssl/crypto/x509/x509_set.c',
+            'third_party/boringssl/crypto/x509/x509_trs.c',
+            'third_party/boringssl/crypto/x509/x509_txt.c',
+            'third_party/boringssl/crypto/x509/x509_v3.c',
+            'third_party/boringssl/crypto/x509/x509_vfy.c',
+            'third_party/boringssl/crypto/x509/x509_vpm.c',
+            'third_party/boringssl/crypto/x509/x509cset.c',
+            'third_party/boringssl/crypto/x509/x509name.c',
+            'third_party/boringssl/crypto/x509/x509rset.c',
+            'third_party/boringssl/crypto/x509/x509spki.c',
+            'third_party/boringssl/crypto/x509/x509type.c',
+            'third_party/boringssl/crypto/x509/x_algor.c',
+            'third_party/boringssl/crypto/x509/x_all.c',
+            'third_party/boringssl/crypto/x509/x_attrib.c',
+            'third_party/boringssl/crypto/x509/x_crl.c',
+            'third_party/boringssl/crypto/x509/x_exten.c',
+            'third_party/boringssl/crypto/x509/x_info.c',
+            'third_party/boringssl/crypto/x509/x_name.c',
+            'third_party/boringssl/crypto/x509/x_pkey.c',
+            'third_party/boringssl/crypto/x509/x_pubkey.c',
+            'third_party/boringssl/crypto/x509/x_req.c',
+            'third_party/boringssl/crypto/x509/x_sig.c',
+            'third_party/boringssl/crypto/x509/x_spki.c',
+            'third_party/boringssl/crypto/x509/x_val.c',
+            'third_party/boringssl/crypto/x509/x_x509.c',
+            'third_party/boringssl/crypto/x509/x_x509a.c',
+            'third_party/boringssl/crypto/x509v3/pcy_cache.c',
+            'third_party/boringssl/crypto/x509v3/pcy_data.c',
+            'third_party/boringssl/crypto/x509v3/pcy_lib.c',
+            'third_party/boringssl/crypto/x509v3/pcy_map.c',
+            'third_party/boringssl/crypto/x509v3/pcy_node.c',
+            'third_party/boringssl/crypto/x509v3/pcy_tree.c',
+            'third_party/boringssl/crypto/x509v3/v3_akey.c',
+            'third_party/boringssl/crypto/x509v3/v3_akeya.c',
+            'third_party/boringssl/crypto/x509v3/v3_alt.c',
+            'third_party/boringssl/crypto/x509v3/v3_bcons.c',
+            'third_party/boringssl/crypto/x509v3/v3_bitst.c',
+            'third_party/boringssl/crypto/x509v3/v3_conf.c',
+            'third_party/boringssl/crypto/x509v3/v3_cpols.c',
+            'third_party/boringssl/crypto/x509v3/v3_crld.c',
+            'third_party/boringssl/crypto/x509v3/v3_enum.c',
+            'third_party/boringssl/crypto/x509v3/v3_extku.c',
+            'third_party/boringssl/crypto/x509v3/v3_genn.c',
+            'third_party/boringssl/crypto/x509v3/v3_ia5.c',
+            'third_party/boringssl/crypto/x509v3/v3_info.c',
+            'third_party/boringssl/crypto/x509v3/v3_int.c',
+            'third_party/boringssl/crypto/x509v3/v3_lib.c',
+            'third_party/boringssl/crypto/x509v3/v3_ncons.c',
+            'third_party/boringssl/crypto/x509v3/v3_pci.c',
+            'third_party/boringssl/crypto/x509v3/v3_pcia.c',
+            'third_party/boringssl/crypto/x509v3/v3_pcons.c',
+            'third_party/boringssl/crypto/x509v3/v3_pku.c',
+            'third_party/boringssl/crypto/x509v3/v3_pmaps.c',
+            'third_party/boringssl/crypto/x509v3/v3_prn.c',
+            'third_party/boringssl/crypto/x509v3/v3_purp.c',
+            'third_party/boringssl/crypto/x509v3/v3_skey.c',
+            'third_party/boringssl/crypto/x509v3/v3_sxnet.c',
+            'third_party/boringssl/crypto/x509v3/v3_utl.c',
+            'third_party/boringssl/ssl/custom_extensions.c',
+            'third_party/boringssl/ssl/d1_both.c',
+            'third_party/boringssl/ssl/d1_clnt.c',
+            'third_party/boringssl/ssl/d1_lib.c',
+            'third_party/boringssl/ssl/d1_meth.c',
+            'third_party/boringssl/ssl/d1_pkt.c',
+            'third_party/boringssl/ssl/d1_srtp.c',
+            'third_party/boringssl/ssl/d1_srvr.c',
+            'third_party/boringssl/ssl/dtls_record.c',
+            'third_party/boringssl/ssl/pqueue/pqueue.c',
+            'third_party/boringssl/ssl/s3_both.c',
+            'third_party/boringssl/ssl/s3_clnt.c',
+            'third_party/boringssl/ssl/s3_enc.c',
+            'third_party/boringssl/ssl/s3_lib.c',
+            'third_party/boringssl/ssl/s3_meth.c',
+            'third_party/boringssl/ssl/s3_pkt.c',
+            'third_party/boringssl/ssl/s3_srvr.c',
+            'third_party/boringssl/ssl/ssl_aead_ctx.c',
+            'third_party/boringssl/ssl/ssl_asn1.c',
+            'third_party/boringssl/ssl/ssl_buffer.c',
+            'third_party/boringssl/ssl/ssl_cert.c',
+            'third_party/boringssl/ssl/ssl_cipher.c',
+            'third_party/boringssl/ssl/ssl_file.c',
+            'third_party/boringssl/ssl/ssl_lib.c',
+            'third_party/boringssl/ssl/ssl_rsa.c',
+            'third_party/boringssl/ssl/ssl_session.c',
+            'third_party/boringssl/ssl/ssl_stat.c',
+            'third_party/boringssl/ssl/t1_enc.c',
+            'third_party/boringssl/ssl/t1_lib.c',
+            'third_party/boringssl/ssl/tls_record.c',
+          ],
+          "include_dirs": [ "third_party/boringssl/include" ]
+        },
+        {
+          'cflags': [
+            '-std=c99',
+            '-Wall',
+            '-Werror'
+          ],
+          'target_name': 'z',
+          'product_prefix': 'lib',
+          'type': 'static_library',
+          'dependencies': [
+          ],
+          'sources': [
+            'third_party/zlib/adler32.c',
+            'third_party/zlib/compress.c',
+            'third_party/zlib/crc32.c',
+            'third_party/zlib/deflate.c',
+            'third_party/zlib/gzclose.c',
+            'third_party/zlib/gzlib.c',
+            'third_party/zlib/gzread.c',
+            'third_party/zlib/gzwrite.c',
+            'third_party/zlib/infback.c',
+            'third_party/zlib/inffast.c',
+            'third_party/zlib/inflate.c',
+            'third_party/zlib/inftrees.c',
+            'third_party/zlib/trees.c',
+            'third_party/zlib/uncompr.c',
+            'third_party/zlib/zutil.c',
+          ],
+          "include_dirs": [ "third_party/boringssl/include" ]
+        },
+      ]
+    }]
+  ],
   'targets': [
     {
       'cflags': [
@@ -147,7 +497,7 @@
             'MACOSX_DEPLOYMENT_TARGET': '10.9'
           }
         }]
-      ],
+      ]
     },
     {
       'cflags': [
@@ -322,7 +672,7 @@
             'MACOSX_DEPLOYMENT_TARGET': '10.9'
           }
         }]
-      ],
+      ]
     },
     {
       'include_dirs': [
@@ -341,13 +691,19 @@
         '-g'
       ],
       "conditions": [
-        ['OS == "mac"', {
+        ['OS=="mac"', {
           'xcode_settings': {
             'MACOSX_DEPLOYMENT_TARGET': '10.9',
             'OTHER_CFLAGS': [
               '-stdlib=libc++'
             ]
           }
+        }],
+        ['OS=="win"', {
+          'dependencies': [
+            "boringssl",
+            "z",
+          ]
         }]
       ],
       "target_name": "grpc_node",
@@ -368,5 +724,16 @@
         "gpr",
       ]
     },
+    {
+      "target_name": "action_after_build",
+      "type": "none",
+      "dependencies": [ "<(module_name)" ],
+      "copies": [
+        {
+          "files": [ "<(PRODUCT_DIR)/<(module_name).node"],
+          "destination": "<(module_path)"
+        }
+      ]
+    }
   ]
 }
diff --git a/build.yaml b/build.yaml
index bbc36a8..368ef76 100644
--- a/build.yaml
+++ b/build.yaml
@@ -5,7 +5,7 @@
   '#': The public version number of the library.
   version:
     major: 0
-    minor: 12
+    minor: 13
     micro: 0
     build: 0
 filegroups:
@@ -2497,9 +2497,8 @@
 configs:
   asan:
     CC: clang
-    CFLAGS: -O0 -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument
+    CPPFLAGS: -O0 -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument
     CXX: clang++
-    CXXFLAGS: -O0 -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument
     LD: clang
     LDFLAGS: -fsanitize=address
     LDXX: clang++
@@ -2510,9 +2509,8 @@
     timeout_multiplier: 1.5
   asan-noleaks:
     CC: clang
-    CFLAGS: -O0 -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument
+    CPPFLAGS: -O0 -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument
     CXX: clang++
-    CXXFLAGS: -O0 -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument
     LD: clang
     LDFLAGS: -fsanitize=address
     LDXX: clang++
@@ -2529,9 +2527,8 @@
     LDFLAGS: -rdynamic
   gcov:
     CC: gcc
-    CFLAGS: -O0 -fprofile-arcs -ftest-coverage -Wno-return-type
+    CPPFLAGS: -O0 -fprofile-arcs -ftest-coverage -Wno-return-type
     CXX: g++
-    CXXFLAGS: -O0 -fprofile-arcs -ftest-coverage -Wno-return-type
     DEFINES: _DEBUG DEBUG GPR_GCOV
     LD: gcc
     LDFLAGS: -fprofile-arcs -ftest-coverage -rdynamic
@@ -2550,20 +2547,17 @@
     valgrind: --tool=memcheck --leak-check=full
   msan:
     CC: clang
-    CFLAGS: -O0 -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer
+    CPPFLAGS: -O0 -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer
       -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -Wno-unused-command-line-argument
       -fPIE -pie
     CXX: clang++
-    CXXFLAGS: -O0 -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer
-      -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -Wno-unused-command-line-argument
-      -fPIE -pie
     DEFINES: NDEBUG
     LD: clang
     LDFLAGS: -fsanitize=memory -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1
       -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,)
     LDXX: clang++
     compile_the_world: true
-    timeout_multiplier: 1.5
+    timeout_multiplier: 2
   mutrace:
     CPPFLAGS: -O0
     DEFINES: _DEBUG DEBUG
@@ -2577,11 +2571,9 @@
     DEFINES: NDEBUG
   tsan:
     CC: clang
-    CFLAGS: -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument
+    CPPFLAGS: -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument
       -fPIE -pie
     CXX: clang++
-    CXXFLAGS: -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument
-      -fPIE -pie
     LD: clang
     LDFLAGS: -fsanitize=thread -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,)
     LDXX: clang++
@@ -2591,19 +2583,31 @@
     timeout_multiplier: 2
   ubsan:
     CC: clang
-    CFLAGS: -O1 -fsanitize=undefined -fno-omit-frame-pointer -Wno-unused-command-line-argument
+    CPPFLAGS: -O1 -fsanitize=undefined -fno-omit-frame-pointer -Wno-unused-command-line-argument
     CXX: clang++
-    CXXFLAGS: -O1 -fsanitize=undefined -fno-omit-frame-pointer -Wno-unused-command-line-argument
     DEFINES: NDEBUG
     LD: clang
     LDFLAGS: -fsanitize=undefined
     LDXX: clang++
     compile_the_world: true
     timeout_multiplier: 1.5
+defaults:
+  boringssl:
+    CFLAGS: -Wno-sign-conversion -Wno-conversion -Wno-unused-value
+    CPPFLAGS: -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM
+      -D_GNU_SOURCE
+  global:
+    CPPFLAGS: -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter
+    LDFLAGS: -g
+  zlib:
+    CFLAGS: -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-implicit-function-declaration
+      $(W_NO_SHIFT_NEGATIVE_VALUE) -fvisibility=hidden
 node_modules:
 - deps:
   - grpc
   - gpr
+  - boringssl
+  - z
   headers:
   - src/node/ext/byte_buffer.h
   - src/node/ext/call.h
diff --git a/include/grpc++/client_context.h b/include/grpc++/client_context.h
index 25eeb38..4e8776e 100644
--- a/include/grpc++/client_context.h
+++ b/include/grpc++/client_context.h
@@ -286,6 +286,7 @@
   /// a client context is constructed and destructed.
   class GlobalCallbacks {
    public:
+    virtual ~GlobalCallbacks() {}
     virtual void DefaultConstructor(ClientContext* context) = 0;
     virtual void Destructor(ClientContext* context) = 0;
   };
diff --git a/include/grpc++/server.h b/include/grpc++/server.h
index 644e66e..f24ed33 100644
--- a/include/grpc++/server.h
+++ b/include/grpc++/server.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -304,6 +304,8 @@
   int num_running_cb_;
   grpc::condition_variable callback_cv_;
 
+  std::shared_ptr<GlobalCallbacks> global_callbacks_;
+
   std::list<SyncRequest>* sync_methods_;
   std::unique_ptr<RpcServiceMethod> unknown_method_;
   bool has_generic_service_;
diff --git a/include/grpc/support/log_win32.h b/include/grpc/support/log_win32.h
index ea6b16d..3546266 100644
--- a/include/grpc/support/log_win32.h
+++ b/include/grpc/support/log_win32.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,7 @@
  * formatted error message, corresponding to the error messageid.
  * Use in conjunction with GetLastError() et al.
  */
-char *gpr_format_message(DWORD messageid);
+char *gpr_format_message(int messageid);
 
 #ifdef __cplusplus
 }
diff --git a/include/grpc/support/thd.h b/include/grpc/support/thd.h
index 58b8a83..56185cc 100644
--- a/include/grpc/support/thd.h
+++ b/include/grpc/support/thd.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -48,7 +48,7 @@
 extern "C" {
 #endif
 
-typedef uint64_t gpr_thd_id;
+typedef uintptr_t gpr_thd_id;
 
 /* Thread creation options. */
 typedef struct {
diff --git a/package.json b/package.json
index 74de532..bd9ad49 100644
--- a/package.json
+++ b/package.json
@@ -22,12 +22,14 @@
     "lint": "node ./node_modules/jshint/bin/jshint src/node/src src/node/test src/node/interop src/node/index.js",
     "test": "./node_modules/.bin/mocha src/node/test && npm run-script lint",
     "gen_docs": "./node_modules/.bin/jsdoc -c src/node/jsdoc_conf.json",
-    "coverage": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha src/node/test"
+    "coverage": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha src/node/test",
+    "preinstall": "npm install node-pre-gyp",
+    "install": "./node_modules/.bin/node-pre-gyp install --fallback-to-build"
   },
   "dependencies": {
-    "bindings": "^1.2.0",
     "lodash": "^3.9.3",
     "nan": "^2.0.0",
+    "node-pre-gyp": "^0.6.19",
     "protobufjs": "^4.0.0"
   },
   "devDependencies": {
@@ -45,6 +47,14 @@
   "engines": {
     "node": ">=0.10.13"
   },
+  "binary": {
+    "module_name": "grpc_node",
+    "module_path": "./build/Release/",
+    "host": "https://storage.googleapis.com/",
+    "remote_path": "grpc-precompiled-binaries/node/{name}/v{version}",
+    "package_name": "{node_abi}-{platform}-{arch}.tar.gz",
+    "module_path": "src/node/extension_binary"
+  },
   "files": [
     "LICENSE",
     "src/node/README.md",
@@ -367,6 +377,32 @@
     "src/core/census/operation.c",
     "src/core/census/tag_set.c",
     "src/core/census/tracing.c",
+    "third_party/zlib/crc32.h",
+    "third_party/zlib/deflate.h",
+    "third_party/zlib/gzguts.h",
+    "third_party/zlib/inffast.h",
+    "third_party/zlib/inffixed.h",
+    "third_party/zlib/inflate.h",
+    "third_party/zlib/inftrees.h",
+    "third_party/zlib/trees.h",
+    "third_party/zlib/zconf.h",
+    "third_party/zlib/zlib.h",
+    "third_party/zlib/zutil.h",
+    "third_party/zlib/adler32.c",
+    "third_party/zlib/compress.c",
+    "third_party/zlib/crc32.c",
+    "third_party/zlib/deflate.c",
+    "third_party/zlib/gzclose.c",
+    "third_party/zlib/gzlib.c",
+    "third_party/zlib/gzread.c",
+    "third_party/zlib/gzwrite.c",
+    "third_party/zlib/infback.c",
+    "third_party/zlib/inffast.c",
+    "third_party/zlib/inflate.c",
+    "third_party/zlib/inftrees.c",
+    "third_party/zlib/trees.c",
+    "third_party/zlib/uncompr.c",
+    "third_party/zlib/zutil.c",
     "include/grpc/support/alloc.h",
     "include/grpc/support/atm.h",
     "include/grpc/support/atm_gcc_atomic.h",
@@ -446,6 +482,407 @@
     "src/core/support/time_precise.c",
     "src/core/support/time_win32.c",
     "src/core/support/tls_pthread.c",
+    "third_party/boringssl/crypto/aes/internal.h",
+    "third_party/boringssl/crypto/asn1/asn1_locl.h",
+    "third_party/boringssl/crypto/bio/internal.h",
+    "third_party/boringssl/crypto/bn/internal.h",
+    "third_party/boringssl/crypto/bn/rsaz_exp.h",
+    "third_party/boringssl/crypto/bytestring/internal.h",
+    "third_party/boringssl/crypto/cipher/internal.h",
+    "third_party/boringssl/crypto/conf/conf_def.h",
+    "third_party/boringssl/crypto/conf/internal.h",
+    "third_party/boringssl/crypto/des/internal.h",
+    "third_party/boringssl/crypto/dh/internal.h",
+    "third_party/boringssl/crypto/digest/internal.h",
+    "third_party/boringssl/crypto/digest/md32_common.h",
+    "third_party/boringssl/crypto/directory.h",
+    "third_party/boringssl/crypto/dsa/internal.h",
+    "third_party/boringssl/crypto/ec/internal.h",
+    "third_party/boringssl/crypto/ec/p256-x86_64-table.h",
+    "third_party/boringssl/crypto/evp/internal.h",
+    "third_party/boringssl/crypto/internal.h",
+    "third_party/boringssl/crypto/modes/internal.h",
+    "third_party/boringssl/crypto/obj/obj_dat.h",
+    "third_party/boringssl/crypto/obj/obj_xref.h",
+    "third_party/boringssl/crypto/pkcs8/internal.h",
+    "third_party/boringssl/crypto/rand/internal.h",
+    "third_party/boringssl/crypto/rsa/internal.h",
+    "third_party/boringssl/crypto/test/scoped_types.h",
+    "third_party/boringssl/crypto/test/test_util.h",
+    "third_party/boringssl/crypto/x509/charmap.h",
+    "third_party/boringssl/crypto/x509/vpm_int.h",
+    "third_party/boringssl/crypto/x509v3/ext_dat.h",
+    "third_party/boringssl/crypto/x509v3/pcy_int.h",
+    "third_party/boringssl/include/openssl/aead.h",
+    "third_party/boringssl/include/openssl/aes.h",
+    "third_party/boringssl/include/openssl/arm_arch.h",
+    "third_party/boringssl/include/openssl/asn1.h",
+    "third_party/boringssl/include/openssl/asn1_mac.h",
+    "third_party/boringssl/include/openssl/asn1t.h",
+    "third_party/boringssl/include/openssl/base.h",
+    "third_party/boringssl/include/openssl/base64.h",
+    "third_party/boringssl/include/openssl/bio.h",
+    "third_party/boringssl/include/openssl/blowfish.h",
+    "third_party/boringssl/include/openssl/bn.h",
+    "third_party/boringssl/include/openssl/buf.h",
+    "third_party/boringssl/include/openssl/buffer.h",
+    "third_party/boringssl/include/openssl/bytestring.h",
+    "third_party/boringssl/include/openssl/cast.h",
+    "third_party/boringssl/include/openssl/chacha.h",
+    "third_party/boringssl/include/openssl/cipher.h",
+    "third_party/boringssl/include/openssl/cmac.h",
+    "third_party/boringssl/include/openssl/conf.h",
+    "third_party/boringssl/include/openssl/cpu.h",
+    "third_party/boringssl/include/openssl/crypto.h",
+    "third_party/boringssl/include/openssl/curve25519.h",
+    "third_party/boringssl/include/openssl/des.h",
+    "third_party/boringssl/include/openssl/dh.h",
+    "third_party/boringssl/include/openssl/digest.h",
+    "third_party/boringssl/include/openssl/dsa.h",
+    "third_party/boringssl/include/openssl/dtls1.h",
+    "third_party/boringssl/include/openssl/ec.h",
+    "third_party/boringssl/include/openssl/ec_key.h",
+    "third_party/boringssl/include/openssl/ecdh.h",
+    "third_party/boringssl/include/openssl/ecdsa.h",
+    "third_party/boringssl/include/openssl/engine.h",
+    "third_party/boringssl/include/openssl/err.h",
+    "third_party/boringssl/include/openssl/evp.h",
+    "third_party/boringssl/include/openssl/ex_data.h",
+    "third_party/boringssl/include/openssl/hkdf.h",
+    "third_party/boringssl/include/openssl/hmac.h",
+    "third_party/boringssl/include/openssl/lhash.h",
+    "third_party/boringssl/include/openssl/lhash_macros.h",
+    "third_party/boringssl/include/openssl/md4.h",
+    "third_party/boringssl/include/openssl/md5.h",
+    "third_party/boringssl/include/openssl/mem.h",
+    "third_party/boringssl/include/openssl/obj.h",
+    "third_party/boringssl/include/openssl/obj_mac.h",
+    "third_party/boringssl/include/openssl/objects.h",
+    "third_party/boringssl/include/openssl/opensslfeatures.h",
+    "third_party/boringssl/include/openssl/opensslv.h",
+    "third_party/boringssl/include/openssl/ossl_typ.h",
+    "third_party/boringssl/include/openssl/pem.h",
+    "third_party/boringssl/include/openssl/pkcs12.h",
+    "third_party/boringssl/include/openssl/pkcs7.h",
+    "third_party/boringssl/include/openssl/pkcs8.h",
+    "third_party/boringssl/include/openssl/poly1305.h",
+    "third_party/boringssl/include/openssl/pqueue.h",
+    "third_party/boringssl/include/openssl/rand.h",
+    "third_party/boringssl/include/openssl/rc4.h",
+    "third_party/boringssl/include/openssl/rsa.h",
+    "third_party/boringssl/include/openssl/safestack.h",
+    "third_party/boringssl/include/openssl/sha.h",
+    "third_party/boringssl/include/openssl/srtp.h",
+    "third_party/boringssl/include/openssl/ssl.h",
+    "third_party/boringssl/include/openssl/ssl3.h",
+    "third_party/boringssl/include/openssl/stack.h",
+    "third_party/boringssl/include/openssl/stack_macros.h",
+    "third_party/boringssl/include/openssl/thread.h",
+    "third_party/boringssl/include/openssl/time_support.h",
+    "third_party/boringssl/include/openssl/tls1.h",
+    "third_party/boringssl/include/openssl/type_check.h",
+    "third_party/boringssl/include/openssl/x509.h",
+    "third_party/boringssl/include/openssl/x509_vfy.h",
+    "third_party/boringssl/include/openssl/x509v3.h",
+    "third_party/boringssl/ssl/internal.h",
+    "third_party/boringssl/ssl/test/async_bio.h",
+    "third_party/boringssl/ssl/test/packeted_bio.h",
+    "third_party/boringssl/ssl/test/scoped_types.h",
+    "third_party/boringssl/ssl/test/test_config.h",
+    "src/boringssl/err_data.c",
+    "third_party/boringssl/crypto/aes/aes.c",
+    "third_party/boringssl/crypto/aes/mode_wrappers.c",
+    "third_party/boringssl/crypto/asn1/a_bitstr.c",
+    "third_party/boringssl/crypto/asn1/a_bool.c",
+    "third_party/boringssl/crypto/asn1/a_bytes.c",
+    "third_party/boringssl/crypto/asn1/a_d2i_fp.c",
+    "third_party/boringssl/crypto/asn1/a_dup.c",
+    "third_party/boringssl/crypto/asn1/a_enum.c",
+    "third_party/boringssl/crypto/asn1/a_gentm.c",
+    "third_party/boringssl/crypto/asn1/a_i2d_fp.c",
+    "third_party/boringssl/crypto/asn1/a_int.c",
+    "third_party/boringssl/crypto/asn1/a_mbstr.c",
+    "third_party/boringssl/crypto/asn1/a_object.c",
+    "third_party/boringssl/crypto/asn1/a_octet.c",
+    "third_party/boringssl/crypto/asn1/a_print.c",
+    "third_party/boringssl/crypto/asn1/a_strnid.c",
+    "third_party/boringssl/crypto/asn1/a_time.c",
+    "third_party/boringssl/crypto/asn1/a_type.c",
+    "third_party/boringssl/crypto/asn1/a_utctm.c",
+    "third_party/boringssl/crypto/asn1/a_utf8.c",
+    "third_party/boringssl/crypto/asn1/asn1_lib.c",
+    "third_party/boringssl/crypto/asn1/asn1_par.c",
+    "third_party/boringssl/crypto/asn1/asn_pack.c",
+    "third_party/boringssl/crypto/asn1/bio_asn1.c",
+    "third_party/boringssl/crypto/asn1/bio_ndef.c",
+    "third_party/boringssl/crypto/asn1/f_enum.c",
+    "third_party/boringssl/crypto/asn1/f_int.c",
+    "third_party/boringssl/crypto/asn1/f_string.c",
+    "third_party/boringssl/crypto/asn1/t_bitst.c",
+    "third_party/boringssl/crypto/asn1/t_pkey.c",
+    "third_party/boringssl/crypto/asn1/tasn_dec.c",
+    "third_party/boringssl/crypto/asn1/tasn_enc.c",
+    "third_party/boringssl/crypto/asn1/tasn_fre.c",
+    "third_party/boringssl/crypto/asn1/tasn_new.c",
+    "third_party/boringssl/crypto/asn1/tasn_prn.c",
+    "third_party/boringssl/crypto/asn1/tasn_typ.c",
+    "third_party/boringssl/crypto/asn1/tasn_utl.c",
+    "third_party/boringssl/crypto/asn1/x_bignum.c",
+    "third_party/boringssl/crypto/asn1/x_long.c",
+    "third_party/boringssl/crypto/base64/base64.c",
+    "third_party/boringssl/crypto/bio/bio.c",
+    "third_party/boringssl/crypto/bio/bio_mem.c",
+    "third_party/boringssl/crypto/bio/buffer.c",
+    "third_party/boringssl/crypto/bio/connect.c",
+    "third_party/boringssl/crypto/bio/fd.c",
+    "third_party/boringssl/crypto/bio/file.c",
+    "third_party/boringssl/crypto/bio/hexdump.c",
+    "third_party/boringssl/crypto/bio/pair.c",
+    "third_party/boringssl/crypto/bio/printf.c",
+    "third_party/boringssl/crypto/bio/socket.c",
+    "third_party/boringssl/crypto/bio/socket_helper.c",
+    "third_party/boringssl/crypto/bn/add.c",
+    "third_party/boringssl/crypto/bn/asm/x86_64-gcc.c",
+    "third_party/boringssl/crypto/bn/bn.c",
+    "third_party/boringssl/crypto/bn/bn_asn1.c",
+    "third_party/boringssl/crypto/bn/cmp.c",
+    "third_party/boringssl/crypto/bn/convert.c",
+    "third_party/boringssl/crypto/bn/ctx.c",
+    "third_party/boringssl/crypto/bn/div.c",
+    "third_party/boringssl/crypto/bn/exponentiation.c",
+    "third_party/boringssl/crypto/bn/gcd.c",
+    "third_party/boringssl/crypto/bn/generic.c",
+    "third_party/boringssl/crypto/bn/kronecker.c",
+    "third_party/boringssl/crypto/bn/montgomery.c",
+    "third_party/boringssl/crypto/bn/mul.c",
+    "third_party/boringssl/crypto/bn/prime.c",
+    "third_party/boringssl/crypto/bn/random.c",
+    "third_party/boringssl/crypto/bn/rsaz_exp.c",
+    "third_party/boringssl/crypto/bn/shift.c",
+    "third_party/boringssl/crypto/bn/sqrt.c",
+    "third_party/boringssl/crypto/buf/buf.c",
+    "third_party/boringssl/crypto/bytestring/ber.c",
+    "third_party/boringssl/crypto/bytestring/cbb.c",
+    "third_party/boringssl/crypto/bytestring/cbs.c",
+    "third_party/boringssl/crypto/chacha/chacha_generic.c",
+    "third_party/boringssl/crypto/chacha/chacha_vec.c",
+    "third_party/boringssl/crypto/cipher/aead.c",
+    "third_party/boringssl/crypto/cipher/cipher.c",
+    "third_party/boringssl/crypto/cipher/derive_key.c",
+    "third_party/boringssl/crypto/cipher/e_aes.c",
+    "third_party/boringssl/crypto/cipher/e_chacha20poly1305.c",
+    "third_party/boringssl/crypto/cipher/e_des.c",
+    "third_party/boringssl/crypto/cipher/e_null.c",
+    "third_party/boringssl/crypto/cipher/e_rc2.c",
+    "third_party/boringssl/crypto/cipher/e_rc4.c",
+    "third_party/boringssl/crypto/cipher/e_ssl3.c",
+    "third_party/boringssl/crypto/cipher/e_tls.c",
+    "third_party/boringssl/crypto/cipher/tls_cbc.c",
+    "third_party/boringssl/crypto/cmac/cmac.c",
+    "third_party/boringssl/crypto/conf/conf.c",
+    "third_party/boringssl/crypto/cpu-arm.c",
+    "third_party/boringssl/crypto/cpu-intel.c",
+    "third_party/boringssl/crypto/crypto.c",
+    "third_party/boringssl/crypto/curve25519/curve25519.c",
+    "third_party/boringssl/crypto/des/des.c",
+    "third_party/boringssl/crypto/dh/check.c",
+    "third_party/boringssl/crypto/dh/dh.c",
+    "third_party/boringssl/crypto/dh/dh_asn1.c",
+    "third_party/boringssl/crypto/dh/params.c",
+    "third_party/boringssl/crypto/digest/digest.c",
+    "third_party/boringssl/crypto/digest/digests.c",
+    "third_party/boringssl/crypto/directory_posix.c",
+    "third_party/boringssl/crypto/directory_win.c",
+    "third_party/boringssl/crypto/dsa/dsa.c",
+    "third_party/boringssl/crypto/dsa/dsa_asn1.c",
+    "third_party/boringssl/crypto/ec/ec.c",
+    "third_party/boringssl/crypto/ec/ec_asn1.c",
+    "third_party/boringssl/crypto/ec/ec_key.c",
+    "third_party/boringssl/crypto/ec/ec_montgomery.c",
+    "third_party/boringssl/crypto/ec/oct.c",
+    "third_party/boringssl/crypto/ec/p224-64.c",
+    "third_party/boringssl/crypto/ec/p256-64.c",
+    "third_party/boringssl/crypto/ec/p256-x86_64.c",
+    "third_party/boringssl/crypto/ec/simple.c",
+    "third_party/boringssl/crypto/ec/util-64.c",
+    "third_party/boringssl/crypto/ec/wnaf.c",
+    "third_party/boringssl/crypto/ecdh/ecdh.c",
+    "third_party/boringssl/crypto/ecdsa/ecdsa.c",
+    "third_party/boringssl/crypto/ecdsa/ecdsa_asn1.c",
+    "third_party/boringssl/crypto/engine/engine.c",
+    "third_party/boringssl/crypto/err/err.c",
+    "third_party/boringssl/crypto/evp/algorithm.c",
+    "third_party/boringssl/crypto/evp/digestsign.c",
+    "third_party/boringssl/crypto/evp/evp.c",
+    "third_party/boringssl/crypto/evp/evp_asn1.c",
+    "third_party/boringssl/crypto/evp/evp_ctx.c",
+    "third_party/boringssl/crypto/evp/p_dsa_asn1.c",
+    "third_party/boringssl/crypto/evp/p_ec.c",
+    "third_party/boringssl/crypto/evp/p_ec_asn1.c",
+    "third_party/boringssl/crypto/evp/p_rsa.c",
+    "third_party/boringssl/crypto/evp/p_rsa_asn1.c",
+    "third_party/boringssl/crypto/evp/pbkdf.c",
+    "third_party/boringssl/crypto/evp/sign.c",
+    "third_party/boringssl/crypto/ex_data.c",
+    "third_party/boringssl/crypto/hkdf/hkdf.c",
+    "third_party/boringssl/crypto/hmac/hmac.c",
+    "third_party/boringssl/crypto/lhash/lhash.c",
+    "third_party/boringssl/crypto/md4/md4.c",
+    "third_party/boringssl/crypto/md5/md5.c",
+    "third_party/boringssl/crypto/mem.c",
+    "third_party/boringssl/crypto/modes/cbc.c",
+    "third_party/boringssl/crypto/modes/cfb.c",
+    "third_party/boringssl/crypto/modes/ctr.c",
+    "third_party/boringssl/crypto/modes/gcm.c",
+    "third_party/boringssl/crypto/modes/ofb.c",
+    "third_party/boringssl/crypto/obj/obj.c",
+    "third_party/boringssl/crypto/obj/obj_xref.c",
+    "third_party/boringssl/crypto/pem/pem_all.c",
+    "third_party/boringssl/crypto/pem/pem_info.c",
+    "third_party/boringssl/crypto/pem/pem_lib.c",
+    "third_party/boringssl/crypto/pem/pem_oth.c",
+    "third_party/boringssl/crypto/pem/pem_pk8.c",
+    "third_party/boringssl/crypto/pem/pem_pkey.c",
+    "third_party/boringssl/crypto/pem/pem_x509.c",
+    "third_party/boringssl/crypto/pem/pem_xaux.c",
+    "third_party/boringssl/crypto/pkcs8/p5_pbe.c",
+    "third_party/boringssl/crypto/pkcs8/p5_pbev2.c",
+    "third_party/boringssl/crypto/pkcs8/p8_pkey.c",
+    "third_party/boringssl/crypto/pkcs8/pkcs8.c",
+    "third_party/boringssl/crypto/poly1305/poly1305.c",
+    "third_party/boringssl/crypto/poly1305/poly1305_arm.c",
+    "third_party/boringssl/crypto/poly1305/poly1305_vec.c",
+    "third_party/boringssl/crypto/rand/rand.c",
+    "third_party/boringssl/crypto/rand/urandom.c",
+    "third_party/boringssl/crypto/rand/windows.c",
+    "third_party/boringssl/crypto/rc4/rc4.c",
+    "third_party/boringssl/crypto/refcount_c11.c",
+    "third_party/boringssl/crypto/refcount_lock.c",
+    "third_party/boringssl/crypto/rsa/blinding.c",
+    "third_party/boringssl/crypto/rsa/padding.c",
+    "third_party/boringssl/crypto/rsa/rsa.c",
+    "third_party/boringssl/crypto/rsa/rsa_asn1.c",
+    "third_party/boringssl/crypto/rsa/rsa_impl.c",
+    "third_party/boringssl/crypto/sha/sha1.c",
+    "third_party/boringssl/crypto/sha/sha256.c",
+    "third_party/boringssl/crypto/sha/sha512.c",
+    "third_party/boringssl/crypto/stack/stack.c",
+    "third_party/boringssl/crypto/thread.c",
+    "third_party/boringssl/crypto/thread_none.c",
+    "third_party/boringssl/crypto/thread_pthread.c",
+    "third_party/boringssl/crypto/thread_win.c",
+    "third_party/boringssl/crypto/time_support.c",
+    "third_party/boringssl/crypto/x509/a_digest.c",
+    "third_party/boringssl/crypto/x509/a_sign.c",
+    "third_party/boringssl/crypto/x509/a_strex.c",
+    "third_party/boringssl/crypto/x509/a_verify.c",
+    "third_party/boringssl/crypto/x509/asn1_gen.c",
+    "third_party/boringssl/crypto/x509/by_dir.c",
+    "third_party/boringssl/crypto/x509/by_file.c",
+    "third_party/boringssl/crypto/x509/i2d_pr.c",
+    "third_party/boringssl/crypto/x509/pkcs7.c",
+    "third_party/boringssl/crypto/x509/t_crl.c",
+    "third_party/boringssl/crypto/x509/t_req.c",
+    "third_party/boringssl/crypto/x509/t_x509.c",
+    "third_party/boringssl/crypto/x509/t_x509a.c",
+    "third_party/boringssl/crypto/x509/x509.c",
+    "third_party/boringssl/crypto/x509/x509_att.c",
+    "third_party/boringssl/crypto/x509/x509_cmp.c",
+    "third_party/boringssl/crypto/x509/x509_d2.c",
+    "third_party/boringssl/crypto/x509/x509_def.c",
+    "third_party/boringssl/crypto/x509/x509_ext.c",
+    "third_party/boringssl/crypto/x509/x509_lu.c",
+    "third_party/boringssl/crypto/x509/x509_obj.c",
+    "third_party/boringssl/crypto/x509/x509_r2x.c",
+    "third_party/boringssl/crypto/x509/x509_req.c",
+    "third_party/boringssl/crypto/x509/x509_set.c",
+    "third_party/boringssl/crypto/x509/x509_trs.c",
+    "third_party/boringssl/crypto/x509/x509_txt.c",
+    "third_party/boringssl/crypto/x509/x509_v3.c",
+    "third_party/boringssl/crypto/x509/x509_vfy.c",
+    "third_party/boringssl/crypto/x509/x509_vpm.c",
+    "third_party/boringssl/crypto/x509/x509cset.c",
+    "third_party/boringssl/crypto/x509/x509name.c",
+    "third_party/boringssl/crypto/x509/x509rset.c",
+    "third_party/boringssl/crypto/x509/x509spki.c",
+    "third_party/boringssl/crypto/x509/x509type.c",
+    "third_party/boringssl/crypto/x509/x_algor.c",
+    "third_party/boringssl/crypto/x509/x_all.c",
+    "third_party/boringssl/crypto/x509/x_attrib.c",
+    "third_party/boringssl/crypto/x509/x_crl.c",
+    "third_party/boringssl/crypto/x509/x_exten.c",
+    "third_party/boringssl/crypto/x509/x_info.c",
+    "third_party/boringssl/crypto/x509/x_name.c",
+    "third_party/boringssl/crypto/x509/x_pkey.c",
+    "third_party/boringssl/crypto/x509/x_pubkey.c",
+    "third_party/boringssl/crypto/x509/x_req.c",
+    "third_party/boringssl/crypto/x509/x_sig.c",
+    "third_party/boringssl/crypto/x509/x_spki.c",
+    "third_party/boringssl/crypto/x509/x_val.c",
+    "third_party/boringssl/crypto/x509/x_x509.c",
+    "third_party/boringssl/crypto/x509/x_x509a.c",
+    "third_party/boringssl/crypto/x509v3/pcy_cache.c",
+    "third_party/boringssl/crypto/x509v3/pcy_data.c",
+    "third_party/boringssl/crypto/x509v3/pcy_lib.c",
+    "third_party/boringssl/crypto/x509v3/pcy_map.c",
+    "third_party/boringssl/crypto/x509v3/pcy_node.c",
+    "third_party/boringssl/crypto/x509v3/pcy_tree.c",
+    "third_party/boringssl/crypto/x509v3/v3_akey.c",
+    "third_party/boringssl/crypto/x509v3/v3_akeya.c",
+    "third_party/boringssl/crypto/x509v3/v3_alt.c",
+    "third_party/boringssl/crypto/x509v3/v3_bcons.c",
+    "third_party/boringssl/crypto/x509v3/v3_bitst.c",
+    "third_party/boringssl/crypto/x509v3/v3_conf.c",
+    "third_party/boringssl/crypto/x509v3/v3_cpols.c",
+    "third_party/boringssl/crypto/x509v3/v3_crld.c",
+    "third_party/boringssl/crypto/x509v3/v3_enum.c",
+    "third_party/boringssl/crypto/x509v3/v3_extku.c",
+    "third_party/boringssl/crypto/x509v3/v3_genn.c",
+    "third_party/boringssl/crypto/x509v3/v3_ia5.c",
+    "third_party/boringssl/crypto/x509v3/v3_info.c",
+    "third_party/boringssl/crypto/x509v3/v3_int.c",
+    "third_party/boringssl/crypto/x509v3/v3_lib.c",
+    "third_party/boringssl/crypto/x509v3/v3_ncons.c",
+    "third_party/boringssl/crypto/x509v3/v3_pci.c",
+    "third_party/boringssl/crypto/x509v3/v3_pcia.c",
+    "third_party/boringssl/crypto/x509v3/v3_pcons.c",
+    "third_party/boringssl/crypto/x509v3/v3_pku.c",
+    "third_party/boringssl/crypto/x509v3/v3_pmaps.c",
+    "third_party/boringssl/crypto/x509v3/v3_prn.c",
+    "third_party/boringssl/crypto/x509v3/v3_purp.c",
+    "third_party/boringssl/crypto/x509v3/v3_skey.c",
+    "third_party/boringssl/crypto/x509v3/v3_sxnet.c",
+    "third_party/boringssl/crypto/x509v3/v3_utl.c",
+    "third_party/boringssl/ssl/custom_extensions.c",
+    "third_party/boringssl/ssl/d1_both.c",
+    "third_party/boringssl/ssl/d1_clnt.c",
+    "third_party/boringssl/ssl/d1_lib.c",
+    "third_party/boringssl/ssl/d1_meth.c",
+    "third_party/boringssl/ssl/d1_pkt.c",
+    "third_party/boringssl/ssl/d1_srtp.c",
+    "third_party/boringssl/ssl/d1_srvr.c",
+    "third_party/boringssl/ssl/dtls_record.c",
+    "third_party/boringssl/ssl/pqueue/pqueue.c",
+    "third_party/boringssl/ssl/s3_both.c",
+    "third_party/boringssl/ssl/s3_clnt.c",
+    "third_party/boringssl/ssl/s3_enc.c",
+    "third_party/boringssl/ssl/s3_lib.c",
+    "third_party/boringssl/ssl/s3_meth.c",
+    "third_party/boringssl/ssl/s3_pkt.c",
+    "third_party/boringssl/ssl/s3_srvr.c",
+    "third_party/boringssl/ssl/ssl_aead_ctx.c",
+    "third_party/boringssl/ssl/ssl_asn1.c",
+    "third_party/boringssl/ssl/ssl_buffer.c",
+    "third_party/boringssl/ssl/ssl_cert.c",
+    "third_party/boringssl/ssl/ssl_cipher.c",
+    "third_party/boringssl/ssl/ssl_file.c",
+    "third_party/boringssl/ssl/ssl_lib.c",
+    "third_party/boringssl/ssl/ssl_rsa.c",
+    "third_party/boringssl/ssl/ssl_session.c",
+    "third_party/boringssl/ssl/ssl_stat.c",
+    "third_party/boringssl/ssl/t1_enc.c",
+    "third_party/boringssl/ssl/t1_lib.c",
+    "third_party/boringssl/ssl/tls_record.c",
     "binding.gyp"
   ],
   "main": "src/node/index.js",
diff --git a/setup.py b/setup.py
index c54ac22..01e9180 100644
--- a/setup.py
+++ b/setup.py
@@ -49,7 +49,7 @@
 
 # Ensure we're in the proper directory whether or not we're being used by pip.
 os.chdir(os.path.dirname(os.path.abspath(__file__)))
-sys.path.insert(0, PYTHON_STEM)
+sys.path.insert(0, os.path.abspath(PYTHON_STEM))
 
 # Break import-style to ensure we can actually find our in-repo dependencies.
 import commands
@@ -119,6 +119,7 @@
 }
 
 INSTALL_REQUIRES = (
+    'six>=1.10',
     'enum34>=1.0.4',
     'futures>=2.2.0',
     # TODO(atash): eventually split the grpcio package into a metapackage
@@ -131,6 +132,7 @@
 ) + INSTALL_REQUIRES
 
 COMMAND_CLASS = {
+    'install': commands.Install,
     'doc': commands.SphinxDocumentation,
     'build_proto_modules': commands.BuildProtoModules,
     'build_project_metadata': commands.BuildProjectMetadata,
@@ -138,6 +140,7 @@
     'build_ext': commands.BuildExt,
     'gather': commands.Gather,
     'run_interop': commands.RunInterop,
+    'bdist_egg_grpc_custom': commands.BdistEggCustomName,
 }
 
 # Ensure that package data is copied over before any commands have been run:
@@ -187,7 +190,7 @@
 
 setuptools.setup(
     name='grpcio',
-    version='0.12.0b5',
+    version='0.12.0b6',
     license=LICENSE,
     ext_modules=CYTHON_EXTENSION_MODULES,
     packages=list(PACKAGES),
diff --git a/src/boringssl/gen_build_yaml.py b/src/boringssl/gen_build_yaml.py
index b635ee4..7c7a579 100755
--- a/src/boringssl/gen_build_yaml.py
+++ b/src/boringssl/gen_build_yaml.py
@@ -82,6 +82,7 @@
               for f in files['ssl_headers'] + files['ssl_internal_headers'] + files['crypto_headers'] + files['crypto_internal_headers']
             ),
             'boringssl': True,
+            'defaults': 'boringssl',
           },
           {
             'name': 'boringssl_test_util',
@@ -89,6 +90,7 @@
             'language': 'c++',
             'secure': 'no',
             'boringssl': True,
+            'defaults': 'boringssl',
             'src': [
               map_dir(f)
               for f in sorted(files['test_support'])
@@ -103,6 +105,7 @@
             'src': [map_dir(test)],
             'vs_proj_dir': 'test/boringssl',
             'boringssl': True,
+            'defaults': 'boringssl',
             'deps': [
                 'boringssl_test_util',
                 'boringssl',
@@ -120,6 +123,7 @@
             'src': [],
             'vs_proj_dir': 'test/boringssl',
             'boringssl': True,
+            'defaults': 'boringssl',
             'deps': [
                 'boringssl_%s_lib' % os.path.splitext(os.path.basename(test))[0],
                 'boringssl_test_util',
@@ -138,6 +142,7 @@
             'flaky': False,
             'language': 'c++',
             'boringssl': True,
+            'defaults': 'boringssl',
             'cpu_cost': 1.0
           }
           for test in files['tests']
diff --git a/src/core/census/initialize.c b/src/core/census/initialize.c
index b7af714..ce7ec09 100644
--- a/src/core/census/initialize.c
+++ b/src/core/census/initialize.c
@@ -37,9 +37,7 @@
 
 int census_initialize(int features) {
   if (features_enabled != CENSUS_FEATURE_NONE) {
-    return 1;
-  }
-  if (features == CENSUS_FEATURE_NONE) {
+    // Must have been a previous call to census_initialize; return error
     return 1;
   }
   features_enabled = features;
diff --git a/src/core/channel/channel_args.c b/src/core/channel/channel_args.c
index 63e440f..055b020 100644
--- a/src/core/channel/channel_args.c
+++ b/src/core/channel/channel_args.c
@@ -35,6 +35,7 @@
 #include "src/core/channel/channel_args.h"
 #include "src/core/support/string.h"
 
+#include <grpc/census.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
@@ -168,10 +169,10 @@
   if (a == NULL) return 0;
   for (i = 0; i < a->num_args; i++) {
     if (0 == strcmp(a->args[i].key, GRPC_ARG_ENABLE_CENSUS)) {
-      return a->args[i].value.integer != 0;
+      return a->args[i].value.integer != 0 && census_enabled();
     }
   }
-  return 0;
+  return census_enabled();
 }
 
 grpc_compression_algorithm grpc_channel_args_get_compression_algorithm(
diff --git a/src/core/client_config/lb_policies/pick_first.c b/src/core/client_config/lb_policies/pick_first.c
index e6ddb1a..5b10600 100644
--- a/src/core/client_config/lb_policies/pick_first.c
+++ b/src/core/client_config/lb_policies/pick_first.c
@@ -76,7 +76,7 @@
 } pick_first_lb_policy;
 
 #define GET_SELECTED(p) \
-  ((grpc_connected_subchannel *)gpr_atm_no_barrier_load(&(p)->selected))
+  ((grpc_connected_subchannel *)gpr_atm_acq_load(&(p)->selected))
 
 void pf_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
   pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
@@ -268,10 +268,10 @@
         selected =
             grpc_subchannel_get_connected_subchannel(selected_subchannel);
         GPR_ASSERT(selected != NULL);
-        gpr_atm_no_barrier_store(&p->selected, (gpr_atm)selected);
         GRPC_CONNECTED_SUBCHANNEL_REF(selected, "picked_first");
         /* drop the pick list: we are connected now */
         GRPC_LB_POLICY_WEAK_REF(&p->base, "destroy_subchannels");
+        gpr_atm_rel_store(&p->selected, (gpr_atm)selected);
         grpc_exec_ctx_enqueue(exec_ctx,
                               grpc_closure_create(destroy_subchannels, p), 1);
         /* update any calls that were waiting for a pick */
diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c
index 145e146..ef58fc0 100644
--- a/src/core/client_config/subchannel.c
+++ b/src/core/client_config/subchannel.c
@@ -317,9 +317,13 @@
   c->connector = connector;
   grpc_connector_ref(c->connector);
   c->num_filters = args->filter_count;
-  c->filters = gpr_malloc(sizeof(grpc_channel_filter *) * c->num_filters);
-  memcpy((void *)c->filters, args->filters,
-         sizeof(grpc_channel_filter *) * c->num_filters);
+  if (c->num_filters > 0) {
+    c->filters = gpr_malloc(sizeof(grpc_channel_filter *) * c->num_filters);
+    memcpy((void *)c->filters, args->filters,
+           sizeof(grpc_channel_filter *) * c->num_filters);
+  } else {
+    c->filters = NULL;
+  }
   c->addr = gpr_malloc(args->addr_len);
   memcpy(c->addr, args->addr, args->addr_len);
   grpc_pollset_set_init(&c->pollset_set);
@@ -517,7 +521,9 @@
   /* build final filter list */
   num_filters = c->num_filters + c->connecting_result.num_filters + 1;
   filters = gpr_malloc(sizeof(*filters) * num_filters);
-  memcpy((void *)filters, c->filters, sizeof(*filters) * c->num_filters);
+  if (c->num_filters > 0) {
+    memcpy((void *)filters, c->filters, sizeof(*filters) * c->num_filters);
+  }
   memcpy((void *)(filters + c->num_filters), c->connecting_result.filters,
          sizeof(*filters) * c->connecting_result.num_filters);
   filters[num_filters - 1] = &grpc_connected_channel_filter;
@@ -553,7 +559,12 @@
   }
 
   /* publish */
-  GPR_ASSERT(gpr_atm_no_barrier_cas(&c->connected_subchannel, 0, (gpr_atm)con));
+  /* 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));
   c->connecting = 0;
 
   /* setup subchannel watching connected subchannel for changes; subchannel ref
diff --git a/src/core/iomgr/iocp_windows.c b/src/core/iomgr/iocp_windows.c
index d3868ce..6cbe7d2 100644
--- a/src/core/iomgr/iocp_windows.c
+++ b/src/core/iomgr/iocp_windows.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -67,7 +67,7 @@
     return 0;
   }
   timeout = gpr_time_sub(deadline, now);
-  return gpr_time_to_millis(gpr_time_add(
+  return (DWORD)gpr_time_to_millis(gpr_time_add(
       timeout, gpr_time_from_nanos(GPR_NS_PER_MS - 1, GPR_TIMESPAN)));
 }
 
@@ -179,11 +179,9 @@
 static void socket_notify_on_iocp(grpc_exec_ctx *exec_ctx,
                                   grpc_winsocket *socket, grpc_closure *closure,
                                   grpc_winsocket_callback_info *info) {
-  int run_now = 0;
   GPR_ASSERT(info->closure == NULL);
   gpr_mu_lock(&socket->state_mu);
   if (info->has_pending_iocp) {
-    run_now = 1;
     info->has_pending_iocp = 0;
     grpc_exec_ctx_enqueue(exec_ctx, closure, 1);
   } else {
diff --git a/src/core/iomgr/pollset_windows.c b/src/core/iomgr/pollset_windows.c
index deb6615..bfd9e69 100644
--- a/src/core/iomgr/pollset_windows.c
+++ b/src/core/iomgr/pollset_windows.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -81,15 +81,6 @@
   }
 }
 
-static void push_back_worker(grpc_pollset_worker *root,
-                             grpc_pollset_worker_link_type type,
-                             grpc_pollset_worker *worker) {
-  worker->links[type].next = root;
-  worker->links[type].prev = worker->links[type].next->links[type].prev;
-  worker->links[type].prev->links[type].next =
-      worker->links[type].next->links[type].prev = worker;
-}
-
 static void push_front_worker(grpc_pollset_worker *root,
                               grpc_pollset_worker_link_type type,
                               grpc_pollset_worker *worker) {
diff --git a/src/core/iomgr/sockaddr_win32.h b/src/core/iomgr/sockaddr_win32.h
index fe2be99..8e3946a 100644
--- a/src/core/iomgr/sockaddr_win32.h
+++ b/src/core/iomgr/sockaddr_win32.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,9 +38,4 @@
 #include <ws2tcpip.h>
 #include <mswsock.h>
 
-#ifdef __MINGW32__
-/* mingw seems to be missing that definition. */
-const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
-#endif
-
 #endif /* GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_WIN32_H */
diff --git a/src/core/iomgr/tcp_server.h b/src/core/iomgr/tcp_server.h
index 3294e13..8f3184f 100644
--- a/src/core/iomgr/tcp_server.h
+++ b/src/core/iomgr/tcp_server.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,28 +34,39 @@
 #ifndef GRPC_INTERNAL_CORE_IOMGR_TCP_SERVER_H
 #define GRPC_INTERNAL_CORE_IOMGR_TCP_SERVER_H
 
+#include "src/core/iomgr/closure.h"
 #include "src/core/iomgr/endpoint.h"
 
 /* Forward decl of grpc_tcp_server */
 typedef struct grpc_tcp_server grpc_tcp_server;
 
-/* Forward decl of grpc_tcp_listener */
-typedef struct grpc_tcp_listener grpc_tcp_listener;
+typedef struct grpc_tcp_server_acceptor grpc_tcp_server_acceptor;
+struct grpc_tcp_server_acceptor {
+  /* grpc_tcp_server_cb functions share a ref on from_server that is valid
+     until the function returns. */
+  grpc_tcp_server *from_server;
+  /* Indices that may be passed to grpc_tcp_server_port_fd(). */
+  unsigned port_index;
+  unsigned fd_index;
+};
 
 /* Called for newly connected TCP connections. */
 typedef void (*grpc_tcp_server_cb)(grpc_exec_ctx *exec_ctx, void *arg,
-                                   grpc_endpoint *ep);
+                                   grpc_endpoint *ep,
+                                   grpc_tcp_server_acceptor *acceptor);
 
-/* Create a server, initially not bound to any ports */
-grpc_tcp_server *grpc_tcp_server_create(void);
+/* Create a server, initially not bound to any ports. The caller owns one ref.
+   If shutdown_complete is not NULL, it will be used by
+   grpc_tcp_server_unref(). */
+grpc_tcp_server *grpc_tcp_server_create(grpc_closure *shutdown_complete);
 
 /* Start listening to bound ports */
 void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *server,
                            grpc_pollset **pollsets, size_t pollset_count,
                            grpc_tcp_server_cb on_accept_cb, void *cb_arg);
 
-/* Add a port to the server, returning the newly created listener on success,
-   or a null pointer on failure.
+/* Add a port to the server, returning the newly allocated port on success, or
+   -1 on failure.
 
    The :: and 0.0.0.0 wildcard addresses are treated identically, accepting
    both IPv4 and IPv6 connections, but :: is the preferred style.  This usually
@@ -63,21 +74,31 @@
    but not dualstack sockets. */
 /* TODO(ctiller): deprecate this, and make grpc_tcp_server_add_ports to handle
                   all of the multiple socket port matching logic in one place */
-grpc_tcp_listener *grpc_tcp_server_add_port(grpc_tcp_server *s,
-                                            const void *addr, size_t addr_len);
+int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
+                             size_t addr_len);
 
-/* Returns the file descriptor of the Nth listening socket on this server,
-   or -1 if the index is out of bounds.
+/* Number of fds at the given port_index, or 0 if port_index is out of
+   bounds. */
+unsigned grpc_tcp_server_port_fd_count(grpc_tcp_server *s, unsigned port_index);
 
-   The file descriptor remains owned by the server, and will be cleaned
-   up when grpc_tcp_server_destroy is called. */
-int grpc_tcp_server_get_fd(grpc_tcp_server *s, unsigned index);
+/* Returns the file descriptor of the Mth (fd_index) listening socket of the Nth
+   (port_index) call to add_port() on this server, or -1 if the indices are out
+   of bounds. The file descriptor remains owned by the server, and will be
+   cleaned up when grpc_tcp_server_destroy is called. */
+int grpc_tcp_server_port_fd(grpc_tcp_server *s, unsigned port_index,
+                            unsigned fd_index);
 
-void grpc_tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *server,
-                             grpc_closure *closure);
+/* Ref s and return s. */
+grpc_tcp_server *grpc_tcp_server_ref(grpc_tcp_server *s);
 
-int grpc_tcp_listener_get_port(grpc_tcp_listener *listener);
-void grpc_tcp_listener_ref(grpc_tcp_listener *listener);
-void grpc_tcp_listener_unref(grpc_tcp_listener *listener);
+/* shutdown_starting is called when ref count has reached zero and the server is
+   about to be destroyed. The server will be deleted after it returns. Calling
+   grpc_tcp_server_ref() from it has no effect. */
+void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s,
+                                           grpc_closure *shutdown_starting);
+
+/* If the recount drops to zero, delete s, and call (exec_ctx==NULL) or enqueue
+   a call (exec_ctx!=NULL) to shutdown_complete. */
+void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s);
 
 #endif /* GRPC_INTERNAL_CORE_IOMGR_TCP_SERVER_H */
diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c
index 49e83cf..adf14ae 100644
--- a/src/core/iomgr/tcp_server_posix.c
+++ b/src/core/iomgr/tcp_server_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -73,6 +73,7 @@
 static int s_max_accept_queue_size;
 
 /* one listening port */
+typedef struct grpc_tcp_listener grpc_tcp_listener;
 struct grpc_tcp_listener {
   int fd;
   grpc_fd *emfd;
@@ -84,9 +85,10 @@
   } addr;
   size_t addr_len;
   int port;
+  unsigned port_index;
+  unsigned fd_index;
   grpc_closure read_closure;
   grpc_closure destroyed_closure;
-  gpr_refcount refs;
   struct grpc_tcp_listener *next;
   /* When we add a listener, more than one can be created, mainly because of
      IPv6. A sibling will still be in the normal list, but will be flagged
@@ -106,6 +108,7 @@
 
 /* the overall server */
 struct grpc_tcp_server {
+  gpr_refcount refs;
   /* Called whenever accept() succeeds on a server port. */
   grpc_tcp_server_cb on_accept_cb;
   void *on_accept_cb_arg;
@@ -122,8 +125,12 @@
 
   /* linked list of server ports */
   grpc_tcp_listener *head;
+  grpc_tcp_listener *tail;
   unsigned nports;
 
+  /* List of closures passed to shutdown_starting_add(). */
+  grpc_closure_list shutdown_starting;
+
   /* shutdown callback */
   grpc_closure *shutdown_complete;
 
@@ -133,28 +140,35 @@
   size_t pollset_count;
 };
 
-grpc_tcp_server *grpc_tcp_server_create(void) {
+grpc_tcp_server *grpc_tcp_server_create(grpc_closure *shutdown_complete) {
   grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server));
+  gpr_ref_init(&s->refs, 1);
   gpr_mu_init(&s->mu);
   s->active_ports = 0;
   s->destroyed_ports = 0;
   s->shutdown = 0;
+  s->shutdown_starting.head = NULL;
+  s->shutdown_starting.tail = NULL;
+  s->shutdown_complete = shutdown_complete;
   s->on_accept_cb = NULL;
   s->on_accept_cb_arg = NULL;
   s->head = NULL;
+  s->tail = NULL;
   s->nports = 0;
   return s;
 }
 
 static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
-  grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, 1);
+  if (s->shutdown_complete != NULL) {
+    grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, 1);
+  }
 
   gpr_mu_destroy(&s->mu);
 
   while (s->head) {
     grpc_tcp_listener *sp = s->head;
     s->head = sp->next;
-    grpc_tcp_listener_unref(sp);
+    gpr_free(sp);
   }
 
   gpr_free(s);
@@ -203,15 +217,12 @@
   }
 }
 
-void grpc_tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
-                             grpc_closure *closure) {
+static void tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
   gpr_mu_lock(&s->mu);
 
   GPR_ASSERT(!s->shutdown);
   s->shutdown = 1;
 
-  s->shutdown_complete = closure;
-
   /* shutdown all fd's */
   if (s->active_ports) {
     grpc_tcp_listener *sp;
@@ -308,6 +319,8 @@
 /* event manager callback when reads are ready */
 static void on_read(grpc_exec_ctx *exec_ctx, void *arg, int success) {
   grpc_tcp_listener *sp = arg;
+  grpc_tcp_server_acceptor acceptor = {sp->server, sp->port_index,
+                                       sp->fd_index};
   grpc_fd *fdobj;
   size_t i;
 
@@ -355,7 +368,8 @@
     }
     sp->server->on_accept_cb(
         exec_ctx, sp->server->on_accept_cb_arg,
-        grpc_tcp_create(fdobj, GRPC_TCP_DEFAULT_READ_SLICE_SIZE, addr_str));
+        grpc_tcp_create(fdobj, GRPC_TCP_DEFAULT_READ_SLICE_SIZE, addr_str),
+        &acceptor);
 
     gpr_free(name);
     gpr_free(addr_str);
@@ -375,7 +389,9 @@
 
 static grpc_tcp_listener *add_socket_to_server(grpc_tcp_server *s, int fd,
                                                const struct sockaddr *addr,
-                                               size_t addr_len) {
+                                               size_t addr_len,
+                                               unsigned port_index,
+                                               unsigned fd_index) {
   grpc_tcp_listener *sp = NULL;
   int port;
   char *addr_str;
@@ -389,17 +405,23 @@
     s->nports++;
     GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server");
     sp = gpr_malloc(sizeof(grpc_tcp_listener));
-    sp->next = s->head;
-    s->head = sp;
+    sp->next = NULL;
+    if (s->head == NULL) {
+      s->head = sp;
+    } else {
+      s->tail->next = sp;
+    }
+    s->tail = sp;
     sp->server = s;
     sp->fd = fd;
     sp->emfd = grpc_fd_create(fd, name);
     memcpy(sp->addr.untyped, addr, addr_len);
     sp->addr_len = addr_len;
     sp->port = port;
+    sp->port_index = port_index;
+    sp->fd_index = fd_index;
     sp->is_sibling = 0;
     sp->sibling = NULL;
-    gpr_ref_init(&sp->refs, 1);
     GPR_ASSERT(sp->emfd);
     gpr_mu_unlock(&s->mu);
     gpr_free(addr_str);
@@ -409,8 +431,8 @@
   return sp;
 }
 
-grpc_tcp_listener *grpc_tcp_server_add_port(grpc_tcp_server *s,
-                                            const void *addr, size_t addr_len) {
+int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
+                             size_t addr_len) {
   grpc_tcp_listener *sp;
   grpc_tcp_listener *sp2 = NULL;
   int fd;
@@ -423,7 +445,11 @@
   struct sockaddr_storage sockname_temp;
   socklen_t sockname_len;
   int port;
-
+  unsigned port_index = 0;
+  unsigned fd_index = 0;
+  if (s->tail != NULL) {
+    port_index = s->tail->port_index + 1;
+  }
   if (((struct sockaddr *)addr)->sa_family == AF_UNIX) {
     unlink_if_unix_domain_socket(addr);
   }
@@ -462,11 +488,13 @@
     addr = (struct sockaddr *)&wild6;
     addr_len = sizeof(wild6);
     fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode);
-    sp = add_socket_to_server(s, fd, addr, addr_len);
+    sp = add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index);
     if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
       goto done;
     }
-
+    if (sp != NULL) {
+      ++fd_index;
+    }
     /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
     if (port == 0 && sp != NULL) {
       grpc_sockaddr_set_port((struct sockaddr *)&wild4, sp->port);
@@ -485,20 +513,46 @@
     addr = (struct sockaddr *)&addr4_copy;
     addr_len = sizeof(addr4_copy);
   }
-  sp = add_socket_to_server(s, fd, addr, addr_len);
-  if (sp != NULL) sp->sibling = sp2;
-  if (sp2 != NULL) sp2->is_sibling = 1;
+  sp = add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index);
+  if (sp2 != NULL && sp != NULL) {
+    sp2->sibling = sp;
+    sp->is_sibling = 1;
+  }
 
 done:
   gpr_free(allocated_addr);
-  return sp;
+  if (sp != NULL) {
+    return sp->port;
+  } else {
+    return -1;
+  }
 }
 
-int grpc_tcp_server_get_fd(grpc_tcp_server *s, unsigned port_index) {
+unsigned grpc_tcp_server_port_fd_count(grpc_tcp_server *s,
+                                       unsigned port_index) {
+  unsigned num_fds = 0;
   grpc_tcp_listener *sp;
-  for (sp = s->head; sp && port_index != 0; sp = sp->next, port_index--)
+  for (sp = s->head; sp && port_index != 0; sp = sp->next) {
+    if (!sp->is_sibling) {
+      --port_index;
+    }
+  }
+  for (; sp; sp = sp->sibling, ++num_fds)
     ;
-  if (port_index == 0 && sp) {
+  return num_fds;
+}
+
+int grpc_tcp_server_port_fd(grpc_tcp_server *s, unsigned port_index,
+                            unsigned fd_index) {
+  grpc_tcp_listener *sp;
+  for (sp = s->head; sp && port_index != 0; sp = sp->next) {
+    if (!sp->is_sibling) {
+      --port_index;
+    }
+  }
+  for (; sp && fd_index != 0; sp = sp->sibling, --fd_index)
+    ;
+  if (sp) {
     return sp->fd;
   } else {
     return -1;
@@ -531,31 +585,33 @@
   gpr_mu_unlock(&s->mu);
 }
 
-int grpc_tcp_listener_get_port(grpc_tcp_listener *listener) {
-  if (listener != NULL) {
-    grpc_tcp_listener *sp = listener;
-    return sp->port;
-  } else {
-    return 0;
-  }
+grpc_tcp_server *grpc_tcp_server_ref(grpc_tcp_server *s) {
+  gpr_ref(&s->refs);
+  return s;
 }
 
-void grpc_tcp_listener_ref(grpc_tcp_listener *listener) {
-  grpc_tcp_listener *sp = listener;
-  gpr_ref(&sp->refs);
+void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s,
+                                           grpc_closure *shutdown_starting) {
+  gpr_mu_lock(&s->mu);
+  grpc_closure_list_add(&s->shutdown_starting, shutdown_starting, 1);
+  gpr_mu_unlock(&s->mu);
 }
 
-void grpc_tcp_listener_unref(grpc_tcp_listener *listener) {
-  grpc_tcp_listener *sp = listener;
-  if (sp->is_sibling) return;
-  if (gpr_unref(&sp->refs)) {
-    grpc_tcp_listener *sibling = sp->sibling;
-    while (sibling) {
-      sp = sibling;
-      sibling = sp->sibling;
-      gpr_free(sp);
+void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
+  if (gpr_unref(&s->refs)) {
+    /* Complete shutdown_starting work before destroying. */
+    grpc_exec_ctx local_exec_ctx = GRPC_EXEC_CTX_INIT;
+    gpr_mu_lock(&s->mu);
+    grpc_exec_ctx_enqueue_list(&local_exec_ctx, &s->shutdown_starting);
+    gpr_mu_unlock(&s->mu);
+    if (exec_ctx == NULL) {
+      grpc_exec_ctx_flush(&local_exec_ctx);
+      tcp_server_destroy(&local_exec_ctx, s);
+      grpc_exec_ctx_finish(&local_exec_ctx);
+    } else {
+      grpc_exec_ctx_finish(&local_exec_ctx);
+      tcp_server_destroy(exec_ctx, s);
     }
-    gpr_free(listener);
   }
 }
 
diff --git a/src/core/iomgr/tcp_server_windows.c b/src/core/iomgr/tcp_server_windows.c
index d38fd88..00d381f 100644
--- a/src/core/iomgr/tcp_server_windows.c
+++ b/src/core/iomgr/tcp_server_windows.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -55,6 +55,7 @@
 #define MIN_SAFE_ACCEPT_QUEUE_SIZE 100
 
 /* one listening port */
+typedef struct grpc_tcp_listener grpc_tcp_listener;
 struct grpc_tcp_listener {
   /* This seemingly magic number comes from AcceptEx's documentation. each
      address buffer needs to have at least 16 more bytes at their end. */
@@ -65,19 +66,20 @@
   grpc_winsocket *socket;
   /* The actual TCP port number. */
   int port;
+  unsigned port_index;
   grpc_tcp_server *server;
   /* The cached AcceptEx for that port. */
   LPFN_ACCEPTEX AcceptEx;
   int shutting_down;
   /* closure for socket notification of accept being ready */
   grpc_closure on_accept;
-  gpr_refcount refs;
   /* linked list */
   struct grpc_tcp_listener *next;
 };
 
 /* the overall server */
 struct grpc_tcp_server {
+  gpr_refcount refs;
   /* Called whenever accept() succeeds on a server port. */
   grpc_tcp_server_cb on_accept_cb;
   void *on_accept_cb_arg;
@@ -89,6 +91,10 @@
 
   /* linked list of server ports */
   grpc_tcp_listener *head;
+  grpc_tcp_listener *tail;
+
+  /* List of closures passed to shutdown_starting_add(). */
+  grpc_closure_list shutdown_starting;
 
   /* shutdown callback */
   grpc_closure *shutdown_complete;
@@ -96,21 +102,25 @@
 
 /* Public function. Allocates the proper data structures to hold a
    grpc_tcp_server. */
-grpc_tcp_server *grpc_tcp_server_create(void) {
+grpc_tcp_server *grpc_tcp_server_create(grpc_closure *shutdown_complete) {
   grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server));
+  gpr_ref_init(&s->refs, 1);
   gpr_mu_init(&s->mu);
   s->active_ports = 0;
   s->on_accept_cb = NULL;
   s->on_accept_cb_arg = NULL;
   s->head = NULL;
-  s->shutdown_complete = NULL;
+  s->tail = NULL;
+  s->shutdown_starting.head = NULL;
+  s->shutdown_starting.tail = NULL;
+  s->shutdown_complete = shutdown_complete;
   return s;
 }
 
-static void dont_care_about_shutdown_completion(void *arg) {}
-
 static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
-  grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, 1);
+  if (s->shutdown_complete != NULL) {
+    grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, 1);
+  }
 
   /* Now that the accepts have been aborted, we can destroy the sockets.
      The IOCP won't get notified on these, so we can flag them as already
@@ -120,20 +130,28 @@
     s->head = sp->next;
     sp->next = NULL;
     grpc_winsocket_destroy(sp->socket);
-    grpc_tcp_listener_unref(sp);
+    gpr_free(sp);
   }
   gpr_free(s);
 }
 
-/* Public function. Stops and destroys a grpc_tcp_server. */
-void grpc_tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
-                             grpc_closure *shutdown_complete) {
+grpc_tcp_server *grpc_tcp_server_ref(grpc_tcp_server *s) {
+  gpr_ref(&s->refs);
+  return s;
+}
+
+void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s,
+                                           grpc_closure *shutdown_starting) {
+  gpr_mu_lock(&s->mu);
+  grpc_closure_list_add(&s->shutdown_starting, shutdown_starting, 1);
+  gpr_mu_unlock(&s->mu);
+}
+
+static void tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
   int immediately_done = 0;
   grpc_tcp_listener *sp;
   gpr_mu_lock(&s->mu);
 
-  s->shutdown_complete = shutdown_complete;
-
   /* First, shutdown all fd's. This will queue abortion calls for all
      of the pending accepts due to the normal operation mechanism. */
   if (s->active_ports == 0) {
@@ -150,6 +168,24 @@
   }
 }
 
+void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
+  if (gpr_unref(&s->refs)) {
+    /* Complete shutdown_starting work before destroying. */
+    grpc_exec_ctx local_exec_ctx = GRPC_EXEC_CTX_INIT;
+    gpr_mu_lock(&s->mu);
+    grpc_exec_ctx_enqueue_list(&local_exec_ctx, &s->shutdown_starting);
+    gpr_mu_unlock(&s->mu);
+    if (exec_ctx == NULL) {
+      grpc_exec_ctx_flush(&local_exec_ctx);
+      tcp_server_destroy(&local_exec_ctx, s);
+      grpc_exec_ctx_finish(&local_exec_ctx);
+    } else {
+      grpc_exec_ctx_finish(&local_exec_ctx);
+      tcp_server_destroy(exec_ctx, s);
+    }
+  }
+}
+
 /* Prepare (bind) a recently-created socket for listening. */
 static int prepare_socket(SOCKET sock, const struct sockaddr *addr,
                           size_t addr_len) {
@@ -277,6 +313,7 @@
 /* Event manager callback when reads are ready. */
 static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, int from_iocp) {
   grpc_tcp_listener *sp = arg;
+  grpc_tcp_server_acceptor acceptor = {sp->server, sp->port_index, 0};
   SOCKET sock = sp->new_socket;
   grpc_winsocket_callback_info *info = &sp->socket->read_info;
   grpc_endpoint *ep = NULL;
@@ -343,7 +380,9 @@
 
   /* The only time we should call our callback, is where we successfully
      managed to accept a connection, and created an endpoint. */
-  if (ep) sp->server->on_accept_cb(exec_ctx, sp->server->on_accept_cb_arg, ep);
+  if (ep)
+    sp->server->on_accept_cb(exec_ctx, sp->server->on_accept_cb_arg, ep,
+                             &acceptor);
   /* As we were notified from the IOCP of one and exactly one accept,
      the former socked we created has now either been destroy or assigned
      to the new connection. We need to create a new one for the next
@@ -353,7 +392,8 @@
 
 static grpc_tcp_listener *add_socket_to_server(grpc_tcp_server *s, SOCKET sock,
                                                const struct sockaddr *addr,
-                                               size_t addr_len) {
+                                               size_t addr_len,
+                                               unsigned port_index) {
   grpc_tcp_listener *sp = NULL;
   int port;
   int status;
@@ -382,15 +422,20 @@
     gpr_mu_lock(&s->mu);
     GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server");
     sp = gpr_malloc(sizeof(grpc_tcp_listener));
-    sp->next = s->head;
-    s->head = sp;
+    sp->next = NULL;
+    if (s->head == NULL) {
+      s->head = sp;
+    } else {
+      s->tail->next = sp;
+    }
+    s->tail = sp;
     sp->server = s;
     sp->socket = grpc_winsocket_create(sock, "listener");
     sp->shutting_down = 0;
     sp->AcceptEx = AcceptEx;
     sp->new_socket = INVALID_SOCKET;
     sp->port = port;
-    gpr_ref_init(&sp->refs, 1);
+    sp->port_index = port_index;
     grpc_closure_init(&sp->on_accept, on_accept, sp);
     GPR_ASSERT(sp->socket);
     gpr_mu_unlock(&s->mu);
@@ -399,8 +444,8 @@
   return sp;
 }
 
-grpc_tcp_listener *grpc_tcp_server_add_port(grpc_tcp_server *s,
-                                            const void *addr, size_t addr_len) {
+int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
+                             size_t addr_len) {
   grpc_tcp_listener *sp;
   SOCKET sock;
   struct sockaddr_in6 addr6_v4mapped;
@@ -409,6 +454,10 @@
   struct sockaddr_storage sockname_temp;
   socklen_t sockname_len;
   int port;
+  unsigned port_index = 0;
+  if (s->tail != NULL) {
+    port_index = s->tail->port_index + 1;
+  }
 
   /* Check if this is a wildcard port, and if so, try to keep the port the same
      as some previously created listener. */
@@ -450,18 +499,39 @@
     gpr_free(utf8_message);
   }
 
-  sp = add_socket_to_server(s, sock, addr, addr_len);
+  sp = add_socket_to_server(s, sock, addr, addr_len, port_index);
   gpr_free(allocated_addr);
 
-  return sp;
+  if (sp) {
+    return sp->port;
+  } else {
+    return -1;
+  }
 }
 
-int grpc_tcp_server_get_fd(grpc_tcp_server *s, unsigned port_index) {
+unsigned grpc_tcp_server_port_fd_count(grpc_tcp_server *s,
+                                       unsigned port_index) {
   grpc_tcp_listener *sp;
-  for (sp = s->head; sp && port_index != 0; sp = sp->next, port_index--)
+  for (sp = s->head; sp && port_index != 0; sp = sp->next, --port_index)
     ;
-  if (port_index == 0 && sp) {
-    return _open_osfhandle(sp->socket->socket, 0);
+  if (sp) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+int grpc_tcp_server_port_fd(grpc_tcp_server *s, unsigned port_index,
+                            unsigned fd_index) {
+  grpc_tcp_listener *sp;
+  if (fd_index != 0) {
+    /* Windows implementation has only one fd per port_index. */
+    return -1;
+  }
+  for (sp = s->head; sp && port_index != 0; sp = sp->next, --port_index)
+    ;
+  if (sp) {
+    return _open_osfhandle((intptr_t)sp->socket->socket, 0);
   } else {
     return -1;
   }
@@ -485,25 +555,4 @@
   gpr_mu_unlock(&s->mu);
 }
 
-int grpc_tcp_listener_get_port(grpc_tcp_listener *listener) {
-  if (listener != NULL) {
-    grpc_tcp_listener *sp = listener;
-    return sp->port;
-  } else {
-    return 0;
-  }
-}
-
-void grpc_tcp_listener_ref(grpc_tcp_listener *listener) {
-  grpc_tcp_listener *sp = listener;
-  gpr_ref(&sp->refs);
-}
-
-void grpc_tcp_listener_unref(grpc_tcp_listener *listener) {
-  grpc_tcp_listener *sp = listener;
-  if (gpr_unref(&sp->refs)) {
-    gpr_free(listener);
-  }
-}
-
 #endif /* GPR_WINSOCK_SOCKET */
diff --git a/src/core/iomgr/tcp_windows.c b/src/core/iomgr/tcp_windows.c
index cc7f7ff..d3f080c 100644
--- a/src/core/iomgr/tcp_windows.c
+++ b/src/core/iomgr/tcp_windows.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -143,10 +143,7 @@
   grpc_closure *cb = tcp->read_cb;
   grpc_winsocket *socket = tcp->socket;
   gpr_slice sub;
-  gpr_slice *slice = NULL;
-  size_t nslices = 0;
   grpc_winsocket_callback_info *info = &socket->read_info;
-  int do_abort = 0;
 
   if (success) {
     if (socket->read_info.wsa_error != 0 && !tcp->shutting_down) {
@@ -238,7 +235,6 @@
   grpc_winsocket *handle = tcp->socket;
   grpc_winsocket_callback_info *info = &handle->write_info;
   grpc_closure *cb;
-  int do_abort = 0;
 
   gpr_mu_lock(&tcp->mu);
   cb = tcp->write_cb;
diff --git a/src/core/iomgr/udp_server.c b/src/core/iomgr/udp_server.c
index a1a6b04..fe006c6 100644
--- a/src/core/iomgr/udp_server.c
+++ b/src/core/iomgr/udp_server.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -425,15 +425,5 @@
   gpr_mu_unlock(&s->mu);
 }
 
-/* TODO(rjshade): Add a test for this method. */
-void grpc_udp_server_write(server_port *sp, const char *buffer, size_t buf_len,
-                           const struct sockaddr *peer_address) {
-  ssize_t rc;
-  rc = sendto(sp->fd, buffer, buf_len, 0, peer_address, sizeof(peer_address));
-  if (rc < 0) {
-    gpr_log(GPR_ERROR, "Unable to send data: %s", strerror(errno));
-  }
-}
-
 #endif
 #endif
diff --git a/src/core/iomgr/udp_server.h b/src/core/iomgr/udp_server.h
index de5736c..73a21c8 100644
--- a/src/core/iomgr/udp_server.h
+++ b/src/core/iomgr/udp_server.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -72,12 +72,4 @@
 void grpc_udp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_udp_server *server,
                              grpc_closure *on_done);
 
-/* Write the contents of buffer to the underlying UDP socket. */
-/*
-void grpc_udp_server_write(grpc_udp_server *s,
-                           const char *buffer,
-                           int buf_len,
-                           const struct sockaddr* to);
-                           */
-
 #endif /* GRPC_INTERNAL_CORE_IOMGR_UDP_SERVER_H */
diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c
index d7fad33..08713fc 100644
--- a/src/core/security/server_secure_chttp2.c
+++ b/src/core/security/server_secure_chttp2.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -126,8 +126,8 @@
   state_unref(state);
 }
 
-static void on_accept(grpc_exec_ctx *exec_ctx, void *statep,
-                      grpc_endpoint *tcp) {
+static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp,
+                      grpc_tcp_server_acceptor *acceptor) {
   grpc_server_secure_state *state = statep;
   state_ref(state);
   grpc_security_connector_do_handshake(exec_ctx, state->sc, tcp,
@@ -144,8 +144,10 @@
 
 static void destroy_done(grpc_exec_ctx *exec_ctx, void *statep, int success) {
   grpc_server_secure_state *state = statep;
-  state->destroy_callback->cb(exec_ctx, state->destroy_callback->cb_arg,
-                              success);
+  if (state->destroy_callback != NULL) {
+    state->destroy_callback->cb(exec_ctx, state->destroy_callback->cb_arg,
+                                success);
+  }
   grpc_security_connector_shutdown(exec_ctx, state->sc);
   state_unref(state);
 }
@@ -161,8 +163,7 @@
   state->destroy_callback = callback;
   tcp = state->tcp;
   gpr_mu_unlock(&state->mu);
-  grpc_closure_init(&state->destroy_closure, destroy_done, state);
-  grpc_tcp_server_destroy(exec_ctx, tcp, &state->destroy_closure);
+  grpc_tcp_server_unref(exec_ctx, tcp);
 }
 
 int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
@@ -199,18 +200,18 @@
   if (!resolved) {
     goto error;
   }
-
-  tcp = grpc_tcp_server_create();
+  state = gpr_malloc(sizeof(*state));
+  memset(state, 0, sizeof(*state));
+  grpc_closure_init(&state->destroy_closure, destroy_done, state);
+  tcp = grpc_tcp_server_create(&state->destroy_closure);
   if (!tcp) {
     goto error;
   }
 
   for (i = 0; i < resolved->naddrs; i++) {
-    grpc_tcp_listener *listener;
-    listener = grpc_tcp_server_add_port(
+    port_temp = grpc_tcp_server_add_port(
         tcp, (struct sockaddr *)&resolved->addrs[i].addr,
         resolved->addrs[i].len);
-    port_temp = grpc_tcp_listener_get_port(listener);
     if (port_temp > 0) {
       if (port_num == -1) {
         port_num = port_temp;
@@ -232,8 +233,6 @@
   }
   grpc_resolved_addresses_destroy(resolved);
 
-  state = gpr_malloc(sizeof(*state));
-  memset(state, 0, sizeof(*state));
   state->server = server;
   state->tcp = tcp;
   state->sc = sc;
@@ -258,7 +257,7 @@
     grpc_resolved_addresses_destroy(resolved);
   }
   if (tcp) {
-    grpc_tcp_server_destroy(&exec_ctx, tcp, NULL);
+    grpc_tcp_server_unref(&exec_ctx, tcp);
   }
   if (state) {
     gpr_free(state);
diff --git a/src/core/support/env_win32.c b/src/core/support/env_win32.c
index 6b1ff10..1025828 100644
--- a/src/core/support/env_win32.c
+++ b/src/core/support/env_win32.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,12 @@
 #include "src/core/support/env.h"
 #include "src/core/support/string.h"
 
+#ifdef __MINGW32__
+errno_t getenv_s(size_t *size_needed, char *buffer, size_t size,
+                 const char *varname);
+#else
 #include <stdlib.h>
+#endif
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
@@ -47,14 +52,17 @@
 char *gpr_getenv(const char *name) {
   size_t size;
   char *result = NULL;
-  char *duplicated;
   errno_t err;
 
-  err = _dupenv_s(&result, &size, name);
-  if (err) return NULL;
-  duplicated = gpr_strdup(result);
-  free(result);
-  return duplicated;
+  err = getenv_s(&size, NULL, 0, name);
+  if (err || (size == 0)) return NULL;
+  result = gpr_malloc(size);
+  err = getenv_s(&size, result, size, name);
+  if (err) {
+    gpr_free(result);
+    return NULL;
+  }
+  return result;
 }
 
 void gpr_setenv(const char *name, const char *value) {
diff --git a/src/core/support/log_win32.c b/src/core/support/log_win32.c
index 40adcd1..e18e667 100644
--- a/src/core/support/log_win32.c
+++ b/src/core/support/log_win32.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -109,13 +109,13 @@
   fflush(stderr);
 }
 
-char *gpr_format_message(DWORD messageid) {
+char *gpr_format_message(int messageid) {
   LPTSTR tmessage;
   char *message;
   DWORD status = FormatMessage(
       FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
           FORMAT_MESSAGE_IGNORE_INSERTS,
-      NULL, messageid, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+      NULL, (DWORD)messageid, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
       (LPTSTR)(&tmessage), 0, NULL);
   if (status == 0) return gpr_strdup("Unable to retrieve error string");
   message = gpr_tchar_to_char(tmessage);
diff --git a/src/core/support/string_win32.c b/src/core/support/string_win32.c
index 914ba87..3b1f702 100644
--- a/src/core/support/string_win32.c
+++ b/src/core/support/string_win32.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -85,8 +85,8 @@
 gpr_char_to_tchar(LPCSTR input) {
   LPTSTR ret;
   int needed = MultiByteToWideChar(CP_UTF8, 0, input, -1, NULL, 0);
-  if (needed == 0) return NULL;
-  ret = gpr_malloc(needed * sizeof(TCHAR));
+  if (needed <= 0) return NULL;
+  ret = gpr_malloc((unsigned)needed * sizeof(TCHAR));
   MultiByteToWideChar(CP_UTF8, 0, input, -1, ret, needed);
   return ret;
 }
@@ -95,8 +95,8 @@
 gpr_tchar_to_char(LPCTSTR input) {
   LPSTR ret;
   int needed = WideCharToMultiByte(CP_UTF8, 0, input, -1, NULL, 0, NULL, NULL);
-  if (needed == 0) return NULL;
-  ret = gpr_malloc(needed);
+  if (needed <= 0) return NULL;
+  ret = gpr_malloc((unsigned)needed);
   WideCharToMultiByte(CP_UTF8, 0, input, -1, ret, needed, NULL, NULL);
   return ret;
 }
diff --git a/src/core/support/sync_win32.c b/src/core/support/sync_win32.c
index 51a082b..84d412a 100644
--- a/src/core/support/sync_win32.c
+++ b/src/core/support/sync_win32.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -94,7 +94,11 @@
     if (now_ms >= deadline_ms) {
       timeout = 1;
     } else {
-      timeout_max_ms = (DWORD)min(deadline_ms - now_ms, INFINITE - 1);
+      if ((deadline_ms - now_ms) >= INFINITE) {
+        timeout_max_ms = INFINITE - 1;
+      } else {
+        timeout_max_ms = (DWORD)(deadline_ms - now_ms);
+      }
       timeout = (SleepConditionVariableCS(cv, &mu->cs, timeout_max_ms) == 0 &&
                  GetLastError() == ERROR_TIMEOUT);
     }
diff --git a/src/core/support/time_win32.c b/src/core/support/time_win32.c
index 2bed0f6..8af957e 100644
--- a/src/core/support/time_win32.c
+++ b/src/core/support/time_win32.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -37,9 +37,12 @@
 
 #ifdef GPR_WIN32
 
+#include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include <src/core/support/time_precise.h>
 #include <sys/timeb.h>
+#include <process.h>
+#include <limits.h>
 
 #include "src/core/support/block_annotate.h"
 
@@ -50,11 +53,12 @@
   LARGE_INTEGER frequency;
   QueryPerformanceFrequency(&frequency);
   QueryPerformanceCounter(&g_start_time);
-  g_time_scale = 1.0 / frequency.QuadPart;
+  g_time_scale = 1.0 / (double)frequency.QuadPart;
 }
 
 gpr_timespec gpr_now(gpr_clock_type clock) {
   gpr_timespec now_tv;
+  LONGLONG diff;
   struct _timeb now_tb;
   LARGE_INTEGER timestamp;
   double now_dbl;
@@ -68,10 +72,14 @@
     case GPR_CLOCK_MONOTONIC:
     case GPR_CLOCK_PRECISE:
       QueryPerformanceCounter(&timestamp);
-      now_dbl = (timestamp.QuadPart - g_start_time.QuadPart) * g_time_scale;
+      diff = timestamp.QuadPart - g_start_time.QuadPart;
+      now_dbl = (double)diff * g_time_scale;
       now_tv.tv_sec = (int64_t)now_dbl;
       now_tv.tv_nsec = (int32_t)((now_dbl - (double)now_tv.tv_sec) * 1e9);
       break;
+    case GPR_TIMESPAN:
+      abort();
+      break;
   }
   return now_tv;
 }
@@ -79,7 +87,7 @@
 void gpr_sleep_until(gpr_timespec until) {
   gpr_timespec now;
   gpr_timespec delta;
-  DWORD sleep_millis;
+  int64_t sleep_millis;
 
   for (;;) {
     /* We could simplify by using clock_nanosleep instead, but it might be
@@ -91,9 +99,10 @@
 
     delta = gpr_time_sub(until, now);
     sleep_millis =
-        (DWORD)delta.tv_sec * GPR_MS_PER_SEC + delta.tv_nsec / GPR_NS_PER_MS;
+        delta.tv_sec * GPR_MS_PER_SEC + delta.tv_nsec / GPR_NS_PER_MS;
+    GPR_ASSERT((sleep_millis >= 0) && (sleep_millis <= INT_MAX));
     GRPC_SCHEDULING_START_BLOCKING_REGION;
-    Sleep(sleep_millis);
+    Sleep((DWORD)sleep_millis);
     GRPC_SCHEDULING_END_BLOCKING_REGION;
   }
 }
diff --git a/src/core/surface/init.c b/src/core/surface/init.c
index 66c5a52..a4a53d3 100644
--- a/src/core/surface/init.c
+++ b/src/core/surface/init.c
@@ -119,8 +119,10 @@
     grpc_iomgr_init();
     grpc_executor_init();
     grpc_tracer_init("GRPC_TRACE");
-    /* Only initialize census if noone else has. */
-    if (census_enabled() == CENSUS_FEATURE_NONE) {
+    /* Only initialize census if no one else has and some features are
+     * available. */
+    if (census_enabled() == CENSUS_FEATURE_NONE &&
+        census_supported() != CENSUS_FEATURE_NONE) {
       if (census_initialize(census_supported())) { /* enable all features. */
         gpr_log(GPR_ERROR, "Could not initialize census.");
       }
diff --git a/src/core/surface/server.c b/src/core/surface/server.c
index 79db138..0928f1e 100644
--- a/src/core/surface/server.c
+++ b/src/core/surface/server.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -779,9 +779,7 @@
     const grpc_channel_filter **filters, size_t filter_count,
     const grpc_channel_args *args) {
   size_t i;
-  /* TODO(census): restore this once we finalize census filter etc.
-     int census_enabled = grpc_channel_args_is_census_enabled(args); */
-  int census_enabled = 0;
+  int census_enabled = grpc_channel_args_is_census_enabled(args);
 
   grpc_server *server = gpr_malloc(sizeof(grpc_server));
 
diff --git a/src/core/surface/server_chttp2.c b/src/core/surface/server_chttp2.c
index 5ce7c19..6e21d2d 100644
--- a/src/core/surface/server_chttp2.c
+++ b/src/core/surface/server_chttp2.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -53,7 +53,8 @@
 }
 
 static void new_transport(grpc_exec_ctx *exec_ctx, void *server,
-                          grpc_endpoint *tcp) {
+                          grpc_endpoint *tcp,
+                          grpc_tcp_server_acceptor *acceptor) {
   /*
    * Beware that the call to grpc_create_chttp2_transport() has to happen before
    * grpc_tcp_server_destroy(). This is fine here, but similar code
@@ -80,7 +81,8 @@
 static void destroy(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp,
                     grpc_closure *destroy_done) {
   grpc_tcp_server *tcp = tcpp;
-  grpc_tcp_server_destroy(exec_ctx, tcp, destroy_done);
+  grpc_tcp_server_unref(exec_ctx, tcp);
+  grpc_exec_ctx_enqueue(exec_ctx, destroy_done, 1);
 }
 
 int grpc_server_add_insecure_http2_port(grpc_server *server, const char *addr) {
@@ -100,15 +102,13 @@
     goto error;
   }
 
-  tcp = grpc_tcp_server_create();
+  tcp = grpc_tcp_server_create(NULL);
   GPR_ASSERT(tcp);
 
   for (i = 0; i < resolved->naddrs; i++) {
-    grpc_tcp_listener *listener;
-    listener = grpc_tcp_server_add_port(
+    port_temp = grpc_tcp_server_add_port(
         tcp, (struct sockaddr *)&resolved->addrs[i].addr,
         resolved->addrs[i].len);
-    port_temp = grpc_tcp_listener_get_port(listener);
     if (port_temp > 0) {
       if (port_num == -1) {
         port_num = port_temp;
@@ -139,7 +139,7 @@
     grpc_resolved_addresses_destroy(resolved);
   }
   if (tcp) {
-    grpc_tcp_server_destroy(&exec_ctx, tcp, NULL);
+    grpc_tcp_server_unref(&exec_ctx, tcp);
   }
   port_num = 0;
 
diff --git a/src/core/surface/server_create.c b/src/core/surface/server_create.c
index f30093e..5e37e80 100644
--- a/src/core/surface/server_create.c
+++ b/src/core/surface/server_create.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -43,9 +43,6 @@
   const grpc_channel_filter *filters[3];
   size_t num_filters = 0;
   filters[num_filters++] = &grpc_compress_filter;
-  if (grpc_channel_args_is_census_enabled(args)) {
-    filters[num_filters++] = &grpc_server_census_filter;
-  }
   GRPC_API_TRACE("grpc_server_create(%p, %p)", 2, (args, reserved));
   return grpc_server_create_from_filters(filters, num_filters, args);
 }
diff --git a/src/core/surface/version.c b/src/core/surface/version.c
index 962a721..262a13f 100644
--- a/src/core/surface/version.c
+++ b/src/core/surface/version.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -36,4 +36,4 @@
 
 #include <grpc/grpc.h>
 
-const char *grpc_version_string(void) { return "0.12.0.0"; }
+const char *grpc_version_string(void) { return "0.13.0.0"; }
diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc
index 2aa5328..710d7cb 100644
--- a/src/cpp/client/client_context.cc
+++ b/src/cpp/client/client_context.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -48,6 +48,7 @@
 class DefaultGlobalClientCallbacks GRPC_FINAL
     : public ClientContext::GlobalCallbacks {
  public:
+  ~DefaultGlobalClientCallbacks() GRPC_OVERRIDE {}
   void DefaultConstructor(ClientContext* context) GRPC_OVERRIDE {}
   void Destructor(ClientContext* context) GRPC_OVERRIDE {}
 };
diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc
index 878775b..3bf9f3f 100644
--- a/src/cpp/server/server.cc
+++ b/src/cpp/server/server.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -53,17 +53,17 @@
 
 class DefaultGlobalCallbacks GRPC_FINAL : public Server::GlobalCallbacks {
  public:
+  ~DefaultGlobalCallbacks() GRPC_OVERRIDE {}
   void PreSynchronousRequest(ServerContext* context) GRPC_OVERRIDE {}
   void PostSynchronousRequest(ServerContext* context) GRPC_OVERRIDE {}
 };
 
-static Server::GlobalCallbacks* g_callbacks = nullptr;
+static std::shared_ptr<Server::GlobalCallbacks> g_callbacks = nullptr;
 static gpr_once g_once_init_callbacks = GPR_ONCE_INIT;
 
 static void InitGlobalCallbacks() {
   if (g_callbacks == nullptr) {
-    static DefaultGlobalCallbacks default_global_callbacks;
-    g_callbacks = &default_global_callbacks;
+    g_callbacks.reset(new DefaultGlobalCallbacks());
   }
 }
 
@@ -234,12 +234,12 @@
       }
     }
 
-    void Run() {
+    void Run(std::shared_ptr<GlobalCallbacks> global_callbacks) {
       ctx_.BeginCompletionOp(&call_);
-      g_callbacks->PreSynchronousRequest(&ctx_);
+      global_callbacks->PreSynchronousRequest(&ctx_);
       method_->handler()->RunHandler(MethodHandler::HandlerParameter(
           &call_, &ctx_, request_payload_, call_.max_message_size()));
-      g_callbacks->PostSynchronousRequest(&ctx_);
+      global_callbacks->PostSynchronousRequest(&ctx_);
       request_payload_ = nullptr;
       void* ignored_tag;
       bool ignored_ok;
@@ -287,6 +287,7 @@
       thread_pool_(thread_pool),
       thread_pool_owned_(thread_pool_owned) {
   gpr_once_init(&g_once_init_callbacks, InitGlobalCallbacks);
+  global_callbacks_ = g_callbacks;
   grpc_server_register_completion_queue(server_, cq_.cq(), nullptr);
 }
 
@@ -311,7 +312,7 @@
 void Server::SetGlobalCallbacks(GlobalCallbacks* callbacks) {
   GPR_ASSERT(g_callbacks == nullptr);
   GPR_ASSERT(callbacks != nullptr);
-  g_callbacks = callbacks;
+  g_callbacks.reset(callbacks);
 }
 
 bool Server::RegisterService(const grpc::string* host, RpcService* service) {
@@ -569,7 +570,7 @@
         }
       }
       GPR_TIMER_SCOPE("cd.Run()", 0);
-      cd.Run();
+      cd.Run(global_callbacks_);
     }
   }
 
diff --git a/src/cpp/util/byte_buffer.cc b/src/cpp/util/byte_buffer.cc
index 2952f94..3a2318d 100644
--- a/src/cpp/util/byte_buffer.cc
+++ b/src/cpp/util/byte_buffer.cc
@@ -31,8 +31,8 @@
  *
  */
 
-#include <grpc/byte_buffer_reader.h>
 #include <grpc++/support/byte_buffer.h>
+#include <grpc/byte_buffer_reader.h>
 
 namespace grpc {
 
@@ -84,8 +84,10 @@
     : buffer_(grpc_byte_buffer_copy(buf.buffer_)) {}
 
 ByteBuffer& ByteBuffer::operator=(const ByteBuffer& buf) {
-  Clear();                                       // first remove existing data
-  buffer_ = grpc_byte_buffer_copy(buf.buffer_);  // then copy
+  Clear();  // first remove existing data
+  if (buf.buffer_) {
+    buffer_ = grpc_byte_buffer_copy(buf.buffer_);  // then copy
+  }
   return *this;
 }
 
diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.csproj b/src/csharp/Grpc.Auth/Grpc.Auth.csproj
index 7e10654..8dd12b5 100644
--- a/src/csharp/Grpc.Auth/Grpc.Auth.csproj
+++ b/src/csharp/Grpc.Auth/Grpc.Auth.csproj
@@ -39,6 +39,18 @@
     <AssemblyOriginatorKeyFile>..\keys\Grpc.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="Google.Apis.Auth, Version=1.10.0.25333, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Google.Apis.Auth.1.10.0\lib\net40\Google.Apis.Auth.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Auth.PlatformServices, Version=1.10.0.25333, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Google.Apis.Auth.1.10.0\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Core, Version=1.10.0.25331, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Google.Apis.Core.1.10.0\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Net" />
     <Reference Include="System.Net.Http" />
@@ -46,15 +58,6 @@
     <Reference Include="BouncyCastle.Crypto">
       <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
     </Reference>
-    <Reference Include="Google.Apis.Auth">
-      <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth.PlatformServices">
-      <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Core">
-      <HintPath>..\packages\Google.Apis.Core.1.9.3\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
-    </Reference>
     <Reference Include="Microsoft.Threading.Tasks">
       <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
     </Reference>
diff --git a/src/csharp/Grpc.Auth/packages.config b/src/csharp/Grpc.Auth/packages.config
index 7a02c95..5fe8ca6 100644
--- a/src/csharp/Grpc.Auth/packages.config
+++ b/src/csharp/Grpc.Auth/packages.config
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
-  <package id="Google.Apis.Auth" version="1.9.3" targetFramework="net45" />
-  <package id="Google.Apis.Core" version="1.9.3" targetFramework="net45" />
+  <package id="Google.Apis.Auth" version="1.10.0" targetFramework="net45" />
+  <package id="Google.Apis.Core" version="1.10.0" targetFramework="net45" />
   <package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" />
   <package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net45" />
   <package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net45" />
diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
index 8307828..7e73c4f 100644
--- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
+++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
@@ -55,8 +55,9 @@
       <Private>False</Private>
     </Reference>
     <Reference Include="System" />
-    <Reference Include="System.Interactive.Async">
-      <HintPath>..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll</HintPath>
+    <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
     </Reference>
   </ItemGroup>
   <ItemGroup>
diff --git a/src/csharp/Grpc.Core.Tests/packages.config b/src/csharp/Grpc.Core.Tests/packages.config
index 62077f4..610831d 100644
--- a/src/csharp/Grpc.Core.Tests/packages.config
+++ b/src/csharp/Grpc.Core.Tests/packages.config
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Ix-Async" version="1.2.3" targetFramework="net45" />
+  <package id="Ix-Async" version="1.2.5" targetFramework="net45" />
   <package id="NUnit" version="2.6.4" targetFramework="net45" />
   <package id="NUnitTestAdapter" version="2.0.0" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj
index 38398a2..307c0e8 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -39,8 +39,9 @@
   </PropertyGroup>
   <ItemGroup>
     <Reference Include="System" />
-    <Reference Include="System.Interactive.Async">
-      <HintPath>..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll</HintPath>
+    <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
     </Reference>
   </ItemGroup>
   <ItemGroup>
diff --git a/src/csharp/Grpc.Core/Grpc.Core.nuspec b/src/csharp/Grpc.Core/Grpc.Core.nuspec
index 67a04af..9a4c1a3 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.nuspec
+++ b/src/csharp/Grpc.Core/Grpc.Core.nuspec
@@ -15,8 +15,8 @@
     <copyright>Copyright 2015, Google Inc.</copyright>
     <tags>gRPC RPC Protocol HTTP/2</tags>
     <dependencies>
-      <dependency id="Ix-Async" version="1.2.3" />
-      <dependency id="grpc.native.csharp" version="$GrpcNativeCsharpVersion$" />
+      <dependency id="Ix-Async" version="1.2.5" />
+      <dependency id="grpc.native.csharp" version="$version$" />
     </dependencies>
   </metadata>
   <files>
diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs
index 818ddb8..6581390 100644
--- a/src/csharp/Grpc.Core/VersionInfo.cs
+++ b/src/csharp/Grpc.Core/VersionInfo.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -41,6 +41,6 @@
         /// <summary>
         /// Current version of gRPC C#
         /// </summary>
-        public const string CurrentVersion = "0.12.0";
+        public const string CurrentVersion = "0.13.0";
     }
 }
diff --git a/src/csharp/Grpc.Core/packages.config b/src/csharp/Grpc.Core/packages.config
index 86a48c5..80daf04 100644
--- a/src/csharp/Grpc.Core/packages.config
+++ b/src/csharp/Grpc.Core/packages.config
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Ix-Async" version="1.2.3" targetFramework="net45" />
+  <package id="Ix-Async" version="1.2.5" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
index 54c68c1..9aeab05 100644
--- a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
+++ b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
@@ -47,7 +47,7 @@
     <Reference Include="System" />
     <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll</HintPath>
+      <HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
     </Reference>
   </ItemGroup>
   <ItemGroup>
diff --git a/src/csharp/Grpc.Examples.Tests/packages.config b/src/csharp/Grpc.Examples.Tests/packages.config
index 10bf1e8..ed30d2d 100644
--- a/src/csharp/Grpc.Examples.Tests/packages.config
+++ b/src/csharp/Grpc.Examples.Tests/packages.config
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>

 <packages>

   <package id="Google.Protobuf" version="3.0.0-beta2" targetFramework="net45" />

-  <package id="Ix-Async" version="1.2.3" targetFramework="net45" />

+  <package id="Ix-Async" version="1.2.5" targetFramework="net45" />

   <package id="NUnit" version="2.6.4" targetFramework="net45" />

 </packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Examples/Grpc.Examples.csproj b/src/csharp/Grpc.Examples/Grpc.Examples.csproj
index c9b0195..15b04c8 100644
--- a/src/csharp/Grpc.Examples/Grpc.Examples.csproj
+++ b/src/csharp/Grpc.Examples/Grpc.Examples.csproj
@@ -43,8 +43,9 @@
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Data.Linq" />
-    <Reference Include="System.Interactive.Async">
-      <HintPath>..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll</HintPath>
+    <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
     </Reference>
   </ItemGroup>
   <ItemGroup>
diff --git a/src/csharp/Grpc.Examples/packages.config b/src/csharp/Grpc.Examples/packages.config
index f5131b8..dfb8304 100644
--- a/src/csharp/Grpc.Examples/packages.config
+++ b/src/csharp/Grpc.Examples/packages.config
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="Google.Protobuf" version="3.0.0-beta2" targetFramework="net45" />
-  <package id="Ix-Async" version="1.2.3" targetFramework="net45" />
+  <package id="Ix-Async" version="1.2.5" targetFramework="net45" />
   <package id="NUnit" version="2.6.4" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
index 7ffab4b..498528a 100644
--- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
+++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
@@ -44,8 +44,9 @@
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
-    <Reference Include="System.Interactive.Async">
-      <HintPath>..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll</HintPath>
+    <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
     </Reference>
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
diff --git a/src/csharp/Grpc.HealthCheck/packages.config b/src/csharp/Grpc.HealthCheck/packages.config
index 04eb42d..358a978 100644
--- a/src/csharp/Grpc.HealthCheck/packages.config
+++ b/src/csharp/Grpc.HealthCheck/packages.config
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="Google.Protobuf" version="3.0.0-beta2" targetFramework="net45" />
-  <package id="Ix-Async" version="1.2.3" targetFramework="net45" />
+  <package id="Ix-Async" version="1.2.5" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
index 74d73e8..f37c146 100644
--- a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
+++ b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
@@ -43,17 +43,17 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
     </Reference>
-    <Reference Include="Google.Apis.Auth, Version=1.9.3.19379, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+    <Reference Include="Google.Apis.Auth, Version=1.10.0.25333, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.dll</HintPath>
+      <HintPath>..\packages\Google.Apis.Auth.1.10.0\lib\net40\Google.Apis.Auth.dll</HintPath>
     </Reference>
-    <Reference Include="Google.Apis.Auth.PlatformServices, Version=1.9.3.19383, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+    <Reference Include="Google.Apis.Auth.PlatformServices, Version=1.10.0.25333, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
+      <HintPath>..\packages\Google.Apis.Auth.1.10.0\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
     </Reference>
-    <Reference Include="Google.Apis.Core, Version=1.9.3.19379, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+    <Reference Include="Google.Apis.Core, Version=1.10.0.25331, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Apis.Core.1.9.3\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
+      <HintPath>..\packages\Google.Apis.Core.1.10.0\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
     </Reference>
     <Reference Include="Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/packages.config b/src/csharp/Grpc.IntegrationTesting.Client/packages.config
index 7a02c95..5fe8ca6 100644
--- a/src/csharp/Grpc.IntegrationTesting.Client/packages.config
+++ b/src/csharp/Grpc.IntegrationTesting.Client/packages.config
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
-  <package id="Google.Apis.Auth" version="1.9.3" targetFramework="net45" />
-  <package id="Google.Apis.Core" version="1.9.3" targetFramework="net45" />
+  <package id="Google.Apis.Auth" version="1.10.0" targetFramework="net45" />
+  <package id="Google.Apis.Core" version="1.10.0" targetFramework="net45" />
   <package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" />
   <package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net45" />
   <package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net45" />
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
index f877b7f..f27b96a 100644
--- a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
+++ b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
@@ -43,17 +43,17 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
     </Reference>
-    <Reference Include="Google.Apis.Auth, Version=1.9.3.19379, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+    <Reference Include="Google.Apis.Auth, Version=1.10.0.25333, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.dll</HintPath>
+      <HintPath>..\packages\Google.Apis.Auth.1.10.0\lib\net40\Google.Apis.Auth.dll</HintPath>
     </Reference>
-    <Reference Include="Google.Apis.Auth.PlatformServices, Version=1.9.3.19383, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+    <Reference Include="Google.Apis.Auth.PlatformServices, Version=1.10.0.25333, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
+      <HintPath>..\packages\Google.Apis.Auth.1.10.0\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
     </Reference>
-    <Reference Include="Google.Apis.Core, Version=1.9.3.19379, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+    <Reference Include="Google.Apis.Core, Version=1.10.0.25331, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Apis.Core.1.9.3\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
+      <HintPath>..\packages\Google.Apis.Core.1.10.0\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
     </Reference>
     <Reference Include="Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/packages.config b/src/csharp/Grpc.IntegrationTesting.Server/packages.config
index 7a02c95..5fe8ca6 100644
--- a/src/csharp/Grpc.IntegrationTesting.Server/packages.config
+++ b/src/csharp/Grpc.IntegrationTesting.Server/packages.config
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
-  <package id="Google.Apis.Auth" version="1.9.3" targetFramework="net45" />
-  <package id="Google.Apis.Core" version="1.9.3" targetFramework="net45" />
+  <package id="Google.Apis.Auth" version="1.10.0" targetFramework="net45" />
+  <package id="Google.Apis.Core" version="1.10.0" targetFramework="net45" />
   <package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" />
   <package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net45" />
   <package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net45" />
diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
index 3042331..3729913 100644
--- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
+++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
@@ -41,6 +41,18 @@
     <Reference Include="CommandLine">
       <HintPath>..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll</HintPath>
     </Reference>
+    <Reference Include="Google.Apis.Auth, Version=1.10.0.25333, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Google.Apis.Auth.1.10.0\lib\net40\Google.Apis.Auth.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Auth.PlatformServices, Version=1.10.0.25333, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Google.Apis.Auth.1.10.0\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Core, Version=1.10.0.25331, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Google.Apis.Core.1.10.0\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
+    </Reference>
     <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\Google.Protobuf.3.0.0-beta2\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
@@ -52,8 +64,9 @@
       <HintPath>..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
     </Reference>
     <Reference Include="System" />
-    <Reference Include="System.Interactive.Async">
-      <HintPath>..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll</HintPath>
+    <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
     </Reference>
     <Reference Include="System.Net" />
     <Reference Include="System.Net.Http" />
@@ -61,15 +74,6 @@
     <Reference Include="BouncyCastle.Crypto">
       <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
     </Reference>
-    <Reference Include="Google.Apis.Auth">
-      <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth.PlatformServices">
-      <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Core">
-      <HintPath>..\packages\Google.Apis.Core.1.9.3\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
-    </Reference>
     <Reference Include="Microsoft.Threading.Tasks">
       <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
     </Reference>
diff --git a/src/csharp/Grpc.IntegrationTesting/packages.config b/src/csharp/Grpc.IntegrationTesting/packages.config
index 68490dc..462dc9d 100644
--- a/src/csharp/Grpc.IntegrationTesting/packages.config
+++ b/src/csharp/Grpc.IntegrationTesting/packages.config
@@ -2,10 +2,10 @@
 <packages>
   <package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
   <package id="CommandLineParser" version="1.9.71" targetFramework="net45" />
-  <package id="Google.Apis.Auth" version="1.9.3" targetFramework="net45" />
-  <package id="Google.Apis.Core" version="1.9.3" targetFramework="net45" />
+  <package id="Google.Apis.Auth" version="1.10.0" targetFramework="net45" />
+  <package id="Google.Apis.Core" version="1.10.0" targetFramework="net45" />
   <package id="Google.Protobuf" version="3.0.0-beta2" targetFramework="net45" />
-  <package id="Ix-Async" version="1.2.3" targetFramework="net45" />
+  <package id="Ix-Async" version="1.2.5" targetFramework="net45" />
   <package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" />
   <package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net45" />
   <package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net45" />
diff --git a/src/csharp/build_packages.bat b/src/csharp/build_packages.bat
index 6912dad..7a34bf3 100644
--- a/src/csharp/build_packages.bat
+++ b/src/csharp/build_packages.bat
@@ -1,8 +1,7 @@
 @rem Builds gRPC NuGet packages
 
 @rem Current package versions
-set VERSION=0.12.0
-set CORE_VERSION=0.12.0
+set VERSION=0.13.0
 set PROTOBUF_VERSION=3.0.0-beta2
 
 @rem Packages that depend on prerelease packages (like Google.Protobuf) need to have prerelease suffix as well.
@@ -38,9 +37,9 @@
 @rem TODO(jtattermusch): re-enable protoc plugin building
 @rem @call ..\..\vsprojects\build_plugins.bat || goto :error
 
-%NUGET% pack grpc.native.csharp\grpc.native.csharp.nuspec -Version %CORE_VERSION% || goto :error
+%NUGET% pack grpc.native.csharp\grpc.native.csharp.nuspec -Version %VERSION% || goto :error
 %NUGET% pack Grpc.Auth\Grpc.Auth.nuspec -Symbols -Version %VERSION% || goto :error
-%NUGET% pack Grpc.Core\Grpc.Core.nuspec -Symbols -Version %VERSION% -Properties GrpcNativeCsharpVersion=%CORE_VERSION% || goto :error
+%NUGET% pack Grpc.Core\Grpc.Core.nuspec -Symbols -Version %VERSION% || goto :error
 %NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION_WITH_BETA% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error
 %NUGET% pack Grpc.nuspec -Version %VERSION% || goto :error
 
diff --git a/src/node/ext/byte_buffer.cc b/src/node/ext/byte_buffer.cc
index c306292..ee703fd 100644
--- a/src/node/ext/byte_buffer.cc
+++ b/src/node/ext/byte_buffer.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -69,7 +69,7 @@
     return scope.Escape(Nan::Null());
   }
   size_t length = grpc_byte_buffer_length(buffer);
-  char *result = reinterpret_cast<char *>(calloc(length, sizeof(char)));
+  char *result = new char[length];
   size_t offset = 0;
   grpc_byte_buffer_reader reader;
   grpc_byte_buffer_reader_init(&reader, buffer);
diff --git a/src/node/index.js b/src/node/index.js
index 0d1a7fd..7eacdc6 100644
--- a/src/node/index.js
+++ b/src/node/index.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -51,7 +51,7 @@
 
 var Metadata = require('./src/metadata.js');
 
-var grpc = require('bindings')('grpc_node');
+var grpc = require('./src/grpc_extension');
 
 /**
  * Load a gRPC object from an existing ProtoBuf.Reflect object.
diff --git a/src/node/src/client.js b/src/node/src/client.js
index d578267..b5247a6 100644
--- a/src/node/src/client.js
+++ b/src/node/src/client.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -51,7 +51,7 @@
 
 var _ = require('lodash');
 
-var grpc = require('bindings')('grpc_node');
+var grpc = require('./grpc_extension');
 
 var common = require('./common');
 
diff --git a/src/node/src/credentials.js b/src/node/src/credentials.js
index dcbfac1..710ab6d 100644
--- a/src/node/src/credentials.js
+++ b/src/node/src/credentials.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -61,7 +61,7 @@
 
 'use strict';
 
-var grpc = require('bindings')('grpc_node.node');
+var grpc = require('./grpc_extension');
 
 var CallCredentials = grpc.CallCredentials;
 
diff --git a/src/node/src/grpc_extension.js b/src/node/src/grpc_extension.js
new file mode 100644
index 0000000..d4eca65
--- /dev/null
+++ b/src/node/src/grpc_extension.js
@@ -0,0 +1,40 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+var binary = require('node-pre-gyp');
+var path = require('path');
+var binding_path = binary.find(path.resolve(
+    path.join(__dirname,'../../../package.json')));
+var binding = require(binding_path);
+
+module.exports = binding;
diff --git a/src/node/src/metadata.js b/src/node/src/metadata.js
index fef79f9..51a9f8a 100644
--- a/src/node/src/metadata.js
+++ b/src/node/src/metadata.js
@@ -49,7 +49,7 @@
 
 var _ = require('lodash');
 
-var grpc = require('bindings')('grpc_node');
+var grpc = require('./grpc_extension');
 
 /**
  * Class for storing metadata. Keys are normalized to lowercase ASCII.
diff --git a/src/node/src/server.js b/src/node/src/server.js
index ceaa9f5..e5aadcd 100644
--- a/src/node/src/server.js
+++ b/src/node/src/server.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -51,7 +51,7 @@
 
 var _ = require('lodash');
 
-var grpc = require('bindings')('grpc_node');
+var grpc = require('./grpc_extension');
 
 var common = require('./common');
 
diff --git a/src/node/test/call_test.js b/src/node/test/call_test.js
index f1f86b3..2300096 100644
--- a/src/node/test/call_test.js
+++ b/src/node/test/call_test.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,7 +34,7 @@
 'use strict';
 
 var assert = require('assert');
-var grpc = require('bindings')('grpc_node');
+var grpc = require('../src/grpc_extension');
 
 /**
  * Helper function to return an absolute deadline given a relative timeout in
diff --git a/src/node/test/channel_test.js b/src/node/test/channel_test.js
index 7163a5f..c0ae2b7 100644
--- a/src/node/test/channel_test.js
+++ b/src/node/test/channel_test.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,7 +34,7 @@
 'use strict';
 
 var assert = require('assert');
-var grpc = require('bindings')('grpc_node');
+var grpc = require('../src/grpc_extension');
 
 /**
  * This is used for testing functions with multiple asynchronous calls that
diff --git a/src/node/test/constant_test.js b/src/node/test/constant_test.js
index b17cd33..712c707 100644
--- a/src/node/test/constant_test.js
+++ b/src/node/test/constant_test.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,7 +34,7 @@
 'use strict';
 
 var assert = require('assert');
-var grpc = require('bindings')('grpc_node');
+var grpc = require('../src/grpc_extension');
 
 /**
  * List of all status names
diff --git a/src/node/test/end_to_end_test.js b/src/node/test/end_to_end_test.js
index 0f6c594..353c6c7 100644
--- a/src/node/test/end_to_end_test.js
+++ b/src/node/test/end_to_end_test.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,7 +34,7 @@
 'use strict';
 
 var assert = require('assert');
-var grpc = require('bindings')('grpc_node');
+var grpc = require('../src/grpc_extension');
 
 /**
  * This is used for testing functions with multiple asynchronous calls that
diff --git a/src/node/test/server_test.js b/src/node/test/server_test.js
index 592f47e..71a9647 100644
--- a/src/node/test/server_test.js
+++ b/src/node/test/server_test.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,7 @@
 var assert = require('assert');
 var fs = require('fs');
 var path = require('path');
-var grpc = require('bindings')('grpc_node');
+var grpc = require('../src/grpc_extension');
 
 describe('server', function() {
   describe('constructor', function() {
diff --git a/src/node/test/surface_test.js b/src/node/test/surface_test.js
index fc765ed..c65d95f 100644
--- a/src/node/test/surface_test.js
+++ b/src/node/test/surface_test.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -952,6 +952,7 @@
   describe('Cancellation', function() {
     it('With a unary call', function(done) {
       done = multiDone(done, 2);
+      var call;
       proxy_impl.unary = function(parent, callback) {
         client.unary(parent.request, function(err, value) {
           try {
@@ -969,12 +970,13 @@
       proxy.start();
       var proxy_client = new Client('localhost:' + proxy_port,
                                     grpc.credentials.createInsecure());
-      var call = proxy_client.unary({}, function(err, value) {
+      call = proxy_client.unary({}, function(err, value) {
         done();
       });
     });
     it('With a client stream call', function(done) {
       done = multiDone(done, 2);
+      var call;
       proxy_impl.clientStream = function(parent, callback) {
         client.clientStream(function(err, value) {
           try {
@@ -992,12 +994,13 @@
       proxy.start();
       var proxy_client = new Client('localhost:' + proxy_port,
                                     grpc.credentials.createInsecure());
-      var call = proxy_client.clientStream(function(err, value) {
+      call = proxy_client.clientStream(function(err, value) {
         done();
       });
     });
     it('With a server stream call', function(done) {
       done = multiDone(done, 2);
+      var call;
       proxy_impl.serverStream = function(parent) {
         var child = client.serverStream(parent.request, null,
                                         {parent: parent});
@@ -1013,13 +1016,14 @@
       proxy.start();
       var proxy_client = new Client('localhost:' + proxy_port,
                                     grpc.credentials.createInsecure());
-      var call = proxy_client.serverStream({});
+      call = proxy_client.serverStream({});
       call.on('error', function(err) {
         done();
       });
     });
     it('With a bidi stream call', function(done) {
       done = multiDone(done, 2);
+      var call;
       proxy_impl.bidiStream = function(parent) {
         var child = client.bidiStream(null, {parent: parent});
         child.on('error', function(err) {
@@ -1034,7 +1038,7 @@
       proxy.start();
       var proxy_client = new Client('localhost:' + proxy_port,
                                     grpc.credentials.createInsecure());
-      var call = proxy_client.bidiStream();
+      call = proxy_client.bidiStream();
       call.on('error', function(err) {
         done();
       });
diff --git a/src/proto/grpc/testing/control.proto b/src/proto/grpc/testing/control.proto
index 0784ebf..7ba6f98 100644
--- a/src/proto/grpc/testing/control.proto
+++ b/src/proto/grpc/testing/control.proto
@@ -1,4 +1,4 @@
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -42,6 +42,7 @@
 enum ServerType {
   SYNC_SERVER = 0;
   ASYNC_SERVER = 1;
+  ASYNC_GENERIC_SERVER = 2;
 }
 
 enum RpcType {
diff --git a/src/proto/grpc/testing/echo_messages.proto b/src/proto/grpc/testing/echo_messages.proto
index f01d645..d05a355 100644
--- a/src/proto/grpc/testing/echo_messages.proto
+++ b/src/proto/grpc/testing/echo_messages.proto
@@ -1,5 +1,5 @@
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -41,6 +41,7 @@
   int32 response_message_length = 6;
   bool echo_peer = 7;
   string expected_client_identity = 8; // will force check_auth_context.
+  bool skip_cancelled_check = 9;
 }
 
 message EchoRequest {
diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py
index bd12c55..a6b8ad3 100644
--- a/src/python/grpcio/commands.py
+++ b/src/python/grpcio/commands.py
@@ -30,16 +30,25 @@
 """Provides distutils command classes for the GRPC Python setup process."""
 
 import distutils
+import glob
 import os
 import os.path
+import platform
 import re
+import shutil
 import subprocess
 import sys
+import traceback
 
 import setuptools
-from setuptools.command import build_py
-from setuptools.command import test
+from setuptools.command import bdist_egg
 from setuptools.command import build_ext
+from setuptools.command import build_py
+from setuptools.command import easy_install
+from setuptools.command import install
+from setuptools.command import test
+
+import support
 
 PYTHON_STEM = os.path.dirname(os.path.abspath(__file__))
 
@@ -56,6 +65,129 @@
   """Simple exception class for GRPC custom commands."""
 
 
+# TODO(atash): Remove this once PyPI has better Linux bdist support. See
+# https://bitbucket.org/pypa/pypi/issues/120/binary-wheels-for-linux-are-not-supported
+def _get_linux_bdist_egg(decorated_basename, target_egg_basename):
+  """Returns a string path to a .egg file for Linux to install.
+
+  If we can retrieve a pre-compiled egg from online, uses it. Else, emits a
+  warning and builds from source.
+  """
+  # Break import style to ensure that setup.py has had a chance to install the
+  # relevant package eggs.
+  from six.moves.urllib import request
+  decorated_path = decorated_basename + '.egg'
+  try:
+    url = (
+        'https://storage.googleapis.com/grpc-precompiled-binaries/'
+        'python/{target}'
+            .format(target=decorated_path))
+    egg_data = request.urlopen(url).read()
+  except IOError as error:
+    raise CommandError(
+        '{}\n\nCould not find the bdist egg {}: {}'
+            .format(traceback.format_exc(), decorated_path, error.message))
+  # Our chosen local egg path.
+  egg_path = target_egg_basename + '.egg'
+  try:
+    with open(egg_path, 'w') as egg_file:
+      egg_file.write(egg_data)
+  except IOError as error:
+    raise CommandError(
+        '{}\n\nCould not write grpcio egg: {}'
+            .format(traceback.format_exc(), error.message))
+  return egg_path
+
+
+class EggNameMixin(object):
+
+  def egg_name(self, with_custom):
+    """
+    Args:
+      with_custom: Boolean describing whether or not to decorate the egg name
+        with custom gRPC-specific target information.
+    """
+    egg_command = self.get_finalized_command('bdist_egg')
+    base = os.path.splitext(os.path.basename(egg_command.egg_output))[0]
+    if with_custom:
+      flavor = 'ucs2' if sys.maxunicode == 65535 else 'ucs4'
+      return '{base}-{flavor}'.format(base=base, flavor=flavor)
+    else:
+      return base
+
+
+class Install(install.install, EggNameMixin):
+  """Custom Install command for gRPC Python.
+
+  This is for bdist shims and whatever else we might need a custom install
+  command for.
+  """
+
+  user_options = install.install.user_options + [
+      # TODO(atash): remove this once manylinux gets on PyPI. See
+      # https://bitbucket.org/pypa/pypi/issues/120/binary-wheels-for-linux-are-not-supported
+      ('use-linux-bdist', None,
+       'Whether to retrieve a binary for Linux instead of building from '
+       'source.'),
+  ]
+
+  def initialize_options(self):
+    install.install.initialize_options(self)
+    self.use_linux_bdist = False
+
+  def finalize_options(self):
+    install.install.finalize_options(self)
+
+  def run(self):
+    if self.use_linux_bdist:
+      try:
+        egg_path = _get_linux_bdist_egg(self.egg_name(True),
+                                        self.egg_name(False))
+      except CommandError as error:
+        sys.stderr.write(
+            '\nWARNING: Failed to acquire grpcio prebuilt binary:\n'
+            '{}.\n\n'.format(error.message))
+        raise
+      try:
+        self._run_bdist_retrieval_install(egg_path)
+      except Exception as error:
+        # if anything else happens (and given how there's no way to really know
+        # what's happening in setuptools here, I mean *anything*), warn the user
+        # and fall back to building from source.
+        sys.stderr.write(
+            '{}\nWARNING: Failed to install grpcio prebuilt binary.\n\n'
+                .format(traceback.format_exc()))
+        install.install.run(self)
+    else:
+      install.install.run(self)
+
+  # TODO(atash): Remove this once PyPI has better Linux bdist support. See
+  # https://bitbucket.org/pypa/pypi/issues/120/binary-wheels-for-linux-are-not-supported
+  def _run_bdist_retrieval_install(self, bdist_egg):
+    easy_install = self.distribution.get_command_class('easy_install')
+    easy_install_command = easy_install(
+        self.distribution, args='x', root=self.root, record=self.record,
+    )
+    easy_install_command.ensure_finalized()
+    easy_install_command.always_copy_from = '.'
+    easy_install_command.package_index.scan(glob.glob('*.egg'))
+    arguments = [bdist_egg]
+    if setuptools.bootstrap_install_from:
+      args.insert(0, setuptools.bootstrap_install_from)
+    easy_install_command.args = arguments
+    easy_install_command.run()
+    setuptools.bootstrap_install_from = None
+
+
+class BdistEggCustomName(bdist_egg.bdist_egg, EggNameMixin):
+  """Thin wrapper around the bdist_egg command to build with our custom name."""
+
+  def run(self):
+    bdist_egg.bdist_egg.run(self)
+    target = os.path.join(self.dist_dir, '{}.egg'.format(self.egg_name(True)))
+    shutil.move(self.get_outputs()[0], target)
+
+
 class SphinxDocumentation(setuptools.Command):
   """Command to generate documentation via sphinx."""
 
@@ -186,7 +318,13 @@
     if compiler in BuildExt.LINK_OPTIONS:
       for extension in self.extensions:
         extension.extra_link_args += list(BuildExt.LINK_OPTIONS[compiler])
-    build_ext.build_ext.build_extensions(self)
+    try:
+      build_ext.build_ext.build_extensions(self)
+    except KeyboardInterrupt:
+      raise
+    except Exception as error:
+      support.diagnose_build_ext_error(self, error)
+      raise CommandError("Failed `build_ext` step.")
 
 
 class Gather(setuptools.Command):
diff --git a/src/python/grpcio/grpc/framework/foundation/logging_pool.py b/src/python/grpcio/grpc/framework/foundation/logging_pool.py
index 7c7a6ee..f82c7f7 100644
--- a/src/python/grpcio/grpc/framework/foundation/logging_pool.py
+++ b/src/python/grpcio/grpc/framework/foundation/logging_pool.py
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -29,7 +29,6 @@
 
 """A thread pool that logs exceptions raised by tasks executed within it."""
 
-import functools
 import logging
 
 from concurrent import futures
@@ -37,12 +36,12 @@
 
 def _wrap(behavior):
   """Wraps an arbitrary callable behavior in exception-logging."""
-  @functools.wraps(behavior)
   def _wrapping(*args, **kwargs):
     try:
       return behavior(*args, **kwargs)
     except Exception as e:
-      logging.exception('Unexpected exception from task run in logging pool!')
+      logging.exception(
+          'Unexpected exception from %s executed in logging pool!', behavior)
       raise
   return _wrapping
 
diff --git a/src/python/grpcio/support.py b/src/python/grpcio/support.py
new file mode 100644
index 0000000..bbc5096
--- /dev/null
+++ b/src/python/grpcio/support.py
@@ -0,0 +1,91 @@
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+import os
+import os.path
+import shutil
+import sys
+import tempfile
+
+from distutils import errors
+
+import commands
+
+
+C_PYTHON_DEV = """
+#include <Python.h>
+int main(int argc, char **argv) { return 0; }
+"""
+C_PYTHON_DEV_ERROR_MESSAGE = """
+Could not find <Python.h>. This could mean the following:
+  * You're on Ubuntu and haven't `apt-get install`ed `python-dev`.
+  * You're on Mac OS X and the usual Python framework was somehow corrupted
+    (check your environment variables or try re-installing?)
+  * You're on Windows and your Python installation was somehow corrupted
+    (check your environment variables or try re-installing?)
+    * Note: Windows users should look into installing `vcpython27`.
+"""
+
+C_CHECKS = {
+  C_PYTHON_DEV: C_PYTHON_DEV_ERROR_MESSAGE,
+}
+
+def _compile(compiler, source_string):
+  tempdir = tempfile.mkdtemp()
+  cpath = os.path.join(tempdir, 'a.c')
+  with open(cpath, 'w') as cfile:
+    cfile.write(source_string)
+  try:
+    compiler.compile([cpath])
+  except errors.CompileError as error:
+    return error
+  finally:
+    shutil.rmtree(tempdir)
+
+def _expect_compile(compiler, source_string, error_message):
+  if _compile(compiler, source_string) is not None:
+    sys.stderr.write(error_message)
+    raise commands.CommandError(
+        "Diagnostics found a compilation environment issue:\n{}"
+            .format(error_message))
+
+def diagnose_build_ext_error(build_ext, error):
+  {
+      errors.CompileError: diagnose_compile_error
+  }[type(error)](build_ext, error)
+
+def diagnose_compile_error(build_ext, error):
+  """Attempt to run a few test files through the compiler to see if we can
+     diagnose the reason for the compile failure."""
+  for c_check, message in C_CHECKS.items():
+    _expect_compile(build_ext.compiler, c_check, message)
+  raise commands.CommandError(
+      "\n\nWe could not diagnose your build failure. Please file an issue at "
+      "http://www.github.com/grpc/grpc with `[Python install]` in the title.")
diff --git a/src/python/grpcio/tests/unit/framework/foundation/_logging_pool_test.py b/src/python/grpcio/tests/unit/framework/foundation/_logging_pool_test.py
index 452802d..0521e1c 100644
--- a/src/python/grpcio/tests/unit/framework/foundation/_logging_pool_test.py
+++ b/src/python/grpcio/tests/unit/framework/foundation/_logging_pool_test.py
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -29,6 +29,7 @@
 
 """Tests for grpc.framework.foundation.logging_pool."""
 
+import threading
 import unittest
 
 from grpc.framework.foundation import logging_pool
@@ -36,6 +37,21 @@
 _POOL_SIZE = 16
 
 
+class _CallableObject(object):
+
+  def __init__(self):
+    self._lock = threading.Lock()
+    self._passed_values = []
+
+  def __call__(self, value):
+    with self._lock:
+      self._passed_values.append(value)
+
+  def passed_values(self):
+    with self._lock:
+      return tuple(self._passed_values)
+
+
 class LoggingPoolTest(unittest.TestCase):
 
   def testUpAndDown(self):
@@ -59,6 +75,14 @@
 
     self.assertIsNotNone(raised_exception)
 
+  def testCallableObjectExecuted(self):
+    callable_object = _CallableObject()
+    passed_object = object()
+    with logging_pool.pool(_POOL_SIZE) as pool:
+      future = pool.submit(callable_object, passed_object)
+    self.assertIsNone(future.result())
+    self.assertSequenceEqual((passed_object,), callable_object.passed_values())
+
 
 if __name__ == '__main__':
   unittest.main(verbosity=2)
diff --git a/src/python/grpcio/tests/unit/framework/interfaces/face/_blocking_invocation_inline_service.py b/src/python/grpcio/tests/unit/framework/interfaces/face/_blocking_invocation_inline_service.py
index 3bcefa6..c8a3a1b 100644
--- a/src/python/grpcio/tests/unit/framework/interfaces/face/_blocking_invocation_inline_service.py
+++ b/src/python/grpcio/tests/unit/framework/interfaces/face/_blocking_invocation_inline_service.py
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -30,9 +30,12 @@
 """Test code for the Face layer of RPC Framework."""
 
 import abc
+import itertools
 import unittest
+from concurrent import futures
 
 # test_interfaces is referenced from specification in this module.
+from grpc.framework.foundation import logging_pool
 from grpc.framework.interfaces.face import face
 from tests.unit.framework.common import test_constants
 from tests.unit.framework.common import test_control
@@ -139,13 +142,50 @@
 
         test_messages.verify(second_request, second_response, self)
 
-  @unittest.skip('Parallel invocations impossible with blocking control flow!')
   def testParallelInvocations(self):
-    raise NotImplementedError()
+    pool = logging_pool.pool(test_constants.PARALLELISM)
+    for (group, method), test_messages_sequence in (
+        self._digest.unary_unary_messages_sequences.iteritems()):
+      for test_messages in test_messages_sequence:
+        requests = []
+        response_futures = []
+        for _ in range(test_constants.PARALLELISM):
+          request = test_messages.request()
+          response_future = pool.submit(
+              self._invoker.blocking(group, method), request,
+              test_constants.LONG_TIMEOUT)
+          requests.append(request)
+          response_futures.append(response_future)
 
-  @unittest.skip('Parallel invocations impossible with blocking control flow!')
+        responses = [
+            response_future.result() for response_future in response_futures]
+
+        for request, response in zip(requests, responses):
+          test_messages.verify(request, response, self)
+    pool.shutdown(wait=True)
+
   def testWaitingForSomeButNotAllParallelInvocations(self):
-    raise NotImplementedError()
+    pool = logging_pool.pool(test_constants.PARALLELISM)
+    for (group, method), test_messages_sequence in (
+        self._digest.unary_unary_messages_sequences.iteritems()):
+      for test_messages in test_messages_sequence:
+        requests = []
+        response_futures_to_indices = {}
+        for index in range(test_constants.PARALLELISM):
+          request = test_messages.request()
+          response_future = pool.submit(
+              self._invoker.blocking(group, method), request,
+              test_constants.LONG_TIMEOUT)
+          requests.append(request)
+          response_futures_to_indices[response_future] = index
+
+        some_completed_response_futures_iterator = itertools.islice(
+            futures.as_completed(response_futures_to_indices),
+            test_constants.PARALLELISM / 2)
+        for response_future in some_completed_response_futures_iterator:
+          index = response_futures_to_indices[response_future]
+          test_messages.verify(requests[index], response_future.result(), self)
+    pool.shutdown(wait=True)
 
   @unittest.skip('Cancellation impossible with blocking control flow!')
   def testCancelledUnaryRequestUnaryResponse(self):
diff --git a/src/python/grpcio/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py b/src/python/grpcio/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py
index fc8daa9..1d36a93 100644
--- a/src/python/grpcio/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py
+++ b/src/python/grpcio/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py
@@ -31,8 +31,10 @@
 
 import abc
 import contextlib
+import itertools
 import threading
 import unittest
+from concurrent import futures
 
 # test_interfaces is referenced from specification in this module.
 from grpc.framework.foundation import logging_pool
@@ -219,6 +221,23 @@
 
         test_messages.verify(second_request, second_response, self)
 
+  def testParallelInvocations(self):
+    for (group, method), test_messages_sequence in (
+        self._digest.unary_unary_messages_sequences.iteritems()):
+      for test_messages in test_messages_sequence:
+        first_request = test_messages.request()
+        second_request = test_messages.request()
+
+        first_response_future = self._invoker.future(group, method)(
+            first_request, test_constants.LONG_TIMEOUT)
+        second_response_future = self._invoker.future(group, method)(
+            second_request, test_constants.LONG_TIMEOUT)
+        first_response = first_response_future.result()
+        second_response = second_response_future.result()
+
+        test_messages.verify(first_request, first_response, self)
+        test_messages.verify(second_request, second_response, self)
+
     for (group, method), test_messages_sequence in (
         self._digest.unary_unary_messages_sequences.iteritems()):
       for test_messages in test_messages_sequence:
@@ -237,26 +256,28 @@
         for request, response in zip(requests, responses):
           test_messages.verify(request, response, self)
 
-  def testParallelInvocations(self):
+  def testWaitingForSomeButNotAllParallelInvocations(self):
+    pool = logging_pool.pool(test_constants.PARALLELISM)
     for (group, method), test_messages_sequence in (
         self._digest.unary_unary_messages_sequences.iteritems()):
       for test_messages in test_messages_sequence:
-        first_request = test_messages.request()
-        second_request = test_messages.request()
+        requests = []
+        response_futures_to_indices = {}
+        for index in range(test_constants.PARALLELISM):
+          request = test_messages.request()
+          inner_response_future = self._invoker.future(group, method)(
+              request, test_constants.LONG_TIMEOUT)
+          outer_response_future = pool.submit(inner_response_future.result)
+          requests.append(request)
+          response_futures_to_indices[outer_response_future] = index
 
-        first_response_future = self._invoker.future(group, method)(
-            first_request, test_constants.LONG_TIMEOUT)
-        second_response_future = self._invoker.future(group, method)(
-            second_request, test_constants.LONG_TIMEOUT)
-        first_response = first_response_future.result()
-        second_response = second_response_future.result()
-
-        test_messages.verify(first_request, first_response, self)
-        test_messages.verify(second_request, second_response, self)
-
-  @unittest.skip('TODO(nathaniel): implement.')
-  def testWaitingForSomeButNotAllParallelInvocations(self):
-    raise NotImplementedError()
+        some_completed_response_futures_iterator = itertools.islice(
+            futures.as_completed(response_futures_to_indices),
+            test_constants.PARALLELISM / 2)
+        for response_future in some_completed_response_futures_iterator:
+          index = response_futures_to_indices[response_future]
+          test_messages.verify(requests[index], response_future.result(), self)
+    pool.shutdown(wait=True)
 
   def testCancelledUnaryRequestUnaryResponse(self):
     for (group, method), test_messages_sequence in (
diff --git a/src/python/grpcio/tests/unit/framework/interfaces/face/_receiver.py b/src/python/grpcio/tests/unit/framework/interfaces/face/_receiver.py
index 2e444ff..42a7f4e 100644
--- a/src/python/grpcio/tests/unit/framework/interfaces/face/_receiver.py
+++ b/src/python/grpcio/tests/unit/framework/interfaces/face/_receiver.py
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -76,7 +76,7 @@
   def unary_response(self):
     with self._condition:
       if self._abortion is not None:
-        raise AssertionError('Aborted with abortion "%s"!' % self._abortion)
+        raise AssertionError('Aborted: "{}"!'.format(self._abortion))
       elif len(self._responses) != 1:
         raise AssertionError(
             '%d responses received, not exactly one!', len(self._responses))
@@ -88,7 +88,7 @@
       if self._abortion is None:
         return list(self._responses)
       else:
-        raise AssertionError('Aborted with abortion "%s"!' % self._abortion)
+        raise AssertionError('Aborted: "{}"!'.format(self._abortion))
 
   def abortion(self):
     with self._condition:
diff --git a/src/ruby/ext/grpc/rb_call.c b/src/ruby/ext/grpc/rb_call.c
index 43adafb..8f33d72 100644
--- a/src/ruby/ext/grpc/rb_call.c
+++ b/src/ruby/ext/grpc/rb_call.c
@@ -525,12 +525,12 @@
   grpc_status_code recv_status;
   char *recv_status_details;
   size_t recv_status_details_capacity;
-  uint write_flag;
+  unsigned write_flag;
 } run_batch_stack;
 
 /* grpc_run_batch_stack_init ensures the run_batch_stack is properly
  * initialized */
-static void grpc_run_batch_stack_init(run_batch_stack *st, uint write_flag) {
+static void grpc_run_batch_stack_init(run_batch_stack *st, unsigned write_flag) {
   MEMZERO(st, run_batch_stack, 1);
   grpc_metadata_array_init(&st->send_metadata);
   grpc_metadata_array_init(&st->send_trailing_metadata);
@@ -696,7 +696,7 @@
   grpc_call_error err;
   VALUE result = Qnil;
   VALUE rb_write_flag = rb_ivar_get(self, id_write_flag);
-  uint write_flag = 0;
+  unsigned write_flag = 0;
   TypedData_Get_Struct(self, grpc_call, &grpc_call_data_type, call);
 
   /* Validate the ops args, adding them to a ruby array */
diff --git a/src/ruby/ext/grpc/rb_call_credentials.c b/src/ruby/ext/grpc/rb_call_credentials.c
index 4d719d7..ebcc659 100644
--- a/src/ruby/ext/grpc/rb_call_credentials.c
+++ b/src/ruby/ext/grpc/rb_call_credentials.c
@@ -79,6 +79,7 @@
 static VALUE grpc_rb_call_credentials_callback_rescue(VALUE args,
                                                       VALUE exception_object) {
   VALUE result = rb_hash_new();
+  (void)args;
   rb_hash_aset(result, rb_str_new2("metadata"), Qnil);
   /* Currently only gives the exception class name. It should be possible get
      more details */
@@ -132,6 +133,7 @@
 }
 
 static void grpc_rb_call_credentials_plugin_destroy(void *state) {
+  (void)state;
   // Not sure what needs to be done here
 }
 
diff --git a/src/ruby/ext/grpc/rb_event_thread.c b/src/ruby/ext/grpc/rb_event_thread.c
index 95af091..516f0bd 100644
--- a/src/ruby/ext/grpc/rb_event_thread.c
+++ b/src/ruby/ext/grpc/rb_event_thread.c
@@ -102,6 +102,7 @@
 
 static void *grpc_rb_wait_for_event_no_gil(void *param) {
   grpc_rb_event *event = NULL;
+  (void)param;
   gpr_mu_lock(&event_queue.mu);
   while ((event = grpc_rb_event_queue_dequeue()) == NULL) {
     gpr_cv_wait(&event_queue.cv,
@@ -117,6 +118,7 @@
 }
 
 static void grpc_rb_event_unblocking_func(void *arg) {
+  (void)arg;
   gpr_mu_lock(&event_queue.mu);
   event_queue.abort = true;
   gpr_cv_signal(&event_queue.cv);
@@ -127,6 +129,7 @@
  * events */
 static VALUE grpc_rb_event_thread(VALUE arg) {
   grpc_rb_event *event;
+  (void)arg;
   while(true) {
     event = (grpc_rb_event*)rb_thread_call_without_gvl(
         grpc_rb_wait_for_event_no_gil, NULL,
diff --git a/src/zlib/gen_build_yaml.py b/src/zlib/gen_build_yaml.py
index 8d6064b..4bd5573 100755
--- a/src/zlib/gen_build_yaml.py
+++ b/src/zlib/gen_build_yaml.py
@@ -54,6 +54,7 @@
   out['libs'] = [{
       'name': 'z',
       'zlib': True,
+      'defaults': 'zlib',
       'build': 'private',
       'language': 'c',
       'secure': 'no',
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 91f26a3..1770d0f 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -130,26 +130,44 @@
 
   prefix ?= /usr/local
 
-  PROTOC = protoc
-  DTRACE = dtrace
+  PROTOC ?= protoc
+  DTRACE ?= dtrace
   CONFIG ?= opt
+  # Doing X ?= Y is the same as:
+  # ifeq ($(origin X), undefined)
+  #  X = Y
+  # endif
+  # but some variables, such as CC, CXX, LD or AR, have defaults.
+  # So instead of using ?= on them, we need to check their origin.
+  # See:
+  #  https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html
+  #  https://www.gnu.org/software/make/manual/html_node/Flavors.html#index-_003f_003d
+  #  https://www.gnu.org/software/make/manual/html_node/Origin-Function.html
+  ifeq ($(origin CC), default)
   CC = $(CC_$(CONFIG))
+  endif
+  ifeq ($(origin CXX), default)
   CXX = $(CXX_$(CONFIG))
+  endif
+  ifeq ($(origin LD), default)
   LD = $(LD_$(CONFIG))
-  LDXX = $(LDXX_$(CONFIG))
+  endif
+  LDXX ?= $(LDXX_$(CONFIG))
+  ifeq ($(origin AR), default)
   AR = ar
+  endif
   ifeq ($(SYSTEM),Linux)
-  STRIP = strip --strip-unneeded
+  STRIP ?= strip --strip-unneeded
   else
   ifeq ($(SYSTEM),Darwin)
-  STRIP = strip -x
+  STRIP ?= strip -x
   else
-  STRIP = strip
+  STRIP ?= strip
   endif
   endif
-  INSTALL = install
-  RM = rm -f
-  PKG_CONFIG = pkg-config
+  INSTALL ?= install
+  RM ?= rm -f
+  PKG_CONFIG ?= pkg-config
 
   ifndef VALID_CONFIG_$(CONFIG)
   $(error Invalid CONFIG value '$(CONFIG)')
@@ -176,10 +194,10 @@
   # cross-compiling, you can override these variables from GNU make's
   # command line: make CC=cross-gcc HOST_CC=gcc
 
-  HOST_CC = $(CC)
-  HOST_CXX = $(CXX)
-  HOST_LD = $(LD)
-  HOST_LDXX = $(LDXX)
+  HOST_CC ?= $(CC)
+  HOST_CXX ?= $(CXX)
+  HOST_LD ?= $(LD)
+  HOST_LDXX ?= $(LDXX)
 
   ifdef EXTRA_DEFINES
   DEFINES += $(EXTRA_DEFINES)
@@ -191,9 +209,11 @@
   else
   CXXFLAGS += -std=c++0x
   endif
-  CFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter
-  CXXFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter
-  LDFLAGS += -g
+  % for arg in ['CFLAGS', 'CXXFLAGS', 'CPPFLAGS', 'LDFLAGS', 'DEFINES']:
+  %  if defaults.get('global', []).get(arg, None) is not None:
+  ${arg} += ${defaults.get('global').get(arg)}
+  %  endif
+  % endfor
 
   CPPFLAGS += $(CPPFLAGS_$(CONFIG))
   CFLAGS += $(CFLAGS_$(CONFIG))
@@ -321,14 +341,6 @@
   IS_GIT_FOLDER = true
   endif
 
-  ifeq ($(SYSTEM),Linux)
-  OPENSSL_REQUIRES_DL = true
-  endif
-
-  ifeq ($(SYSTEM),Darwin)
-  OPENSSL_REQUIRES_DL = true
-  endif
-
   ifeq ($(HAS_PKG_CONFIG),true)
   OPENSSL_ALPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.2 openssl
   OPENSSL_NPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.1 openssl
@@ -342,25 +354,20 @@
   OPENSSL_LIBS = ssl crypto
   endif
 
-  OPENSSL_ALPN_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/openssl-alpn.c $(addprefix -l, $(OPENSSL_LIBS)) $(LDFLAGS)
-  OPENSSL_NPN_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/openssl-npn.c $(addprefix -l, $(OPENSSL_LIBS)) $(LDFLAGS)
-  ZLIB_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/zlib.c -lz $(LDFLAGS)
-  PROTOBUF_CHECK_CMD = $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/protobuf.cc -lprotobuf $(LDFLAGS)
-
-  ifeq ($(OPENSSL_REQUIRES_DL),true)
-  OPENSSL_ALPN_CHECK_CMD += -ldl
-  OPENSSL_NPN_CHECK_CMD += -ldl
-  endif
+  OPENSSL_ALPN_CHECK_CMD = $(CC) $(CPPFLAGS) $(CFLAGS) -o $(TMPOUT) test/build/openssl-alpn.c $(addprefix -l, $(OPENSSL_LIBS)) $(LDFLAGS)
+  OPENSSL_NPN_CHECK_CMD = $(CC) $(CPPFLAGS) $(CFLAGS) -o $(TMPOUT) test/build/openssl-npn.c $(addprefix -l, $(OPENSSL_LIBS)) $(LDFLAGS)
+  ZLIB_CHECK_CMD = $(CC) $(CPPFLAGS) $(CFLAGS) -o $(TMPOUT) test/build/zlib.c -lz $(LDFLAGS)
+  PROTOBUF_CHECK_CMD = $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $(TMPOUT) test/build/protobuf.cc -lprotobuf $(LDFLAGS)
 
   endif # HAS_PKG_CONFIG
 
-  PERFTOOLS_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/perftools.c -lprofiler $(LDFLAGS)
+  PERFTOOLS_CHECK_CMD = $(CC) $(CPPFLAGS) $(CFLAGS) -o $(TMPOUT) test/build/perftools.c -lprofiler $(LDFLAGS)
 
   PROTOC_CHECK_CMD = which protoc > /dev/null
   PROTOC_CHECK_VERSION_CMD = protoc --version | grep -q libprotoc.3
   DTRACE_CHECK_CMD = which dtrace > /dev/null
-  SYSTEMTAP_HEADERS_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/systemtap.c $(LDFLAGS)
-  ZOOKEEPER_CHECK_CMD = $(CC) $(CFLAGS) $(CPPFLAGS) -o $(TMPOUT) test/build/zookeeper.c $(LDFLAGS) -lzookeeper_mt
+  SYSTEMTAP_HEADERS_CHECK_CMD = $(CC) $(CPPFLAGS) $(CFLAGS) -o $(TMPOUT) test/build/systemtap.c $(LDFLAGS)
+  ZOOKEEPER_CHECK_CMD = $(CC) $(CPPFLAGS) $(CFLAGS) -o $(TMPOUT) test/build/zookeeper.c $(LDFLAGS) -lzookeeper_mt
 
   ifndef REQUIRE_CUSTOM_LIBRARIES_$(CONFIG)
   HAS_SYSTEM_PERFTOOLS ?= $(shell $(PERFTOOLS_CHECK_CMD) 2> /dev/null && echo true || echo false)
@@ -515,9 +522,6 @@
   OPENSSL_MERGE_LIBS += $(LIBDIR)/$(CONFIG)/libboringssl.a
   # need to prefix these to ensure overriding system libraries
   CPPFLAGS := -Ithird_party/boringssl/include $(CPPFLAGS)
-  ifeq ($(OPENSSL_REQUIRES_DL),true)
-  LIBS_SECURE = dl
-  endif # OPENSSL_REQUIRES_DL
   else # EMBED_OPENSSL=false
   ifeq ($(HAS_PKG_CONFIG),true)
   OPENSSL_PKG_CONFIG = true
@@ -537,10 +541,7 @@
   CPPFLAGS += -DTSI_OPENSSL_ALPN_SUPPORT=0
   LIBS_SECURE = $(OPENSSL_LIBS)
   endif # HAS_SYSTEM_OPENSSL_NPN
-  ifeq ($(OPENSSL_REQUIRES_DL),true)
-  LIBS_SECURE += dl
   PC_LIBS_SECURE = $(addprefix -l, $(LIBS_SECURE))
-  endif # OPENSSL_REQUIRES_DL=true
   endif # EMBED_OPENSSL
   endif # NO_SECURE
 
@@ -1199,12 +1200,12 @@
   $(OBJDIR)/$(CONFIG)/%.o : %.c
   	$(E) "[C]       Compiling $<"
   	$(Q) mkdir -p `dirname $@`
-  	$(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
+  	$(Q) $(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
 
   $(OBJDIR)/$(CONFIG)/%.o : $(GENDIR)/%.pb.cc
   	$(E) "[CXX]     Compiling $<"
   	$(Q) mkdir -p `dirname $@`
-  	$(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
+  	$(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
 
   $(OBJDIR)/$(CONFIG)/src/compiler/%.o : src/compiler/%.cc
   	$(E) "[HOSTCXX] Compiling $<"
@@ -1214,7 +1215,7 @@
   $(OBJDIR)/$(CONFIG)/%.o : %.cc
   	$(E) "[CXX]     Compiling $<"
   	$(Q) mkdir -p `dirname $@`
-  	$(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
+  	$(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
 
   install: install_c install_cxx install-plugins install-certs verify-install
 
@@ -1436,16 +1437,10 @@
 
   LIB${lib.name.upper()}_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIB${lib.name.upper()}_SRC))))
 
-  % if lib.boringssl:
-  # boringssl needs an override to ensure that it does not include
-  # system openssl headers regardless of other configuration
-  # we do so here with a target specific variable assignment
-  $(LIB${lib.name.upper()}_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -fvisibility=hidden
-  $(LIB${lib.name.upper()}_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -fvisibility=hidden
-  $(LIB${lib.name.upper()}_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
-  % elif lib.zlib:
-  $(LIB${lib.name.upper()}_OBJS): CFLAGS := $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-implicit-function-declaration $(W_NO_SHIFT_NEGATIVE_VALUE) -fvisibility=hidden
-  % else:
+  % if lib.get('defaults', None):
+  %  for name, value in defaults.get(lib.defaults).iteritems():
+  $(LIB${lib.name.upper()}_OBJS): ${name} += ${value}
+  %  endfor
   % endif
 
   ## If the library requires OpenSSL, let's add some restrictions.
@@ -1505,7 +1500,10 @@
   else
 
   % endif
-  $(LIBDIR)/$(CONFIG)/lib${lib.name}.a: $(ZLIB_DEP) $(OPENSSL_DEP) \
+  $(LIBDIR)/$(CONFIG)/lib${lib.name}.a: \
+  % if lib.name != 'z':
+  $(ZLIB_DEP) \
+  % endif
   % endif
   % if lib.language == 'c++':
    $(PROTOBUF_DEP)\
@@ -1790,7 +1788,7 @@
   $(OBJDIR)/$(CONFIG)/${os.path.splitext(src)[0]}.o : ${src}
   	$(E) "[C]       Compiling $<"
   	$(Q) mkdir -p `dirname $@`
-  	$(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -std=c89 -pedantic -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
+  	$(Q) $(CC) $(CPPFLAGS) $(CFLAGS) -std=c89 -pedantic -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
   % endfor
   % endif
 
diff --git a/templates/binding.gyp.template b/templates/binding.gyp.template
index 8014ff3..71276e7 100644
--- a/templates/binding.gyp.template
+++ b/templates/binding.gyp.template
@@ -7,7 +7,7 @@
   # This file can be regenerated from the template by running
   # tools/buildgen/generate_projects.sh
 
-  # Copyright 2015, Google Inc.
+  # Copyright 2015-2016, Google Inc.
   # All rights reserved.
   #
   # Redistribution and use in source and binary forms, with or without
@@ -56,12 +56,16 @@
       ],
       'include_dirs': [
         '.',
-        'include',
-        '<(node_root_dir)/deps/openssl/openssl/include',
-        '<(node_root_dir)/deps/zlib'
+        'include'
       ],
       'conditions': [
-        ['OS != "win"', {
+        ['OS == "win"', {
+          "include_dirs": [ "third_party/boringssl/include" ]
+        }, {
+          'include_dirs': [
+            '<(node_root_dir)/deps/openssl/openssl/include',
+            '<(node_root_dir)/deps/zlib'
+          ],
           'conditions': [
             ['config=="gcov"', {
               'cflags': [
@@ -74,24 +78,58 @@
                 '-fprofile-arcs'
               ]
             }
-           ]
+           ],
+           ["target_arch=='ia32'", {
+               "include_dirs": [ "<(node_root_dir)/deps/openssl/config/piii" ]
+           }],
+           ["target_arch=='x64'", {
+               "include_dirs": [ "<(node_root_dir)/deps/openssl/config/k8" ]
+           }],
+           ["target_arch=='arm'", {
+               "include_dirs": [ "<(node_root_dir)/deps/openssl/config/arm" ]
+           }]
           ]
-        }],
-        ["target_arch=='ia32'", {
-            "include_dirs": [ "<(node_root_dir)/deps/openssl/config/piii" ]
-        }],
-        ["target_arch=='x64'", {
-            "include_dirs": [ "<(node_root_dir)/deps/openssl/config/k8" ]
-        }],
-        ["target_arch=='arm'", {
-            "include_dirs": [ "<(node_root_dir)/deps/openssl/config/arm" ]
         }]
       ]
     },
+    'conditions': [
+      ['OS == "win"', {
+        'targets': [
+          # Only want to compile BoringSSL and zlib under Windows
+          % for module in node_modules:
+          % for lib in libs:
+          % if lib.name in module.transitive_deps and lib.name in ('boringssl', 'z'):
+          {
+            'cflags': [
+              '-std=c99',
+              '-Wall',
+              '-Werror'
+            ],
+            'target_name': '${lib.name}',
+            'product_prefix': 'lib',
+            'type': 'static_library',
+            'dependencies': [
+              % for dep in getattr(lib, 'deps', []):
+              '${dep}',
+              % endfor
+            ],
+            'sources': [
+              % for source in lib.src:
+              '${source}',
+              % endfor
+            ],
+            "include_dirs": [ "third_party/boringssl/include" ]
+          },
+          % endif
+          % endfor
+          % endfor
+        ]
+      }]
+    ],
     'targets': [
       % for module in node_modules:
       % for lib in libs:
-      % if lib.name in module.transitive_deps:
+      % if lib.name in module.transitive_deps and lib.name not in ('boringssl', 'z'):
       {
         'cflags': [
           '-std=c99',
@@ -117,7 +155,7 @@
               'MACOSX_DEPLOYMENT_TARGET': '10.9'
             }
           }]
-        ],
+        ]
       },
       % endif
       % endfor
@@ -138,13 +176,22 @@
           '-g'
         ],
         "conditions": [
-          ['OS == "mac"', {
+          ['OS=="mac"', {
             'xcode_settings': {
               'MACOSX_DEPLOYMENT_TARGET': '10.9',
               'OTHER_CFLAGS': [
                 '-stdlib=libc++'
               ]
             }
+          }],
+          ['OS=="win"', {
+            'dependencies': [
+              % for dep in getattr(module, 'deps', []):
+              % if dep in ('boringssl', 'z'):
+              "${dep}",
+              % endif
+              % endfor
+            ]
           }]
         ],
         "target_name": "${module.name}",
@@ -155,10 +202,23 @@
         ],
         "dependencies": [
           % for dep in getattr(module, 'deps', []):
+          % if dep not in ('boringssl', 'z'):
           "${dep}",
+          % endif
           % endfor
         ]
       },
       % endfor
+      {
+        "target_name": "action_after_build",
+        "type": "none",
+        "dependencies": [ "<(module_name)" ],
+        "copies": [
+          {
+            "files": [ "<(PRODUCT_DIR)/<(module_name).node"],
+            "destination": "<(module_path)"
+          }
+        ]
+      }
     ]
   }
diff --git a/templates/package.json.template b/templates/package.json.template
index ec6827e..ed4dca5 100644
--- a/templates/package.json.template
+++ b/templates/package.json.template
@@ -24,12 +24,14 @@
       "lint": "node ./node_modules/jshint/bin/jshint src/node/src src/node/test src/node/interop src/node/index.js",
       "test": "./node_modules/.bin/mocha src/node/test && npm run-script lint",
       "gen_docs": "./node_modules/.bin/jsdoc -c src/node/jsdoc_conf.json",
-      "coverage": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha src/node/test"
+      "coverage": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha src/node/test",
+      "preinstall": "npm install node-pre-gyp",
+      "install": "./node_modules/.bin/node-pre-gyp install --fallback-to-build"
     },
     "dependencies": {
-      "bindings": "^1.2.0",
       "lodash": "^3.9.3",
       "nan": "^2.0.0",
+      "node-pre-gyp": "^0.6.19",
       "protobufjs": "^4.0.0"
     },
     "devDependencies": {
@@ -47,6 +49,14 @@
     "engines": {
       "node": ">=0.10.13"
     },
+    "binary": {
+      "module_name": "grpc_node",
+      "module_path": "./build/Release/",
+      "host": "https://storage.googleapis.com/",
+      "remote_path": "grpc-precompiled-binaries/node/{name}/v{version}",
+      "package_name": "{node_abi}-{platform}-{arch}.tar.gz",
+      "module_path": "src/node/extension_binary"
+    },
     "files": [
       "LICENSE",
       "src/node/README.md",
diff --git a/templates/src/core/surface/version.c.template b/templates/src/core/surface/version.c.template
index 31a5af9..4788dc4 100644
--- a/templates/src/core/surface/version.c.template
+++ b/templates/src/core/surface/version.c.template
@@ -2,7 +2,7 @@
 --- |
   /*
    *
-   * Copyright 2015, Google Inc.
+   * Copyright 2015-2016, Google Inc.
    * All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without
diff --git a/templates/src/csharp/Grpc.Core/VersionInfo.cs.template b/templates/src/csharp/Grpc.Core/VersionInfo.cs.template
new file mode 100644
index 0000000..48197ba
--- /dev/null
+++ b/templates/src/csharp/Grpc.Core/VersionInfo.cs.template
@@ -0,0 +1,48 @@
+%YAML 1.2
+--- |
+  #region Copyright notice and license
+  
+  // Copyright 2015-2016, Google Inc.
+  // All rights reserved.
+  //
+  // Redistribution and use in source and binary forms, with or without
+  // modification, are permitted provided that the following conditions are
+  // met:
+  //
+  //     * Redistributions of source code must retain the above copyright
+  // notice, this list of conditions and the following disclaimer.
+  //     * Redistributions in binary form must reproduce the above
+  // copyright notice, this list of conditions and the following disclaimer
+  // in the documentation and/or other materials provided with the
+  // distribution.
+  //     * Neither the name of Google Inc. nor the names of its
+  // contributors may be used to endorse or promote products derived from
+  // this software without specific prior written permission.
+  //
+  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  
+  #endregion
+  
+  namespace Grpc.Core
+  {
+      /// <summary>
+      /// Provides info about current version of gRPC.
+      /// </summary>
+      public static class VersionInfo
+      {
+          /// <summary>
+          /// Current version of gRPC C#
+          /// </summary>
+          public const string CurrentVersion = "${settings.version.major}.${settings.version.minor}.${settings.version.micro}";
+      }
+  }
diff --git a/templates/src/csharp/build_packages.bat.template b/templates/src/csharp/build_packages.bat.template
new file mode 100644
index 0000000..bf831a9
--- /dev/null
+++ b/templates/src/csharp/build_packages.bat.template
@@ -0,0 +1,58 @@
+%YAML 1.2
+--- |
+  @rem Builds gRPC NuGet packages
+  
+  @rem Current package versions
+  set VERSION=${settings.version.major}.${settings.version.minor}.${settings.version.micro}
+  set PROTOBUF_VERSION=3.0.0-beta2
+  
+  @rem Packages that depend on prerelease packages (like Google.Protobuf) need to have prerelease suffix as well.
+  set VERSION_WITH_BETA=%VERSION%-beta
+  
+  @rem Adjust the location of nuget.exe
+  set NUGET=C:\nuget\nuget.exe
+  
+  @rem Collect the artifacts built by the previous build step if running on Jenkins
+  @rem TODO(jtattermusch): is there a better way to do this?
+  xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=windows\artifacts\* grpc.native.csharp\windows_x86${"\\"}
+  xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=windows\artifacts\* grpc.native.csharp\windows_x64${"\\"}
+  xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=linux\artifacts\* grpc.native.csharp\linux_x86${"\\"}
+  xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=linux\artifacts\* grpc.native.csharp\linux_x64${"\\"}
+  xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=macos\artifacts\* grpc.native.csharp\macosx_x86${"\\"}
+  xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=macos\artifacts\* grpc.native.csharp\macosx_x64${"\\"}
+  
+  @rem Fetch all dependencies
+  %%NUGET% restore ..\..\vsprojects\grpc_csharp_ext.sln || goto :error
+  %%NUGET% restore Grpc.sln || goto :error
+  
+  setlocal
+  
+  @call "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" x86
+  
+  @rem We won't use the native libraries from this step, but without this Grpc.sln will fail.  
+  msbuild ..\..\vsprojects\grpc_csharp_ext.sln /p:Configuration=Release /p:PlatformToolset=v120 || goto :error
+  
+  msbuild Grpc.sln /p:Configuration=ReleaseSigned || goto :error
+  
+  endlocal
+  
+  @rem TODO(jtattermusch): re-enable protoc plugin building
+  @rem @call ..\..\vsprojects\build_plugins.bat || goto :error
+  
+  %%NUGET% pack grpc.native.csharp\grpc.native.csharp.nuspec -Version %VERSION% || goto :error
+  %%NUGET% pack Grpc.Auth\Grpc.Auth.nuspec -Symbols -Version %VERSION% || goto :error
+  %%NUGET% pack Grpc.Core\Grpc.Core.nuspec -Symbols -Version %VERSION% || goto :error
+  %%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION_WITH_BETA% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error
+  %%NUGET% pack Grpc.nuspec -Version %VERSION% || goto :error
+  
+  @rem TODO(jtattermusch): re-enable building Grpc.Tools package
+  @rem %NUGET% pack Grpc.Tools.nuspec -Version %VERSION% || goto :error
+  
+  @rem copy resulting nuget packages to artifacts directory
+  xcopy /Y /I *.nupkg ..\..\artifacts${"\\"}
+  
+  goto :EOF
+  
+  :error
+  echo Failed!
+  exit /b %errorlevel%
diff --git a/test/core/client_config/set_initial_connect_string_test.c b/test/core/client_config/set_initial_connect_string_test.c
index ceca56c..33cab71 100644
--- a/test/core/client_config/set_initial_connect_string_test.c
+++ b/test/core/client_config/set_initial_connect_string_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -78,7 +78,8 @@
   }
 }
 
-static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp) {
+static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
+                       grpc_tcp_server_acceptor *acceptor) {
   test_tcp_server *server = arg;
   grpc_closure_init(&on_read, handle_read, NULL);
   gpr_slice_buffer_init(&state.incoming_buffer);
diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c
index 530381e..f7097ac 100644
--- a/test/core/iomgr/tcp_server_posix_test.c
+++ b/test/core/iomgr/tcp_server_posix_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -33,11 +33,15 @@
 
 #include "src/core/iomgr/tcp_server.h"
 #include "src/core/iomgr/iomgr.h"
+#include "src/core/iomgr/sockaddr_utils.h"
+#include <grpc/grpc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 #include <grpc/support/time.h>
+#include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 
+#include <errno.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <string.h>
@@ -48,11 +52,69 @@
 static grpc_pollset g_pollset;
 static int g_nconnects = 0;
 
-static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp) {
+typedef struct on_connect_result {
+  /* Owns a ref to server. */
+  grpc_tcp_server *server;
+  unsigned port_index;
+  unsigned fd_index;
+  int server_fd;
+} on_connect_result;
+
+typedef struct server_weak_ref {
+  grpc_tcp_server *server;
+
+  /* arg is this server_weak_ref. */
+  grpc_closure server_shutdown;
+} server_weak_ref;
+
+static on_connect_result g_result = {NULL, 0, 0, -1};
+
+static void on_connect_result_init(on_connect_result *result) {
+  result->server = NULL;
+  result->port_index = 0;
+  result->fd_index = 0;
+  result->server_fd = -1;
+}
+
+static void on_connect_result_set(on_connect_result *result,
+                                  const grpc_tcp_server_acceptor *acceptor) {
+  result->server = grpc_tcp_server_ref(acceptor->from_server);
+  result->port_index = acceptor->port_index;
+  result->fd_index = acceptor->fd_index;
+  result->server_fd = grpc_tcp_server_port_fd(
+      result->server, acceptor->port_index, acceptor->fd_index);
+}
+
+static void server_weak_ref_shutdown(grpc_exec_ctx *exec_ctx, void *arg,
+                                     int success) {
+  server_weak_ref *weak_ref = arg;
+  weak_ref->server = NULL;
+}
+
+static void server_weak_ref_init(server_weak_ref *weak_ref) {
+  weak_ref->server = NULL;
+  grpc_closure_init(&weak_ref->server_shutdown, server_weak_ref_shutdown,
+                    weak_ref);
+}
+
+/* Make weak_ref->server_shutdown a shutdown_starting cb on server.
+   grpc_tcp_server promises that the server object will live until
+   weak_ref->server_shutdown has returned. A strong ref on grpc_tcp_server
+   should be held until server_weak_ref_set() returns to avoid a race where the
+   server is deleted before the shutdown_starting cb is added. */
+static void server_weak_ref_set(server_weak_ref *weak_ref,
+                                grpc_tcp_server *server) {
+  grpc_tcp_server_shutdown_starting_add(server, &weak_ref->server_shutdown);
+  weak_ref->server = server;
+}
+
+static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
+                       grpc_tcp_server_acceptor *acceptor) {
   grpc_endpoint_shutdown(exec_ctx, tcp);
   grpc_endpoint_destroy(exec_ctx, tcp);
 
   gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  on_connect_result_set(&g_result, acceptor);
   g_nconnects++;
   grpc_pollset_kick(&g_pollset, NULL);
   gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
@@ -60,107 +122,184 @@
 
 static void test_no_op(void) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_tcp_server *s = grpc_tcp_server_create();
-  grpc_tcp_server_destroy(&exec_ctx, s, NULL);
+  grpc_tcp_server *s = grpc_tcp_server_create(NULL);
+  grpc_tcp_server_unref(&exec_ctx, s);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_no_op_with_start(void) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_tcp_server *s = grpc_tcp_server_create();
+  grpc_tcp_server *s = grpc_tcp_server_create(NULL);
   LOG_TEST("test_no_op_with_start");
   grpc_tcp_server_start(&exec_ctx, s, NULL, 0, on_connect, NULL);
-  grpc_tcp_server_destroy(&exec_ctx, s, NULL);
+  grpc_tcp_server_unref(&exec_ctx, s);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_no_op_with_port(void) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   struct sockaddr_in addr;
-  grpc_tcp_server *s = grpc_tcp_server_create();
+  grpc_tcp_server *s = grpc_tcp_server_create(NULL);
   LOG_TEST("test_no_op_with_port");
 
   memset(&addr, 0, sizeof(addr));
   addr.sin_family = AF_INET;
   GPR_ASSERT(
-      grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr)));
+      grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr)) > 0);
 
-  grpc_tcp_server_destroy(&exec_ctx, s, NULL);
+  grpc_tcp_server_unref(&exec_ctx, s);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_no_op_with_port_and_start(void) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   struct sockaddr_in addr;
-  grpc_tcp_server *s = grpc_tcp_server_create();
+  grpc_tcp_server *s = grpc_tcp_server_create(NULL);
   LOG_TEST("test_no_op_with_port_and_start");
 
   memset(&addr, 0, sizeof(addr));
   addr.sin_family = AF_INET;
   GPR_ASSERT(
-      grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr)));
+      grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr)) > 0);
 
   grpc_tcp_server_start(&exec_ctx, s, NULL, 0, on_connect, NULL);
 
-  grpc_tcp_server_destroy(&exec_ctx, s, NULL);
+  grpc_tcp_server_unref(&exec_ctx, s);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
-static void test_connect(int n) {
+static void tcp_connect(grpc_exec_ctx *exec_ctx, const struct sockaddr *remote,
+                        socklen_t remote_len, on_connect_result *result) {
+  gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10);
+  int clifd = socket(remote->sa_family, SOCK_STREAM, 0);
+  int nconnects_before;
+
+  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  nconnects_before = g_nconnects;
+  on_connect_result_init(&g_result);
+  GPR_ASSERT(clifd >= 0);
+  gpr_log(GPR_DEBUG, "start connect");
+  GPR_ASSERT(connect(clifd, remote, remote_len) == 0);
+  gpr_log(GPR_DEBUG, "wait");
+  while (g_nconnects == nconnects_before &&
+         gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) > 0) {
+    grpc_pollset_worker worker;
+    grpc_pollset_work(exec_ctx, &g_pollset, &worker,
+                      gpr_now(GPR_CLOCK_MONOTONIC), deadline);
+    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+    grpc_exec_ctx_finish(exec_ctx);
+    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  }
+  gpr_log(GPR_DEBUG, "wait done");
+  GPR_ASSERT(g_nconnects == nconnects_before + 1);
+  close(clifd);
+  *result = g_result;
+
+  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+}
+
+/* Tests a tcp server with multiple ports. TODO(daniel-j-born): Multiple fds for
+   the same port should be tested. */
+static void test_connect(unsigned n) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   struct sockaddr_storage addr;
+  struct sockaddr_storage addr1;
   socklen_t addr_len = sizeof(addr);
-  int svrfd, clifd;
-  grpc_tcp_server *s = grpc_tcp_server_create();
-  int nconnects_before;
-  gpr_timespec deadline;
+  unsigned svr_fd_count;
+  int svr_port;
+  unsigned svr1_fd_count;
+  int svr1_port;
+  grpc_tcp_server *s = grpc_tcp_server_create(NULL);
   grpc_pollset *pollsets[1];
-  int i;
+  unsigned i;
+  server_weak_ref weak_ref;
+  server_weak_ref_init(&weak_ref);
   LOG_TEST("test_connect");
   gpr_log(GPR_INFO, "clients=%d", n);
-
   memset(&addr, 0, sizeof(addr));
-  addr.ss_family = AF_INET;
-  GPR_ASSERT(grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, addr_len));
+  memset(&addr1, 0, sizeof(addr1));
+  addr.ss_family = addr1.ss_family = AF_INET;
+  svr_port = grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, addr_len);
+  GPR_ASSERT(svr_port > 0);
+  /* Cannot use wildcard (port==0), because add_port() will try to reuse the
+     same port as a previous add_port(). */
+  svr1_port = grpc_pick_unused_port_or_die();
+  grpc_sockaddr_set_port((struct sockaddr *)&addr1, svr1_port);
+  GPR_ASSERT(grpc_tcp_server_add_port(s, (struct sockaddr *)&addr1, addr_len) ==
+             svr1_port);
 
-  svrfd = grpc_tcp_server_get_fd(s, 0);
-  GPR_ASSERT(svrfd >= 0);
-  GPR_ASSERT(getsockname(svrfd, (struct sockaddr *)&addr, &addr_len) == 0);
-  GPR_ASSERT(addr_len <= sizeof(addr));
+  /* Bad port_index. */
+  GPR_ASSERT(grpc_tcp_server_port_fd_count(s, 2) == 0);
+  GPR_ASSERT(grpc_tcp_server_port_fd(s, 2, 0) < 0);
+
+  /* Bad fd_index. */
+  GPR_ASSERT(grpc_tcp_server_port_fd(s, 0, 100) < 0);
+  GPR_ASSERT(grpc_tcp_server_port_fd(s, 1, 100) < 0);
+
+  /* Got at least one fd per port. */
+  svr_fd_count = grpc_tcp_server_port_fd_count(s, 0);
+  GPR_ASSERT(svr_fd_count >= 1);
+  svr1_fd_count = grpc_tcp_server_port_fd_count(s, 1);
+  GPR_ASSERT(svr1_fd_count >= 1);
+
+  for (i = 0; i < svr_fd_count; ++i) {
+    int fd = grpc_tcp_server_port_fd(s, 0, i);
+    GPR_ASSERT(fd >= 0);
+    if (i == 0) {
+      GPR_ASSERT(getsockname(fd, (struct sockaddr *)&addr, &addr_len) == 0);
+      GPR_ASSERT(addr_len <= sizeof(addr));
+    }
+  }
+  for (i = 0; i < svr1_fd_count; ++i) {
+    int fd = grpc_tcp_server_port_fd(s, 1, i);
+    GPR_ASSERT(fd >= 0);
+    if (i == 0) {
+      GPR_ASSERT(getsockname(fd, (struct sockaddr *)&addr1, &addr_len) == 0);
+      GPR_ASSERT(addr_len <= sizeof(addr1));
+    }
+  }
 
   pollsets[0] = &g_pollset;
   grpc_tcp_server_start(&exec_ctx, s, pollsets, 1, on_connect, NULL);
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
-
   for (i = 0; i < n; i++) {
-    deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10);
-
-    nconnects_before = g_nconnects;
-    clifd = socket(addr.ss_family, SOCK_STREAM, 0);
-    GPR_ASSERT(clifd >= 0);
-    gpr_log(GPR_DEBUG, "start connect");
-    GPR_ASSERT(connect(clifd, (struct sockaddr *)&addr, addr_len) == 0);
-
-    gpr_log(GPR_DEBUG, "wait");
-    while (g_nconnects == nconnects_before &&
-           gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) > 0) {
-      grpc_pollset_worker worker;
-      grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
-                        gpr_now(GPR_CLOCK_MONOTONIC), deadline);
-      gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
-      grpc_exec_ctx_finish(&exec_ctx);
-      gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+    on_connect_result result;
+    int svr_fd;
+    on_connect_result_init(&result);
+    tcp_connect(&exec_ctx, (struct sockaddr *)&addr, addr_len, &result);
+    GPR_ASSERT(result.server_fd >= 0);
+    svr_fd = result.server_fd;
+    GPR_ASSERT(grpc_tcp_server_port_fd(s, result.port_index, result.fd_index) ==
+               result.server_fd);
+    GPR_ASSERT(result.port_index == 0);
+    GPR_ASSERT(result.fd_index < svr_fd_count);
+    GPR_ASSERT(result.server == s);
+    if (weak_ref.server == NULL) {
+      server_weak_ref_set(&weak_ref, result.server);
     }
-    gpr_log(GPR_DEBUG, "wait done");
+    grpc_tcp_server_unref(&exec_ctx, result.server);
 
-    GPR_ASSERT(g_nconnects == nconnects_before + 1);
-    close(clifd);
+    on_connect_result_init(&result);
+    tcp_connect(&exec_ctx, (struct sockaddr *)&addr1, addr_len, &result);
+    GPR_ASSERT(result.server_fd >= 0);
+    GPR_ASSERT(result.server_fd != svr_fd);
+    GPR_ASSERT(grpc_tcp_server_port_fd(s, result.port_index, result.fd_index) ==
+               result.server_fd);
+    GPR_ASSERT(result.port_index == 1);
+    GPR_ASSERT(result.fd_index < svr_fd_count);
+    GPR_ASSERT(result.server == s);
+    grpc_tcp_server_unref(&exec_ctx, result.server);
   }
 
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  /* Weak ref to server valid until final unref. */
+  GPR_ASSERT(weak_ref.server != NULL);
+  GPR_ASSERT(grpc_tcp_server_port_fd(s, 0, 0) >= 0);
 
-  grpc_tcp_server_destroy(&exec_ctx, s, NULL);
+  grpc_tcp_server_unref(&exec_ctx, s);
+
+  /* Weak ref lost. */
+  GPR_ASSERT(weak_ref.server == NULL);
+
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
@@ -172,7 +311,7 @@
   grpc_closure destroyed;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_test_init(argc, argv);
-  grpc_iomgr_init();
+  grpc_init();
   grpc_pollset_init(&g_pollset);
 
   test_no_op();
@@ -185,6 +324,6 @@
   grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
   grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
-  grpc_iomgr_shutdown();
+  grpc_shutdown();
   return 0;
 }
diff --git a/test/core/support/alloc_test.c b/test/core/support/alloc_test.c
index a7051a4..6bdba8c 100644
--- a/test/core/support/alloc_test.c
+++ b/test/core/support/alloc_test.c
@@ -39,7 +39,9 @@
 
 static void *fake_realloc(void *addr, size_t size) { return (void *)size; }
 
-static void fake_free(void *addr) { *((intptr_t *)addr) = 0xdeadd00d; }
+static void fake_free(void *addr) {
+  *((intptr_t *)addr) = (intptr_t)0xdeadd00d;
+}
 
 static void test_custom_allocs() {
   const gpr_allocation_functions default_fns = gpr_get_allocation_functions();
@@ -52,7 +54,7 @@
   GPR_ASSERT((void *)(size_t)0xcafed00d == gpr_realloc(0, 0xcafed00d));
 
   gpr_free(&addr_to_free);
-  GPR_ASSERT(addr_to_free == 0xdeadd00d);
+  GPR_ASSERT(addr_to_free == (intptr_t)0xdeadd00d);
 
   /* Restore and check we don't get funky values and that we don't leak */
   gpr_set_allocation_functions(default_fns);
diff --git a/test/core/transport/chttp2/hpack_table_test.c b/test/core/transport/chttp2/hpack_table_test.c
index 39f4174..3c5f2e4 100644
--- a/test/core/transport/chttp2/hpack_table_test.c
+++ b/test/core/transport/chttp2/hpack_table_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -236,7 +236,7 @@
 
   /* overflow the string buffer, check find still works */
   for (i = 0; i < 10000; i++) {
-    gpr_ltoa(i, buffer);
+    int64_ttoa(i, buffer);
     elem = grpc_mdelem_from_strings("test", buffer);
     GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem));
     GRPC_MDELEM_UNREF(elem);
@@ -256,7 +256,7 @@
 
   for (i = 0; i < tbl.num_ents; i++) {
     uint32_t expect = 9999 - i;
-    gpr_ltoa(expect, buffer);
+    int64_ttoa(expect, buffer);
 
     r = find_simple(&tbl, "test", buffer);
     GPR_ASSERT(r.index == i + 1 + GRPC_CHTTP2_LAST_STATIC_ENTRY);
diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c
index 732a51c..11cefbf 100644
--- a/test/core/util/port_posix.c
+++ b/test/core/util/port_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -37,6 +37,7 @@
 
 #include "test/core/util/port.h"
 
+#include <math.h>
 #include <netinet/in.h>
 #include <sys/socket.h>
 #include <stdio.h>
@@ -229,10 +230,10 @@
     grpc_httpcli_request req;
     memset(&req, 0, sizeof(req));
     GPR_ASSERT(pr->retries < 10);
+    sleep(1 + (unsigned)(pow(1.3, pr->retries) * rand() / RAND_MAX));
     pr->retries++;
     req.host = pr->server;
     req.path = "/get";
-    sleep(1);
     grpc_httpcli_get(exec_ctx, pr->ctx, &pr->pollset, &req,
                      GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), got_port_from_server,
                      pr);
diff --git a/test/core/util/reconnect_server.c b/test/core/util/reconnect_server.c
index 28e5212..57225aa 100644
--- a/test/core/util/reconnect_server.c
+++ b/test/core/util/reconnect_server.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -66,7 +66,8 @@
   }
 }
 
-static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp) {
+static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
+                       grpc_tcp_server_acceptor *acceptor) {
   char *peer;
   char *last_colon;
   reconnect_server *server = (reconnect_server *)arg;
diff --git a/test/core/util/test_tcp_server.c b/test/core/util/test_tcp_server.c
index 53b574d..aaba7be 100644
--- a/test/core/util/test_tcp_server.c
+++ b/test/core/util/test_tcp_server.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -45,10 +45,17 @@
 #include "src/core/iomgr/tcp_server.h"
 #include "test/core/util/port.h"
 
+static void on_server_destroyed(grpc_exec_ctx *exec_ctx, void *data,
+                                int success) {
+  test_tcp_server *server = data;
+  server->shutdown = 1;
+}
+
 void test_tcp_server_init(test_tcp_server *server,
                           grpc_tcp_server_cb on_connect, void *user_data) {
   grpc_init();
   server->tcp_server = NULL;
+  grpc_closure_init(&server->shutdown_complete, on_server_destroyed, server);
   server->shutdown = 0;
   grpc_pollset_init(&server->pollset);
   server->pollsets[0] = &server->pollset;
@@ -58,7 +65,6 @@
 
 void test_tcp_server_start(test_tcp_server *server, int port) {
   struct sockaddr_in addr;
-  grpc_tcp_listener *listener;
   int port_added;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
@@ -66,9 +72,9 @@
   addr.sin_port = htons((uint16_t)port);
   memset(&addr.sin_addr, 0, sizeof(addr.sin_addr));
 
-  server->tcp_server = grpc_tcp_server_create();
-  listener = grpc_tcp_server_add_port(server->tcp_server, &addr, sizeof(addr));
-  port_added = grpc_tcp_listener_get_port(listener);
+  server->tcp_server = grpc_tcp_server_create(&server->shutdown_complete);
+  port_added =
+      grpc_tcp_server_add_port(server->tcp_server, &addr, sizeof(addr));
   GPR_ASSERT(port_added == port);
 
   grpc_tcp_server_start(&exec_ctx, server->tcp_server, server->pollsets, 1,
@@ -91,22 +97,14 @@
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
-static void on_server_destroyed(grpc_exec_ctx *exec_ctx, void *data,
-                                int success) {
-  test_tcp_server *server = data;
-  server->shutdown = 1;
-}
-
 static void do_nothing(grpc_exec_ctx *exec_ctx, void *arg, int success) {}
 
 void test_tcp_server_destroy(test_tcp_server *server) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   gpr_timespec shutdown_deadline;
-  grpc_closure server_shutdown_cb;
   grpc_closure do_nothing_cb;
-  grpc_closure_init(&server_shutdown_cb, on_server_destroyed, server);
+  grpc_tcp_server_unref(&exec_ctx, server->tcp_server);
   grpc_closure_init(&do_nothing_cb, do_nothing, NULL);
-  grpc_tcp_server_destroy(&exec_ctx, server->tcp_server, &server_shutdown_cb);
   shutdown_deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
                                    gpr_time_from_seconds(5, GPR_TIMESPAN));
   while (!server->shutdown &&
diff --git a/test/core/util/test_tcp_server.h b/test/core/util/test_tcp_server.h
index deb65ee..51119cf 100644
--- a/test/core/util/test_tcp_server.h
+++ b/test/core/util/test_tcp_server.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -39,6 +39,7 @@
 
 typedef struct test_tcp_server {
   grpc_tcp_server *tcp_server;
+  grpc_closure shutdown_complete;
   int shutdown;
   grpc_pollset pollset;
   grpc_pollset *pollsets[1];
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index f8027bc..5a414eb 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -244,7 +244,8 @@
           gpr_time_from_micros(request->param().server_cancel_after_us(),
                                GPR_TIMESPAN)));
       return Status::CANCELLED;
-    } else {
+    } else if (!request->has_param() ||
+               !request->param().skip_cancelled_check()) {
       EXPECT_FALSE(context->IsCancelled());
     }
 
@@ -823,6 +824,7 @@
   EchoRequest request;
   EchoResponse response;
   request.set_message("Hello");
+  request.mutable_param()->set_skip_cancelled_check(true);
 
   ClientContext context;
   std::chrono::system_clock::time_point deadline =
diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc
index f270cd0..e423ee2 100644
--- a/test/cpp/qps/client_async.cc
+++ b/test/cpp/qps/client_async.cc
@@ -46,13 +46,14 @@
 #include <grpc++/client_context.h>
 #include <grpc++/generic/generic_stub.h>
 #include <grpc/grpc.h>
+#include <grpc/support/cpu.h>
 #include <grpc/support/histogram.h>
 #include <grpc/support/log.h>
 
+#include "src/proto/grpc/testing/services.grpc.pb.h"
 #include "test/cpp/qps/client.h"
 #include "test/cpp/qps/timer.h"
 #include "test/cpp/util/create_test_channel.h"
-#include "src/proto/grpc/testing/services.grpc.pb.h"
 
 namespace grpc {
 namespace testing {
@@ -164,14 +165,15 @@
               std::function<std::unique_ptr<StubType>(std::shared_ptr<Channel>)>
                   create_stub)
       : ClientImpl<StubType, RequestType>(config, create_stub),
+        num_async_threads_(NumThreads(config)),
         channel_lock_(new std::mutex[config.client_channels()]),
         contexts_(config.client_channels()),
         max_outstanding_per_channel_(config.outstanding_rpcs_per_channel()),
         channel_count_(config.client_channels()),
-        pref_channel_inc_(config.async_client_threads()) {
-    SetupLoadTest(config, config.async_client_threads());
+        pref_channel_inc_(num_async_threads_) {
+    SetupLoadTest(config, num_async_threads_);
 
-    for (int i = 0; i < config.async_client_threads(); i++) {
+    for (int i = 0; i < num_async_threads_; i++) {
       cli_cqs_.emplace_back(new CompletionQueue);
       if (!closed_loop_) {
         rpc_deadlines_.emplace_back();
@@ -324,6 +326,9 @@
     return true;
   }
 
+ protected:
+  int num_async_threads_;
+
  private:
   class boolean {  // exists only to avoid data-race on vector<bool>
    public:
@@ -338,6 +343,15 @@
    private:
     bool val_;
   };
+  static int NumThreads(const ClientConfig& config) {
+    int num_threads = config.async_client_threads();
+    if (num_threads <= 0) {  // Use dynamic sizing
+      num_threads = gpr_cpu_num_cores();
+      gpr_log(GPR_INFO, "Sizing client server to %d threads", num_threads);
+    }
+    return num_threads;
+  }
+
   std::vector<std::unique_ptr<CompletionQueue>> cli_cqs_;
 
   std::vector<deadline_list> rpc_deadlines_;  // per thread deadlines
@@ -363,7 +377,7 @@
  public:
   explicit AsyncUnaryClient(const ClientConfig& config)
       : AsyncClient(config, SetupCtx, BenchmarkStubCreator) {
-    StartThreads(config.async_client_threads());
+    StartThreads(num_async_threads_);
   }
   ~AsyncUnaryClient() GRPC_OVERRIDE { EndThreads(); }
 
@@ -461,7 +475,7 @@
     // async streaming currently only supports closed loop
     GPR_ASSERT(closed_loop_);
 
-    StartThreads(config.async_client_threads());
+    StartThreads(num_async_threads_);
   }
 
   ~AsyncStreamingClient() GRPC_OVERRIDE { EndThreads(); }
@@ -566,7 +580,7 @@
     // async streaming currently only supports closed loop
     GPR_ASSERT(closed_loop_);
 
-    StartThreads(config.async_client_threads());
+    StartThreads(num_async_threads_);
   }
 
   ~GenericAsyncStreamingClient() GRPC_OVERRIDE { EndThreads(); }
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index acb265b..4914e19 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,24 +31,24 @@
  *
  */
 
+#include <deque>
 #include <list>
 #include <thread>
-#include <deque>
 #include <vector>
 
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/host_port.h>
 #include <grpc++/client_context.h>
 #include <grpc++/create_channel.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
+#include <grpc/support/log.h>
 
 #include "src/core/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"
 #include "test/cpp/qps/driver.h"
 #include "test/cpp/qps/histogram.h"
 #include "test/cpp/qps/qps_worker.h"
-#include "src/proto/grpc/testing/services.grpc.pb.h"
 
 using std::list;
 using std::thread;
@@ -142,6 +142,12 @@
     }
   }
 
+  // if num_clients is set to <=0, do dynamic sizing: all workers
+  // except for servers are clients
+  if (num_clients <= 0) {
+    num_clients = workers.size() - num_servers;
+  }
+
   // TODO(ctiller): support running multiple configurations, and binpack
   // client/server pairs
   // to available workers
@@ -161,6 +167,8 @@
   // where class contained in std::vector must have a copy constructor
   auto* servers = new ServerData[num_servers];
   for (size_t i = 0; i < num_servers; i++) {
+    gpr_log(GPR_INFO, "Starting server on %s (worker #%d)", workers[i].c_str(),
+            i);
     servers[i].stub = WorkerService::NewStub(
         CreateChannel(workers[i], InsecureChannelCredentials()));
     ServerArgs args;
@@ -188,6 +196,8 @@
   // where class contained in std::vector must have a copy constructor
   auto* clients = new ClientData[num_clients];
   for (size_t i = 0; i < num_clients; i++) {
+    gpr_log(GPR_INFO, "Starting client on %s (worker #%d)",
+            workers[i + num_servers].c_str(), i + num_servers);
     clients[i].stub = WorkerService::NewStub(
         CreateChannel(workers[i + num_servers], InsecureChannelCredentials()));
     ClientArgs args;
diff --git a/test/cpp/qps/generic_async_streaming_ping_pong_test.cc b/test/cpp/qps/generic_async_streaming_ping_pong_test.cc
index 2b2e1c8..81c0f24 100644
--- a/test/cpp/qps/generic_async_streaming_ping_pong_test.cc
+++ b/test/cpp/qps/generic_async_streaming_ping_pong_test.cc
@@ -60,7 +60,7 @@
   bbuf->set_req_size(0);
 
   ServerConfig server_config;
-  server_config.set_server_type(ASYNC_SERVER);
+  server_config.set_server_type(ASYNC_GENERIC_SERVER);
   server_config.set_host("localhost");
   server_config.set_async_server_threads(1);
 
diff --git a/test/cpp/qps/qps_driver.cc b/test/cpp/qps/qps_driver.cc
index 9816a09..680e4b1 100644
--- a/test/cpp/qps/qps_driver.cc
+++ b/test/cpp/qps/qps_driver.cc
@@ -153,7 +153,7 @@
 
   ServerConfig server_config;
   server_config.set_server_type(server_type);
-  server_config.set_host("localhost");
+  server_config.set_host("::");  // Use the wildcard server address
   server_config.set_async_server_threads(FLAGS_async_server_threads);
 
   if (FLAGS_secure_test) {
@@ -170,7 +170,7 @@
   GPR_ASSERT(!client_config.payload_config().has_bytebuf_params() ||
              (client_config.client_type() == ASYNC_CLIENT &&
               client_config.rpc_type() == STREAMING &&
-              server_config.server_type() == ASYNC_SERVER));
+              server_config.server_type() == ASYNC_GENERIC_SERVER));
 
   const auto result = RunScenario(
       client_config, FLAGS_num_clients, server_config, FLAGS_num_servers,
diff --git a/test/cpp/qps/qps_worker.cc b/test/cpp/qps/qps_worker.cc
index c0276d0..6316605 100644
--- a/test/cpp/qps/qps_worker.cc
+++ b/test/cpp/qps/qps_worker.cc
@@ -61,6 +61,11 @@
 namespace testing {
 
 static std::unique_ptr<Client> CreateClient(const ClientConfig& config) {
+  gpr_log(GPR_INFO, "Starting client of type %s %s %d",
+          ClientType_Name(config.client_type()).c_str(),
+          RpcType_Name(config.rpc_type()).c_str(),
+          config.payload_config().has_bytebuf_params());
+
   switch (config.client_type()) {
     case ClientType::SYNC_CLIENT:
       return (config.rpc_type() == RpcType::UNARY)
@@ -81,6 +86,9 @@
 static void LimitCores(int cores) {}
 
 static std::unique_ptr<Server> CreateServer(const ServerConfig& config) {
+  gpr_log(GPR_INFO, "Starting server of type %s",
+          ServerType_Name(config.server_type()).c_str());
+
   if (config.core_limit() > 0) {
     LimitCores(config.core_limit());
   }
@@ -89,6 +97,8 @@
       return CreateSynchronousServer(config);
     case ServerType::ASYNC_SERVER:
       return CreateAsyncServer(config);
+    case ServerType::ASYNC_GENERIC_SERVER:
+      return CreateAsyncGenericServer(config);
     default:
       abort();
   }
@@ -169,22 +179,29 @@
     if (!args.has_setup()) {
       return Status(StatusCode::INVALID_ARGUMENT, "");
     }
+    gpr_log(GPR_INFO, "RunClientBody: about to create client");
     auto client = CreateClient(args.setup());
     if (!client) {
       return Status(StatusCode::INVALID_ARGUMENT, "");
     }
+    gpr_log(GPR_INFO, "RunClientBody: client created");
     ClientStatus status;
     if (!stream->Write(status)) {
       return Status(StatusCode::UNKNOWN, "");
     }
+    gpr_log(GPR_INFO, "RunClientBody: creation status reported");
     while (stream->Read(&args)) {
+      gpr_log(GPR_INFO, "RunClientBody: Message read");
       if (!args.has_mark()) {
+        gpr_log(GPR_INFO, "RunClientBody: Message is not a mark!");
         return Status(StatusCode::INVALID_ARGUMENT, "");
       }
       *status.mutable_stats() = client->Mark(args.mark().reset());
       stream->Write(status);
+      gpr_log(GPR_INFO, "RunClientBody: Mark response given");
     }
 
+    gpr_log(GPR_INFO, "RunClientBody: Returning");
     return Status::OK;
   }
 
@@ -200,24 +217,31 @@
     if (server_port_ != 0) {
       args.mutable_setup()->set_port(server_port_);
     }
+    gpr_log(GPR_INFO, "RunServerBody: about to create server");
     auto server = CreateServer(args.setup());
     if (!server) {
       return Status(StatusCode::INVALID_ARGUMENT, "");
     }
+    gpr_log(GPR_INFO, "RunServerBody: server created");
     ServerStatus status;
     status.set_port(server->port());
     status.set_cores(server->cores());
     if (!stream->Write(status)) {
       return Status(StatusCode::UNKNOWN, "");
     }
+    gpr_log(GPR_INFO, "RunServerBody: creation status reported");
     while (stream->Read(&args)) {
+      gpr_log(GPR_INFO, "RunServerBody: Message read");
       if (!args.has_mark()) {
+        gpr_log(GPR_INFO, "RunServerBody: Message not a mark!");
         return Status(StatusCode::INVALID_ARGUMENT, "");
       }
       *status.mutable_stats() = server->Mark(args.mark().reset());
       stream->Write(status);
+      gpr_log(GPR_INFO, "RunServerBody: Mark response given");
     }
 
+    gpr_log(GPR_INFO, "RunServerBody: Returning");
     return Status::OK;
   }
 
diff --git a/test/cpp/qps/server.h b/test/cpp/qps/server.h
index 32a3e85..196fdac 100644
--- a/test/cpp/qps/server.h
+++ b/test/cpp/qps/server.h
@@ -108,6 +108,7 @@
 
 std::unique_ptr<Server> CreateSynchronousServer(const ServerConfig& config);
 std::unique_ptr<Server> CreateAsyncServer(const ServerConfig& config);
+std::unique_ptr<Server> CreateAsyncGenericServer(const ServerConfig& config);
 
 }  // namespace testing
 }  // namespace grpc
diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc
index d530dac..ffa6226 100644
--- a/test/cpp/qps/server_async.cc
+++ b/test/cpp/qps/server_async.cc
@@ -50,8 +50,8 @@
 #include <grpc/support/log.h>
 #include <gtest/gtest.h>
 
-#include "test/cpp/qps/server.h"
 #include "src/proto/grpc/testing/services.grpc.pb.h"
+#include "test/cpp/qps/server.h"
 
 namespace grpc {
 namespace testing {
@@ -85,7 +85,13 @@
 
     register_service(&builder, &async_service_);
 
-    for (int i = 0; i < config.async_server_threads(); i++) {
+    int num_threads = config.async_server_threads();
+    if (num_threads <= 0) {  // dynamic sizing
+      num_threads = cores();
+      gpr_log(GPR_INFO, "Sizing async server to %d threads", num_threads);
+    }
+
+    for (int i = 0; i < num_threads; i++) {
       srv_cqs_.emplace_back(builder.AddCompletionQueue());
     }
 
@@ -96,8 +102,8 @@
     auto process_rpc_bound =
         std::bind(process_rpc, config.payload_config(), _1, _2);
 
-    for (int i = 0; i < 10000 / config.async_server_threads(); i++) {
-      for (int j = 0; j < config.async_server_threads(); j++) {
+    for (int i = 0; i < 10000 / num_threads; i++) {
+      for (int j = 0; j < num_threads; j++) {
         if (request_unary_function) {
           auto request_unary =
               std::bind(request_unary_function, &async_service_, _1, _2, _3,
@@ -115,10 +121,10 @@
       }
     }
 
-    for (int i = 0; i < config.async_server_threads(); i++) {
+    for (int i = 0; i < num_threads; i++) {
       shutdown_state_.emplace_back(new PerThreadShutdownState());
     }
-    for (int i = 0; i < config.async_server_threads(); i++) {
+    for (int i = 0; i < num_threads; i++) {
       threads_.emplace_back(&AsyncQpsServerTest::ThreadFunc, this, i);
     }
   }
@@ -373,7 +379,7 @@
                                 const ByteBuffer *request,
                                 ByteBuffer *response) {
   int resp_size = payload_config.bytebuf_params().resp_size();
-  std::unique_ptr<char> buf(new char[resp_size]);
+  std::unique_ptr<char[]> buf(new char[resp_size]);
   gpr_slice s = gpr_slice_from_copied_buffer(buf.get(), resp_size);
   Slice slice(s, Slice::STEAL_REF);
   *response = ByteBuffer(&slice, 1);
diff --git a/tools/buildgen/generate_projects.py b/tools/buildgen/generate_projects.py
index 083a978..965dd29 100755
--- a/tools/buildgen/generate_projects.py
+++ b/tools/buildgen/generate_projects.py
@@ -47,6 +47,7 @@
 argp = argparse.ArgumentParser()
 argp.add_argument('json', nargs='+')
 argp.add_argument('--templates', nargs='+', default=[])
+argp.add_argument('--jobs', '-j', default=multiprocessing.cpu_count(), type=int)
 args = argp.parse_args()
 
 json = args.json
@@ -87,7 +88,7 @@
     cmd.append(root + '/' + f)
     jobs.append(jobset.JobSpec(cmd, shortname=out, timeout_seconds=None))
 
-jobset.run(jobs, maxjobs=multiprocessing.cpu_count())
+jobset.run(jobs, maxjobs=args.jobs)
 
 if test is not None:
   for s, g in test.iteritems():
diff --git a/tools/jenkins/grpc_artifact_linux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile
similarity index 100%
rename from tools/jenkins/grpc_artifact_linux_x64/Dockerfile
rename to tools/dockerfile/grpc_artifact_linux_x64/Dockerfile
diff --git a/tools/jenkins/grpc_artifact_linux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile
similarity index 100%
rename from tools/jenkins/grpc_artifact_linux_x86/Dockerfile
rename to tools/dockerfile/grpc_artifact_linux_x86/Dockerfile
diff --git a/tools/jenkins/grpc_interop_csharp/Dockerfile b/tools/dockerfile/grpc_interop_csharp/Dockerfile
similarity index 98%
rename from tools/jenkins/grpc_interop_csharp/Dockerfile
rename to tools/dockerfile/grpc_interop_csharp/Dockerfile
index 3789cd3..c3c7948 100644
--- a/tools/jenkins/grpc_interop_csharp/Dockerfile
+++ b/tools/dockerfile/grpc_interop_csharp/Dockerfile
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/jenkins/grpc_interop_csharp/build_interop.sh b/tools/dockerfile/grpc_interop_csharp/build_interop.sh
similarity index 100%
rename from tools/jenkins/grpc_interop_csharp/build_interop.sh
rename to tools/dockerfile/grpc_interop_csharp/build_interop.sh
diff --git a/tools/jenkins/grpc_interop_stress_cxx/Dockerfile b/tools/dockerfile/grpc_interop_cxx/Dockerfile
similarity index 100%
copy from tools/jenkins/grpc_interop_stress_cxx/Dockerfile
copy to tools/dockerfile/grpc_interop_cxx/Dockerfile
diff --git a/tools/jenkins/grpc_interop_cxx/build_interop.sh b/tools/dockerfile/grpc_interop_cxx/build_interop.sh
similarity index 97%
rename from tools/jenkins/grpc_interop_cxx/build_interop.sh
rename to tools/dockerfile/grpc_interop_cxx/build_interop.sh
index 1c0828d..903c31b 100755
--- a/tools/jenkins/grpc_interop_cxx/build_interop.sh
+++ b/tools/dockerfile/grpc_interop_cxx/build_interop.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/jenkins/grpc_interop_go/Dockerfile b/tools/dockerfile/grpc_interop_go/Dockerfile
similarity index 97%
rename from tools/jenkins/grpc_interop_go/Dockerfile
rename to tools/dockerfile/grpc_interop_go/Dockerfile
index bb60f09..f83e18c 100644
--- a/tools/jenkins/grpc_interop_go/Dockerfile
+++ b/tools/dockerfile/grpc_interop_go/Dockerfile
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/jenkins/grpc_interop_go/build_interop.sh b/tools/dockerfile/grpc_interop_go/build_interop.sh
similarity index 98%
rename from tools/jenkins/grpc_interop_go/build_interop.sh
rename to tools/dockerfile/grpc_interop_go/build_interop.sh
index e891549..224b004 100755
--- a/tools/jenkins/grpc_interop_go/build_interop.sh
+++ b/tools/dockerfile/grpc_interop_go/build_interop.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/jenkins/grpc_interop_go/Dockerfile b/tools/dockerfile/grpc_interop_http2/Dockerfile
similarity index 97%
copy from tools/jenkins/grpc_interop_go/Dockerfile
copy to tools/dockerfile/grpc_interop_http2/Dockerfile
index bb60f09..f83e18c 100644
--- a/tools/jenkins/grpc_interop_go/Dockerfile
+++ b/tools/dockerfile/grpc_interop_http2/Dockerfile
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/jenkins/grpc_interop_http2/build_interop.sh b/tools/dockerfile/grpc_interop_http2/build_interop.sh
similarity index 97%
rename from tools/jenkins/grpc_interop_http2/build_interop.sh
rename to tools/dockerfile/grpc_interop_http2/build_interop.sh
index 46ddaf9..5f701e3 100755
--- a/tools/jenkins/grpc_interop_http2/build_interop.sh
+++ b/tools/dockerfile/grpc_interop_http2/build_interop.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/jenkins/grpc_interop_java/Dockerfile b/tools/dockerfile/grpc_interop_java/Dockerfile
similarity index 98%
rename from tools/jenkins/grpc_interop_java/Dockerfile
rename to tools/dockerfile/grpc_interop_java/Dockerfile
index 1ec24a9..5ba5324 100644
--- a/tools/jenkins/grpc_interop_java/Dockerfile
+++ b/tools/dockerfile/grpc_interop_java/Dockerfile
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/jenkins/grpc_interop_java/build_interop.sh b/tools/dockerfile/grpc_interop_java/build_interop.sh
similarity index 97%
rename from tools/jenkins/grpc_interop_java/build_interop.sh
rename to tools/dockerfile/grpc_interop_java/build_interop.sh
index 9997c63..9c9591a 100755
--- a/tools/jenkins/grpc_interop_java/build_interop.sh
+++ b/tools/dockerfile/grpc_interop_java/build_interop.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/jenkins/grpc_interop_node/Dockerfile b/tools/dockerfile/grpc_interop_node/Dockerfile
similarity index 98%
rename from tools/jenkins/grpc_interop_node/Dockerfile
rename to tools/dockerfile/grpc_interop_node/Dockerfile
index db5aff8..3f0f918 100644
--- a/tools/jenkins/grpc_interop_node/Dockerfile
+++ b/tools/dockerfile/grpc_interop_node/Dockerfile
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/jenkins/grpc_interop_node/build_interop.sh b/tools/dockerfile/grpc_interop_node/build_interop.sh
similarity index 95%
rename from tools/jenkins/grpc_interop_node/build_interop.sh
rename to tools/dockerfile/grpc_interop_node/build_interop.sh
index 3b69715..526dd61 100755
--- a/tools/jenkins/grpc_interop_node/build_interop.sh
+++ b/tools/dockerfile/grpc_interop_node/build_interop.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -45,4 +45,4 @@
 
 # build Node interop client & server
 npm install -g node-gyp
-(npm install && node-gyp rebuild)
+npm install --unsafe-perm --build-from-source
diff --git a/tools/jenkins/grpc_interop_php/Dockerfile b/tools/dockerfile/grpc_interop_php/Dockerfile
similarity index 98%
rename from tools/jenkins/grpc_interop_php/Dockerfile
rename to tools/dockerfile/grpc_interop_php/Dockerfile
index cf3e791..4f5b3fc 100644
--- a/tools/jenkins/grpc_interop_php/Dockerfile
+++ b/tools/dockerfile/grpc_interop_php/Dockerfile
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/jenkins/grpc_interop_php/build_interop.sh b/tools/dockerfile/grpc_interop_php/build_interop.sh
similarity index 98%
rename from tools/jenkins/grpc_interop_php/build_interop.sh
rename to tools/dockerfile/grpc_interop_php/build_interop.sh
index 87262f1..2bffbd8 100755
--- a/tools/jenkins/grpc_interop_php/build_interop.sh
+++ b/tools/dockerfile/grpc_interop_php/build_interop.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/jenkins/grpc_interop_python/Dockerfile b/tools/dockerfile/grpc_interop_python/Dockerfile
similarity index 98%
rename from tools/jenkins/grpc_interop_python/Dockerfile
rename to tools/dockerfile/grpc_interop_python/Dockerfile
index 047604b..ef4432d 100644
--- a/tools/jenkins/grpc_interop_python/Dockerfile
+++ b/tools/dockerfile/grpc_interop_python/Dockerfile
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/jenkins/grpc_interop_python/build_interop.sh b/tools/dockerfile/grpc_interop_python/build_interop.sh
similarity index 97%
rename from tools/jenkins/grpc_interop_python/build_interop.sh
rename to tools/dockerfile/grpc_interop_python/build_interop.sh
index 39c9367..203b012 100755
--- a/tools/jenkins/grpc_interop_python/build_interop.sh
+++ b/tools/dockerfile/grpc_interop_python/build_interop.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/jenkins/grpc_interop_ruby/Dockerfile b/tools/dockerfile/grpc_interop_ruby/Dockerfile
similarity index 98%
rename from tools/jenkins/grpc_interop_ruby/Dockerfile
rename to tools/dockerfile/grpc_interop_ruby/Dockerfile
index ff201fa..b3383af 100644
--- a/tools/jenkins/grpc_interop_ruby/Dockerfile
+++ b/tools/dockerfile/grpc_interop_ruby/Dockerfile
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/jenkins/grpc_interop_ruby/build_interop.sh b/tools/dockerfile/grpc_interop_ruby/build_interop.sh
similarity index 97%
rename from tools/jenkins/grpc_interop_ruby/build_interop.sh
rename to tools/dockerfile/grpc_interop_ruby/build_interop.sh
index c5023f5..04288bf 100755
--- a/tools/jenkins/grpc_interop_ruby/build_interop.sh
+++ b/tools/dockerfile/grpc_interop_ruby/build_interop.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/jenkins/grpc_interop_stress_cxx/Dockerfile b/tools/dockerfile/grpc_interop_stress_cxx/Dockerfile
similarity index 100%
rename from tools/jenkins/grpc_interop_stress_cxx/Dockerfile
rename to tools/dockerfile/grpc_interop_stress_cxx/Dockerfile
diff --git a/tools/jenkins/grpc_interop_stress_cxx/build_interop_stress.sh b/tools/dockerfile/grpc_interop_stress_cxx/build_interop_stress.sh
similarity index 100%
rename from tools/jenkins/grpc_interop_stress_cxx/build_interop_stress.sh
rename to tools/dockerfile/grpc_interop_stress_cxx/build_interop_stress.sh
diff --git a/tools/jenkins/grpc_linuxbrew/Dockerfile b/tools/dockerfile/grpc_linuxbrew/Dockerfile
similarity index 98%
rename from tools/jenkins/grpc_linuxbrew/Dockerfile
rename to tools/dockerfile/grpc_linuxbrew/Dockerfile
index 848489e..8c179da 100644
--- a/tools/jenkins/grpc_linuxbrew/Dockerfile
+++ b/tools/dockerfile/grpc_linuxbrew/Dockerfile
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/jenkins/grpc_interop_cxx/Dockerfile b/tools/dockerfile/grpc_sanity/Dockerfile
similarity index 78%
rename from tools/jenkins/grpc_interop_cxx/Dockerfile
rename to tools/dockerfile/grpc_sanity/Dockerfile
index 1fa1907..6f7797d 100644
--- a/tools/jenkins/grpc_interop_cxx/Dockerfile
+++ b/tools/dockerfile/grpc_sanity/Dockerfile
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -27,12 +27,11 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-# A work-in-progress Dockerfile that allows running gRPC test suites
-# inside a docker container.
+# Dockerfile for running gRPC sanity tests
 
 FROM debian:jessie
 
-# Install Git.
+# Install Git and basic packages.
 RUN apt-get update && apt-get install -y \
   autoconf \
   autotools-dev \
@@ -43,13 +42,16 @@
   gcc \
   gcc-multilib \
   git \
+  golang \
   gyp \
+  lcov \
   libc6 \
   libc6-dbg \
   libc6-dev \
   libgtest-dev \
   libtool \
   make \
+  perl \
   strace \
   python-dev \
   python-setuptools \
@@ -59,17 +61,19 @@
   wget \
   zip && apt-get clean
 
-# Prepare ccache
-RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
-RUN ln -s /usr/bin/ccache /usr/local/bin/g++
-RUN ln -s /usr/bin/ccache /usr/local/bin/cc
-RUN ln -s /usr/bin/ccache /usr/local/bin/c++
-RUN ln -s /usr/bin/ccache /usr/local/bin/clang
-RUN ln -s /usr/bin/ccache /usr/local/bin/clang++
+##################
+# Sanity test dependencies
+RUN apt-get update && apt-get install -y python-pip
+RUN pip install simplejson mako
 
 ##################
-# C++ dependencies
-RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev clang
+# Docker "inception".
+# Note this is quite the ugly hack.
+# This makes sure that the docker binary we inject has its dependencies.
+RUN curl https://get.docker.com/ | sh
+RUN apt-get remove --purge -y docker-engine
+
+RUN mkdir /var/local/jenkins
 
 # Define the default command.
 CMD ["bash"]
diff --git a/tools/jenkins/grpc_jenkins_slave_32bits/Dockerfile b/tools/dockerfile/grpc_tests_multilang_x64/Dockerfile
similarity index 93%
copy from tools/jenkins/grpc_jenkins_slave_32bits/Dockerfile
copy to tools/dockerfile/grpc_tests_multilang_x64/Dockerfile
index 2323f23..7785f3d 100644
--- a/tools/jenkins/grpc_jenkins_slave_32bits/Dockerfile
+++ b/tools/dockerfile/grpc_tests_multilang_x64/Dockerfile
@@ -27,10 +27,9 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-# A work-in-progress Dockerfile that allows running gRPC test suites
-# inside a docker container.
+# Dockerfile for running gRPC test suites inside a docker container.
 
-FROM 32bit/debian:jessie
+FROM debian:jessie
 
 # Install Git and basic packages.
 RUN apt-get update && apt-get install -y \
@@ -95,8 +94,6 @@
 RUN cd /var/local && wget www.nuget.org/NuGet.exe
 ENV NUGET mono /var/local/NuGet.exe
 
-# TODO(jtattermusch): add dependencies for other languages
-
 ##################
 # Node dependencies
 
@@ -128,11 +125,12 @@
 RUN apt-get update && apt-get install -y \
     python-all-dev \
     python3-all-dev \
-    python-pip \
-    python-virtualenv
+    python-pip
 
 # Install Python packages from PyPI
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2
+RUN pip install pip --upgrade
+RUN pip install virtualenv
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 tox
 
 # For sanity test
 RUN pip install simplejson mako
@@ -153,12 +151,8 @@
 
 ##################
 # Zookeeper dependencies
-
-# Install dependencies
-
 RUN apt-get install -y libzookeeper-mt-dev
 
-
 RUN mkdir /var/local/jenkins
 
 # Define the default command.
diff --git a/tools/jenkins/grpc_jenkins_slave_32bits/Dockerfile b/tools/dockerfile/grpc_tests_multilang_x86/Dockerfile
similarity index 96%
rename from tools/jenkins/grpc_jenkins_slave_32bits/Dockerfile
rename to tools/dockerfile/grpc_tests_multilang_x86/Dockerfile
index 2323f23..c5cd45e 100644
--- a/tools/jenkins/grpc_jenkins_slave_32bits/Dockerfile
+++ b/tools/dockerfile/grpc_tests_multilang_x86/Dockerfile
@@ -27,8 +27,7 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-# A work-in-progress Dockerfile that allows running gRPC test suites
-# inside a docker container.
+# Dockerfile for running gRPC test suites inside a docker container.
 
 FROM 32bit/debian:jessie
 
@@ -95,8 +94,6 @@
 RUN cd /var/local && wget www.nuget.org/NuGet.exe
 ENV NUGET mono /var/local/NuGet.exe
 
-# TODO(jtattermusch): add dependencies for other languages
-
 ##################
 # Node dependencies
 
@@ -153,9 +150,6 @@
 
 ##################
 # Zookeeper dependencies
-
-# Install dependencies
-
 RUN apt-get install -y libzookeeper-mt-dev
 
 
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 500d110..ad0ad65 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         = 0.12.0.0
+PROJECT_NUMBER         = 0.13.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.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index ba1dec0..1d4b0ce 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         = 0.12.0.0
+PROJECT_NUMBER         = 0.13.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 b/tools/doxygen/Doxyfile.core
index 3a1d097..db3db4e 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         = 0.12.0.0
+PROJECT_NUMBER         = 0.13.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 5eea5a3..699af45 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         = 0.12.0.0
+PROJECT_NUMBER         = 0.13.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/jenkins/build_docker_and_run_tests.sh b/tools/jenkins/build_docker_and_run_tests.sh
index 562cfcb..58163bb 100755
--- a/tools/jenkins/build_docker_and_run_tests.sh
+++ b/tools/jenkins/build_docker_and_run_tests.sh
@@ -47,11 +47,15 @@
 # Create a local branch so the child Docker script won't complain
 git branch -f jenkins-docker
 
-# Use image name based on Dockerfile checksum
-DOCKER_IMAGE_NAME=grpc_jenkins_slave${docker_suffix}_`sha1sum tools/jenkins/grpc_jenkins_slave/Dockerfile | cut -f1 -d\ `
+# Inputs
+# DOCKERFILE_DIR - Directory in which Dockerfile file is located.
+# DOCKER_RUN_SCRIPT - Script to run under docker (relative to grpc repo root)
+
+# Use image name based on Dockerfile location checksum
+DOCKER_IMAGE_NAME=$(basename $DOCKERFILE_DIR)_$(sha1sum $DOCKERFILE_DIR/Dockerfile | cut -f1 -d\ )
 
 # Make sure docker image has been built. Should be instantaneous if so.
-docker build -t $DOCKER_IMAGE_NAME tools/jenkins/grpc_jenkins_slave$docker_suffix
+docker build -t $DOCKER_IMAGE_NAME $DOCKERFILE_DIR
 
 # Choose random name for docker container
 CONTAINER_NAME="run_tests_$(uuidgen)"
@@ -76,7 +80,7 @@
   -w /var/local/git/grpc \
   --name=$CONTAINER_NAME \
   $DOCKER_IMAGE_NAME \
-  bash -l /var/local/jenkins/grpc/tools/jenkins/docker_run_tests.sh || DOCKER_FAILED="true"
+  bash -l "/var/local/jenkins/grpc/$DOCKER_RUN_SCRIPT" || DOCKER_FAILED="true"
 
 if [ "$XML_REPORT" != "" ]
 then
diff --git a/tools/jenkins/build_interop_image.sh b/tools/jenkins/build_interop_image.sh
index 7393706..28d5f31 100755
--- a/tools/jenkins/build_interop_image.sh
+++ b/tools/jenkins/build_interop_image.sh
@@ -71,10 +71,10 @@
 fi
 
 # Use image name based on Dockerfile checksum
-BASE_IMAGE=${BASE_NAME}_base:`sha1sum tools/jenkins/$BASE_NAME/Dockerfile | cut -f1 -d\ `
+BASE_IMAGE=${BASE_NAME}_base:`sha1sum tools/dockerfile/$BASE_NAME/Dockerfile | cut -f1 -d\ `
 
 # Make sure base docker image has been built. Should be instantaneous if so.
-docker build -t $BASE_IMAGE --force-rm=true tools/jenkins/$BASE_NAME || exit $?
+docker build -t $BASE_IMAGE --force-rm=true tools/dockerfile/$BASE_NAME || exit $?
 
 # Create a local branch so the child Docker script won't complain
 git branch -f jenkins-docker
@@ -92,7 +92,7 @@
   -v /tmp/ccache:/tmp/ccache \
   --name=$CONTAINER_NAME \
   $BASE_IMAGE \
-  bash -l /var/local/jenkins/grpc/tools/jenkins/$BASE_NAME/build_interop.sh \
+  bash -l /var/local/jenkins/grpc/tools/dockerfile/$BASE_NAME/build_interop.sh \
   && docker commit $CONTAINER_NAME $INTEROP_IMAGE \
   && echo "Successfully built image $INTEROP_IMAGE")
 EXITCODE=$?
diff --git a/tools/jenkins/build_interop_stress_image.sh b/tools/jenkins/build_interop_stress_image.sh
index 395eaa3..92f2dab 100755
--- a/tools/jenkins/build_interop_stress_image.sh
+++ b/tools/jenkins/build_interop_stress_image.sh
@@ -55,10 +55,10 @@
 fi
 
 # Use image name based on Dockerfile checksum
-BASE_IMAGE=${BASE_NAME}_base:`sha1sum tools/jenkins/$BASE_NAME/Dockerfile | cut -f1 -d\ `
+BASE_IMAGE=${BASE_NAME}_base:`sha1sum tools/dockerfile/$BASE_NAME/Dockerfile | cut -f1 -d\ `
 
 # Make sure base docker image has been built. Should be instantaneous if so.
-docker build -t $BASE_IMAGE --force-rm=true tools/jenkins/$BASE_NAME || exit $?
+docker build -t $BASE_IMAGE --force-rm=true tools/dockerfile/$BASE_NAME || exit $?
 
 # Create a local branch so the child Docker script won't complain
 git branch -f jenkins-docker
@@ -75,7 +75,7 @@
   -v /tmp/ccache:/tmp/ccache \
   --name=$CONTAINER_NAME \
   $BASE_IMAGE \
-  bash -l /var/local/jenkins/grpc/tools/jenkins/$BASE_NAME/build_interop_stress.sh \
+  bash -l /var/local/jenkins/grpc/tools/dockerfile/$BASE_NAME/build_interop_stress.sh \
   && docker commit $CONTAINER_NAME $INTEROP_IMAGE \
   && echo "Successfully built image $INTEROP_IMAGE")
 EXITCODE=$?
diff --git a/tools/jenkins/docker_run_tests.sh b/tools/jenkins/docker_run_tests.sh
index 148a0f5..26e5585 100755
--- a/tools/jenkins/docker_run_tests.sh
+++ b/tools/jenkins/docker_run_tests.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -43,8 +43,12 @@
 mkdir -p /var/local/git
 git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
 
-nvm use 0.12
-rvm use ruby-2.1
+nvm use 0.12 || true
+
+if [ -x "$(command -v rvm)" ]
+then
+  rvm use ruby-2.1
+fi
 
 mkdir -p reports
 
diff --git a/tools/jenkins/grpc_interop_http2/Dockerfile b/tools/jenkins/grpc_interop_http2/Dockerfile
deleted file mode 100644
index bb60f09..0000000
--- a/tools/jenkins/grpc_interop_http2/Dockerfile
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-FROM golang:1.4
-
-# Using login shell removes Go from path, so we add it.
-RUN ln -s /usr/src/go/bin/go /usr/local/bin
-
-# Define the default command.
-CMD ["bash"]
diff --git a/tools/jenkins/grpc_jenkins_slave/Dockerfile b/tools/jenkins/grpc_jenkins_slave/Dockerfile
deleted file mode 100644
index 48541b0..0000000
--- a/tools/jenkins/grpc_jenkins_slave/Dockerfile
+++ /dev/null
@@ -1,172 +0,0 @@
-# Copyright 2015-2016, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# A work-in-progress Dockerfile that allows running gRPC test suites
-# inside a docker container.
-
-FROM debian:jessie
-
-# Install Git and basic packages.
-RUN apt-get update && apt-get install -y \
-  autoconf \
-  autotools-dev \
-  build-essential \
-  bzip2 \
-  ccache \
-  curl \
-  gcc \
-  gcc-multilib \
-  git \
-  golang \
-  gyp \
-  lcov \
-  libc6 \
-  libc6-dbg \
-  libc6-dev \
-  libgtest-dev \
-  libtool \
-  make \
-  perl \
-  strace \
-  python-dev \
-  python-setuptools \
-  python-yaml \
-  telnet \
-  unzip \
-  wget \
-  zip && apt-get clean
-
-# Prepare ccache
-RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
-RUN ln -s /usr/bin/ccache /usr/local/bin/g++
-RUN ln -s /usr/bin/ccache /usr/local/bin/cc
-RUN ln -s /usr/bin/ccache /usr/local/bin/c++
-RUN ln -s /usr/bin/ccache /usr/local/bin/clang
-RUN ln -s /usr/bin/ccache /usr/local/bin/clang++
-
-##################
-# C++ dependencies
-RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev clang
-
-#################
-# C# dependencies
-
-# Update to a newer version of mono
-RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
-
-# Install dependencies
-RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \
-    mono-devel \
-    nunit \
-    nunit-console \
-    monodevelop
-
-# Download NuGet
-RUN cd /var/local && wget www.nuget.org/NuGet.exe
-ENV NUGET mono /var/local/NuGet.exe
-
-# TODO(jtattermusch): add dependencies for other languages
-
-##################
-# Node dependencies
-
-# Install nvm
-RUN touch .profile
-RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.25.4/install.sh | bash
-RUN /bin/bash -l -c "nvm install 0.12 && npm config set cache /tmp/npm-cache"
-
-##################
-# Ruby dependencies
-
-# Install rvm
-RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
-RUN \curl -sSL https://get.rvm.io | bash -s stable
-
-# Install Ruby 2.1
-RUN /bin/bash -l -c "rvm install ruby-2.1"
-RUN /bin/bash -l -c "rvm use --default ruby-2.1"
-RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
-RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc"
-RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc"
-RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc"
-
-##################
-# Python dependencies
-
-# Install dependencies
-
-RUN apt-get update && apt-get install -y \
-    python-all-dev \
-    python3-all-dev \
-    python-pip
-
-# Install Python packages from PyPI
-RUN pip install pip --upgrade
-RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 tox
-
-# For sanity test
-RUN pip install simplejson mako
-
-##################
-# PHP dependencies
-
-# Install dependencies
-
-RUN /bin/bash -l -c "echo 'deb http://packages.dotdeb.org wheezy-php55 all' \
-    >> /etc/apt/sources.list.d/dotdeb.list"
-RUN /bin/bash -l -c "echo 'deb-src http://packages.dotdeb.org wheezy-php55 all' \
-    >> /etc/apt/sources.list.d/dotdeb.list"
-RUN wget http://www.dotdeb.org/dotdeb.gpg -O- | apt-key add -
-
-RUN apt-get update && apt-get install -y \
-    git php5 php5-dev phpunit unzip
-
-##################
-# Zookeeper dependencies
-
-# Install dependencies
-
-RUN apt-get install -y libzookeeper-mt-dev
-
-##################
-# Docker "inception".
-# Note this is quite the ugly hack.
-# This makes sure that the docker binary we inject has its dependencies.
-RUN curl https://get.docker.com/ | sh
-RUN apt-get remove --purge -y docker-engine
-
-RUN mkdir /var/local/jenkins
-
-# Define the default command.
-CMD ["bash"]
diff --git a/tools/jenkins/run_distribution.sh b/tools/jenkins/run_distribution.sh
index 64c60f1..446ce16 100755
--- a/tools/jenkins/run_distribution.sh
+++ b/tools/jenkins/run_distribution.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -47,11 +47,11 @@
 
   if [ "$dist_channel" == "homebrew" ]; then
 
-    sha1=$(sha1sum tools/jenkins/grpc_linuxbrew/Dockerfile | cut -f1 -d\ )
+    sha1=$(sha1sum tools/dockerfile/grpc_linuxbrew/Dockerfile | cut -f1 -d\ )
     DOCKER_IMAGE_NAME=grpc_linuxbrew_$sha1
 
     # build docker image, contains all pre-requisites
-    docker build -t $DOCKER_IMAGE_NAME tools/jenkins/grpc_linuxbrew
+    docker build -t $DOCKER_IMAGE_NAME tools/dockerfile/grpc_linuxbrew
 
     # run per-language homebrew installation script
     docker run --rm=true $DOCKER_IMAGE_NAME bash -l \
diff --git a/tools/jenkins/run_jenkins.sh b/tools/jenkins/run_jenkins.sh
index 49b2fa5..4cb31e6 100755
--- a/tools/jenkins/run_jenkins.sh
+++ b/tools/jenkins/run_jenkins.sh
@@ -39,52 +39,18 @@
 # NOTE: No empty lines should appear in this file before igncr is set!
 set -ex -o igncr || set -ex
 
-# Grabbing the machine's architecture
-arch=`uname -m`
-
-case $platform in
-  i386)
-    arch="i386"
-    platform="linux"
-    docker_suffix=_32bits
-    ;;
-esac
-
 if [ "$platform" == "linux" ]
 then
-  echo "building $language on Linux"
-
-  ./tools/run_tests/run_tests.py --use_docker -t -l $language -c $config -x report.xml -j 3 $@ || TESTS_FAILED="true"
-
-elif [ "$platform" == "windows" ]
-then
-  echo "building $language on Windows"
-
-  # Prevent msbuild from picking up "platform" env variable, which would break the build
-  unset platform
-
-  python tools/run_tests/run_tests.py -t -l $language -c $config -x report.xml -j 3 $@ || TESTS_FAILED="true"
-
-elif [ "$platform" == "macos" ]
-then
-  echo "building $language on MacOS"
-
-  # Prevent msbuild from picking up "platform" env variable, which would break the build
-  unset platform
-
-  ./tools/run_tests/run_tests.py -t -l $language -c $config -x report.xml -j 3 $@ || TESTS_FAILED="true"
-
+  USE_DOCKER_MAYBE="--use_docker"
 elif [ "$platform" == "freebsd" ]
 then
-  echo "building $language on FreeBSD"
-
-  MAKE=gmake ./tools/run_tests/run_tests.py -t -l $language -c $config -x report.xml -j 3 $@ || TESTS_FAILED="true"
-
-else
-  echo "Unknown platform $platform"
-  exit 1
+  export MAKE=gmake
 fi
 
+unset platform  # variable named 'platform' breaks the windows build
+
+python tools/run_tests/run_tests.py $USE_DOCKER_MAYBE -t -l $language -c $config -x report.xml -j 2 $@ || TESTS_FAILED="true"
+
 if [ ! -e reports/index.html ]
 then
   mkdir -p reports
diff --git a/tools/jenkins/run_portability.sh b/tools/jenkins/run_portability.sh
index afce4ad..6f15da7 100755
--- a/tools/jenkins/run_portability.sh
+++ b/tools/jenkins/run_portability.sh
@@ -1,5 +1,5 @@
 #!/usr/bin/env bash
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -41,6 +41,14 @@
 
 echo "building $scenario"
 
+# If scenario has _bo suffix, add --build_only flag.
+# Short suffix name had to been chosen due to path length limit on Windows.
+if [ "$scenario" != "${scenario%_bo}" ]
+then
+  scenario="${scenario%_bo}"
+  BUILD_ONLY_MAYBE="--build_only"
+fi
+
 parts=($(echo $scenario | tr '_' ' '))  # split scenario into parts
 
 curr_platform=${parts[0]}  # variable named 'platform' breaks the windows build
@@ -48,13 +56,10 @@
 curr_compiler=${parts[2]}
 
 config='dbg'
-maybe_build_only='--build_only'
 
-if [ "$curr_platform" == "windows" ]
+if [ "$curr_platform" == "linux" ]
 then
-  win_arch="windows_${curr_arch}"
-  python tools/run_tests/run_tests.py -t -l $language -c $config --arch ${win_arch} --compiler ${curr_compiler} ${maybe_build_only} -x report.xml $@
-else
-  echo "Unsupported scenario."
-  exit 1
+  USE_DOCKER_MAYBE="--use_docker"
 fi
+
+python tools/run_tests/run_tests.py $USE_DOCKER_MAYBE $BUILD_ONLY_MAYBE -t -l $language -c $config --arch ${curr_arch} --compiler ${curr_compiler} -x report.xml -j 3 $@
diff --git a/tools/run_tests/build_artifacts.py b/tools/run_tests/build_artifacts.py
index 0fd5bc6..0337f1b 100755
--- a/tools/run_tests/build_artifacts.py
+++ b/tools/run_tests/build_artifacts.py
@@ -129,18 +129,19 @@
                              '/p:PlatformToolset=v120',
                              '/p:Platform=%s' % msbuild_platform],
                             shell=True)
-    if self.platform == 'linux':
-      environ = {'CONFIG': 'opt'}
-      return create_docker_jobspec(self.name,
-                            'tools/jenkins/grpc_artifact_linux_%s' % self.arch,
-                            'tools/run_tests/build_artifact_csharp.sh')
     else:
-      environ = {'CONFIG': 'opt'}
-      if self.platform == 'macos':
+      environ = {'CONFIG': 'opt',
+                 'EMBED_OPENSSL': 'true',
+                 'EMBED_ZLIB': 'true'}
+      if self.platform == 'linux':
+        return create_docker_jobspec(self.name,
+            'tools/dockerfile/grpc_artifact_linux_%s' % self.arch,
+            'tools/run_tests/build_artifact_csharp.sh')
+      else:
         environ.update(macos_arch_env(self.arch))
-      return create_jobspec(self.name,
-                            ['tools/run_tests/build_artifact_csharp.sh'],
-                            environ=environ)
+        return create_jobspec(self.name,
+                              ['tools/run_tests/build_artifact_csharp.sh'],
+                              environ=environ)
 
   def __str__(self):
     return self.name
diff --git a/tools/run_tests/build_node.sh b/tools/run_tests/build_node.sh
index faa7b62..8f2ab44 100755
--- a/tools/run_tests/build_node.sh
+++ b/tools/run_tests/build_node.sh
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -36,4 +36,4 @@
 # change to grpc repo root
 cd $(dirname $0)/../..
 
-npm install --unsafe-perm
+npm install --unsafe-perm --build-from-source
diff --git a/tools/run_tests/configs.json b/tools/run_tests/configs.json
index b21793d..9d7b8a3 100644
--- a/tools/run_tests/configs.json
+++ b/tools/run_tests/configs.json
@@ -59,7 +59,7 @@
   }, 
   {
     "config": "msan", 
-    "timeout_multiplier": 1.5
+    "timeout_multiplier": 2
   }, 
   {
     "config": "mutrace"
diff --git a/tools/run_tests/jobset.py b/tools/run_tests/jobset.py
index beeb99c..adf178b 100755
--- a/tools/run_tests/jobset.py
+++ b/tools/run_tests/jobset.py
@@ -360,7 +360,7 @@
       if self.cancelled(): return False
       current_cpu_cost = self.cpu_cost()
       if current_cpu_cost == 0: break
-      if current_cpu_cost + spec.cpu_cost < self._maxjobs: break
+      if current_cpu_cost + spec.cpu_cost <= self._maxjobs: break
       self.reap()
     if self.cancelled(): return False
     if spec.hash_targets:
diff --git a/tools/run_tests/post_tests_ruby.sh b/tools/run_tests/post_tests_ruby.sh
index 66a9fbc..1a02e56 100755
--- a/tools/run_tests/post_tests_ruby.sh
+++ b/tools/run_tests/post_tests_ruby.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -43,4 +43,4 @@
 rm $tmp2
 rm $tmp1
 
-cp -rv $root/src/ruby/coverage $root/reports/ruby
+cp -rv $root/coverage $root/reports/ruby
diff --git a/tools/run_tests/run_node.sh b/tools/run_tests/run_node.sh
index fff579f..f93c9c3 100755
--- a/tools/run_tests/run_node.sh
+++ b/tools/run_tests/run_node.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -51,5 +51,5 @@
   echo '<html><head><meta http-equiv="refresh" content="0;URL=lcov-report/index.html"></head></html>' > \
     ../reports/node_coverage/index.html
 else
-  JUNIT_REPORT_PATH=src/node/reports.xml JUNIT_REPORT_STACK=1 ./node_modules/.bin/mocha --reporter mocha-jenkins-reporter src/node/test || true
+  JUNIT_REPORT_PATH=src/node/reports.xml JUNIT_REPORT_STACK=1 ./node_modules/.bin/mocha --reporter mocha-jenkins-reporter src/node/test
 fi
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index f8b0102..fbc7401 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -151,9 +151,9 @@
   def make_targets(self, test_regex):
     if platform_string() != 'windows' and test_regex != '.*':
       # use the regex to minimize the number of things to build
-      return [target['name']
+      return [os.path.basename(target['name'])
               for target in get_c_tests(False, self.test_lang)
-              if re.search(test_regex, target['name'])]
+              if re.search(test_regex, '/' + target['name'])]
     if platform_string() == 'windows':
       # don't build tools on windows just yet
       return ['buildtests_%s' % self.make_target]
@@ -183,6 +183,9 @@
   def supports_multi_config(self):
     return True
 
+  def dockerfile_dir(self, config, arch):
+    return None
+
   def __str__(self):
     return self.make_target
 
@@ -215,6 +218,9 @@
   def supports_multi_config(self):
     return False
 
+  def dockerfile_dir(self, config, arch):
+    return None
+
   def __str__(self):
     return 'node'
 
@@ -246,6 +252,9 @@
   def supports_multi_config(self):
     return False
 
+  def dockerfile_dir(self, config, arch):
+    return None
+
   def __str__(self):
     return 'php'
 
@@ -299,6 +308,9 @@
   def supports_multi_config(self):
     return False
 
+  def dockerfile_dir(self, config, arch):
+    return None
+
   def __str__(self):
     return 'python'
 
@@ -330,6 +342,9 @@
   def supports_multi_config(self):
     return False
 
+  def dockerfile_dir(self, config, arch):
+    return None
+
   def __str__(self):
     return 'ruby'
 
@@ -412,6 +427,9 @@
   def supports_multi_config(self):
     return False
 
+  def dockerfile_dir(self, config, arch):
+    return None
+
   def __str__(self):
     return 'csharp'
 
@@ -443,6 +461,9 @@
   def supports_multi_config(self):
     return False
 
+  def dockerfile_dir(self, config, arch):
+    return None
+
   def __str__(self):
     return 'objc'
 
@@ -451,8 +472,10 @@
 
   def test_specs(self, config, args):
     import yaml
-    with open('tools/run_tests/sanity_tests.yaml', 'r') as f:
-      return [config.job_spec([cmd['script']], None, timeout_seconds=None, environ={'TEST': 'true'}, cpu_cost=cmd.get('cpu_cost', 1))
+    with open('tools/run_tests/sanity/sanity_tests.yaml', 'r') as f:
+      return [config.job_spec(cmd['script'].split(), None,
+                              timeout_seconds=None, environ={'TEST': 'true'},
+                              cpu_cost=cmd.get('cpu_cost', 1))
               for cmd in yaml.load(f)]
 
   def pre_build_steps(self):
@@ -476,6 +499,9 @@
   def supports_multi_config(self):
     return False
 
+  def dockerfile_dir(self, config, arch):
+    return 'tools/dockerfile/grpc_sanity'
+
   def __str__(self):
     return 'sanity'
 
@@ -506,6 +532,9 @@
   def supports_multi_config(self):
     return True
 
+  def dockerfile_dir(self, config, arch):
+    return None
+
   def __str__(self):
     return self.make_target
 
@@ -538,15 +567,37 @@
 
 def _windows_arch_option(arch):
   """Returns msbuild cmdline option for selected architecture."""
-  if arch == 'default' or arch == 'windows_x86':
+  if arch == 'default' or arch == 'x86':
     return '/p:Platform=Win32'
-  elif arch == 'windows_x64':
+  elif arch == 'x64':
     return '/p:Platform=x64'
   else:
-    print 'Architecture %s not supported on current platform.' % arch
+    print 'Architecture %s not supported.' % arch
     sys.exit(1)
 
-    
+
+def _check_arch_option(arch):
+  """Checks that architecture option is valid."""
+  if platform_string() == 'windows':
+    _windows_arch_option(arch)
+  elif platform_string() == 'linux':
+    # On linux, we need to be running under docker with the right architecture.
+    runtime_arch = platform.architecture()[0]
+    if arch == 'default':
+      return
+    elif runtime_arch == '64bit' and arch == 'x64':
+      return
+    elif runtime_arch == '32bit' and arch == 'x86':
+      return
+    else:
+      print 'Architecture %s does not match current runtime architecture.' % arch
+      sys.exit(1)
+  else:
+    if args.arch != 'default':
+      print 'Architecture %s not supported on current platform.' % args.arch
+      sys.exit(1)
+
+
 def _windows_build_bat(compiler):
   """Returns name of build.bat for selected compiler."""
   if compiler == 'default' or compiler == 'vs2013':
@@ -558,8 +609,8 @@
   else:
     print 'Compiler %s not supported.' % compiler
     sys.exit(1)
-    
-    
+
+
 def _windows_toolset_option(compiler):
   """Returns msbuild PlatformToolset for selected compiler."""
   if compiler == 'default' or compiler == 'vs2013':
@@ -571,7 +622,21 @@
   else:
     print 'Compiler %s not supported.' % compiler
     sys.exit(1)
-   
+
+
+def _get_dockerfile_dir(language, cfg, arch):
+  """Returns dockerfile to use"""
+  custom = language.dockerfile_dir(cfg, arch)
+  if custom:
+    return custom
+  else:
+    if arch == 'default' or arch == 'x64':
+      return 'tools/dockerfile/grpc_tests_multilang_x64'
+    elif arch == 'x86':
+      return 'tools/dockerfile/grpc_tests_multilang_x86'
+    else:
+      print 'Architecture %s not supported with current settings.' % arch
+      sys.exit(1)
 
 def runs_per_test_type(arg_str):
     """Auxilary function to parse the "runs_per_test" flag.
@@ -638,7 +703,7 @@
                   const=True,
                   help='Allow flaky tests to show as passing (re-runs failed tests up to five times)')
 argp.add_argument('--arch',
-                  choices=['default', 'windows_x86', 'windows_x64'],
+                  choices=['default', 'x86', 'x64'],
                   default='default',
                   help='Selects architecture to target. For some platforms "default" is the only supported choice.')
 argp.add_argument('--compiler',
@@ -662,36 +727,6 @@
 
 jobset.measure_cpu_costs = args.measure_cpu_costs
 
-if args.use_docker:
-  if not args.travis:
-    print 'Seen --use_docker flag, will run tests under docker.'
-    print
-    print 'IMPORTANT: The changes you are testing need to be locally committed'
-    print 'because only the committed changes in the current branch will be'
-    print 'copied to the docker environment.'
-    time.sleep(5)
-
-  child_argv = [ arg for arg in sys.argv if not arg == '--use_docker' ]
-  run_tests_cmd = 'tools/run_tests/run_tests.py %s' % ' '.join(child_argv[1:])
-
-  # TODO(jtattermusch): revisit if we need special handling for arch here
-  # set arch command prefix in case we are working with different arch.
-  arch_env = os.getenv('arch')
-  if arch_env:
-    run_test_cmd = 'arch %s %s' % (arch_env, run_test_cmd)
-
-  env = os.environ.copy()
-  env['RUN_TESTS_COMMAND'] = run_tests_cmd
-  if args.xml_report:
-    env['XML_REPORT'] = args.xml_report
-  if not args.travis:
-    env['TTY_FLAG'] = '-t'  # enables Ctrl-C when not on Jenkins.
-
-  subprocess.check_call(['tools/jenkins/build_docker_and_run_tests.sh'],
-                        shell=True,
-                        env=env)
-  sys.exit(0)
-
 # update submodules if necessary
 need_to_regenerate_projects = False
 for spec in args.update_submodules:
@@ -755,16 +790,46 @@
   else:
     language_make_options = next(iter(languages)).make_options()
 
-if platform_string() != 'windows':
-  if args.arch != 'default':
-    print 'Architecture %s not supported on current platform.' % args.arch
-    sys.exit(1)
-  if args.compiler != 'default':
+if len(languages) != 1 or len(build_configs) != 1:
+  print 'Multi-language and multi-config testing is not supported.'
+  sys.exit(1)
+
+if args.use_docker:
+  if not args.travis:
+    print 'Seen --use_docker flag, will run tests under docker.'
+    print
+    print 'IMPORTANT: The changes you are testing need to be locally committed'
+    print 'because only the committed changes in the current branch will be'
+    print 'copied to the docker environment.'
+    time.sleep(5)
+
+  child_argv = [ arg for arg in sys.argv if not arg == '--use_docker' ]
+  run_tests_cmd = 'python tools/run_tests/run_tests.py %s' % ' '.join(child_argv[1:])
+
+  env = os.environ.copy()
+  env['RUN_TESTS_COMMAND'] = run_tests_cmd
+  env['DOCKERFILE_DIR'] = _get_dockerfile_dir(next(iter(languages)),
+                                              next(iter(build_configs)),
+                                              args.arch)
+  env['DOCKER_RUN_SCRIPT'] = 'tools/jenkins/docker_run_tests.sh'
+  if args.xml_report:
+    env['XML_REPORT'] = args.xml_report
+  if not args.travis:
+    env['TTY_FLAG'] = '-t'  # enables Ctrl-C when not on Jenkins.
+
+  subprocess.check_call(['tools/jenkins/build_docker_and_run_tests.sh'],
+                        shell=True,
+                        env=env)
+  sys.exit(0)
+
+if platform_string() != 'windows' and args.compiler != 'default':
     print 'Compiler %s not supported on current platform.' % args.compiler
     sys.exit(1)
 
-if platform_string() == 'windows':
-  def make_jobspec(cfg, targets, makefile='Makefile'):
+_check_arch_option(args.arch)
+
+def make_jobspec(cfg, targets, makefile='Makefile'):
+  if platform_string() == 'windows':
     extra_args = []
     # better do parallel compilation
     # empirically /m:2 gives the best performance/price and should prevent
@@ -782,8 +847,7 @@
                       language_make_options,
                       shell=True, timeout_seconds=None)
       for target in targets]
-else:
-  def make_jobspec(cfg, targets, makefile='Makefile'):
+  else:
     if targets:
       return [jobset.JobSpec([os.getenv('MAKE', 'make'),
                               '-f', makefile,
@@ -796,6 +860,7 @@
                              timeout_seconds=None)]
     else:
       return []
+
 make_targets = {}
 for l in languages:
   makefile = l.makefile_name()
@@ -994,13 +1059,15 @@
     check_cancelled, newline_on_success, cache, xml_report=None, build_only=False):
   """Do one pass of building & running tests."""
   # build latest sequentially
-  num_failures, _ = jobset.run(
+  num_failures, resultset = jobset.run(
       build_steps, maxjobs=1, stop_on_failure=True,
       newline_on_success=newline_on_success, travis=args.travis)
   if num_failures:
     return [BuildAndRunError.BUILD]
 
   if build_only:
+    if xml_report:
+      report_utils.render_junit_xml_report(resultset, xml_report)
     return []
 
   # start antagonists
diff --git a/tools/run_tests/check_cache_mk.sh b/tools/run_tests/sanity/check_cache_mk.sh
similarity index 100%
rename from tools/run_tests/check_cache_mk.sh
rename to tools/run_tests/sanity/check_cache_mk.sh
diff --git a/tools/run_tests/check_sources_and_headers.py b/tools/run_tests/sanity/check_sources_and_headers.py
similarity index 66%
rename from tools/run_tests/check_sources_and_headers.py
rename to tools/run_tests/sanity/check_sources_and_headers.py
index 50574f4..3974af0 100755
--- a/tools/run_tests/check_sources_and_headers.py
+++ b/tools/run_tests/sanity/check_sources_and_headers.py
@@ -33,9 +33,9 @@
 import re
 import sys
 
-root = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../..'))
+root = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..'))
 with open(os.path.join(root, 'tools', 'run_tests', 'sources_and_headers.json')) as f:
-	js = json.loads(f.read())
+  js = json.loads(f.read())
 
 re_inc1 = re.compile(r'^#\s*include\s*"([^"]*)"')
 assert re_inc1.match('#include "foo"').group(1) == 'foo'
@@ -43,41 +43,41 @@
 assert re_inc2.match('#include <grpc++/foo>').group(1) == 'grpc++/foo'
 
 def get_target(name):
-	for target in js:
-		if target['name'] == name:
-			return target
-	assert False, 'no target %s' % name
+  for target in js:
+    if target['name'] == name:
+      return target
+  assert False, 'no target %s' % name
 
 def target_has_header(target, name):
-#	print target['name'], name
-	if name in target['headers']:
-		return True
-	for dep in target['deps']:
-		if target_has_header(get_target(dep), name):
-			return True
-	if name == 'src/core/profiling/stap_probes.h':
-		return True
-	return False
+  # print target['name'], name
+  if name in target['headers']:
+    return True
+  for dep in target['deps']:
+    if target_has_header(get_target(dep), name):
+      return True
+  if name == 'src/core/profiling/stap_probes.h':
+    return True
+  return False
 
 errors = 0
 for target in js:
-	for fn in target['src']:
-		with open(os.path.join(root, fn)) as f:
-			src = f.read().splitlines()
-		for line in src:
-			m = re_inc1.match(line)
-			if m:
-				if not target_has_header(target, m.group(1)):
-					print (
-						'target %s (%s) does not name header %s as a dependency' % (
-							target['name'], fn, m.group(1)))
-					errors += 1
-			m = re_inc2.match(line)
-			if m:
-				if not target_has_header(target, 'include/' + m.group(1)):
-					print (
-						'target %s (%s) does not name header %s as a dependency' % (
-							target['name'], fn, m.group(1)))
-					errors += 1
+  for fn in target['src']:
+    with open(os.path.join(root, fn)) as f:
+      src = f.read().splitlines()
+    for line in src:
+      m = re_inc1.match(line)
+      if m:
+        if not target_has_header(target, m.group(1)):
+          print (
+            'target %s (%s) does not name header %s as a dependency' % (
+              target['name'], fn, m.group(1)))
+          errors += 1
+      m = re_inc2.match(line)
+      if m:
+        if not target_has_header(target, 'include/' + m.group(1)):
+          print (
+            'target %s (%s) does not name header %s as a dependency' % (
+              target['name'], fn, m.group(1)))
+          errors += 1
 
 assert errors == 0
diff --git a/tools/run_tests/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh
similarity index 98%
rename from tools/run_tests/check_submodules.sh
rename to tools/run_tests/sanity/check_submodules.sh
index b4ca4fa..f49230e 100755
--- a/tools/run_tests/check_submodules.sh
+++ b/tools/run_tests/sanity/check_submodules.sh
@@ -34,7 +34,7 @@
 
 export TEST=true
 
-cd `dirname $0`/../..
+cd `dirname $0`/../../..
 
 submodules=`mktemp /tmp/submXXXXXX`
 want_submodules=`mktemp /tmp/submXXXXXX`
diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml
new file mode 100644
index 0000000..809e6ce
--- /dev/null
+++ b/tools/run_tests/sanity/sanity_tests.yaml
@@ -0,0 +1,9 @@
+# a set of tests that are run in parallel for sanity tests
+- script: tools/run_tests/sanity/check_sources_and_headers.py
+- script: tools/run_tests/sanity/check_submodules.sh
+- script: tools/run_tests/sanity/check_cache_mk.sh
+- script: tools/buildgen/generate_projects.sh -j 3
+  cpu_cost: 3
+- script: tools/distrib/check_copyright.py
+- script: tools/distrib/clang_format_code.sh
+- script: tools/distrib/check_trailing_newlines.sh
diff --git a/tools/run_tests/sanity_tests.yaml b/tools/run_tests/sanity_tests.yaml
deleted file mode 100644
index 160acde..0000000
--- a/tools/run_tests/sanity_tests.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-# a set of tests that are run in parallel for sanity tests
-- script: tools/run_tests/check_sources_and_headers.py
-- script: tools/run_tests/check_submodules.sh
-- script: tools/run_tests/check_cache_mk.sh
-- script: tools/buildgen/generate_projects.sh
-  cpu_cost: 100
-- script: tools/distrib/check_copyright.py
-- script: tools/distrib/clang_format_code.sh
-- script: tools/distrib/check_trailing_newlines.sh
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 8c76b3f..1604c8b 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -2433,6 +2433,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2456,6 +2457,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2479,6 +2481,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2502,6 +2505,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2525,6 +2529,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2551,6 +2556,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2577,6 +2583,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2603,6 +2610,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2629,6 +2637,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2655,6 +2664,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2681,6 +2691,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2707,6 +2718,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2733,6 +2745,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2759,6 +2772,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2785,6 +2799,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2811,6 +2826,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2837,6 +2853,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2863,6 +2880,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2889,6 +2907,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2915,6 +2934,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2941,6 +2961,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2967,6 +2988,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -2993,6 +3015,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3019,6 +3042,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3045,6 +3069,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3071,6 +3096,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3097,6 +3123,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3123,6 +3150,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3149,6 +3177,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3174,6 +3203,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3197,6 +3227,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3220,6 +3251,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3245,6 +3277,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3268,6 +3301,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3291,6 +3325,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3314,6 +3349,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3337,6 +3373,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3360,6 +3397,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3383,6 +3421,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3406,6 +3445,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3429,6 +3469,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3452,6 +3493,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3477,6 +3519,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3500,6 +3543,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3523,6 +3567,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3548,6 +3593,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3571,6 +3617,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3594,6 +3641,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3617,6 +3665,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3640,6 +3689,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3665,6 +3715,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3688,6 +3739,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3711,6 +3763,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3734,6 +3787,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3757,6 +3811,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3780,6 +3835,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3803,6 +3859,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3826,6 +3883,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
@@ -3849,6 +3907,7 @@
       "windows"
     ], 
     "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
     "exclude_configs": [
       "asan"
     ], 
diff --git a/tools/tsan_suppressions.txt b/tools/tsan_suppressions.txt
index 65e7e2e..09e68cd 100644
--- a/tools/tsan_suppressions.txt
+++ b/tools/tsan_suppressions.txt
@@ -5,4 +5,4 @@
 # https://www.mail-archive.com/openssl-dev@openssl.org/msg09019.html
 race:ssleay_rand_add
 race:ssleay_rand_bytes
-
+race:__sleep_for