Merge pull request #1774 from ctiller/maybe-we-should-run-some-more-tests

Re-enable some tests
diff --git a/Makefile b/Makefile
index cdd675b..6b9a122 100644
--- a/Makefile
+++ b/Makefile
@@ -1158,7 +1158,7 @@
 
 privatelibs_c:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_fake_security.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_fullstack.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_fullstack_uds_posix.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_fullstack.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_socket_pair.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_socket_pair_with_grpc_trace.a $(LIBDIR)/$(CONFIG)/libend2end_test_bad_hostname.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_accept.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_accept_and_writes_closed.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_invoke.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_before_invoke.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_in_a_vacuum.a $(LIBDIR)/$(CONFIG)/libend2end_test_census_simple_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_disappearing_server.a $(LIBDIR)/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_inflight_calls.a $(LIBDIR)/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_tags.a $(LIBDIR)/$(CONFIG)/libend2end_test_empty_batch.a $(LIBDIR)/$(CONFIG)/libend2end_test_graceful_server_shutdown.a $(LIBDIR)/$(CONFIG)/libend2end_test_invoke_large_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_max_concurrent_streams.a $(LIBDIR)/$(CONFIG)/libend2end_test_max_message_length.a $(LIBDIR)/$(CONFIG)/libend2end_test_no_op.a $(LIBDIR)/$(CONFIG)/libend2end_test_ping_pong_streaming.a $(LIBDIR)/$(CONFIG)/libend2end_test_registered_call.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_binary_metadata_and_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_metadata_and_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_payload_and_call_creds.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_trailing_metadata_and_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_with_large_metadata.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_with_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_server_finishes_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_simple_delayed_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_simple_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_simple_request_with_high_initial_sequence_number.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a
 
-privatelibs_cxx:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a
+privatelibs_cxx:  $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a
 
 buildtests: buildtests_c buildtests_cxx
 
@@ -3217,6 +3217,57 @@
 endif
 
 
+LIBGRPC++_BENCHMARK_CONFIG_SRC = \
+    $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc \
+    test/cpp/qps/report.cc \
+    test/cpp/util/benchmark_config.cc \
+
+
+LIBGRPC++_BENCHMARK_CONFIG_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_BENCHMARK_CONFIG_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure libraries if you don't have OpenSSL with ALPN.
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a: openssl_dep_error
+
+
+else
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a: protobuf_dep_error
+
+
+else
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_BENCHMARK_CONFIG_OBJS)
+	$(E) "[AR]      Creating $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a
+	$(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a $(LIBGRPC++_BENCHMARK_CONFIG_OBJS)
+ifeq ($(SYSTEM),Darwin)
+	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a
+endif
+
+
+
+
+endif
+
+endif
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(LIBGRPC++_BENCHMARK_CONFIG_OBJS:.o=.dep)
+endif
+endif
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/report.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/benchmark_config.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
+
+
 LIBGRPC++_TEST_CONFIG_SRC = \
     test/cpp/util/test_config.cc \
 
@@ -3730,7 +3781,6 @@
     test/cpp/qps/client_sync.cc \
     test/cpp/qps/driver.cc \
     test/cpp/qps/qps_worker.cc \
-    test/cpp/qps/report.cc \
     test/cpp/qps/server_async.cc \
     test/cpp/qps/server_sync.cc \
     test/cpp/qps/timer.cc \
@@ -3781,7 +3831,6 @@
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/client_sync.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_worker.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/report.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/server_async.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/server_sync.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/timer.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
@@ -7127,16 +7176,16 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/async_streaming_ping_pong_test: $(PROTOBUF_DEP) $(ASYNC_STREAMING_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/async_streaming_ping_pong_test: $(PROTOBUF_DEP) $(ASYNC_STREAMING_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(ASYNC_STREAMING_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/async_streaming_ping_pong_test
+	$(Q) $(LDXX) $(LDFLAGS) $(ASYNC_STREAMING_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/async_streaming_ping_pong_test
 
 endif
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/async_streaming_ping_pong_test.o:  $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/async_streaming_ping_pong_test.o:  $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 deps_async_streaming_ping_pong_test: $(ASYNC_STREAMING_PING_PONG_TEST_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
@@ -7167,16 +7216,16 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/async_unary_ping_pong_test: $(PROTOBUF_DEP) $(ASYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/async_unary_ping_pong_test: $(PROTOBUF_DEP) $(ASYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(ASYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/async_unary_ping_pong_test
+	$(Q) $(LDXX) $(LDFLAGS) $(ASYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/async_unary_ping_pong_test
 
 endif
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/async_unary_ping_pong_test.o:  $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/async_unary_ping_pong_test.o:  $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 deps_async_unary_ping_pong_test: $(ASYNC_UNARY_PING_PONG_TEST_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
@@ -7965,16 +8014,16 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/qps_driver: $(PROTOBUF_DEP) $(QPS_DRIVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
+$(BINDIR)/$(CONFIG)/qps_driver: $(PROTOBUF_DEP) $(QPS_DRIVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(QPS_DRIVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_driver
+	$(Q) $(LDXX) $(LDFLAGS) $(QPS_DRIVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_driver
 
 endif
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_driver.o:  $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_driver.o:  $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a
 deps_qps_driver: $(QPS_DRIVER_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
@@ -8005,16 +8054,16 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/qps_test: $(PROTOBUF_DEP) $(QPS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
+$(BINDIR)/$(CONFIG)/qps_test: $(PROTOBUF_DEP) $(QPS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(QPS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_test
+	$(Q) $(LDXX) $(LDFLAGS) $(QPS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_test
 
 endif
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_test.o:  $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_test.o:  $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
 deps_qps_test: $(QPS_TEST_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
@@ -8205,16 +8254,16 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/sync_streaming_ping_pong_test: $(PROTOBUF_DEP) $(SYNC_STREAMING_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/sync_streaming_ping_pong_test: $(PROTOBUF_DEP) $(SYNC_STREAMING_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(SYNC_STREAMING_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/sync_streaming_ping_pong_test
+	$(Q) $(LDXX) $(LDFLAGS) $(SYNC_STREAMING_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/sync_streaming_ping_pong_test
 
 endif
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/sync_streaming_ping_pong_test.o:  $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/sync_streaming_ping_pong_test.o:  $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 deps_sync_streaming_ping_pong_test: $(SYNC_STREAMING_PING_PONG_TEST_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
@@ -8245,16 +8294,16 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/sync_unary_ping_pong_test: $(PROTOBUF_DEP) $(SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/sync_unary_ping_pong_test: $(PROTOBUF_DEP) $(SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/sync_unary_ping_pong_test
+	$(Q) $(LDXX) $(LDFLAGS) $(SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/sync_unary_ping_pong_test
 
 endif
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/sync_unary_ping_pong_test.o:  $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/sync_unary_ping_pong_test.o:  $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_benchmark_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 deps_sync_unary_ping_pong_test: $(SYNC_UNARY_PING_PONG_TEST_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
diff --git a/build.json b/build.json
index b253b35..0a42d70 100644
--- a/build.json
+++ b/build.json
@@ -526,6 +526,16 @@
       "vs_project_guid": "{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}"
     },
     {
+      "name": "grpc++_benchmark_config",
+      "build": "private",
+      "language": "c++",
+      "src": [
+        "test/cpp/qps/qpstest.proto",
+        "test/cpp/qps/report.cc",
+        "test/cpp/util/benchmark_config.cc"
+      ]
+    },
+    {
       "name": "grpc++_test_config",
       "build": "private",
       "language": "c++",
@@ -589,7 +599,8 @@
         "src/compiler/ruby_generator.cc"
       ],
       "deps": [],
-      "secure": "no"
+      "secure": "no",
+      "vs_project_guid": "{B6E81D84-2ACB-41B8-8781-493A944C7817}"
     },
     {
       "name": "interop_client_helper",
@@ -694,7 +705,6 @@
         "test/cpp/qps/client_sync.cc",
         "test/cpp/qps/driver.cc",
         "test/cpp/qps/qps_worker.cc",
-        "test/cpp/qps/report.cc",
         "test/cpp/qps/server_async.cc",
         "test/cpp/qps/server_sync.cc",
         "test/cpp/qps/timer.cc"
@@ -1817,6 +1827,7 @@
       "deps": [
         "qps",
         "grpc++_test_util",
+        "grpc++_benchmark_config",
         "grpc_test_util",
         "grpc++",
         "grpc",
@@ -1834,6 +1845,7 @@
       "deps": [
         "qps",
         "grpc++_test_util",
+        "grpc++_benchmark_config",
         "grpc_test_util",
         "grpc++",
         "grpc",
@@ -1991,7 +2003,8 @@
       "deps": [
         "grpc_plugin_support"
       ],
-      "secure": "no"
+      "secure": "no",
+      "vs_project_guid": "{7E51A25F-AC59-488F-906C-C60FAAE706AA}"
     },
     {
       "name": "grpc_csharp_plugin",
@@ -2003,7 +2016,8 @@
       "deps": [
         "grpc_plugin_support"
       ],
-      "secure": "no"
+      "secure": "no",
+      "vs_project_guid": "{3C813052-A49A-4662-B90A-1ADBEC7EE453}"
     },
     {
       "name": "grpc_objective_c_plugin",
@@ -2015,7 +2029,8 @@
       "deps": [
         "grpc_plugin_support"
       ],
-      "secure": "no"
+      "secure": "no",
+      "vs_project_guid": "{19564640-CEE6-4921-ABA5-676ED79A36F6}"
     },
     {
       "name": "grpc_python_plugin",
@@ -2027,7 +2042,8 @@
       "deps": [
         "grpc_plugin_support"
       ],
-      "secure": "no"
+      "secure": "no",
+      "vs_project_guid": "{DF52D501-A6CF-4E6F-BA38-6EBE2E8DAFB2}"
     },
     {
       "name": "grpc_ruby_plugin",
@@ -2039,7 +2055,8 @@
       "deps": [
         "grpc_plugin_support"
       ],
-      "secure": "no"
+      "secure": "no",
+      "vs_project_guid": "{069E9D05-B78B-4751-9252-D21EBAE7DE8E}"
     },
     {
       "name": "interop_client",
@@ -2174,7 +2191,8 @@
         "grpc",
         "gpr_test_util",
         "gpr",
-        "grpc++_test_config"
+        "grpc++_test_config",
+        "grpc++_benchmark_config"
       ]
     },
     {
@@ -2187,6 +2205,7 @@
       "deps": [
         "qps",
         "grpc++_test_util",
+        "grpc++_benchmark_config",
         "grpc_test_util",
         "grpc++",
         "grpc",
@@ -2275,6 +2294,7 @@
       "deps": [
         "qps",
         "grpc++_test_util",
+        "grpc++_benchmark_config",
         "grpc_test_util",
         "grpc++",
         "grpc",
@@ -2292,6 +2312,7 @@
       "deps": [
         "qps",
         "grpc++_test_util",
+        "grpc++_benchmark_config",
         "grpc_test_util",
         "grpc++",
         "grpc",
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index acac147..b0d2b5d 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -86,23 +86,25 @@
 grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file,
                                const Parameters &params) {
   grpc::string output;
-  grpc::protobuf::io::StringOutputStream output_stream(&output);
-  grpc::protobuf::io::Printer printer(&output_stream, '$');
-  std::map<grpc::string, grpc::string> vars;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    grpc::protobuf::io::StringOutputStream output_stream(&output);
+    grpc::protobuf::io::Printer printer(&output_stream, '$');
+    std::map<grpc::string, grpc::string> vars;
 
-  vars["filename"] = file->name();
-  vars["filename_identifier"] = FilenameIdentifier(file->name());
-  vars["filename_base"] = grpc_generator::StripProto(file->name());
+    vars["filename"] = file->name();
+    vars["filename_identifier"] = FilenameIdentifier(file->name());
+    vars["filename_base"] = grpc_generator::StripProto(file->name());
 
-  printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
-  printer.Print(vars, "// If you make any local change, they will be lost.\n");
-  printer.Print(vars, "// source: $filename$\n");
-  printer.Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
-  printer.Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
-  printer.Print(vars, "\n");
-  printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
-  printer.Print(vars, "\n");
-
+    printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
+    printer.Print(vars, "// If you make any local change, they will be lost.\n");
+    printer.Print(vars, "// source: $filename$\n");
+    printer.Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
+    printer.Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
+    printer.Print(vars, "\n");
+    printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
+    printer.Print(vars, "\n");
+  }
   return output;
 }
 
@@ -626,100 +628,108 @@
 grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
                                const Parameters &params) {
   grpc::string output;
-  grpc::protobuf::io::StringOutputStream output_stream(&output);
-  grpc::protobuf::io::Printer printer(&output_stream, '$');
-  std::map<grpc::string, grpc::string> vars;
+  {
+	// Scope the output stream so it closes and finalizes output to the string.
+    grpc::protobuf::io::StringOutputStream output_stream(&output);
+    grpc::protobuf::io::Printer printer(&output_stream, '$');
+    std::map<grpc::string, grpc::string> vars;
 
-  if (!params.services_namespace.empty()) {
-    vars["services_namespace"] = params.services_namespace;
-    printer.Print(vars, "\nnamespace $services_namespace$ {\n\n");
+    if (!params.services_namespace.empty()) {
+      vars["services_namespace"] = params.services_namespace;
+      printer.Print(vars, "\nnamespace $services_namespace$ {\n\n");
+    }
+
+    for (int i = 0; i < file->service_count(); ++i) {
+      PrintHeaderService(&printer, file->service(i), &vars);
+      printer.Print("\n");
+    }
+
+    if (!params.services_namespace.empty()) {
+      printer.Print(vars, "}  // namespace $services_namespace$\n\n");
+    }
   }
-
-  for (int i = 0; i < file->service_count(); ++i) {
-    PrintHeaderService(&printer, file->service(i), &vars);
-    printer.Print("\n");
-  }
-
-  if (!params.services_namespace.empty()) {
-    printer.Print(vars, "}  // namespace $services_namespace$\n\n");
-  }
-
   return output;
 }
 
 grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file,
                                const Parameters &params) {
   grpc::string output;
-  grpc::protobuf::io::StringOutputStream output_stream(&output);
-  grpc::protobuf::io::Printer printer(&output_stream, '$');
-  std::map<grpc::string, grpc::string> vars;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    grpc::protobuf::io::StringOutputStream output_stream(&output);
+    grpc::protobuf::io::Printer printer(&output_stream, '$');
+    std::map<grpc::string, grpc::string> vars;
 
-  vars["filename"] = file->name();
-  vars["filename_identifier"] = FilenameIdentifier(file->name());
+    vars["filename"] = file->name();
+    vars["filename_identifier"] = FilenameIdentifier(file->name());
 
-  if (!file->package().empty()) {
-    std::vector<grpc::string> parts =
-        grpc_generator::tokenize(file->package(), ".");
+    if (!file->package().empty()) {
+      std::vector<grpc::string> parts =
+          grpc_generator::tokenize(file->package(), ".");
 
-    for (auto part = parts.rbegin(); part != parts.rend(); part++) {
-      vars["part"] = *part;
-      printer.Print(vars, "}  // namespace $part$\n");
+      for (auto part = parts.rbegin(); part != parts.rend(); part++) {
+        vars["part"] = *part;
+        printer.Print(vars, "}  // namespace $part$\n");
+      }
+      printer.Print(vars, "\n");
     }
+
     printer.Print(vars, "\n");
+    printer.Print(vars, "#endif  // GRPC_$filename_identifier$__INCLUDED\n");
   }
-
-  printer.Print(vars, "\n");
-  printer.Print(vars, "#endif  // GRPC_$filename_identifier$__INCLUDED\n");
-
   return output;
 }
 
 grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file,
                                const Parameters &params) {
   grpc::string output;
-  grpc::protobuf::io::StringOutputStream output_stream(&output);
-  grpc::protobuf::io::Printer printer(&output_stream, '$');
-  std::map<grpc::string, grpc::string> vars;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    grpc::protobuf::io::StringOutputStream output_stream(&output);
+    grpc::protobuf::io::Printer printer(&output_stream, '$');
+    std::map<grpc::string, grpc::string> vars;
 
-  vars["filename"] = file->name();
-  vars["filename_base"] = grpc_generator::StripProto(file->name());
+    vars["filename"] = file->name();
+    vars["filename_base"] = grpc_generator::StripProto(file->name());
 
-  printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
-  printer.Print(vars, "// If you make any local change, they will be lost.\n");
-  printer.Print(vars, "// source: $filename$\n\n");
-  printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
-  printer.Print(vars, "#include \"$filename_base$.grpc.pb.h\"\n");
-  printer.Print(vars, "\n");
-
+    printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
+    printer.Print(vars, "// If you make any local change, they will be lost.\n");
+    printer.Print(vars, "// source: $filename$\n\n");
+    printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
+    printer.Print(vars, "#include \"$filename_base$.grpc.pb.h\"\n");
+    printer.Print(vars, "\n");
+  }
   return output;
 }
 
 grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file,
                                const Parameters &param) {
   grpc::string output;
-  grpc::protobuf::io::StringOutputStream output_stream(&output);
-  grpc::protobuf::io::Printer printer(&output_stream, '$');
-  std::map<grpc::string, grpc::string> vars;
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    grpc::protobuf::io::StringOutputStream output_stream(&output);
+    grpc::protobuf::io::Printer printer(&output_stream, '$');
+    std::map<grpc::string, grpc::string> vars;
 
-  printer.Print(vars, "#include <grpc++/async_unary_call.h>\n");
-  printer.Print(vars, "#include <grpc++/channel_interface.h>\n");
-  printer.Print(vars, "#include <grpc++/impl/client_unary_call.h>\n");
-  printer.Print(vars, "#include <grpc++/impl/rpc_service_method.h>\n");
-  printer.Print(vars, "#include <grpc++/impl/service_type.h>\n");
-  printer.Print(vars, "#include <grpc++/stream.h>\n");
+    printer.Print(vars, "#include <grpc++/async_unary_call.h>\n");
+    printer.Print(vars, "#include <grpc++/channel_interface.h>\n");
+    printer.Print(vars, "#include <grpc++/impl/client_unary_call.h>\n");
+    printer.Print(vars, "#include <grpc++/impl/rpc_service_method.h>\n");
+    printer.Print(vars, "#include <grpc++/impl/service_type.h>\n");
+    printer.Print(vars, "#include <grpc++/stream.h>\n");
 
-  if (!file->package().empty()) {
-    std::vector<grpc::string> parts =
-        grpc_generator::tokenize(file->package(), ".");
+    if (!file->package().empty()) {
+      std::vector<grpc::string> parts =
+          grpc_generator::tokenize(file->package(), ".");
 
-    for (auto part = parts.begin(); part != parts.end(); part++) {
-      vars["part"] = *part;
-      printer.Print(vars, "namespace $part$ {\n");
+      for (auto part = parts.begin(); part != parts.end(); part++) {
+        vars["part"] = *part;
+        printer.Print(vars, "namespace $part$ {\n");
+      }
     }
+
+    printer.Print(vars, "\n");
   }
-
-  printer.Print(vars, "\n");
-
   return output;
 }
 
@@ -1077,26 +1087,29 @@
 grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file,
                                const Parameters &params) {
   grpc::string output;
-  grpc::protobuf::io::StringOutputStream output_stream(&output);
-  grpc::protobuf::io::Printer printer(&output_stream, '$');
-  std::map<grpc::string, grpc::string> vars;
-  // Package string is empty or ends with a dot. It is used to fully qualify
-  // method names.
-  vars["Package"] = file->package();
-  if (!file->package().empty()) {
-    vars["Package"].append(".");
-  }
-  if (!params.services_namespace.empty()) {
-    vars["ns"] = params.services_namespace + "::";
-    vars["prefix"] = params.services_namespace;
-  } else {
-    vars["ns"] = "";
-    vars["prefix"] = "";
-  }
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    grpc::protobuf::io::StringOutputStream output_stream(&output);
+    grpc::protobuf::io::Printer printer(&output_stream, '$');
+    std::map<grpc::string, grpc::string> vars;
+    // Package string is empty or ends with a dot. It is used to fully qualify
+    // method names.
+    vars["Package"] = file->package();
+    if (!file->package().empty()) {
+      vars["Package"].append(".");
+    }
+    if (!params.services_namespace.empty()) {
+      vars["ns"] = params.services_namespace + "::";
+      vars["prefix"] = params.services_namespace;
+    } else {
+      vars["ns"] = "";
+      vars["prefix"] = "";
+    }
 
-  for (int i = 0; i < file->service_count(); ++i) {
-    PrintSourceService(&printer, file->service(i), &vars);
-    printer.Print("\n");
+    for (int i = 0; i < file->service_count(); ++i) {
+      PrintSourceService(&printer, file->service(i), &vars);
+      printer.Print("\n");
+    }
   }
   return output;
 }
diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc
index 5dd078b..ccb0b68 100644
--- a/src/compiler/csharp_generator.cc
+++ b/src/compiler/csharp_generator.cc
@@ -474,35 +474,39 @@
 
 grpc::string GetServices(const FileDescriptor *file) {
   grpc::string output;
-  StringOutputStream output_stream(&output);
-  Printer out(&output_stream, '$');
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
 
-  // Don't write out any output if there no services, to avoid empty service
-  // files being generated for proto files that don't declare any.
-  if (file->service_count() == 0) {
-    return output;
+    StringOutputStream output_stream(&output);
+    Printer out(&output_stream, '$');
+
+    // Don't write out any output if there no services, to avoid empty service
+    // files being generated for proto files that don't declare any.
+    if (file->service_count() == 0) {
+      return output;
+    }
+
+    // Write out a file header.
+    out.Print("// Generated by the protocol buffer compiler.  DO NOT EDIT!\n");
+    out.Print("// source: $filename$\n", "filename", file->name());
+    out.Print("#region Designer generated code\n");
+    out.Print("\n");
+    out.Print("using System;\n");
+    out.Print("using System.Threading;\n");
+    out.Print("using System.Threading.Tasks;\n");
+    out.Print("using Grpc.Core;\n");
+    // TODO(jtattermusch): add using for protobuf message classes
+    out.Print("\n");
+
+    out.Print("namespace $namespace$ {\n", "namespace", GetFileNamespace(file));
+    out.Indent();
+    for (int i = 0; i < file->service_count(); i++) {
+      GenerateService(&out, file->service(i));
+    }
+    out.Outdent();
+    out.Print("}\n");
+    out.Print("#endregion\n");
   }
-
-  // Write out a file header.
-  out.Print("// Generated by the protocol buffer compiler.  DO NOT EDIT!\n");
-  out.Print("// source: $filename$\n", "filename", file->name());
-  out.Print("#region Designer generated code\n");
-  out.Print("\n");
-  out.Print("using System;\n");
-  out.Print("using System.Threading;\n");
-  out.Print("using System.Threading.Tasks;\n");
-  out.Print("using Grpc.Core;\n");
-  // TODO(jtattermusch): add using for protobuf message classes
-  out.Print("\n");
-
-  out.Print("namespace $namespace$ {\n", "namespace", GetFileNamespace(file));
-  out.Indent();
-  for (int i = 0; i < file->service_count(); i++) {
-    GenerateService(&out, file->service(i));
-  }
-  out.Outdent();
-  out.Print("}\n");
-  out.Print("#endregion\n");
   return output;
 }
 
diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc
index 8f35302..1bf0254 100644
--- a/src/compiler/objective_c_generator.cc
+++ b/src/compiler/objective_c_generator.cc
@@ -176,65 +176,71 @@
 
 string GetHeader(const ServiceDescriptor *service, const string prefix) {
   string output;
-  grpc::protobuf::io::StringOutputStream output_stream(&output);
-  Printer printer(&output_stream, '$');
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    grpc::protobuf::io::StringOutputStream output_stream(&output);
+    Printer printer(&output_stream, '$');
   
-  printer.Print("@protocol GRXWriteable;\n");
-  printer.Print("@protocol GRXWriter;\n\n");
+    printer.Print("@protocol GRXWriteable;\n");
+    printer.Print("@protocol GRXWriter;\n\n");
 
-  map<string, string> vars = {{"service_name", service->name()},
-                              {"prefix",       prefix}};
-  printer.Print(vars, "@protocol $prefix$$service_name$ <NSObject>\n\n");
+    map<string, string> vars = {{"service_name", service->name()},
+                                {"prefix",       prefix}};
+    printer.Print(vars, "@protocol $prefix$$service_name$ <NSObject>\n\n");
 
-  for (int i = 0; i < service->method_count(); i++) {
-    PrintMethodDeclarations(&printer, service->method(i), vars);
+    for (int i = 0; i < service->method_count(); i++) {
+      PrintMethodDeclarations(&printer, service->method(i), vars);
+    }
+    printer.Print("@end\n\n");
+
+    printer.Print("// Basic service implementation, over gRPC, that only does"
+        " marshalling and parsing.\n");
+    printer.Print(vars, "@interface $prefix$$service_name$ :"
+      " ProtoService<$prefix$$service_name$>\n");
+    printer.Print("- (instancetype)initWithHost:(NSString *)host"
+      " NS_DESIGNATED_INITIALIZER;\n");
+    printer.Print("@end\n");
   }
-  printer.Print("@end\n\n");
-
-  printer.Print("// Basic service implementation, over gRPC, that only does"
-      " marshalling and parsing.\n");
-  printer.Print(vars, "@interface $prefix$$service_name$ :"
-    " ProtoService<$prefix$$service_name$>\n");
-  printer.Print("- (instancetype)initWithHost:(NSString *)host"
-    " NS_DESIGNATED_INITIALIZER;\n");
-  printer.Print("@end\n");
   return output;
 }
 
 string GetSource(const ServiceDescriptor *service, const string prefix) {
   string output;
-  grpc::protobuf::io::StringOutputStream output_stream(&output);
-  Printer printer(&output_stream, '$');
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    grpc::protobuf::io::StringOutputStream output_stream(&output);
+    Printer printer(&output_stream, '$');
 
-  map<string, string> vars = {{"service_name", service->name()},
-                              {"package", service->file()->package()},
-                              {"prefix",       prefix}};
+    map<string, string> vars = {{"service_name", service->name()},
+                                {"package", service->file()->package()},
+                                {"prefix",       prefix}};
 
-  printer.Print(vars,
-      "static NSString *const kPackageName = @\"$package$\";\n");
-  printer.Print(vars,
-      "static NSString *const kServiceName = @\"$service_name$\";\n\n");
+    printer.Print(vars,
+        "static NSString *const kPackageName = @\"$package$\";\n");
+    printer.Print(vars,
+        "static NSString *const kServiceName = @\"$service_name$\";\n\n");
 
-  printer.Print(vars, "@implementation $prefix$$service_name$\n\n");
+    printer.Print(vars, "@implementation $prefix$$service_name$\n\n");
+  
+    printer.Print("// Designated initializer\n");
+    printer.Print("- (instancetype)initWithHost:(NSString *)host {\n");
+    printer.Print("  return (self = [super initWithHost:host"
+        " packageName:kPackageName serviceName:kServiceName]);\n");
+    printer.Print("}\n\n");
+    printer.Print("// Override superclass initializer to disallow different"
+        " package and service names.\n");
+    printer.Print("- (instancetype)initWithHost:(NSString *)host\n");
+    printer.Print("                 packageName:(NSString *)packageName\n");
+    printer.Print("                 serviceName:(NSString *)serviceName {\n");
+    printer.Print("  return [self initWithHost:host];\n");
+    printer.Print("}\n\n\n");
 
-  printer.Print("// Designated initializer\n");
-  printer.Print("- (instancetype)initWithHost:(NSString *)host {\n");
-  printer.Print("  return (self = [super initWithHost:host"
-      " packageName:kPackageName serviceName:kServiceName]);\n");
-  printer.Print("}\n\n");
-  printer.Print("// Override superclass initializer to disallow different"
-      " package and service names.\n");
-  printer.Print("- (instancetype)initWithHost:(NSString *)host\n");
-  printer.Print("                 packageName:(NSString *)packageName\n");
-  printer.Print("                 serviceName:(NSString *)serviceName {\n");
-  printer.Print("  return [self initWithHost:host];\n");
-  printer.Print("}\n\n\n");
+    for (int i = 0; i < service->method_count(); i++) {
+      PrintMethodImplementations(&printer, service->method(i), vars);
+    }
 
-  for (int i = 0; i < service->method_count(); i++) {
-    PrintMethodImplementations(&printer, service->method(i), vars);
+    printer.Print("@end\n");
   }
-
-  printer.Print("@end\n");
   return output;
 }
 
diff --git a/src/compiler/ruby_generator.cc b/src/compiler/ruby_generator.cc
index a0bb928..2991375 100644
--- a/src/compiler/ruby_generator.cc
+++ b/src/compiler/ruby_generator.cc
@@ -119,49 +119,52 @@
 
 grpc::string GetServices(const FileDescriptor *file) {
   grpc::string output;
-  StringOutputStream output_stream(&output);
-  Printer out(&output_stream, '$');
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
 
-  // Don't write out any output if there no services, to avoid empty service
-  // files being generated for proto files that don't declare any.
-  if (file->service_count() == 0) {
-    return output;
+    StringOutputStream output_stream(&output);
+    Printer out(&output_stream, '$');
+
+    // Don't write out any output if there no services, to avoid empty service
+    // files being generated for proto files that don't declare any.
+    if (file->service_count() == 0) {
+      return output;
+    }
+
+    // Write out a file header.
+    std::map<grpc::string, grpc::string> header_comment_vars = ListToDict(
+        {"file.name", file->name(), "file.package", file->package(), });
+    out.Print("# Generated by the protocol buffer compiler.  DO NOT EDIT!\n");
+    out.Print(header_comment_vars,
+              "# Source: $file.name$ for package '$file.package$'\n");
+
+    out.Print("\n");
+    out.Print("require 'grpc'\n");
+    // Write out require statemment to import the separately generated file
+    // that defines the messages used by the service. This is generated by the
+    // main ruby plugin.
+    std::map<grpc::string, grpc::string> dep_vars =
+        ListToDict({"dep.name", MessagesRequireName(file), });
+    out.Print(dep_vars, "require '$dep.name$'\n");
+
+    // Write out services within the modules
+    out.Print("\n");
+    std::vector<grpc::string> modules = Split(file->package(), '.');
+    for (size_t i = 0; i < modules.size(); ++i) {
+      std::map<grpc::string, grpc::string> module_vars =
+          ListToDict({"module.name", CapitalizeFirst(modules[i]), });
+      out.Print(module_vars, "module $module.name$\n");
+      out.Indent();
+    }
+    for (int i = 0; i < file->service_count(); ++i) {
+      auto service = file->service(i);
+      PrintService(service, file->package(), &out);
+    }
+    for (size_t i = 0; i < modules.size(); ++i) {
+      out.Outdent();
+      out.Print("end\n");
+    }
   }
-
-  // Write out a file header.
-  std::map<grpc::string, grpc::string> header_comment_vars = ListToDict(
-      {"file.name", file->name(), "file.package", file->package(), });
-  out.Print("# Generated by the protocol buffer compiler.  DO NOT EDIT!\n");
-  out.Print(header_comment_vars,
-            "# Source: $file.name$ for package '$file.package$'\n");
-
-  out.Print("\n");
-  out.Print("require 'grpc'\n");
-  // Write out require statemment to import the separately generated file
-  // that defines the messages used by the service. This is generated by the
-  // main ruby plugin.
-  std::map<grpc::string, grpc::string> dep_vars =
-      ListToDict({"dep.name", MessagesRequireName(file), });
-  out.Print(dep_vars, "require '$dep.name$'\n");
-
-  // Write out services within the modules
-  out.Print("\n");
-  std::vector<grpc::string> modules = Split(file->package(), '.');
-  for (size_t i = 0; i < modules.size(); ++i) {
-    std::map<grpc::string, grpc::string> module_vars =
-        ListToDict({"module.name", CapitalizeFirst(modules[i]), });
-    out.Print(module_vars, "module $module.name$\n");
-    out.Indent();
-  }
-  for (int i = 0; i < file->service_count(); ++i) {
-    auto service = file->service(i);
-    PrintService(service, file->package(), &out);
-  }
-  for (size_t i = 0; i < modules.size(); ++i) {
-    out.Outdent();
-    out.Print("end\n");
-  }
-
   return output;
 }
 
diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c
index 78f8d06..42e242a 100644
--- a/src/core/channel/client_channel.c
+++ b/src/core/channel/client_channel.c
@@ -144,6 +144,7 @@
   call_data *calld = elem->call_data;
   channel_data *chand = elem->channel_data;
   if (op->send_ops) {
+    grpc_stream_ops_unref_owned_objects(op->send_ops->ops, op->send_ops->nops);
     op->on_done_send(op->send_user_data, 0);
   }
   if (op->recv_ops) {
diff --git a/src/core/iomgr/fd_posix.c b/src/core/iomgr/fd_posix.c
index 9c8133d..63615ea 100644
--- a/src/core/iomgr/fd_posix.c
+++ b/src/core/iomgr/fd_posix.c
@@ -96,8 +96,10 @@
   gpr_atm_rel_store(&r->writest, NOT_READY);
   gpr_atm_rel_store(&r->shutdown, 0);
   r->fd = fd;
-  r->watcher_root.next = r->watcher_root.prev = &r->watcher_root;
+  r->inactive_watcher_root.next = r->inactive_watcher_root.prev =
+      &r->inactive_watcher_root;
   r->freelist_next = NULL;
+  r->read_watcher = r->write_watcher = NULL;
   return r;
 }
 
@@ -147,14 +149,34 @@
   return (gpr_atm_acq_load(&fd->refst) & 1) == 0;
 }
 
-static void wake_watchers(grpc_fd *fd) {
-  grpc_fd_watcher *watcher;
+static void maybe_wake_one_watcher_locked(grpc_fd *fd) {
+  if (fd->inactive_watcher_root.next != &fd->inactive_watcher_root) {
+    grpc_pollset_force_kick(fd->inactive_watcher_root.next->pollset);
+  } else if (fd->read_watcher) {
+    grpc_pollset_force_kick(fd->read_watcher->pollset);
+  } else if (fd->write_watcher) {
+    grpc_pollset_force_kick(fd->write_watcher->pollset);
+  }
+}
+
+static void maybe_wake_one_watcher(grpc_fd *fd) {
   gpr_mu_lock(&fd->watcher_mu);
-  for (watcher = fd->watcher_root.next; watcher != &fd->watcher_root;
-       watcher = watcher->next) {
+  maybe_wake_one_watcher_locked(fd);
+  gpr_mu_unlock(&fd->watcher_mu);
+}
+
+static void wake_all_watchers(grpc_fd *fd) {
+  grpc_fd_watcher *watcher;
+  for (watcher = fd->inactive_watcher_root.next;
+       watcher != &fd->inactive_watcher_root; watcher = watcher->next) {
     grpc_pollset_force_kick(watcher->pollset);
   }
-  gpr_mu_unlock(&fd->watcher_mu);
+  if (fd->read_watcher) {
+    grpc_pollset_force_kick(fd->read_watcher->pollset);
+  }
+  if (fd->write_watcher && fd->write_watcher != fd->read_watcher) {
+    grpc_pollset_force_kick(fd->write_watcher->pollset);
+  }
 }
 
 void grpc_fd_orphan(grpc_fd *fd, grpc_iomgr_cb_func on_done, void *user_data) {
@@ -162,7 +184,7 @@
   fd->on_done_user_data = user_data;
   shutdown(fd->fd, SHUT_RDWR);
   ref_by(fd, 1); /* remove active status, but keep referenced */
-  wake_watchers(fd);
+  wake_all_watchers(fd);
   unref_by(fd, 2); /* drop the reference */
 }
 
@@ -204,7 +226,7 @@
            set_ready call.  NOTE: we don't have an ABA problem here,
            since we should never have concurrent calls to the same
            notify_on function. */
-        wake_watchers(fd);
+        maybe_wake_one_watcher(fd);
         return;
       }
     /* swap was unsuccessful due to an intervening set_ready call.
@@ -290,29 +312,65 @@
 gpr_uint32 grpc_fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset,
                               gpr_uint32 read_mask, gpr_uint32 write_mask,
                               grpc_fd_watcher *watcher) {
+  gpr_uint32 mask = 0;
   /* keep track of pollers that have requested our events, in case they change
    */
   grpc_fd_ref(fd);
 
   gpr_mu_lock(&fd->watcher_mu);
-  watcher->next = &fd->watcher_root;
-  watcher->prev = watcher->next->prev;
-  watcher->next->prev = watcher->prev->next = watcher;
+  /* if there is nobody polling for read, but we need to, then start doing so */
+  if (!fd->read_watcher && gpr_atm_acq_load(&fd->readst) > READY) {
+    fd->read_watcher = watcher;
+    mask |= read_mask;
+  }
+  /* if there is nobody polling for write, but we need to, then start doing so
+   */
+  if (!fd->write_watcher && gpr_atm_acq_load(&fd->writest) > READY) {
+    fd->write_watcher = watcher;
+    mask |= write_mask;
+  }
+  /* if not polling, remember this watcher in case we need someone to later */
+  if (mask == 0) {
+    watcher->next = &fd->inactive_watcher_root;
+    watcher->prev = watcher->next->prev;
+    watcher->next->prev = watcher->prev->next = watcher;
+  }
   watcher->pollset = pollset;
   watcher->fd = fd;
   gpr_mu_unlock(&fd->watcher_mu);
 
-  return (gpr_atm_acq_load(&fd->readst) != READY ? read_mask : 0) |
-         (gpr_atm_acq_load(&fd->writest) != READY ? write_mask : 0);
+  return mask;
 }
 
-void grpc_fd_end_poll(grpc_fd_watcher *watcher) {
-  gpr_mu_lock(&watcher->fd->watcher_mu);
-  watcher->next->prev = watcher->prev;
-  watcher->prev->next = watcher->next;
-  gpr_mu_unlock(&watcher->fd->watcher_mu);
+void grpc_fd_end_poll(grpc_fd_watcher *watcher, int got_read, int got_write) {
+  int was_polling = 0;
+  int kick = 0;
+  grpc_fd *fd = watcher->fd;
 
-  grpc_fd_unref(watcher->fd);
+  gpr_mu_lock(&fd->watcher_mu);
+  if (watcher == fd->read_watcher) {
+    /* remove read watcher, kick if we still need a read */
+    was_polling = 1;
+    kick = kick || !got_read;
+    fd->read_watcher = NULL;
+  }
+  if (watcher == fd->write_watcher) {
+    /* remove write watcher, kick if we still need a write */
+    was_polling = 1;
+    kick = kick || !got_write;
+    fd->write_watcher = NULL;
+  }
+  if (!was_polling) {
+    /* remove from inactive list */
+    watcher->next->prev = watcher->prev;
+    watcher->prev->next = watcher->next;
+  }
+  if (kick) {
+    maybe_wake_one_watcher_locked(fd);
+  }
+  gpr_mu_unlock(&fd->watcher_mu);
+
+  grpc_fd_unref(fd);
 }
 
 void grpc_fd_become_readable(grpc_fd *fd, int allow_synchronous_callback) {
diff --git a/src/core/iomgr/fd_posix.h b/src/core/iomgr/fd_posix.h
index be21f2b..cfc533b 100644
--- a/src/core/iomgr/fd_posix.h
+++ b/src/core/iomgr/fd_posix.h
@@ -66,8 +66,32 @@
   gpr_mu set_state_mu;
   gpr_atm shutdown;
 
+  /* The watcher list.
+     
+     The following watcher related fields are protected by watcher_mu.
+     
+     An fd_watcher is an ephemeral object created when an fd wants to
+     begin polling, and destroyed after the poll.
+     
+     It denotes the fd's interest in whether to read poll or write poll
+     or both or neither on this fd.
+
+     If a watcher is asked to poll for reads or writes, the read_watcher
+     or write_watcher fields are set respectively. A watcher may be asked
+     to poll for both, in which case both fields will be set.
+
+     read_watcher and write_watcher may be NULL if no watcher has been
+     asked to poll for reads or writes.
+
+     If an fd_watcher is not asked to poll for reads or writes, it's added
+     to a linked list of inactive watchers, rooted at inactive_watcher_root.
+     If at a later time there becomes need of a poller to poll, one of
+     the inactive pollers may be kicked out of their poll loops to take
+     that responsibility. */
   gpr_mu watcher_mu;
-  grpc_fd_watcher watcher_root;
+  grpc_fd_watcher inactive_watcher_root;
+  grpc_fd_watcher *read_watcher;
+  grpc_fd_watcher *write_watcher;
 
   gpr_atm readst;
   gpr_atm writest;
@@ -103,7 +127,7 @@
                               gpr_uint32 read_mask, gpr_uint32 write_mask,
                               grpc_fd_watcher *rec);
 /* Complete polling previously started with grpc_fd_begin_poll */
-void grpc_fd_end_poll(grpc_fd_watcher *rec);
+void grpc_fd_end_poll(grpc_fd_watcher *rec, int got_read, int got_write);
 
 /* Return 1 if this fd is orphaned, 0 otherwise */
 int grpc_fd_is_orphaned(grpc_fd *fd);
diff --git a/src/core/iomgr/pollset_multipoller_with_poll_posix.c b/src/core/iomgr/pollset_multipoller_with_poll_posix.c
index 25b7cfda..4d36107 100644
--- a/src/core/iomgr/pollset_multipoller_with_poll_posix.c
+++ b/src/core/iomgr/pollset_multipoller_with_poll_posix.c
@@ -98,7 +98,7 @@
   pollset_hdr *h;
   h = pollset->data.ptr;
   for (i = 1; i < h->pfd_count; i++) {
-    grpc_fd_end_poll(&h->watchers[i]);
+    grpc_fd_end_poll(&h->watchers[i], h->pfds[i].revents & POLLIN, h->pfds[i].revents & POLLOUT);
   }
 }
 
diff --git a/src/core/iomgr/pollset_posix.c b/src/core/iomgr/pollset_posix.c
index f496ac5..826c792 100644
--- a/src/core/iomgr/pollset_posix.c
+++ b/src/core/iomgr/pollset_posix.c
@@ -420,10 +420,12 @@
 
   pfd[1].events = grpc_fd_begin_poll(fd, pollset, POLLIN, POLLOUT, &fd_watcher);
 
-  r = poll(pfd, GPR_ARRAY_SIZE(pfd), timeout);
+  /* poll fd count (argument 2) is shortened by one if we have no events
+     to poll on - such that it only includes the kicker */
+  r = poll(pfd, GPR_ARRAY_SIZE(pfd) - (pfd[1].events == 0), timeout);
   GRPC_TIMER_MARK(GRPC_PTAG_POLL_FINISHED, r);
 
-  grpc_fd_end_poll(&fd_watcher);
+  grpc_fd_end_poll(&fd_watcher, pfd[1].revents & POLLIN, pfd[1].revents & POLLOUT);
 
   if (r < 0) {
     if (errno != EINTR) {
diff --git a/src/core/surface/lame_client.c b/src/core/surface/lame_client.c
index 3186292..a3b0b26 100644
--- a/src/core/surface/lame_client.c
+++ b/src/core/surface/lame_client.c
@@ -55,6 +55,7 @@
   channel_data *chand = elem->channel_data;
   GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
   if (op->send_ops) {
+    grpc_stream_ops_unref_owned_objects(op->send_ops->ops, op->send_ops->nops);
     op->on_done_send(op->send_user_data, 0);
   }
   if (op->recv_ops) {
diff --git a/src/php/bin/run_gen_code_test.sh b/src/php/bin/run_gen_code_test.sh
index 79abbe6..4882a2b 100755
--- a/src/php/bin/run_gen_code_test.sh
+++ b/src/php/bin/run_gen_code_test.sh
@@ -29,9 +29,9 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 cd $(dirname $0)
-GRPC_TEST_HOST=localhost:7070 php -d extension_dir=../ext/grpc/modules/ \
+GRPC_TEST_HOST=localhost:50051 php -d extension_dir=../ext/grpc/modules/ \
   -d extension=grpc.so /usr/local/bin/phpunit -v --debug --strict \
   ../tests/generated_code/GeneratedCodeTest.php
-GRPC_TEST_HOST=localhost:7070 php -d extension_dir=../ext/grpc/modules/ \
+GRPC_TEST_HOST=localhost:50051 php -d extension_dir=../ext/grpc/modules/ \
   -d extension=grpc.so /usr/local/bin/phpunit -v --debug --strict \
   ../tests/generated_code/GeneratedCodeWithCallbackTest.php
diff --git a/templates/vsprojects/grpc.sln.template b/templates/vsprojects/grpc.sln.template
index 7465852..70be6b4 100644
--- a/templates/vsprojects/grpc.sln.template
+++ b/templates/vsprojects/grpc.sln.template
@@ -1,48 +1,5 @@
-## Template for Visual Studio solution
-## based on http://msdn.microsoft.com/en-us/library/bb165951(v=vs.90).aspx
-## NOTE: tabs in this file are needed by Visual Studio to correctly interpret
-## the file.
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.21005.1
-MinimumVisualStudioVersion = 10.0.40219.1
+<%namespace file="sln_defs.include" import="gen_solution"/>\
 <%
-## Visual Studio uses GUIDs for project types
-## http://msdn.microsoft.com/en-us/library/hb23x61k%28v=vs.80%29.aspx
-cpp_proj_type = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"
+solution_projects = [p for p in vsprojects if p.build != 'protoc']
 %>\
-% for project in vsprojects:
-Project("${cpp_proj_type}") = "${project.name}", "${project.name}\${project.name}.vcxproj", "${project.vs_project_guid}"
-  % if project.get('deps', None):
-	ProjectSection(ProjectDependencies) = postProject
-    % for dep in project.get('deps', []):
-		${vsproject_dict[dep].vs_project_guid} = ${vsproject_dict[dep].vs_project_guid}
-    % endfor
-	EndProjectSection
-  % endif
-EndProject
-% endfor
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Win32 = Debug|Win32
-		Debug|x64 = Debug|x64
-		Release|Win32 = Release|Win32
-		Release|x64 = Release|x64
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-% for project in vsprojects:
-		${project.vs_project_guid}.Debug|Win32.ActiveCfg = Debug|Win32
-		${project.vs_project_guid}.Debug|Win32.Build.0 = Debug|Win32
-		${project.vs_project_guid}.Debug|x64.ActiveCfg = Debug|x64
-		${project.vs_project_guid}.Debug|x64.Build.0 = Debug|x64
-		${project.vs_project_guid}.Release|Win32.ActiveCfg = Release|Win32
-		${project.vs_project_guid}.Release|Win32.Build.0 = Release|Win32
-		${project.vs_project_guid}.Release|x64.ActiveCfg = Release|x64
-		${project.vs_project_guid}.Release|x64.Build.0 = Release|x64
-% endfor
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
+${gen_solution(solution_projects)}
\ No newline at end of file
diff --git a/templates/vsprojects/grpc_cpp_plugin/grpc_cpp_plugin.vcxproj.template b/templates/vsprojects/grpc_cpp_plugin/grpc_cpp_plugin.vcxproj.template
new file mode 100644
index 0000000..49ab1b7
--- /dev/null
+++ b/templates/vsprojects/grpc_cpp_plugin/grpc_cpp_plugin.vcxproj.template
@@ -0,0 +1,2 @@
+<%namespace file="../vcxproj_defs.include" import="gen_project"/>\
+${gen_project('grpc_cpp_plugin', targets, configuration_type='Application')}
diff --git a/templates/vsprojects/grpc_csharp_plugin/grpc_csharp_plugin.vcxproj.template b/templates/vsprojects/grpc_csharp_plugin/grpc_csharp_plugin.vcxproj.template
new file mode 100644
index 0000000..9d94e27
--- /dev/null
+++ b/templates/vsprojects/grpc_csharp_plugin/grpc_csharp_plugin.vcxproj.template
@@ -0,0 +1,2 @@
+<%namespace file="../vcxproj_defs.include" import="gen_project"/>\
+${gen_project('grpc_csharp_plugin', targets, configuration_type='Application')}
diff --git a/templates/vsprojects/grpc_objective_c_plugin/grpc_objective_c_plugin.vcxproj.template b/templates/vsprojects/grpc_objective_c_plugin/grpc_objective_c_plugin.vcxproj.template
new file mode 100644
index 0000000..794c731
--- /dev/null
+++ b/templates/vsprojects/grpc_objective_c_plugin/grpc_objective_c_plugin.vcxproj.template
@@ -0,0 +1,2 @@
+<%namespace file="../vcxproj_defs.include" import="gen_project"/>\
+${gen_project('grpc_objective_c_plugin', targets, configuration_type='Application')}
diff --git a/templates/vsprojects/grpc_plugin_support/grpc_plugin_support.vcxproj.template b/templates/vsprojects/grpc_plugin_support/grpc_plugin_support.vcxproj.template
new file mode 100644
index 0000000..409e88f
--- /dev/null
+++ b/templates/vsprojects/grpc_plugin_support/grpc_plugin_support.vcxproj.template
@@ -0,0 +1,2 @@
+<%namespace file="../vcxproj_defs.include" import="gen_project"/>\
+${gen_project('grpc_plugin_support', libs)}
diff --git a/templates/vsprojects/grpc_protoc_plugins.sln.template b/templates/vsprojects/grpc_protoc_plugins.sln.template
new file mode 100644
index 0000000..1c171f4
--- /dev/null
+++ b/templates/vsprojects/grpc_protoc_plugins.sln.template
@@ -0,0 +1,5 @@
+<%namespace file="sln_defs.include" import="gen_solution"/>\
+<%
+solution_projects = [p for p in vsprojects if p.build == 'protoc']
+%>\
+${gen_solution(solution_projects)}
\ No newline at end of file
diff --git a/templates/vsprojects/grpc_python_plugin/grpc_python_plugin.vcxproj.template b/templates/vsprojects/grpc_python_plugin/grpc_python_plugin.vcxproj.template
new file mode 100644
index 0000000..977e015
--- /dev/null
+++ b/templates/vsprojects/grpc_python_plugin/grpc_python_plugin.vcxproj.template
@@ -0,0 +1,2 @@
+<%namespace file="../vcxproj_defs.include" import="gen_project"/>\
+${gen_project('grpc_python_plugin', targets, configuration_type='Application')}
diff --git a/templates/vsprojects/grpc_ruby_plugin/grpc_ruby_plugin.vcxproj.template b/templates/vsprojects/grpc_ruby_plugin/grpc_ruby_plugin.vcxproj.template
new file mode 100644
index 0000000..ecf42ae
--- /dev/null
+++ b/templates/vsprojects/grpc_ruby_plugin/grpc_ruby_plugin.vcxproj.template
@@ -0,0 +1,2 @@
+<%namespace file="../vcxproj_defs.include" import="gen_project"/>\
+${gen_project('grpc_ruby_plugin', targets, configuration_type='Application')}
diff --git a/templates/vsprojects/sln_defs.include b/templates/vsprojects/sln_defs.include
new file mode 100644
index 0000000..ee05d0f
--- /dev/null
+++ b/templates/vsprojects/sln_defs.include
@@ -0,0 +1,50 @@
+<%def name="gen_solution(solution_projects)">\
+## Template for Visual Studio solution
+## based on http://msdn.microsoft.com/en-us/library/bb165951(v=vs.90).aspx
+## NOTE: tabs in this file are needed by Visual Studio to correctly interpret
+## the file.
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.21005.1
+MinimumVisualStudioVersion = 10.0.40219.1
+<%
+## Visual Studio uses GUIDs for project types
+## http://msdn.microsoft.com/en-us/library/hb23x61k%28v=vs.80%29.aspx
+cpp_proj_type = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"
+%>\
+% for project in solution_projects:
+Project("${cpp_proj_type}") = "${project.name}", "${project.name}\${project.name}.vcxproj", "${project.vs_project_guid}"
+  % if project.get('deps', None):
+	ProjectSection(ProjectDependencies) = postProject
+    % for dep in project.get('deps', []):
+		${vsproject_dict[dep].vs_project_guid} = ${vsproject_dict[dep].vs_project_guid}
+    % endfor
+	EndProjectSection
+  % endif
+EndProject
+% endfor
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+% for project in solution_projects:
+		${project.vs_project_guid}.Debug|Win32.ActiveCfg = Debug|Win32
+		${project.vs_project_guid}.Debug|Win32.Build.0 = Debug|Win32
+		${project.vs_project_guid}.Debug|x64.ActiveCfg = Debug|x64
+		${project.vs_project_guid}.Debug|x64.Build.0 = Debug|x64
+		${project.vs_project_guid}.Release|Win32.ActiveCfg = Release|Win32
+		${project.vs_project_guid}.Release|Win32.Build.0 = Release|Win32
+		${project.vs_project_guid}.Release|x64.ActiveCfg = Release|x64
+		${project.vs_project_guid}.Release|x64.Build.0 = Release|x64
+% endfor
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
+</%def>\
\ No newline at end of file
diff --git a/templates/vsprojects/vcxproj_defs.include b/templates/vsprojects/vcxproj_defs.include
index 87412de..55ec373 100644
--- a/templates/vsprojects/vcxproj_defs.include
+++ b/templates/vsprojects/vcxproj_defs.include
@@ -19,7 +19,10 @@
   if not project_guid:
     project_guid = project.vs_project_guid
   if configuration_type == 'Application':
-    props.extend(['winsock', 'protobuf', 'zlib', 'openssl'])
+    if target.build == 'protoc':
+      props.extend(['protoc'])
+    else:
+      props.extend(['winsock', 'protobuf', 'zlib', 'openssl'])
     if target.language == 'c++':
       props.extend(['protobuf'])
   props.extend(['global'])
diff --git a/test/cpp/qps/async_streaming_ping_pong_test.cc b/test/cpp/qps/async_streaming_ping_pong_test.cc
index d4871c0..411df4d 100644
--- a/test/cpp/qps/async_streaming_ping_pong_test.cc
+++ b/test/cpp/qps/async_streaming_ping_pong_test.cc
@@ -31,12 +31,15 @@
  *
  */
 
+#include <set>
+
 #include <grpc/support/log.h>
 
 #include <signal.h>
 
 #include "test/cpp/qps/driver.h"
 #include "test/cpp/qps/report.h"
+#include "test/cpp/util/benchmark_config.h"
 
 namespace grpc {
 namespace testing {
@@ -64,16 +67,17 @@
   const auto result =
       RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
 
-  ReportQPS(*result);
-  ReportLatency(*result);
+  GetReporter()->ReportQPS(*result);
+  GetReporter()->ReportLatency(*result);
 }
 
 }  // namespace testing
 }  // namespace grpc
 
 int main(int argc, char** argv) {
+  grpc::testing::InitBenchmark(&argc, &argv, true);
+
   signal(SIGPIPE, SIG_IGN);
   grpc::testing::RunAsyncStreamingPingPong();
-
   return 0;
 }
diff --git a/test/cpp/qps/async_unary_ping_pong_test.cc b/test/cpp/qps/async_unary_ping_pong_test.cc
index 35f188c..eda31b5 100644
--- a/test/cpp/qps/async_unary_ping_pong_test.cc
+++ b/test/cpp/qps/async_unary_ping_pong_test.cc
@@ -31,12 +31,15 @@
  *
  */
 
+#include <set>
+
 #include <grpc/support/log.h>
 
 #include <signal.h>
 
 #include "test/cpp/qps/driver.h"
 #include "test/cpp/qps/report.h"
+#include "test/cpp/util/benchmark_config.h"
 
 namespace grpc {
 namespace testing {
@@ -64,16 +67,16 @@
   const auto result =
       RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
 
-  ReportQPS(*result);
-  ReportLatency(*result);
+  GetReporter()->ReportQPS(*result);
+  GetReporter()->ReportLatency(*result);
 }
-
 }  // namespace testing
 }  // namespace grpc
 
 int main(int argc, char** argv) {
+  grpc::testing::InitBenchmark(&argc, &argv, true);
   signal(SIGPIPE, SIG_IGN);
-  grpc::testing::RunAsyncUnaryPingPong();
 
+  grpc::testing::RunAsyncUnaryPingPong();
   return 0;
 }
diff --git a/test/cpp/qps/qps_driver.cc b/test/cpp/qps/qps_driver.cc
index 008830d..281e2e8 100644
--- a/test/cpp/qps/qps_driver.cc
+++ b/test/cpp/qps/qps_driver.cc
@@ -31,12 +31,15 @@
  *
  */
 
+#include <memory>
+#include <set>
+
 #include <gflags/gflags.h>
 #include <grpc/support/log.h>
 
 #include "test/cpp/qps/driver.h"
 #include "test/cpp/qps/report.h"
-#include "test/cpp/util/test_config.h"
+#include "test/cpp/util/benchmark_config.h"
 
 DEFINE_int32(num_clients, 1, "Number of client binaries");
 DEFINE_int32(num_servers, 1, "Number of server binaries");
@@ -68,9 +71,10 @@
 using grpc::testing::RpcType;
 using grpc::testing::ResourceUsage;
 
-int main(int argc, char** argv) {
-  grpc::testing::InitTest(&argc, &argv, true);
+namespace grpc {
+namespace testing {
 
+static void QpsDriver() {
   RpcType rpc_type;
   GPR_ASSERT(RpcType_Parse(FLAGS_rpc_type, &rpc_type));
 
@@ -107,9 +111,20 @@
       client_config, FLAGS_num_clients, server_config, FLAGS_num_servers,
       FLAGS_warmup_seconds, FLAGS_benchmark_seconds, FLAGS_local_workers);
 
-  ReportQPSPerCore(*result, server_config);
-  ReportLatency(*result);
-  ReportTimes(*result);
+  GetReporter()->ReportQPS(*result);
+  GetReporter()->ReportQPSPerCore(*result, server_config);
+  GetReporter()->ReportLatency(*result);
+  GetReporter()->ReportTimes(*result);
+}
+
+}  // namespace testing
+}  // namespace grpc
+
+int main(int argc, char** argv) {
+  grpc::testing::InitBenchmark(&argc, &argv, true);
+
+  signal(SIGPIPE, SIG_IGN);
+  grpc::testing::QpsDriver();
 
   return 0;
 }
diff --git a/test/cpp/qps/qps_test.cc b/test/cpp/qps/qps_test.cc
index 9a81d0f..63a37ae 100644
--- a/test/cpp/qps/qps_test.cc
+++ b/test/cpp/qps/qps_test.cc
@@ -31,12 +31,15 @@
  *
  */
 
+#include <set>
+
 #include <grpc/support/log.h>
 
 #include <signal.h>
 
 #include "test/cpp/qps/driver.h"
 #include "test/cpp/qps/report.h"
+#include "test/cpp/util/benchmark_config.h"
 
 namespace grpc {
 namespace testing {
@@ -64,14 +67,16 @@
   const auto result =
       RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
 
-  ReportQPSPerCore(*result, server_config);
-  ReportLatency(*result);
+  GetReporter()->ReportQPSPerCore(*result, server_config);
+  GetReporter()->ReportLatency(*result);
 }
 
 }  // namespace testing
 }  // namespace grpc
 
 int main(int argc, char** argv) {
+  grpc::testing::InitBenchmark(&argc, &argv, true);
+
   signal(SIGPIPE, SIG_IGN);
   grpc::testing::RunQPS();
 
diff --git a/test/cpp/qps/report.cc b/test/cpp/qps/report.cc
index 3115ff3..e116175 100644
--- a/test/cpp/qps/report.cc
+++ b/test/cpp/qps/report.cc
@@ -39,27 +39,55 @@
 namespace grpc {
 namespace testing {
 
-// QPS: XXX
-void ReportQPS(const ScenarioResult& result) {
+void CompositeReporter::add(std::unique_ptr<Reporter> reporter) {
+  reporters_.emplace_back(std::move(reporter));
+}
+
+void CompositeReporter::ReportQPS(const ScenarioResult& result) const {
+  for (size_t i = 0; i < reporters_.size(); ++i) {
+    reporters_[i]->ReportQPS(result);
+  }
+}
+
+void CompositeReporter::ReportQPSPerCore(const ScenarioResult& result,
+                                         const ServerConfig& config) const {
+  for (size_t i = 0; i < reporters_.size(); ++i) {
+    reporters_[i]->ReportQPSPerCore(result, config);
+  }
+}
+
+void CompositeReporter::ReportLatency(const ScenarioResult& result) const {
+  for (size_t i = 0; i < reporters_.size(); ++i) {
+    reporters_[i]->ReportLatency(result);
+  }
+}
+
+void CompositeReporter::ReportTimes(const ScenarioResult& result) const {
+  for (size_t i = 0; i < reporters_.size(); ++i) {
+    reporters_[i]->ReportTimes(result);
+  }
+}
+
+
+void GprLogReporter::ReportQPS(const ScenarioResult& result) const {
   gpr_log(GPR_INFO, "QPS: %.1f",
           result.latencies.Count() /
               average(result.client_resources,
                       [](ResourceUsage u) { return u.wall_time; }));
 }
 
-// QPS: XXX (YYY/server core)
-void ReportQPSPerCore(const ScenarioResult& result,
-                      const ServerConfig& server_config) {
-  auto qps = result.latencies.Count() /
-             average(result.client_resources,
-                     [](ResourceUsage u) { return u.wall_time; });
+void GprLogReporter::ReportQPSPerCore(const ScenarioResult& result,
+                                      const ServerConfig& server_config) const {
+  auto qps =
+      result.latencies.Count() /
+      average(result.client_resources,
+          [](ResourceUsage u) { return u.wall_time; });
 
   gpr_log(GPR_INFO, "QPS: %.1f (%.1f/server core)", qps,
           qps / server_config.threads());
 }
 
-// Latency (50/90/95/99/99.9%-ile): AA/BB/CC/DD/EE us
-void ReportLatency(const ScenarioResult& result) {
+void GprLogReporter::ReportLatency(const ScenarioResult& result) const {
   gpr_log(GPR_INFO,
           "Latencies (50/90/95/99/99.9%%-ile): %.1f/%.1f/%.1f/%.1f/%.1f us",
           result.latencies.Percentile(50) / 1000,
@@ -69,7 +97,7 @@
           result.latencies.Percentile(99.9) / 1000);
 }
 
-void ReportTimes(const ScenarioResult& result) {
+void GprLogReporter::ReportTimes(const ScenarioResult& result) const {
   gpr_log(GPR_INFO, "Server system time: %.2f%%",
           100.0 * sum(result.server_resources,
                       [](ResourceUsage u) { return u.system_time; }) /
diff --git a/test/cpp/qps/report.h b/test/cpp/qps/report.h
index 343e426..630275e 100644
--- a/test/cpp/qps/report.h
+++ b/test/cpp/qps/report.h
@@ -34,22 +34,77 @@
 #ifndef TEST_QPS_REPORT_H
 #define TEST_QPS_REPORT_H
 
+#include <memory>
+#include <set>
+#include <vector>
+#include <grpc++/config.h>
+
 #include "test/cpp/qps/driver.h"
+#include "test/cpp/qps/qpstest.grpc.pb.h"
 
 namespace grpc {
 namespace testing {
 
-// QPS: XXX
-void ReportQPS(const ScenarioResult& result);
-// QPS: XXX (YYY/server core)
-void ReportQPSPerCore(const ScenarioResult& result, const ServerConfig& config);
-// Latency (50/90/95/99/99.9%-ile): AA/BB/CC/DD/EE us
-void ReportLatency(const ScenarioResult& result);
-// Server system time: XX%
-// Server user time: XX%
-// Client system time: XX%
-// Client user time: XX%
-void ReportTimes(const ScenarioResult& result);
+/** Interface for all reporters. */
+class Reporter {
+ public:
+  /** Construct a reporter with the given \a name. */
+  Reporter(const string& name) : name_(name) {}
+
+  virtual ~Reporter() {}
+
+  /** Returns this reporter's name.
+   *
+   * Names are constants, set at construction time. */
+  string name() const { return name_; }
+
+  /** Reports QPS for the given \a result. */
+  virtual void ReportQPS(const ScenarioResult& result) const = 0;
+
+  /** Reports QPS per core as (YYY/server core). */
+  virtual void ReportQPSPerCore(const ScenarioResult& result,
+                                const ServerConfig& config) const = 0;
+
+  /** Reports latencies for the 50, 90, 95, 99 and 99.9 percentiles, in ms. */
+  virtual void ReportLatency(const ScenarioResult& result) const = 0;
+
+  /** Reports system and user time for client and server systems. */
+  virtual void ReportTimes(const ScenarioResult& result) const = 0;
+
+ private:
+  const string name_;
+};
+
+/** A composite for all reporters to be considered. */
+class CompositeReporter : public Reporter {
+ public:
+  CompositeReporter() : Reporter("CompositeReporter") {}
+
+  /** Adds a \a reporter to the composite. */
+  void add(std::unique_ptr<Reporter> reporter);
+
+  void ReportQPS(const ScenarioResult& result) const GRPC_OVERRIDE;
+  void ReportQPSPerCore(const ScenarioResult& result,
+                        const ServerConfig& config) const GRPC_OVERRIDE;
+  void ReportLatency(const ScenarioResult& result) const GRPC_OVERRIDE;
+  void ReportTimes(const ScenarioResult& result) const GRPC_OVERRIDE;
+
+ private:
+  std::vector<std::unique_ptr<Reporter> > reporters_;
+};
+
+/** Reporter to gpr_log(GPR_INFO). */
+class GprLogReporter : public Reporter {
+ public:
+  GprLogReporter(const string& name) : Reporter(name) {}
+
+ private:
+  void ReportQPS(const ScenarioResult& result) const GRPC_OVERRIDE;
+  void ReportQPSPerCore(const ScenarioResult& result,
+                        const ServerConfig& config) const GRPC_OVERRIDE;
+  void ReportLatency(const ScenarioResult& result) const GRPC_OVERRIDE;
+  void ReportTimes(const ScenarioResult& result) const GRPC_OVERRIDE;
+};
 
 }  // namespace testing
 }  // namespace grpc
diff --git a/test/cpp/qps/sync_streaming_ping_pong_test.cc b/test/cpp/qps/sync_streaming_ping_pong_test.cc
index 2183068..d53905a 100644
--- a/test/cpp/qps/sync_streaming_ping_pong_test.cc
+++ b/test/cpp/qps/sync_streaming_ping_pong_test.cc
@@ -31,12 +31,15 @@
  *
  */
 
+#include <set>
+
 #include <grpc/support/log.h>
 
 #include <signal.h>
 
 #include "test/cpp/qps/driver.h"
 #include "test/cpp/qps/report.h"
+#include "test/cpp/util/benchmark_config.h"
 
 namespace grpc {
 namespace testing {
@@ -63,14 +66,15 @@
   const auto result =
       RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
 
-  ReportQPS(*result);
-  ReportLatency(*result);
+  GetReporter()->ReportQPS(*result);
+  GetReporter()->ReportLatency(*result);
 }
-
 }  // namespace testing
 }  // namespace grpc
 
 int main(int argc, char** argv) {
+  grpc::testing::InitBenchmark(&argc, &argv, true);
+
   signal(SIGPIPE, SIG_IGN);
   grpc::testing::RunSynchronousStreamingPingPong();
 
diff --git a/test/cpp/qps/sync_unary_ping_pong_test.cc b/test/cpp/qps/sync_unary_ping_pong_test.cc
index 137ef79..d276d13 100644
--- a/test/cpp/qps/sync_unary_ping_pong_test.cc
+++ b/test/cpp/qps/sync_unary_ping_pong_test.cc
@@ -31,12 +31,15 @@
  *
  */
 
+#include <set>
+
 #include <grpc/support/log.h>
 
 #include <signal.h>
 
 #include "test/cpp/qps/driver.h"
 #include "test/cpp/qps/report.h"
+#include "test/cpp/util/benchmark_config.h"
 
 namespace grpc {
 namespace testing {
@@ -63,14 +66,16 @@
   const auto result =
       RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
 
-  ReportQPS(*result);
-  ReportLatency(*result);
+  GetReporter()->ReportQPS(*result);
+  GetReporter()->ReportLatency(*result);
 }
 
 }  // namespace testing
 }  // namespace grpc
 
 int main(int argc, char** argv) {
+  grpc::testing::InitBenchmark(&argc, &argv, true);
+
   signal(SIGPIPE, SIG_IGN);
   grpc::testing::RunSynchronousUnaryPingPong();
 
diff --git a/test/cpp/util/benchmark_config.cc b/test/cpp/util/benchmark_config.cc
new file mode 100644
index 0000000..5b3c1da
--- /dev/null
+++ b/test/cpp/util/benchmark_config.cc
@@ -0,0 +1,69 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <gflags/gflags.h>
+#include "test/cpp/util/benchmark_config.h"
+
+DEFINE_bool(enable_log_reporter, true,
+            "Enable reporting of benchmark results through GprLog");
+
+// In some distros, gflags is in the namespace google, and in some others,
+// in gflags. This hack is enabling us to find both.
+namespace google {}
+namespace gflags {}
+using namespace google;
+using namespace gflags;
+
+namespace grpc {
+namespace testing {
+
+void InitBenchmark(int* argc, char*** argv, bool remove_flags) {
+  ParseCommandLineFlags(argc, argv, remove_flags);
+}
+
+static std::shared_ptr<Reporter> InitBenchmarkReporters() {
+  auto* composite_reporter = new CompositeReporter;
+  if (FLAGS_enable_log_reporter) {
+    composite_reporter->add(
+        std::unique_ptr<Reporter>(new GprLogReporter("LogReporter")));
+  }
+  return std::shared_ptr<Reporter>(composite_reporter);
+}
+
+std::shared_ptr<Reporter> GetReporter() {
+  static std::shared_ptr<Reporter> reporter(InitBenchmarkReporters());
+  return reporter;
+}
+
+}  // namespace testing
+}  // namespace grpc
diff --git a/test/cpp/util/benchmark_config.h b/test/cpp/util/benchmark_config.h
new file mode 100644
index 0000000..6b308a1
--- /dev/null
+++ b/test/cpp/util/benchmark_config.h
@@ -0,0 +1,57 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_TEST_CPP_UTIL_BENCHMARK_CONFIG_H
+#define GRPC_TEST_CPP_UTIL_BENCHMARK_CONFIG_H
+
+#include <memory>
+#include <vector>
+
+#include "test/cpp/qps/report.h"
+
+namespace grpc {
+namespace testing {
+
+void InitBenchmark(int* argc, char*** argv, bool remove_flags);
+
+/** Returns the benchmark Reporter instance.
+ *
+ * The returned instance will take care of generating reports for all the actual
+ * reporters configured via the "enable_*_reporter" command line flags (see
+ * benchmark_config.cc). */
+std::shared_ptr<Reporter> GetReporter();
+
+}  // namespace testing
+}  // namespace grpc
+
+#endif  // GRPC_TEST_CPP_UTIL_BENCHMARK_CONFIG_H
diff --git a/tools/buildgen/plugins/generate_vsprojects.py b/tools/buildgen/plugins/generate_vsprojects.py
index 09a5bdb..150e72e 100755
--- a/tools/buildgen/plugins/generate_vsprojects.py
+++ b/tools/buildgen/plugins/generate_vsprojects.py
@@ -70,7 +70,7 @@
                 if project.get('vs_project_guid', None)]
 
   projects = [project for project in projects
-                if project['language'] != 'c++' or project['build'] == 'all']
+                if project['language'] != 'c++' or project['build'] == 'all' or project['build'] == 'protoc']
 
   project_dict = dict([(p['name'], p) for p in projects])
 
diff --git a/tools/dockerfile/grpc_csharp_mono/build.sh b/tools/dockerfile/grpc_csharp_mono/build.sh
new file mode 100755
index 0000000..a7737d7
--- /dev/null
+++ b/tools/dockerfile/grpc_csharp_mono/build.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+cp -R /var/local/git-clone/grpc /var/local/git
+
+make install_grpc_csharp_ext -j12 -C /var/local/git/grpc
+
+cd /var/local/git/grpc/src/csharp && mono /var/local/NuGet.exe restore Grpc.sln
+
+cd /var/local/git/grpc/src/csharp && xbuild Grpc.sln
+
diff --git a/tools/dockerfile/grpc_php/build.sh b/tools/dockerfile/grpc_php/build.sh
new file mode 100755
index 0000000..fbbc61d
--- /dev/null
+++ b/tools/dockerfile/grpc_php/build.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+cp -R /var/local/git-clone/grpc /var/local/git
+
+make clean -C /var/local/git/grpc
+
+make install_c -j12 -C /var/local/git/grpc
+
+cd /var/local/git/grpc/src/php/ext/grpc && git pull && phpize
+
+cd /var/local/git/grpc/src/php/ext/grpc \
+  && ./configure \
+  && make
+
+cd /var/local/git/grpc/src/php && composer install
+
+cd /var/local/git/grpc/src/php && protoc-gen-php -i tests/interop/ -o tests/interop/ tests/interop/test.proto
+
diff --git a/vsprojects/.gitignore b/vsprojects/.gitignore
index dc63b1b..d69021e 100644
--- a/vsprojects/.gitignore
+++ b/vsprojects/.gitignore
@@ -3,7 +3,7 @@
 *.suo
 *.user
 test_bin
-grpc.opensdf
-grpc.sdf
+*.opensdf
+*.sdf
 third_party/*.user
 /packages
diff --git a/vsprojects/README.md b/vsprojects/README.md
index 355ef75..14178da 100644
--- a/vsprojects/README.md
+++ b/vsprojects/README.md
@@ -31,4 +31,13 @@
 ```
 > REM Run from this directory.
 > make.bat alarm_test
-```
\ No newline at end of file
+```
+
+# Building protoc plugins
+For generating service stub code, gRPC relies on plugins for `protoc` (the protocol buffer compiler). The solution `grpc_protoc_plugins.sln` allows you to build
+Windows .exe binaries of gRPC protoc plugins.
+
+1. Open solution `third_party\protobuf\vsprojects\protobuf.sln`
+2. Accept the conversion to newer Visual Studio version and ignore errors about gtest.
+3. Build libprotoc in Release mode.
+4. Open solution `vsprojects\grpc_protoc_plugins.sln` and build it in Release mode. As a result, you should obtain a set of gRPC protoc plugin binaries (`grpc_cpp_plugin.exe`, `grpc_csharp_plugin.exe`, ...)
diff --git a/vsprojects/grpc_cpp_plugin/grpc_cpp_plugin.vcxproj b/vsprojects/grpc_cpp_plugin/grpc_cpp_plugin.vcxproj
new file mode 100644
index 0000000..d2669b4
--- /dev/null
+++ b/vsprojects/grpc_cpp_plugin/grpc_cpp_plugin.vcxproj
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{7E51A25F-AC59-488F-906C-C60FAAE706AA}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <TargetName>grpc_cpp_plugin</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <TargetName>grpc_cpp_plugin</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <TargetName>grpc_cpp_plugin</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <TargetName>grpc_cpp_plugin</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\src\compiler\cpp_plugin.cc">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\grpc_plugin_support\grpc_plugin_support.vcxproj">
+      <Project>{B6E81D84-2ACB-41B8-8781-493A944C7817}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
+
diff --git a/vsprojects/grpc_csharp_plugin/grpc_csharp_plugin.vcxproj b/vsprojects/grpc_csharp_plugin/grpc_csharp_plugin.vcxproj
new file mode 100644
index 0000000..10d1e96
--- /dev/null
+++ b/vsprojects/grpc_csharp_plugin/grpc_csharp_plugin.vcxproj
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{3C813052-A49A-4662-B90A-1ADBEC7EE453}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <TargetName>grpc_csharp_plugin</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <TargetName>grpc_csharp_plugin</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <TargetName>grpc_csharp_plugin</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <TargetName>grpc_csharp_plugin</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\src\compiler\csharp_plugin.cc">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\grpc_plugin_support\grpc_plugin_support.vcxproj">
+      <Project>{B6E81D84-2ACB-41B8-8781-493A944C7817}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
+
diff --git a/vsprojects/grpc_objective_c_plugin/grpc_objective_c_plugin.vcxproj b/vsprojects/grpc_objective_c_plugin/grpc_objective_c_plugin.vcxproj
new file mode 100644
index 0000000..23affd1
--- /dev/null
+++ b/vsprojects/grpc_objective_c_plugin/grpc_objective_c_plugin.vcxproj
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{19564640-CEE6-4921-ABA5-676ED79A36F6}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <TargetName>grpc_objective_c_plugin</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <TargetName>grpc_objective_c_plugin</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <TargetName>grpc_objective_c_plugin</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <TargetName>grpc_objective_c_plugin</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\src\compiler\objective_c_plugin.cc">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\grpc_plugin_support\grpc_plugin_support.vcxproj">
+      <Project>{B6E81D84-2ACB-41B8-8781-493A944C7817}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
+
diff --git a/vsprojects/grpc_plugin_support/grpc_plugin_support.vcxproj b/vsprojects/grpc_plugin_support/grpc_plugin_support.vcxproj
new file mode 100644
index 0000000..c0188e5
--- /dev/null
+++ b/vsprojects/grpc_plugin_support/grpc_plugin_support.vcxproj
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{B6E81D84-2ACB-41B8-8781-493A944C7817}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <TargetName>grpc_plugin_support</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <TargetName>grpc_plugin_support</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <TargetName>grpc_plugin_support</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <TargetName>grpc_plugin_support</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\src\compiler\config.h" />
+    <ClInclude Include="..\..\src\compiler\cpp_generator.h" />
+    <ClInclude Include="..\..\src\compiler\cpp_generator_helpers.h" />
+    <ClInclude Include="..\..\src\compiler\csharp_generator.h" />
+    <ClInclude Include="..\..\src\compiler\csharp_generator_helpers.h" />
+    <ClInclude Include="..\..\src\compiler\generator_helpers.h" />
+    <ClInclude Include="..\..\src\compiler\objective_c_generator.h" />
+    <ClInclude Include="..\..\src\compiler\objective_c_generator_helpers.h" />
+    <ClInclude Include="..\..\src\compiler\python_generator.h" />
+    <ClInclude Include="..\..\src\compiler\ruby_generator.h" />
+    <ClInclude Include="..\..\src\compiler\ruby_generator_helpers-inl.h" />
+    <ClInclude Include="..\..\src\compiler\ruby_generator_map-inl.h" />
+    <ClInclude Include="..\..\src\compiler\ruby_generator_string-inl.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\src\compiler\cpp_generator.cc">
+    </ClCompile>
+    <ClCompile Include="..\..\src\compiler\csharp_generator.cc">
+    </ClCompile>
+    <ClCompile Include="..\..\src\compiler\objective_c_generator.cc">
+    </ClCompile>
+    <ClCompile Include="..\..\src\compiler\python_generator.cc">
+    </ClCompile>
+    <ClCompile Include="..\..\src\compiler\ruby_generator.cc">
+    </ClCompile>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
+
diff --git a/vsprojects/grpc_protoc_plugins.sln b/vsprojects/grpc_protoc_plugins.sln
new file mode 100644
index 0000000..be3ccf9
--- /dev/null
+++ b/vsprojects/grpc_protoc_plugins.sln
@@ -0,0 +1,93 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.21005.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_plugin_support", "grpc_plugin_support\grpc_plugin_support.vcxproj", "{B6E81D84-2ACB-41B8-8781-493A944C7817}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_cpp_plugin", "grpc_cpp_plugin\grpc_cpp_plugin.vcxproj", "{7E51A25F-AC59-488F-906C-C60FAAE706AA}"
+	ProjectSection(ProjectDependencies) = postProject
+		{B6E81D84-2ACB-41B8-8781-493A944C7817} = {B6E81D84-2ACB-41B8-8781-493A944C7817}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_csharp_plugin", "grpc_csharp_plugin\grpc_csharp_plugin.vcxproj", "{3C813052-A49A-4662-B90A-1ADBEC7EE453}"
+	ProjectSection(ProjectDependencies) = postProject
+		{B6E81D84-2ACB-41B8-8781-493A944C7817} = {B6E81D84-2ACB-41B8-8781-493A944C7817}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_objective_c_plugin", "grpc_objective_c_plugin\grpc_objective_c_plugin.vcxproj", "{19564640-CEE6-4921-ABA5-676ED79A36F6}"
+	ProjectSection(ProjectDependencies) = postProject
+		{B6E81D84-2ACB-41B8-8781-493A944C7817} = {B6E81D84-2ACB-41B8-8781-493A944C7817}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_python_plugin", "grpc_python_plugin\grpc_python_plugin.vcxproj", "{DF52D501-A6CF-4E6F-BA38-6EBE2E8DAFB2}"
+	ProjectSection(ProjectDependencies) = postProject
+		{B6E81D84-2ACB-41B8-8781-493A944C7817} = {B6E81D84-2ACB-41B8-8781-493A944C7817}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_ruby_plugin", "grpc_ruby_plugin\grpc_ruby_plugin.vcxproj", "{069E9D05-B78B-4751-9252-D21EBAE7DE8E}"
+	ProjectSection(ProjectDependencies) = postProject
+		{B6E81D84-2ACB-41B8-8781-493A944C7817} = {B6E81D84-2ACB-41B8-8781-493A944C7817}
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Debug|Win32.ActiveCfg = Debug|Win32
+		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Debug|Win32.Build.0 = Debug|Win32
+		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Debug|x64.ActiveCfg = Debug|x64
+		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Debug|x64.Build.0 = Debug|x64
+		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Release|Win32.ActiveCfg = Release|Win32
+		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Release|Win32.Build.0 = Release|Win32
+		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Release|x64.ActiveCfg = Release|x64
+		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Release|x64.Build.0 = Release|x64
+		{7E51A25F-AC59-488F-906C-C60FAAE706AA}.Debug|Win32.ActiveCfg = Debug|Win32
+		{7E51A25F-AC59-488F-906C-C60FAAE706AA}.Debug|Win32.Build.0 = Debug|Win32
+		{7E51A25F-AC59-488F-906C-C60FAAE706AA}.Debug|x64.ActiveCfg = Debug|x64
+		{7E51A25F-AC59-488F-906C-C60FAAE706AA}.Debug|x64.Build.0 = Debug|x64
+		{7E51A25F-AC59-488F-906C-C60FAAE706AA}.Release|Win32.ActiveCfg = Release|Win32
+		{7E51A25F-AC59-488F-906C-C60FAAE706AA}.Release|Win32.Build.0 = Release|Win32
+		{7E51A25F-AC59-488F-906C-C60FAAE706AA}.Release|x64.ActiveCfg = Release|x64
+		{7E51A25F-AC59-488F-906C-C60FAAE706AA}.Release|x64.Build.0 = Release|x64
+		{3C813052-A49A-4662-B90A-1ADBEC7EE453}.Debug|Win32.ActiveCfg = Debug|Win32
+		{3C813052-A49A-4662-B90A-1ADBEC7EE453}.Debug|Win32.Build.0 = Debug|Win32
+		{3C813052-A49A-4662-B90A-1ADBEC7EE453}.Debug|x64.ActiveCfg = Debug|x64
+		{3C813052-A49A-4662-B90A-1ADBEC7EE453}.Debug|x64.Build.0 = Debug|x64
+		{3C813052-A49A-4662-B90A-1ADBEC7EE453}.Release|Win32.ActiveCfg = Release|Win32
+		{3C813052-A49A-4662-B90A-1ADBEC7EE453}.Release|Win32.Build.0 = Release|Win32
+		{3C813052-A49A-4662-B90A-1ADBEC7EE453}.Release|x64.ActiveCfg = Release|x64
+		{3C813052-A49A-4662-B90A-1ADBEC7EE453}.Release|x64.Build.0 = Release|x64
+		{19564640-CEE6-4921-ABA5-676ED79A36F6}.Debug|Win32.ActiveCfg = Debug|Win32
+		{19564640-CEE6-4921-ABA5-676ED79A36F6}.Debug|Win32.Build.0 = Debug|Win32
+		{19564640-CEE6-4921-ABA5-676ED79A36F6}.Debug|x64.ActiveCfg = Debug|x64
+		{19564640-CEE6-4921-ABA5-676ED79A36F6}.Debug|x64.Build.0 = Debug|x64
+		{19564640-CEE6-4921-ABA5-676ED79A36F6}.Release|Win32.ActiveCfg = Release|Win32
+		{19564640-CEE6-4921-ABA5-676ED79A36F6}.Release|Win32.Build.0 = Release|Win32
+		{19564640-CEE6-4921-ABA5-676ED79A36F6}.Release|x64.ActiveCfg = Release|x64
+		{19564640-CEE6-4921-ABA5-676ED79A36F6}.Release|x64.Build.0 = Release|x64
+		{DF52D501-A6CF-4E6F-BA38-6EBE2E8DAFB2}.Debug|Win32.ActiveCfg = Debug|Win32
+		{DF52D501-A6CF-4E6F-BA38-6EBE2E8DAFB2}.Debug|Win32.Build.0 = Debug|Win32
+		{DF52D501-A6CF-4E6F-BA38-6EBE2E8DAFB2}.Debug|x64.ActiveCfg = Debug|x64
+		{DF52D501-A6CF-4E6F-BA38-6EBE2E8DAFB2}.Debug|x64.Build.0 = Debug|x64
+		{DF52D501-A6CF-4E6F-BA38-6EBE2E8DAFB2}.Release|Win32.ActiveCfg = Release|Win32
+		{DF52D501-A6CF-4E6F-BA38-6EBE2E8DAFB2}.Release|Win32.Build.0 = Release|Win32
+		{DF52D501-A6CF-4E6F-BA38-6EBE2E8DAFB2}.Release|x64.ActiveCfg = Release|x64
+		{DF52D501-A6CF-4E6F-BA38-6EBE2E8DAFB2}.Release|x64.Build.0 = Release|x64
+		{069E9D05-B78B-4751-9252-D21EBAE7DE8E}.Debug|Win32.ActiveCfg = Debug|Win32
+		{069E9D05-B78B-4751-9252-D21EBAE7DE8E}.Debug|Win32.Build.0 = Debug|Win32
+		{069E9D05-B78B-4751-9252-D21EBAE7DE8E}.Debug|x64.ActiveCfg = Debug|x64
+		{069E9D05-B78B-4751-9252-D21EBAE7DE8E}.Debug|x64.Build.0 = Debug|x64
+		{069E9D05-B78B-4751-9252-D21EBAE7DE8E}.Release|Win32.ActiveCfg = Release|Win32
+		{069E9D05-B78B-4751-9252-D21EBAE7DE8E}.Release|Win32.Build.0 = Release|Win32
+		{069E9D05-B78B-4751-9252-D21EBAE7DE8E}.Release|x64.ActiveCfg = Release|x64
+		{069E9D05-B78B-4751-9252-D21EBAE7DE8E}.Release|x64.Build.0 = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/vsprojects/grpc_python_plugin/grpc_python_plugin.vcxproj b/vsprojects/grpc_python_plugin/grpc_python_plugin.vcxproj
new file mode 100644
index 0000000..eadc0a0
--- /dev/null
+++ b/vsprojects/grpc_python_plugin/grpc_python_plugin.vcxproj
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{DF52D501-A6CF-4E6F-BA38-6EBE2E8DAFB2}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <TargetName>grpc_python_plugin</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <TargetName>grpc_python_plugin</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <TargetName>grpc_python_plugin</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <TargetName>grpc_python_plugin</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\src\compiler\python_plugin.cc">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\grpc_plugin_support\grpc_plugin_support.vcxproj">
+      <Project>{B6E81D84-2ACB-41B8-8781-493A944C7817}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
+
diff --git a/vsprojects/grpc_ruby_plugin/grpc_ruby_plugin.vcxproj b/vsprojects/grpc_ruby_plugin/grpc_ruby_plugin.vcxproj
new file mode 100644
index 0000000..0655bc8
--- /dev/null
+++ b/vsprojects/grpc_ruby_plugin/grpc_ruby_plugin.vcxproj
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{069E9D05-B78B-4751-9252-D21EBAE7DE8E}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
+    <Import Project="..\global.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <TargetName>grpc_ruby_plugin</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <TargetName>grpc_ruby_plugin</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <TargetName>grpc_ruby_plugin</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <TargetName>grpc_ruby_plugin</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\src\compiler\ruby_plugin.cc">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\grpc_plugin_support\grpc_plugin_support.vcxproj">
+      <Project>{B6E81D84-2ACB-41B8-8781-493A944C7817}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
+
diff --git a/vsprojects/protoc.props b/vsprojects/protoc.props
new file mode 100644
index 0000000..6024022
--- /dev/null
+++ b/vsprojects/protoc.props
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>

+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+  <ImportGroup Label="PropertySheets" />

+  <PropertyGroup Label="UserMacros" />

+  <PropertyGroup />

+  <ItemDefinitionGroup>

+    <Link>

+      <AdditionalDependencies>libprotoc.lib;%(AdditionalDependencies)</AdditionalDependencies>

+      <AdditionalLibraryDirectories>$(ProjectDir)\..\..\third_party\protobuf\vsprojects\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

+    </Link>

+  </ItemDefinitionGroup>

+  <ItemGroup />

+</Project>
\ No newline at end of file