diff --git a/Makefile b/Makefile
index 186aec6b82b45c3e91550b225cdea0152e088d9d..8c6fc3220da66fb292cdb9327de95c3616c97e2b 100644
--- a/Makefile
+++ b/Makefile
@@ -942,13 +942,13 @@ static: static_c static_cxx
 
 static_c:  $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
 
-static_cxx:  $(LIBDIR)/$(CONFIG)/libgrpc++.a
+static_cxx:  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
 
 shared: shared_c shared_cxx
 
 shared_c:  $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT)
 
-shared_cxx:  $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT)
+shared_cxx:  $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT)
 
 shared_csharp: shared_c  $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT)
 grpc_csharp_ext: shared_csharp
@@ -1844,6 +1844,8 @@ strip-static_cxx: static_cxx
 ifeq ($(CONFIG),opt)
 	$(E) "[STRIP]   Stripping libgrpc++.a"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++.a
+	$(E) "[STRIP]   Stripping libgrpc++_unsecure.a"
+	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
 endif
 
 strip-shared_c: shared_c
@@ -1860,6 +1862,8 @@ strip-shared_cxx: shared_cxx
 ifeq ($(CONFIG),opt)
 	$(E) "[STRIP]   Stripping libgrpc++.so"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT)
+	$(E) "[STRIP]   Stripping libgrpc++_unsecure.so"
+	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT)
 endif
 
 strip-shared_csharp: shared_csharp
@@ -2019,6 +2023,9 @@ install-static_cxx: static_cxx strip-static_cxx
 	$(E) "[INSTALL] Installing libgrpc++.a"
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(prefix)/lib/libgrpc++.a
+	$(E) "[INSTALL] Installing libgrpc++_unsecure.a"
+	$(Q) $(INSTALL) -d $(prefix)/lib
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(prefix)/lib/libgrpc++_unsecure.a
 
 
 
@@ -2083,6 +2090,19 @@ ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf libgrpc++.$(SHARED_EXT) $(prefix)/lib/libgrpc++.so
 endif
 endif
+ifeq ($(SYSTEM),MINGW32)
+	$(E) "[INSTALL] Installing grpc++_unsecure.$(SHARED_EXT)"
+	$(Q) $(INSTALL) -d $(prefix)/lib
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/grpc++_unsecure.$(SHARED_EXT)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure-imp.a $(prefix)/lib/libgrpc++_unsecure-imp.a
+else
+	$(E) "[INSTALL] Installing libgrpc++_unsecure.$(SHARED_EXT)"
+	$(Q) $(INSTALL) -d $(prefix)/lib
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc++_unsecure.$(SHARED_EXT)
+ifneq ($(SYSTEM),Darwin)
+	$(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc++_unsecure.so
+endif
+endif
 ifneq ($(SYSTEM),MINGW32)
 ifneq ($(SYSTEM),Darwin)
 	$(Q) ldconfig || true
@@ -2350,7 +2370,6 @@ LIBGRPC_SRC = \
     src/core/security/server_secure_chttp2.c \
     src/core/surface/init_secure.c \
     src/core/surface/secure_channel_create.c \
-    src/core/surface/secure_server_create.c \
     src/core/tsi/fake_transport_security.c \
     src/core/tsi/ssl_transport_security.c \
     src/core/tsi/transport_security.c \
@@ -2496,7 +2515,6 @@ src/core/security/security_context.c: $(OPENSSL_DEP)
 src/core/security/server_secure_chttp2.c: $(OPENSSL_DEP)
 src/core/surface/init_secure.c: $(OPENSSL_DEP)
 src/core/surface/secure_channel_create.c: $(OPENSSL_DEP)
-src/core/surface/secure_server_create.c: $(OPENSSL_DEP)
 src/core/tsi/fake_transport_security.c: $(OPENSSL_DEP)
 src/core/tsi/ssl_transport_security.c: $(OPENSSL_DEP)
 src/core/tsi/transport_security.c: $(OPENSSL_DEP)
@@ -2602,13 +2620,13 @@ $(LIBDIR)/$(CONFIG)/libgrpc.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBGRPC_OBJS)
 	$(Q) mkdir -p `dirname $@`
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc.a
 	$(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBGRPC_OBJS)
-	$(Q) rm -rf tmp-merge
-	$(Q) mkdir tmp-merge
-	$(Q) ( cd tmp-merge ; $(AR) x ../$(LIBDIR)/$(CONFIG)/libgrpc.a )
-	$(Q) for l in $(OPENSSL_MERGE_LIBS) ; do ( cd tmp-merge ; ar x ../$${l} ) ; done
-	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc.a tmp-merge/__.SYMDEF*
-	$(Q) ar rcs $(LIBDIR)/$(CONFIG)/libgrpc.a tmp-merge/*
-	$(Q) rm -rf tmp-merge
+	$(Q) rm -rf tmp-merge-grpc
+	$(Q) mkdir tmp-merge-grpc
+	$(Q) ( cd tmp-merge-grpc ; $(AR) x ../$(LIBDIR)/$(CONFIG)/libgrpc.a )
+	$(Q) for l in $(OPENSSL_MERGE_LIBS) ; do ( cd tmp-merge-grpc ; ar x ../$${l} ) ; done
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc.a tmp-merge-grpc/__.SYMDEF*
+	$(Q) ar rcs $(LIBDIR)/$(CONFIG)/libgrpc.a tmp-merge-grpc/*
+	$(Q) rm -rf tmp-merge-grpc
 ifeq ($(SYSTEM),Darwin)
 	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc.a
 endif
@@ -2659,7 +2677,6 @@ $(OBJDIR)/$(CONFIG)/src/core/security/security_context.o:
 $(OBJDIR)/$(CONFIG)/src/core/security/server_secure_chttp2.o: 
 $(OBJDIR)/$(CONFIG)/src/core/surface/init_secure.o: 
 $(OBJDIR)/$(CONFIG)/src/core/surface/secure_channel_create.o: 
-$(OBJDIR)/$(CONFIG)/src/core/surface/secure_server_create.o: 
 $(OBJDIR)/$(CONFIG)/src/core/tsi/fake_transport_security.o: 
 $(OBJDIR)/$(CONFIG)/src/core/tsi/ssl_transport_security.o: 
 $(OBJDIR)/$(CONFIG)/src/core/tsi/transport_security.o: 
@@ -3074,17 +3091,21 @@ $(OBJDIR)/$(CONFIG)/src/core/transport/transport.o:
 
 
 LIBGRPC++_SRC = \
+    src/cpp/client/secure_credentials.cc \
+    src/cpp/server/secure_server_credentials.cc \
     src/cpp/client/channel.cc \
     src/cpp/client/channel_arguments.cc \
     src/cpp/client/client_context.cc \
     src/cpp/client/client_unary_call.cc \
     src/cpp/client/create_channel.cc \
     src/cpp/client/credentials.cc \
+    src/cpp/client/insecure_credentials.cc \
     src/cpp/client/internal_stub.cc \
     src/cpp/common/call.cc \
     src/cpp/common/completion_queue.cc \
     src/cpp/common/rpc_method.cc \
     src/cpp/proto/proto_utils.cc \
+    src/cpp/server/insecure_server_credentials.cc \
     src/cpp/server/server.cc \
     src/cpp/server/server_builder.cc \
     src/cpp/server/server_context.cc \
@@ -3151,17 +3172,21 @@ ifneq ($(OPENSSL_DEP),)
 # This is to ensure the embedded OpenSSL is built beforehand, properly
 # installing headers to their final destination on the drive. We need this
 # otherwise parallel compilation will fail if a source is compiled first.
+src/cpp/client/secure_credentials.cc: $(OPENSSL_DEP)
+src/cpp/server/secure_server_credentials.cc: $(OPENSSL_DEP)
 src/cpp/client/channel.cc: $(OPENSSL_DEP)
 src/cpp/client/channel_arguments.cc: $(OPENSSL_DEP)
 src/cpp/client/client_context.cc: $(OPENSSL_DEP)
 src/cpp/client/client_unary_call.cc: $(OPENSSL_DEP)
 src/cpp/client/create_channel.cc: $(OPENSSL_DEP)
 src/cpp/client/credentials.cc: $(OPENSSL_DEP)
+src/cpp/client/insecure_credentials.cc: $(OPENSSL_DEP)
 src/cpp/client/internal_stub.cc: $(OPENSSL_DEP)
 src/cpp/common/call.cc: $(OPENSSL_DEP)
 src/cpp/common/completion_queue.cc: $(OPENSSL_DEP)
 src/cpp/common/rpc_method.cc: $(OPENSSL_DEP)
 src/cpp/proto/proto_utils.cc: $(OPENSSL_DEP)
+src/cpp/server/insecure_server_credentials.cc: $(OPENSSL_DEP)
 src/cpp/server/server.cc: $(OPENSSL_DEP)
 src/cpp/server/server_builder.cc: $(OPENSSL_DEP)
 src/cpp/server/server_context.cc: $(OPENSSL_DEP)
@@ -3186,15 +3211,15 @@ ifeq ($(SYSTEM),MINGW32)
 $(LIBDIR)/$(CONFIG)/grpc++.$(SHARED_EXT): $(LIBGRPC++_OBJS)  $(ZLIB_DEP)$(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT)$(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++.def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++-imp.a -o $(LIBDIR)/$(CONFIG)/grpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr-imp -lgrpc-imp
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++.def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++-imp.a -o $(LIBDIR)/$(CONFIG)/grpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr-imp -lgrpc-imp
 else
 $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc
 else
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc
 	$(Q) ln -sf libgrpc++.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++.so.0
 	$(Q) ln -sf libgrpc++.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++.so
 endif
@@ -3210,17 +3235,21 @@ ifneq ($(NO_DEPS),true)
 endif
 endif
 
+$(OBJDIR)/$(CONFIG)/src/cpp/client/secure_credentials.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/server/secure_server_credentials.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/client/channel.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/client/channel_arguments.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/client/client_context.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/client/client_unary_call.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/client/create_channel.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/client/credentials.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/client/insecure_credentials.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/client/internal_stub.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/common/call.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/common/completion_queue.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/common/rpc_method.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/proto/proto_utils.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/server/insecure_server_credentials.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/server/server.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/server/server_builder.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/server/server_context.o: 
@@ -3295,6 +3324,125 @@ endif
 $(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o:     $(GENDIR)/test/cpp/util/messages.pb.cc    $(GENDIR)/test/cpp/util/echo.pb.cc    $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc
 
 
+LIBGRPC++_UNSECURE_SRC = \
+    src/cpp/client/channel.cc \
+    src/cpp/client/channel_arguments.cc \
+    src/cpp/client/client_context.cc \
+    src/cpp/client/client_unary_call.cc \
+    src/cpp/client/create_channel.cc \
+    src/cpp/client/credentials.cc \
+    src/cpp/client/insecure_credentials.cc \
+    src/cpp/client/internal_stub.cc \
+    src/cpp/common/call.cc \
+    src/cpp/common/completion_queue.cc \
+    src/cpp/common/rpc_method.cc \
+    src/cpp/proto/proto_utils.cc \
+    src/cpp/server/insecure_server_credentials.cc \
+    src/cpp/server/server.cc \
+    src/cpp/server/server_builder.cc \
+    src/cpp/server/server_context.cc \
+    src/cpp/server/server_credentials.cc \
+    src/cpp/server/thread_pool.cc \
+    src/cpp/util/status.cc \
+    src/cpp/util/time.cc \
+
+PUBLIC_HEADERS_CXX += \
+    include/grpc++/async_unary_call.h \
+    include/grpc++/channel_arguments.h \
+    include/grpc++/channel_interface.h \
+    include/grpc++/client_context.h \
+    include/grpc++/completion_queue.h \
+    include/grpc++/config.h \
+    include/grpc++/create_channel.h \
+    include/grpc++/credentials.h \
+    include/grpc++/impl/call.h \
+    include/grpc++/impl/client_unary_call.h \
+    include/grpc++/impl/internal_stub.h \
+    include/grpc++/impl/rpc_method.h \
+    include/grpc++/impl/rpc_service_method.h \
+    include/grpc++/impl/service_type.h \
+    include/grpc++/server.h \
+    include/grpc++/server_builder.h \
+    include/grpc++/server_context.h \
+    include/grpc++/server_credentials.h \
+    include/grpc++/status.h \
+    include/grpc++/status_code_enum.h \
+    include/grpc++/stream.h \
+    include/grpc++/thread_pool_interface.h \
+
+LIBGRPC++_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_UNSECURE_SRC))))
+
+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++_unsecure.a: protobuf_dep_error
+
+ifeq ($(SYSTEM),MINGW32)
+$(LIBDIR)/$(CONFIG)/grpc++_unsecure.$(SHARED_EXT): protobuf_dep_error
+else
+$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT): protobuf_dep_error
+endif
+
+else
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_UNSECURE_OBJS)
+	$(E) "[AR]      Creating $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
+	$(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBGRPC++_UNSECURE_OBJS)
+ifeq ($(SYSTEM),Darwin)
+	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
+endif
+
+
+
+ifeq ($(SYSTEM),MINGW32)
+$(LIBDIR)/$(CONFIG)/grpc++_unsecure.$(SHARED_EXT): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP)$(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT)$(LIBDIR)/$(CONFIG)/grpc_unsecure.$(SHARED_EXT)
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_unsecure.def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure-imp.a -o $(LIBDIR)/$(CONFIG)/grpc++_unsecure.$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr-imp -lgrpc_unsecure-imp
+else
+$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT)
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+ifeq ($(SYSTEM),Darwin)
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
+else
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
+	$(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.so.0
+	$(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.so
+endif
+endif
+
+endif
+
+ifneq ($(NO_DEPS),true)
+-include $(LIBGRPC++_UNSECURE_OBJS:.o=.dep)
+endif
+
+$(OBJDIR)/$(CONFIG)/src/cpp/client/channel.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/client/channel_arguments.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/client/client_context.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/client/client_unary_call.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/client/create_channel.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/client/credentials.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/client/insecure_credentials.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/client/internal_stub.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/common/call.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/common/completion_queue.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/common/rpc_method.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/proto/proto_utils.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/server/insecure_server_credentials.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/server/server.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/server/server_builder.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/server/server_context.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/server/server_credentials.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/server/thread_pool.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/util/status.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/util/time.o: 
+
+
 LIBPUBSUB_CLIENT_LIB_SRC = \
     $(GENDIR)/examples/pubsub/label.pb.cc \
     $(GENDIR)/examples/pubsub/empty.pb.cc \
@@ -3468,15 +3616,15 @@ ifeq ($(SYSTEM),MINGW32)
 $(LIBDIR)/$(CONFIG)/grpc_csharp_ext.$(SHARED_EXT): $(LIBGRPC_CSHARP_EXT_OBJS)  $(ZLIB_DEP)$(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT)$(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_csharp_ext.def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext-imp.a -o $(LIBDIR)/$(CONFIG)/grpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) -lgpr-imp -lgrpc-imp
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_csharp_ext.def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext-imp.a -o $(LIBDIR)/$(CONFIG)/grpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) -lgpr-imp -lgrpc-imp
 else
 $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT): $(LIBGRPC_CSHARP_EXT_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) -lgpr -lgrpc
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) -lgpr -lgrpc
 else
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) -lgpr -lgrpc
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) -lgpr -lgrpc
 	$(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.so.0
 	$(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.so
 endif
diff --git a/build.json b/build.json
index fdf87f311d93ee08032dd69c087f0e5e36a2a1d7..c9500ebe1bd781a9b3249d3a284e27a34172e491 100644
--- a/build.json
+++ b/build.json
@@ -9,6 +9,61 @@
     }
   },
   "filegroups": [
+    {
+      "name": "grpc++_base",
+      "public_headers": [
+        "include/grpc++/async_unary_call.h",
+        "include/grpc++/channel_arguments.h",
+        "include/grpc++/channel_interface.h",
+        "include/grpc++/client_context.h",
+        "include/grpc++/completion_queue.h",
+        "include/grpc++/config.h",
+        "include/grpc++/create_channel.h",
+        "include/grpc++/credentials.h",
+        "include/grpc++/impl/call.h",
+        "include/grpc++/impl/client_unary_call.h",
+        "include/grpc++/impl/internal_stub.h",
+        "include/grpc++/impl/rpc_method.h",
+        "include/grpc++/impl/rpc_service_method.h",
+        "include/grpc++/impl/service_type.h",
+        "include/grpc++/server.h",
+        "include/grpc++/server_builder.h",
+        "include/grpc++/server_context.h",
+        "include/grpc++/server_credentials.h",
+        "include/grpc++/status.h",
+        "include/grpc++/status_code_enum.h",
+        "include/grpc++/stream.h",
+        "include/grpc++/thread_pool_interface.h"
+      ],
+      "headers": [
+        "src/cpp/client/channel.h",
+        "src/cpp/proto/proto_utils.h",
+        "src/cpp/server/thread_pool.h",
+        "src/cpp/util/time.h"
+      ],
+      "src": [
+        "src/cpp/client/channel.cc",
+        "src/cpp/client/channel_arguments.cc",
+        "src/cpp/client/client_context.cc",
+        "src/cpp/client/client_unary_call.cc",
+        "src/cpp/client/create_channel.cc",
+        "src/cpp/client/credentials.cc",
+        "src/cpp/client/insecure_credentials.cc",
+        "src/cpp/client/internal_stub.cc",
+        "src/cpp/common/call.cc",
+        "src/cpp/common/completion_queue.cc",
+        "src/cpp/common/rpc_method.cc",
+        "src/cpp/proto/proto_utils.cc",
+        "src/cpp/server/insecure_server_credentials.cc",
+        "src/cpp/server/server.cc",
+        "src/cpp/server/server_builder.cc",
+        "src/cpp/server/server_context.cc",
+        "src/cpp/server/server_credentials.cc",
+        "src/cpp/server/thread_pool.cc",
+        "src/cpp/util/status.cc",
+        "src/cpp/util/time.cc"
+      ]
+    },
     {
       "name": "grpc_base",
       "public_headers": [
@@ -80,7 +135,6 @@
         "src/core/surface/completion_queue.h",
         "src/core/surface/event_string.h",
         "src/core/surface/init.h",
-        "src/core/surface/lame_client.h",
         "src/core/surface/server.h",
         "src/core/surface/surface_trace.h",
         "src/core/transport/chttp2/bin_encoder.h",
@@ -276,7 +330,7 @@
         "src/core/support/time_posix.c",
         "src/core/support/time_win32.c"
       ],
-      "secure": false,
+      "secure": "no",
       "vs_project_guid": "{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}"
     },
     {
@@ -333,7 +387,6 @@
         "src/core/security/server_secure_chttp2.c",
         "src/core/surface/init_secure.c",
         "src/core/surface/secure_channel_create.c",
-        "src/core/surface/secure_server_create.c",
         "src/core/tsi/fake_transport_security.c",
         "src/core/tsi/ssl_transport_security.c",
         "src/core/tsi/transport_security.c"
@@ -345,7 +398,7 @@
       "filegroups": [
         "grpc_base"
       ],
-      "secure": true,
+      "secure": "yes",
       "vs_project_guid": "{29D16885-7228-4C31-81ED-5F9187C7F2A9}"
     },
     {
@@ -385,68 +438,26 @@
       "filegroups": [
         "grpc_base"
       ],
-      "secure": false,
+      "secure": "no",
       "vs_project_guid": "{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}"
     },
     {
       "name": "grpc++",
       "build": "all",
       "language": "c++",
-      "public_headers": [
-        "include/grpc++/async_unary_call.h",
-        "include/grpc++/channel_arguments.h",
-        "include/grpc++/channel_interface.h",
-        "include/grpc++/client_context.h",
-        "include/grpc++/completion_queue.h",
-        "include/grpc++/config.h",
-        "include/grpc++/create_channel.h",
-        "include/grpc++/credentials.h",
-        "include/grpc++/impl/call.h",
-        "include/grpc++/impl/client_unary_call.h",
-        "include/grpc++/impl/internal_stub.h",
-        "include/grpc++/impl/rpc_method.h",
-        "include/grpc++/impl/rpc_service_method.h",
-        "include/grpc++/impl/service_type.h",
-        "include/grpc++/server.h",
-        "include/grpc++/server_builder.h",
-        "include/grpc++/server_context.h",
-        "include/grpc++/server_credentials.h",
-        "include/grpc++/status.h",
-        "include/grpc++/status_code_enum.h",
-        "include/grpc++/stream.h",
-        "include/grpc++/thread_pool_interface.h"
-      ],
-      "headers": [
-        "src/cpp/client/channel.h",
-        "src/cpp/proto/proto_utils.h",
-        "src/cpp/server/thread_pool.h",
-        "src/cpp/util/time.h"
-      ],
       "src": [
-        "src/cpp/client/channel.cc",
-        "src/cpp/client/channel_arguments.cc",
-        "src/cpp/client/client_context.cc",
-        "src/cpp/client/client_unary_call.cc",
-        "src/cpp/client/create_channel.cc",
-        "src/cpp/client/credentials.cc",
-        "src/cpp/client/internal_stub.cc",
-        "src/cpp/common/call.cc",
-        "src/cpp/common/completion_queue.cc",
-        "src/cpp/common/rpc_method.cc",
-        "src/cpp/proto/proto_utils.cc",
-        "src/cpp/server/server.cc",
-        "src/cpp/server/server_builder.cc",
-        "src/cpp/server/server_context.cc",
-        "src/cpp/server/server_credentials.cc",
-        "src/cpp/server/thread_pool.cc",
-        "src/cpp/util/status.cc",
-        "src/cpp/util/time.cc"
+        "src/cpp/client/secure_credentials.cc",
+        "src/cpp/server/secure_server_credentials.cc"
       ],
       "deps": [
         "gpr",
         "grpc"
       ],
-      "secure": true,
+      "baselib": true,
+      "filegroups": [
+        "grpc++_base"
+      ],
+      "secure": "check",
       "vs_project_guid": "{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}"
     },
     {
@@ -460,6 +471,20 @@
         "test/cpp/util/create_test_channel.cc"
       ]
     },
+    {
+      "name": "grpc++_unsecure",
+      "build": "all",
+      "language": "c++",
+      "deps": [
+        "gpr",
+        "grpc_unsecure"
+      ],
+      "baselib": true,
+      "filegroups": [
+        "grpc++_base"
+      ],
+      "secure": "no"
+    },
     {
       "name": "pubsub_client_lib",
       "build": "private",
@@ -1686,7 +1711,7 @@
         "src/compiler/cpp_plugin.cc"
       ],
       "deps": [],
-      "secure": false
+      "secure": "no"
     },
     {
       "name": "grpc_python_plugin",
@@ -1700,7 +1725,7 @@
         "src/compiler/python_plugin.cc"
       ],
       "deps": [],
-      "secure": false
+      "secure": "no"
     },
     {
       "name": "grpc_ruby_plugin",
@@ -1711,7 +1736,7 @@
         "src/compiler/ruby_plugin.cc"
       ],
       "deps": [],
-      "secure": false
+      "secure": "no"
     },
     {
       "name": "interop_client",
diff --git a/examples/pubsub/main.cc b/examples/pubsub/main.cc
index ce22cfa1560e9cbd25f382025061112618d189c5..6f7737e2476ffa04088321e39210bcf7a486182e 100644
--- a/examples/pubsub/main.cc
+++ b/examples/pubsub/main.cc
@@ -79,8 +79,7 @@ int main(int argc, char** argv) {
 
   ss << FLAGS_server_host << ":" << FLAGS_server_port;
 
-  std::unique_ptr<grpc::Credentials> creds =
-      grpc::CredentialsFactory::GoogleDefaultCredentials();
+  std::unique_ptr<grpc::Credentials> creds = grpc::GoogleDefaultCredentials();
   std::shared_ptr<grpc::ChannelInterface> channel =
       grpc::CreateChannel(ss.str(), creds, grpc::ChannelArguments());
 
diff --git a/examples/pubsub/publisher_test.cc b/examples/pubsub/publisher_test.cc
index c988b4802ebacc3fc658a2c348607f7fafb33640..f9b6bb3418d21fcfcc7db4a5af343bb25ff540dd 100644
--- a/examples/pubsub/publisher_test.cc
+++ b/examples/pubsub/publisher_test.cc
@@ -40,6 +40,7 @@
 #include <grpc++/server.h>
 #include <grpc++/server_builder.h>
 #include <grpc++/server_context.h>
+#include <grpc++/server_credentials.h>
 #include <grpc++/status.h>
 #include <gtest/gtest.h>
 
@@ -106,12 +107,11 @@ class PublisherTest : public ::testing::Test {
     int port = grpc_pick_unused_port_or_die();
     server_address_ << "localhost:" << port;
     ServerBuilder builder;
-    builder.AddPort(server_address_.str());
+    builder.AddPort(server_address_.str(), grpc::InsecureServerCredentials());
     builder.RegisterService(&service_);
     server_ = builder.BuildAndStart();
 
-    channel_ =
-        CreateChannelDeprecated(server_address_.str(), ChannelArguments());
+    channel_ = CreateChannel(server_address_.str(), grpc::InsecureCredentials(), ChannelArguments());
 
     publisher_.reset(new grpc::examples::pubsub::Publisher(channel_));
   }
diff --git a/examples/pubsub/subscriber_test.cc b/examples/pubsub/subscriber_test.cc
index 4ff125f4b3ae9d0dd068f39d8e72a7c898455602..2d606336adde9177fd040256bff9909c2dddb36a 100644
--- a/examples/pubsub/subscriber_test.cc
+++ b/examples/pubsub/subscriber_test.cc
@@ -40,6 +40,7 @@
 #include <grpc++/server.h>
 #include <grpc++/server_builder.h>
 #include <grpc++/server_context.h>
+#include <grpc++/server_credentials.h>
 #include <grpc++/status.h>
 #include <gtest/gtest.h>
 
@@ -104,12 +105,11 @@ class SubscriberTest : public ::testing::Test {
     int port = grpc_pick_unused_port_or_die();
     server_address_ << "localhost:" << port;
     ServerBuilder builder;
-    builder.AddPort(server_address_.str());
+    builder.AddPort(server_address_.str(), grpc::InsecureServerCredentials());
     builder.RegisterService(&service_);
     server_ = builder.BuildAndStart();
 
-    channel_ =
-        CreateChannelDeprecated(server_address_.str(), ChannelArguments());
+    channel_ = CreateChannel(server_address_.str(), grpc::InsecureCredentials(), ChannelArguments());
 
     subscriber_.reset(new grpc::examples::pubsub::Subscriber(channel_));
   }
diff --git a/include/grpc++/async_unary_call.h b/include/grpc++/async_unary_call.h
index f86a1ea5185a66a3723c6b7a3dc2f67a99c26385..658941bb6d47ed78b5e4d8f8508367bb19490aea 100644
--- a/include/grpc++/async_unary_call.h
+++ b/include/grpc++/async_unary_call.h
@@ -92,7 +92,7 @@ class ServerAsyncResponseWriter GRPC_FINAL
   explicit ServerAsyncResponseWriter(ServerContext* ctx)
       : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
 
-  void SendInitialMetadata(void* tag) {
+  void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
     GPR_ASSERT(!ctx_->sent_initial_metadata_);
 
     meta_buf_.Reset(tag);
diff --git a/include/grpc++/channel_arguments.h b/include/grpc++/channel_arguments.h
index ad96ef14ae3ed6832be58adbdc7c7782418726ec..b649ba23b85509f8a97749c444791158dad11b54 100644
--- a/include/grpc++/channel_arguments.h
+++ b/include/grpc++/channel_arguments.h
@@ -62,6 +62,9 @@ class ChannelArguments {
   void SetInt(const grpc::string& key, int value);
   void SetString(const grpc::string& key, const grpc::string& value);
 
+  // Populates given channel_args with args_, does not take ownership.
+  void SetChannelArgs(grpc_channel_args* channel_args) const;
+
  private:
   friend class Channel;
   friend class testing::ChannelArgumentsTest;
@@ -73,9 +76,6 @@ class ChannelArguments {
   // Returns empty string when it is not set.
   grpc::string GetSslTargetNameOverride() const;
 
-  // Populates given channel_args with args_, does not take ownership.
-  void SetChannelArgs(grpc_channel_args* channel_args) const;
-
   std::vector<grpc_arg> args_;
   std::list<grpc::string> strings_;
 };
diff --git a/include/grpc++/create_channel.h b/include/grpc++/create_channel.h
index 3f13188365cd126ee36868331263c4751e93a124..da375b97db457f1edf225e7934da734efb96b1ff 100644
--- a/include/grpc++/create_channel.h
+++ b/include/grpc++/create_channel.h
@@ -43,11 +43,6 @@ namespace grpc {
 class ChannelArguments;
 class ChannelInterface;
 
-// Deprecation warning: This function will soon be deleted
-// (See pull request #711)
-std::shared_ptr<ChannelInterface> CreateChannelDeprecated(
-    const grpc::string& target, const ChannelArguments& args);
-
 // If creds does not hold an object or is invalid, a lame channel is returned.
 std::shared_ptr<ChannelInterface> CreateChannel(
     const grpc::string& target, const std::unique_ptr<Credentials>& creds,
diff --git a/include/grpc++/credentials.h b/include/grpc++/credentials.h
index 12c1a2fc98a6eaa1d0bc3ca62e5b0eb7142d19e5..c677cc3e0a3edd8bc01f3d0805ece638e5213760 100644
--- a/include/grpc++/credentials.h
+++ b/include/grpc++/credentials.h
@@ -39,29 +39,29 @@
 
 #include <grpc++/config.h>
 
-struct grpc_credentials;
-
 namespace grpc {
+class ChannelArguments;
+class ChannelInterface;
+class SecureCredentials;
 
-// grpc_credentials wrapper class. Typical use in C++ applications is limited
-// to creating an instance using CredentialsFactory, and passing it down
-// during channel construction.
-
-class Credentials GRPC_FINAL {
+class Credentials {
  public:
-  ~Credentials();
+  virtual ~Credentials();
 
-  // TODO(abhikumar): Specify a plugin API here to be implemented by
-  // credentials that do not have a corresponding implementation in C.
+ protected:
+  friend std::unique_ptr<Credentials> CompositeCredentials(
+    const std::unique_ptr<Credentials>& creds1,
+    const std::unique_ptr<Credentials>& creds2);
 
- private:
-  explicit Credentials(grpc_credentials*);
-  grpc_credentials* GetRawCreds();
+  virtual SecureCredentials* AsSecureCredentials() = 0;
 
-  friend class Channel;
-  friend class CredentialsFactory;
+ private:
+  friend std::shared_ptr<ChannelInterface> CreateChannel(
+      const grpc::string& target, const std::unique_ptr<Credentials>& creds,
+      const ChannelArguments& args);
 
-  grpc_credentials* creds_;
+  virtual std::shared_ptr<ChannelInterface> CreateChannel(
+      const grpc::string& target, const ChannelArguments& args) = 0;
 };
 
 // Options used to build SslCredentials
@@ -79,57 +79,44 @@ struct SslCredentialsOptions {
   grpc::string pem_cert_chain;
 };
 
-// Factory for building different types of Credentials
-// The methods may return empty unique_ptr when credentials cannot be created.
+// Factories for building different types of Credentials
+// The functions may return empty unique_ptr when credentials cannot be created.
 // If a Credentials pointer is returned, it can still be invalid when used to
 // create a channel. A lame channel will be created then and all rpcs will
 // fail on it.
-class CredentialsFactory {
- public:
-  // Builds google credentials with reasonable defaults.
-  // WARNING: Do NOT use this credentials to connect to a non-google service as
-  // this could result in an oauth2 token leak.
-  static std::unique_ptr<Credentials> GoogleDefaultCredentials();
-
-  // Builds SSL Credentials given SSL specific options
-  static std::unique_ptr<Credentials> SslCredentials(
-      const SslCredentialsOptions& options);
-
-  // Builds credentials for use when running in GCE
-  // WARNING: Do NOT use this credentials to connect to a non-google service as
-  // this could result in an oauth2 token leak.
-  static std::unique_ptr<Credentials> ComputeEngineCredentials();
-
-  // Builds service account credentials.
-  // WARNING: Do NOT use this credentials to connect to a non-google service as
-  // this could result in an oauth2 token leak.
-  // json_key is the JSON key string containing the client's private key.
-  // scope is a space-delimited list of the requested permissions.
-  // token_lifetime is the lifetime of each token acquired through this service
-  // account credentials. It should be positive and should not exceed
-  // grpc_max_auth_token_lifetime or will be cropped to this value.
-  static std::unique_ptr<Credentials> ServiceAccountCredentials(
-      const grpc::string& json_key, const grpc::string& scope,
-      std::chrono::seconds token_lifetime);
-
-  // Builds JWT credentials.
-  // json_key is the JSON key string containing the client's private key.
-  // token_lifetime is the lifetime of each Json Web Token (JWT) created with
-  // this credentials.  It should not exceed grpc_max_auth_token_lifetime or
-  // will be cropped to this value.
-  static std::unique_ptr<Credentials> JWTCredentials(
-      const grpc::string& json_key, std::chrono::seconds token_lifetime);
-
-  // Builds IAM credentials.
-  static std::unique_ptr<Credentials> IAMCredentials(
-      const grpc::string& authorization_token,
-      const grpc::string& authority_selector);
-
-  // Combines two credentials objects into a composite credentials
-  static std::unique_ptr<Credentials> CompositeCredentials(
-      const std::unique_ptr<Credentials>& creds1,
-      const std::unique_ptr<Credentials>& creds2);
-};
+
+// Builds credentials with reasonable defaults.
+std::unique_ptr<Credentials> GoogleDefaultCredentials();
+
+// Builds SSL Credentials given SSL specific options
+std::unique_ptr<Credentials> SslCredentials(
+    const SslCredentialsOptions& options);
+
+// Builds credentials for use when running in GCE
+std::unique_ptr<Credentials> ComputeEngineCredentials();
+
+// Builds service account credentials.
+// json_key is the JSON key string containing the client's private key.
+// scope is a space-delimited list of the requested permissions.
+// token_lifetime is the lifetime of each token acquired through this service
+// account credentials. It should be positive and should not exceed
+// grpc_max_auth_token_lifetime or will be cropped to this value.
+std::unique_ptr<Credentials> ServiceAccountCredentials(
+    const grpc::string& json_key, const grpc::string& scope,
+    std::chrono::seconds token_lifetime);
+
+// Builds IAM credentials.
+std::unique_ptr<Credentials> IAMCredentials(
+    const grpc::string& authorization_token,
+    const grpc::string& authority_selector);
+
+// Combines two credentials objects into a composite credentials
+std::unique_ptr<Credentials> CompositeCredentials(
+    const std::unique_ptr<Credentials>& creds1,
+    const std::unique_ptr<Credentials>& creds2);
+
+// Credentials for an unencrypted, unauthenticated channel
+std::unique_ptr<Credentials> InsecureCredentials();
 
 }  // namespace grpc
 
diff --git a/include/grpc++/server.h b/include/grpc++/server.h
index e3ba93e4877781ca1bd0d9d3f9ed0d22a4e1ea76..43c8432caf5fda06f98c338ee757acc23483f544 100644
--- a/include/grpc++/server.h
+++ b/include/grpc++/server.h
@@ -75,15 +75,14 @@ class Server GRPC_FINAL : private CallHook,
   class AsyncRequest;
 
   // ServerBuilder use only
-  Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned,
-         ServerCredentials* creds);
-  Server();
+  Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned);
+  Server() = delete;
   // Register a service. This call does not take ownership of the service.
   // The service must exist for the lifetime of the Server instance.
   bool RegisterService(RpcService* service);
   bool RegisterAsyncService(AsynchronousService* service);
   // Add a listening port. Can be called multiple times.
-  int AddPort(const grpc::string& addr);
+  int AddPort(const grpc::string& addr, ServerCredentials* creds);
   // Start the server.
   bool Start();
 
@@ -97,7 +96,7 @@ class Server GRPC_FINAL : private CallHook,
   void RequestAsyncCall(void* registered_method, ServerContext* context,
                         grpc::protobuf::Message* request,
                         ServerAsyncStreamingInterface* stream,
-                        CompletionQueue* cq, void* tag);
+                        CompletionQueue* cq, void* tag) GRPC_OVERRIDE;
 
   // Completion queue.
   CompletionQueue cq_;
@@ -113,13 +112,11 @@ class Server GRPC_FINAL : private CallHook,
   std::list<SyncRequest> sync_methods_;
 
   // Pointer to the c grpc server.
-  grpc_server* server_;
+  grpc_server* const server_;
 
   ThreadPoolInterface* thread_pool_;
   // Whether the thread pool is created and owned by the server.
   bool thread_pool_owned_;
-  // Whether the server is created with credentials.
-  bool secure_;
 };
 
 }  // namespace grpc
diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h
index 5566002dc22c5127adf19117ef82a7c369442bb7..a3270775637ce064bf052dadb3e978c68aaa93be 100644
--- a/include/grpc++/server_builder.h
+++ b/include/grpc++/server_builder.h
@@ -65,11 +65,9 @@ class ServerBuilder {
   void RegisterAsyncService(AsynchronousService* service);
 
   // Add a listening port. Can be called multiple times.
-  void AddPort(const grpc::string& addr);
-
-  // Set a ServerCredentials. Can only be called once.
-  // TODO(yangg) move this to be part of AddPort
-  void SetCredentials(const std::shared_ptr<ServerCredentials>& creds);
+  void AddPort(const grpc::string& addr,
+               std::shared_ptr<ServerCredentials> creds,
+               int* selected_port = nullptr);
 
   // Set the thread pool used for running appliation rpc handlers.
   // Does not take ownership.
@@ -79,9 +77,15 @@ class ServerBuilder {
   std::unique_ptr<Server> BuildAndStart();
 
  private:
+  struct Port {
+    grpc::string addr;
+    std::shared_ptr<ServerCredentials> creds;
+    int* selected_port;
+  };
+
   std::vector<RpcService*> services_;
   std::vector<AsynchronousService*> async_services_;
-  std::vector<grpc::string> ports_;
+  std::vector<Port> ports_;
   std::shared_ptr<ServerCredentials> creds_;
   ThreadPoolInterface* thread_pool_;
 };
diff --git a/include/grpc++/server_credentials.h b/include/grpc++/server_credentials.h
index 45cd279e0b03413757bdd8be739ba5c1d00e1684..83ae9fd1eb0fd0c773580d8f56f638f97c3f4bf1 100644
--- a/include/grpc++/server_credentials.h
+++ b/include/grpc++/server_credentials.h
@@ -39,24 +39,21 @@
 
 #include <grpc++/config.h>
 
-struct grpc_server_credentials;
+struct grpc_server;
 
 namespace grpc {
+class Server;
 
 // grpc_server_credentials wrapper class.
-class ServerCredentials GRPC_FINAL {
+class ServerCredentials {
  public:
-  ~ServerCredentials();
+  virtual ~ServerCredentials();
 
  private:
-  explicit ServerCredentials(grpc_server_credentials* c_creds);
+  friend class ::grpc::Server;
 
-  grpc_server_credentials* GetRawCreds();
-
-  friend class ServerCredentialsFactory;
-  friend class Server;
-
-  grpc_server_credentials* creds_;
+  virtual int AddPortToServer(const grpc::string& addr,
+                              grpc_server* server) = 0;
 };
 
 // Options to create ServerCredentials with SSL
@@ -69,13 +66,11 @@ struct SslServerCredentialsOptions {
   std::vector<PemKeyCertPair> pem_key_cert_pairs;
 };
 
-// Factory for building different types of ServerCredentials
-class ServerCredentialsFactory {
- public:
-  // Builds SSL ServerCredentials given SSL specific options
-  static std::shared_ptr<ServerCredentials> SslCredentials(
-      const SslServerCredentialsOptions& options);
-};
+// Builds SSL ServerCredentials given SSL specific options
+std::shared_ptr<ServerCredentials> SslServerCredentials(
+    const SslServerCredentialsOptions& options);
+
+std::shared_ptr<ServerCredentials> InsecureServerCredentials();
 
 }  // namespace grpc
 
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index bb1653101f4e529917f385dedbc6c5cad7822c90..e401da873bb034b82f4ed9ab152c2884c3481318 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -436,6 +436,9 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
 grpc_channel *grpc_channel_create(const char *target,
                                   const grpc_channel_args *args);
 
+/* Create a lame client: this client fails every operation attempted on it. */
+grpc_channel *grpc_lame_client_channel_create(void);
+
 /* Close and destroy a grpc channel */
 void grpc_channel_destroy(grpc_channel *channel);
 
diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h
index 577f03e85fee2a03817e813722769dc5cf9cb4af..ab2cc08489ddd7629648dc6071874b2a3c220b5d 100644
--- a/include/grpc/grpc_security.h
+++ b/include/grpc/grpc_security.h
@@ -169,17 +169,12 @@ grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
 
 /* --- Secure server creation. --- */
 
-/* Creates a secure server using the passed-in server credentials. */
-grpc_server *grpc_secure_server_create(grpc_server_credentials *creds,
-                                       grpc_completion_queue *cq,
-                                       const grpc_channel_args *args);
-
 /* Add a HTTP2 over an encrypted link over tcp listener.
    Server must have been created with grpc_secure_server_create.
    Returns bound port number on success, 0 on failure.
    REQUIRES: server not started */
-int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr);
-
+int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
+                                      grpc_server_credentials *creds);
 
 #ifdef __cplusplus
 }
diff --git a/src/core/iomgr/pollset_posix.c b/src/core/iomgr/pollset_posix.c
index 0151550a81823a40ce0b0d19e40f28f1e9b16ba1..0bb722e2b12c44748d089f68e66cd200c522f2f0 100644
--- a/src/core/iomgr/pollset_posix.c
+++ b/src/core/iomgr/pollset_posix.c
@@ -66,7 +66,7 @@ static void backup_poller(void *p) {
     gpr_timespec next_poll = gpr_time_add(last_poll, delta);
     grpc_pollset_work(&g_backup_pollset, gpr_time_add(gpr_now(), gpr_time_from_seconds(1)));
     gpr_mu_unlock(&g_backup_pollset.mu);
-    /*gpr_sleep_until(next_poll);*/
+    gpr_sleep_until(next_poll);
     gpr_mu_lock(&g_backup_pollset.mu);
     last_poll = next_poll;
   }
diff --git a/src/core/iomgr/resolve_address_posix.c b/src/core/iomgr/resolve_address_posix.c
index 85085dc37d10405c83319199aba053bb13882d98..9a9283c93c386cd7319d599774cbf722a02201b4 100644
--- a/src/core/iomgr/resolve_address_posix.c
+++ b/src/core/iomgr/resolve_address_posix.c
@@ -109,7 +109,7 @@ grpc_resolved_addresses *grpc_blocking_resolve_address(
     };
     int i;
     for (i = 0; i < (int)(sizeof(svc) / sizeof(svc[0])); i++) {
-      if (!strcmp(port, svc[i][0])) {
+      if (strcmp(port, svc[i][0]) == 0) {
         s = getaddrinfo(host, svc[i][1], &hints, &result);
         break;
       }
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c
index 7e72b238c80ed28747f53816aab8c3cf404bf1fd..3ad1e7edd7617b7274ac19041ac694b64e704547 100644
--- a/src/core/security/credentials.c
+++ b/src/core/security/credentials.c
@@ -348,7 +348,7 @@ static void jwt_get_request_metadata(grpc_credentials *creds,
   {
     gpr_mu_lock(&c->cache_mu);
     if (c->cached.service_url != NULL &&
-        !strcmp(c->cached.service_url, service_url) &&
+        strcmp(c->cached.service_url, service_url) == 0 &&
         c->cached.jwt_md != NULL &&
         (gpr_time_cmp(gpr_time_sub(c->cached.jwt_expiration, gpr_now()),
                       refresh_threshold) > 0)) {
@@ -957,7 +957,7 @@ static grpc_credentials_array get_creds_array(grpc_credentials **creds_addr) {
   grpc_credentials *creds = *creds_addr;
   result.creds_array = creds_addr;
   result.num_creds = 1;
-  if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE)) {
+  if (strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) == 0) {
     result = *grpc_composite_credentials_get_credentials(creds);
   }
   return result;
@@ -995,7 +995,7 @@ const grpc_credentials_array *grpc_composite_credentials_get_credentials(
     grpc_credentials *creds) {
   const grpc_composite_credentials *c =
       (const grpc_composite_credentials *)creds;
-  GPR_ASSERT(!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE));
+  GPR_ASSERT(strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) == 0);
   return &c->inner;
 }
 
@@ -1003,14 +1003,14 @@ grpc_credentials *grpc_credentials_contains_type(
     grpc_credentials *creds, const char *type,
     grpc_credentials **composite_creds) {
   size_t i;
-  if (!strcmp(creds->type, type)) {
+  if (strcmp(creds->type, type) == 0) {
     if (composite_creds != NULL) *composite_creds = NULL;
     return creds;
-  } else if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE)) {
+  } else if (strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) == 0) {
     const grpc_credentials_array *inner_creds_array =
         grpc_composite_credentials_get_credentials(creds);
     for (i = 0; i < inner_creds_array->num_creds; i++) {
-      if (!strcmp(type, inner_creds_array->creds_array[i]->type)) {
+      if (strcmp(type, inner_creds_array->creds_array[i]->type) == 0) {
         if (composite_creds != NULL) *composite_creds = creds;
         return inner_creds_array->creds_array[i];
       }
diff --git a/src/core/security/factories.c b/src/core/security/factories.c
index c9701b9080db47e6e5a8bf2e9daa9310f49318fd..02267d55457c5f0563dd5b2a3275721a761352b6 100644
--- a/src/core/security/factories.c
+++ b/src/core/security/factories.c
@@ -33,9 +33,9 @@
 
 #include <string.h>
 
+#include <grpc/grpc.h>
 #include "src/core/security/credentials.h"
 #include "src/core/security/security_context.h"
-#include "src/core/surface/lame_client.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/useful.h>
@@ -50,31 +50,3 @@ grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
   return grpc_secure_channel_create_with_factories(
       factories, GPR_ARRAY_SIZE(factories), creds, target, args);
 }
-
-grpc_server *grpc_secure_server_create(grpc_server_credentials *creds,
-                                       grpc_completion_queue *cq,
-                                       const grpc_channel_args *args) {
-  grpc_security_status status = GRPC_SECURITY_ERROR;
-  grpc_security_context *ctx = NULL;
-  grpc_server *server = NULL;
-  if (creds == NULL) return NULL; /* TODO(ctiller): Return lame server. */
-
-  if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) {
-    status = grpc_ssl_server_security_context_create(
-        grpc_ssl_server_credentials_get_config(creds), &ctx);
-  } else if (!strcmp(creds->type,
-                     GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY)) {
-    ctx = grpc_fake_server_security_context_create();
-    status = GRPC_SECURITY_OK;
-  }
-
-  if (status != GRPC_SECURITY_OK) {
-    gpr_log(GPR_ERROR,
-            "Unable to create secure server with credentials of type %s.",
-            creds->type);
-    return NULL; /* TODO(ctiller): Return lame server. */
-  }
-  server = grpc_secure_server_create_internal(cq, args, ctx);
-  grpc_security_context_unref(ctx);
-  return server;
-}
diff --git a/src/core/security/google_default_credentials.c b/src/core/security/google_default_credentials.c
index dc0e453b8781851f31b022f6873efb95ed460400..bdc907e7b33ada137d4af315799ac63db8f669ac 100644
--- a/src/core/security/google_default_credentials.c
+++ b/src/core/security/google_default_credentials.c
@@ -75,8 +75,8 @@ static void on_compute_engine_detection_http_response(
     size_t i;
     for (i = 0; i < response->hdr_count; i++) {
       grpc_httpcli_header *header = &response->hdrs[i];
-      if (!strcmp(header->key, "Metadata-Flavor") &&
-          !strcmp(header->value, "Google")) {
+      if (strcmp(header->key, "Metadata-Flavor") == 0 &&
+          strcmp(header->value, "Google") == 0) {
         detector->success = 1;
         break;
       }
diff --git a/src/core/security/json_token.c b/src/core/security/json_token.c
index 26d57036a6d58d66b968faf499960fdf0f14ac0a..40b612b2065e11213f82a33834407a6a452376b9 100644
--- a/src/core/security/json_token.c
+++ b/src/core/security/json_token.c
@@ -257,7 +257,7 @@ static char *dot_concat_and_free_strings(char *str1, char *str2) {
 }
 
 const EVP_MD *openssl_digest_from_algorithm(const char *algorithm) {
-  if (!strcmp(algorithm, GRPC_JWT_RSA_SHA256_ALGORITHM)) {
+  if (strcmp(algorithm, GRPC_JWT_RSA_SHA256_ALGORITHM) == 0) {
     return EVP_sha256();
   } else {
     gpr_log(GPR_ERROR, "Unknown algorithm %s.", algorithm);
diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c
index 0dc37fa73c0e33d9cec0458cf8e4013b647763f4..e180cad52b26ea74dda96aae4ba3cdd546e72936 100644
--- a/src/core/security/security_context.c
+++ b/src/core/security/security_context.c
@@ -42,7 +42,6 @@
 #include "src/core/support/env.h"
 #include "src/core/support/file.h"
 #include "src/core/support/string.h"
-#include "src/core/surface/lame_client.h"
 #include "src/core/transport/chttp2/alpn.h"
 
 #include <grpc/support/alloc.h>
@@ -422,7 +421,7 @@ static grpc_security_status ssl_channel_check_call_host(
   /* If the target name was overridden, then the original target_name was
      'checked' transitively during the previous peer check at the end of the
      handshake. */
-  if (c->overridden_target_name != NULL && !strcmp(host, c->target_name)) {
+  if (c->overridden_target_name != NULL && strcmp(host, c->target_name) == 0) {
     return GRPC_SECURITY_OK;
   } else {
     return GRPC_SECURITY_ERROR;
@@ -611,7 +610,7 @@ grpc_channel *grpc_ssl_channel_create(grpc_credentials *ssl_creds,
 
   for (i = 0; args && i < args->num_args; i++) {
     grpc_arg *arg = &args->args[i];
-    if (!strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) &&
+    if (strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) == 0 &&
         arg->type == GRPC_ARG_STRING) {
       overridden_target_name = arg->value.string;
       break;
diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c
index bd6f8473cb74ac952f4ea2d9be0a0071ac327487..c155b80b7e6aa0b10f6f001daf73100a4dca0325 100644
--- a/src/core/security/server_secure_chttp2.c
+++ b/src/core/security/server_secure_chttp2.c
@@ -33,6 +33,8 @@
 
 #include <grpc/grpc.h>
 
+#include <string.h>
+
 #include "src/core/channel/http_filter.h"
 #include "src/core/channel/http_server_filter.h"
 #include "src/core/iomgr/endpoint.h"
@@ -50,6 +52,7 @@
 typedef struct grpc_server_secure_state {
   grpc_server *server;
   grpc_tcp_server *tcp;
+  grpc_security_context *ctx;
   int is_shutdown;
   gpr_mu mu;
   gpr_refcount refcount;
@@ -61,6 +64,7 @@ static void state_ref(grpc_server_secure_state *state) {
 
 static void state_unref(grpc_server_secure_state *state) {
   if (gpr_unref(&state->refcount)) {
+    grpc_security_context_unref(state->ctx);
     gpr_free(state);
   }
 }
@@ -99,15 +103,10 @@ static void on_secure_transport_setup_done(void *statep,
 
 static void on_accept(void *statep, grpc_endpoint *tcp) {
   grpc_server_secure_state *state = statep;
-  const grpc_channel_args *args = grpc_server_get_channel_args(state->server);
-  grpc_security_context *ctx = grpc_find_security_context_in_args(args);
-  GPR_ASSERT(ctx);
   state_ref(state);
-  grpc_setup_secure_transport(ctx, tcp, on_secure_transport_setup_done, state);
+  grpc_setup_secure_transport(state->ctx, tcp, on_secure_transport_setup_done, state);
 }
 
-/* Note: the following code is the same with server_chttp2.c */
-
 /* Server callback: start listening on our ports */
 static void start(grpc_server *server, void *statep, grpc_pollset **pollsets,
                   size_t pollset_count) {
@@ -126,7 +125,7 @@ static void destroy(grpc_server *server, void *statep) {
   state_unref(state);
 }
 
-int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) {
+int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, grpc_server_credentials *creds) {
   grpc_resolved_addresses *resolved = NULL;
   grpc_tcp_server *tcp = NULL;
   grpc_server_secure_state *state = NULL;
@@ -134,7 +133,29 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) {
   unsigned count = 0;
   int port_num = -1;
   int port_temp;
+  grpc_security_status status = GRPC_SECURITY_ERROR;
+  grpc_security_context *ctx = NULL;
+
+  /* create security context */
+  if (creds == NULL) goto error;
+
+  if (strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL) == 0) {
+    status = grpc_ssl_server_security_context_create(
+        grpc_ssl_server_credentials_get_config(creds), &ctx);
+  } else if (strcmp(creds->type,
+                    GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY) == 0) {
+    ctx = grpc_fake_server_security_context_create();
+    status = GRPC_SECURITY_OK;
+  }
 
+  if (status != GRPC_SECURITY_OK) {
+    gpr_log(GPR_ERROR,
+            "Unable to create secure server with credentials of type %s.",
+            creds->type);
+    goto error;
+  }
+
+  /* resolve address */
   resolved = grpc_blocking_resolve_address(addr, "https");
   if (!resolved) {
     goto error;
@@ -173,6 +194,7 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) {
   state = gpr_malloc(sizeof(*state));
   state->server = server;
   state->tcp = tcp;
+  state->ctx = ctx;
   state->is_shutdown = 0;
   gpr_mu_init(&state->mu);
   gpr_ref_init(&state->refcount, 1);
@@ -184,11 +206,17 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) {
 
 /* Error path: cleanup and return */
 error:
+  if (ctx) {
+    grpc_security_context_unref(ctx);
+  }
   if (resolved) {
     grpc_resolved_addresses_destroy(resolved);
   }
   if (tcp) {
     grpc_tcp_server_destroy(tcp);
   }
+  if (state) {
+    gpr_free(state);
+  }
   return 0;
 }
diff --git a/src/core/surface/lame_client.c b/src/core/surface/lame_client.c
index 57f6ddf0f7ff6bca8b82e02946dd7cbb8a3e1bb9..b40c48381f4296da467ce53df4cd9ac9b8420258 100644
--- a/src/core/surface/lame_client.c
+++ b/src/core/surface/lame_client.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/surface/lame_client.h"
+#include <grpc/grpc.h>
 
 #include <string.h>
 
diff --git a/src/core/tsi/fake_transport_security.c b/src/core/tsi/fake_transport_security.c
index f58f04ea20b8ebe17b92c43d4c8970bdd997b024..9ce1ddb95e2676353caced21e8eeb6c6dc991228 100644
--- a/src/core/tsi/fake_transport_security.c
+++ b/src/core/tsi/fake_transport_security.c
@@ -102,8 +102,8 @@ static tsi_result tsi_fake_handshake_message_from_string(
     const char* msg_string, tsi_fake_handshake_message* msg) {
   int i;
   for (i = 0; i < TSI_FAKE_HANDSHAKE_MESSAGE_MAX; i++) {
-    if (!strncmp(msg_string, tsi_fake_handshake_message_strings[i],
-                 strlen(tsi_fake_handshake_message_strings[i]))) {
+    if (strncmp(msg_string, tsi_fake_handshake_message_strings[i],
+                strlen(tsi_fake_handshake_message_strings[i])) == 0) {
       *msg = i;
       return TSI_OK;
     }
diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c
index dc43f7e270cf52ccc6d803a986f14311f6d583e4..33645ca8b866193c5f0f82c9654eb794eae989c1 100644
--- a/src/core/tsi/ssl_transport_security.c
+++ b/src/core/tsi/ssl_transport_security.c
@@ -1083,7 +1083,8 @@ static int does_entry_match_name(const char* entry, size_t entry_length,
     if (entry_length == 0) return 0;
   }
 
-  if ((name_length == entry_length) && !strncmp(name, entry, entry_length)) {
+  if ((name_length == entry_length) &&
+      strncmp(name, entry, entry_length) == 0) {
     return 1; /* Perfect match. */
   }
   if (entry[0] != '*') return 0;
@@ -1110,7 +1111,7 @@ static int does_entry_match_name(const char* entry, size_t entry_length,
     name_subdomain_length--;
   }
   return ((entry_length > 0) && (name_subdomain_length == entry_length) &&
-          !strncmp(entry, name_subdomain, entry_length));
+          strncmp(entry, name_subdomain, entry_length) == 0);
 }
 
 static int ssl_server_handshaker_factory_servername_callback(SSL* ssl, int* ap,
diff --git a/src/core/tsi/transport_security.c b/src/core/tsi/transport_security.c
index c8c74c5de5998739bd6b20501ba17e9d72f1f577..f4ab9d2bc6d12feab4e4b5554e2bc0aa6605ea58 100644
--- a/src/core/tsi/transport_security.c
+++ b/src/core/tsi/transport_security.c
@@ -208,7 +208,7 @@ const tsi_peer_property* tsi_peer_get_property_by_name(const tsi_peer* self,
       return property;
     }
     if (name != NULL && property->name != NULL &&
-        !strcmp(property->name, name)) {
+        strcmp(property->name, name) == 0) {
       return property;
     }
   }
diff --git a/src/cpp/client/channel.cc b/src/cpp/client/channel.cc
index 450cf67ac8be9a546fa91ba92428930de6ca8ecc..5380d3a232c3739ef634e4922311faa18ee8e204 100644
--- a/src/cpp/client/channel.cc
+++ b/src/cpp/client/channel.cc
@@ -53,43 +53,23 @@
 
 namespace grpc {
 
-Channel::Channel(const grpc::string &target, const ChannelArguments &args)
-    : target_(target) {
-  grpc_channel_args channel_args;
-  args.SetChannelArgs(&channel_args);
-  c_channel_ = grpc_channel_create(
-      target_.c_str(), channel_args.num_args > 0 ? &channel_args : nullptr);
-}
-
-Channel::Channel(const grpc::string &target,
-                 const std::unique_ptr<Credentials> &creds,
-                 const ChannelArguments &args)
-    : target_(args.GetSslTargetNameOverride().empty()
-                  ? target
-                  : args.GetSslTargetNameOverride()) {
-  grpc_channel_args channel_args;
-  args.SetChannelArgs(&channel_args);
-  grpc_credentials *c_creds = creds ? creds->GetRawCreds() : nullptr;
-  c_channel_ = grpc_secure_channel_create(
-      c_creds, target.c_str(),
-      channel_args.num_args > 0 ? &channel_args : nullptr);
-}
+Channel::Channel(const grpc::string& target, grpc_channel* channel)
+    : target_(target), c_channel_(channel) {}
 
 Channel::~Channel() { grpc_channel_destroy(c_channel_); }
 
-Call Channel::CreateCall(const RpcMethod &method, ClientContext *context,
-                         CompletionQueue *cq) {
-  auto c_call =
-      grpc_channel_create_call(
-          c_channel_, cq->cq(), method.name(),
-          context->authority().empty() ? target_.c_str()
-                                       : context->authority().c_str(),
-          context->RawDeadline());
+Call Channel::CreateCall(const RpcMethod& method, ClientContext* context,
+                         CompletionQueue* cq) {
+  auto c_call = grpc_channel_create_call(c_channel_, cq->cq(), method.name(),
+                                         context->authority().empty()
+                                             ? target_.c_str()
+                                             : context->authority().c_str(),
+                                         context->RawDeadline());
   context->set_call(c_call);
   return Call(c_call, this, cq);
 }
 
-void Channel::PerformOpsOnCall(CallOpBuffer *buf, Call *call) {
+void Channel::PerformOpsOnCall(CallOpBuffer* buf, Call* call) {
   static const size_t MAX_OPS = 8;
   size_t nops = MAX_OPS;
   grpc_op ops[MAX_OPS];
diff --git a/src/cpp/client/channel.h b/src/cpp/client/channel.h
index 63c6e2bde6d4fc9c0cb286ad37fe526c86dd74d2..a1de3817e6947773dbdff3d9c534f094d2132420 100644
--- a/src/cpp/client/channel.h
+++ b/src/cpp/client/channel.h
@@ -51,10 +51,7 @@ class StreamContextInterface;
 
 class Channel GRPC_FINAL : public ChannelInterface {
  public:
-  Channel(const grpc::string &target, const ChannelArguments &args);
-  Channel(const grpc::string &target, const std::unique_ptr<Credentials> &creds,
-          const ChannelArguments &args);
-
+  Channel(const grpc::string &target, grpc_channel *c_channel);
   ~Channel() GRPC_OVERRIDE;
 
   virtual Call CreateCall(const RpcMethod &method, ClientContext *context,
@@ -63,7 +60,7 @@ class Channel GRPC_FINAL : public ChannelInterface {
 
  private:
   const grpc::string target_;
-  grpc_channel *c_channel_;  // owned
+  grpc_channel *const c_channel_;  // owned
 };
 
 }  // namespace grpc
diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc
index 583e072799bfd4a379772de76b07555f9c3d2397..57d215d0f333a8a91c1bfe4755fe45eb17cc9098 100644
--- a/src/cpp/client/create_channel.cc
+++ b/src/cpp/client/create_channel.cc
@@ -40,14 +40,10 @@
 namespace grpc {
 class ChannelArguments;
 
-std::shared_ptr<ChannelInterface> CreateChannelDeprecated(
-    const grpc::string &target, const ChannelArguments &args) {
-  return std::shared_ptr<ChannelInterface>(new Channel(target, args));
-}
-
 std::shared_ptr<ChannelInterface> CreateChannel(
     const grpc::string &target, const std::unique_ptr<Credentials> &creds,
     const ChannelArguments &args) {
-  return std::shared_ptr<ChannelInterface>(new Channel(target, creds, args));
+  return creds ? creds->CreateChannel(target, args) : 
+  	std::shared_ptr<ChannelInterface>(new Channel(target, grpc_lame_client_channel_create()));
 }
 }  // namespace grpc
diff --git a/src/cpp/client/credentials.cc b/src/cpp/client/credentials.cc
index eff0892810b81a2c748e3f76e68dd88c8c820303..e8062849887c0582f713b8fca79f1a6ab6923383 100644
--- a/src/cpp/client/credentials.cc
+++ b/src/cpp/client/credentials.cc
@@ -31,98 +31,10 @@
  *
  */
 
-#include <string>
-
-#include <grpc/grpc_security.h>
-#include <grpc/support/log.h>
-
 #include <grpc++/credentials.h>
 
 namespace grpc {
 
-Credentials::Credentials(grpc_credentials *c_creds) : creds_(c_creds) {}
-
-Credentials::~Credentials() { grpc_credentials_release(creds_); }
-grpc_credentials *Credentials::GetRawCreds() { return creds_; }
-
-std::unique_ptr<Credentials> CredentialsFactory::GoogleDefaultCredentials() {
-  grpc_credentials *c_creds = grpc_google_default_credentials_create();
-  std::unique_ptr<Credentials> cpp_creds(
-      c_creds == nullptr ? nullptr : new Credentials(c_creds));
-  return cpp_creds;
-}
-
-// Builds SSL Credentials given SSL specific options
-std::unique_ptr<Credentials> CredentialsFactory::SslCredentials(
-    const SslCredentialsOptions &options) {
-  grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {
-      options.pem_private_key.c_str(), options.pem_cert_chain.c_str()};
-
-  grpc_credentials *c_creds = grpc_ssl_credentials_create(
-      options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(),
-      options.pem_private_key.empty() ? nullptr : &pem_key_cert_pair);
-  std::unique_ptr<Credentials> cpp_creds(
-      c_creds == nullptr ? nullptr : new Credentials(c_creds));
-  return cpp_creds;
-}
-
-// Builds credentials for use when running in GCE
-std::unique_ptr<Credentials> CredentialsFactory::ComputeEngineCredentials() {
-  grpc_credentials *c_creds = grpc_compute_engine_credentials_create();
-  std::unique_ptr<Credentials> cpp_creds(
-      c_creds == nullptr ? nullptr : new Credentials(c_creds));
-  return cpp_creds;
-}
-
-// Builds service account credentials.
-std::unique_ptr<Credentials> CredentialsFactory::ServiceAccountCredentials(
-    const grpc::string &json_key, const grpc::string &scope,
-    std::chrono::seconds token_lifetime) {
-  gpr_timespec lifetime = gpr_time_from_seconds(
-      token_lifetime.count() > 0 ? token_lifetime.count() : 0);
-  grpc_credentials *c_creds = grpc_service_account_credentials_create(
-      json_key.c_str(), scope.c_str(), lifetime);
-  std::unique_ptr<Credentials> cpp_creds(
-      c_creds == nullptr ? nullptr : new Credentials(c_creds));
-  return cpp_creds;
-}
-
-// Builds JWT credentials.
-std::unique_ptr<Credentials> CredentialsFactory::JWTCredentials(
-    const grpc::string &json_key, std::chrono::seconds token_lifetime) {
-  gpr_timespec lifetime = gpr_time_from_seconds(
-      token_lifetime.count() > 0 ? token_lifetime.count() : 0);
-  grpc_credentials *c_creds =
-      grpc_jwt_credentials_create(json_key.c_str(), lifetime);
-  std::unique_ptr<Credentials> cpp_creds(
-      c_creds == nullptr ? nullptr : new Credentials(c_creds));
-  return cpp_creds;
-}
-
-// Builds IAM credentials.
-std::unique_ptr<Credentials> CredentialsFactory::IAMCredentials(
-    const grpc::string &authorization_token,
-    const grpc::string &authority_selector) {
-  grpc_credentials *c_creds = grpc_iam_credentials_create(
-      authorization_token.c_str(), authority_selector.c_str());
-  std::unique_ptr<Credentials> cpp_creds(
-      c_creds == nullptr ? nullptr : new Credentials(c_creds));
-  return cpp_creds;
-}
-
-// Combines two credentials objects into a composite credentials.
-std::unique_ptr<Credentials> CredentialsFactory::CompositeCredentials(
-    const std::unique_ptr<Credentials> &creds1,
-    const std::unique_ptr<Credentials> &creds2) {
-  // Note that we are not saving unique_ptrs to the two credentials
-  // passed in here. This is OK because the underlying C objects (i.e.,
-  // creds1 and creds2) into grpc_composite_credentials_create will see their
-  // refcounts incremented.
-  grpc_credentials *c_creds = grpc_composite_credentials_create(
-      creds1->GetRawCreds(), creds2->GetRawCreds());
-  std::unique_ptr<Credentials> cpp_creds(
-      c_creds == nullptr ? nullptr : new Credentials(c_creds));
-  return cpp_creds;
-}
+Credentials::~Credentials() {}
 
 }  // namespace grpc
diff --git a/src/core/surface/secure_server_create.c b/src/cpp/client/insecure_credentials.cc
similarity index 66%
rename from src/core/surface/secure_server_create.c
rename to src/cpp/client/insecure_credentials.cc
index 1d5b9279977cbe2bd40da3082905b564d5ef9eaa..2dcfe69591aef588056d20a5e172210bed97d808 100644
--- a/src/core/surface/secure_server_create.c
+++ b/src/cpp/client/insecure_credentials.cc
@@ -31,27 +31,35 @@
  *
  */
 
-#include <grpc/grpc.h>
+#include <string>
 
-#include "src/core/channel/channel_args.h"
-#include "src/core/security/security_context.h"
-#include "src/core/surface/completion_queue.h"
-#include "src/core/surface/server.h"
+#include <grpc/grpc.h>
 #include <grpc/support/log.h>
 
-grpc_server *grpc_secure_server_create_internal(
-    grpc_completion_queue *cq, const grpc_channel_args *args,
-    grpc_security_context *context) {
-  grpc_arg context_arg;
-  grpc_channel_args *args_copy;
-  grpc_server *server;
-  if (grpc_find_security_context_in_args(args) != NULL) {
-    gpr_log(GPR_ERROR, "Cannot set security context in channel args.");
+#include <grpc++/channel_arguments.h>
+#include <grpc++/config.h>
+#include <grpc++/credentials.h>
+#include "src/cpp/client/channel.h"
+
+namespace grpc {
+
+namespace {
+class InsecureCredentialsImpl GRPC_FINAL : public Credentials {
+ public:
+  std::shared_ptr<grpc::ChannelInterface> CreateChannel(
+      const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE {
+    grpc_channel_args channel_args;
+    args.SetChannelArgs(&channel_args);
+    return std::shared_ptr<ChannelInterface>(new Channel(
+        target, grpc_channel_create(target.c_str(), &channel_args)));
   }
 
-  context_arg = grpc_security_context_to_arg(context);
-  args_copy = grpc_channel_args_copy_and_add(args, &context_arg);
-  server = grpc_server_create_from_filters(cq, NULL, 0, args_copy);
-  grpc_channel_args_destroy(args_copy);
-  return server;
+  SecureCredentials* AsSecureCredentials() { return nullptr; }
+};
+}  // namespace
+
+std::unique_ptr<Credentials> InsecureCredentials() {
+  return std::unique_ptr<Credentials>(new InsecureCredentialsImpl());
 }
+
+}  // namespace grpc
diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc
new file mode 100644
index 0000000000000000000000000000000000000000..5eb5c547942bc97a19edd788421aa3ed9f91351c
--- /dev/null
+++ b/src/cpp/client/secure_credentials.cc
@@ -0,0 +1,131 @@
+/*
+ *
+ * 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 <string>
+
+#include <grpc/grpc_security.h>
+#include <grpc/support/log.h>
+
+#include <grpc++/channel_arguments.h>
+#include <grpc++/config.h>
+#include <grpc++/credentials.h>
+#include "src/cpp/client/channel.h"
+
+namespace grpc {
+
+class SecureCredentials GRPC_FINAL : public Credentials {
+ public:
+  explicit SecureCredentials(grpc_credentials* c_creds) : c_creds_(c_creds) {}
+  ~SecureCredentials() GRPC_OVERRIDE { grpc_credentials_release(c_creds_); }
+  grpc_credentials* GetRawCreds() { return c_creds_; }
+
+  std::shared_ptr<grpc::ChannelInterface> CreateChannel(
+      const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE {
+    grpc_channel_args channel_args;
+    args.SetChannelArgs(&channel_args);
+    return std::shared_ptr<ChannelInterface>(new Channel(
+        target,
+        grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args)));
+  }
+
+  SecureCredentials* AsSecureCredentials() { return this; }
+
+ private:
+  grpc_credentials* const c_creds_;
+};
+
+namespace {
+std::unique_ptr<Credentials> WrapCredentials(grpc_credentials* creds) {
+  return creds == nullptr
+             ? nullptr
+             : std::unique_ptr<Credentials>(new SecureCredentials(creds));
+}
+}  // namespace
+
+std::unique_ptr<Credentials> GoogleDefaultCredentials() {
+  return WrapCredentials(grpc_google_default_credentials_create());
+}
+
+// Builds SSL Credentials given SSL specific options
+std::unique_ptr<Credentials> SslCredentials(
+    const SslCredentialsOptions& options) {
+  grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {
+      options.pem_private_key.c_str(), options.pem_cert_chain.c_str()};
+
+  grpc_credentials* c_creds = grpc_ssl_credentials_create(
+      options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(),
+      options.pem_private_key.empty() ? nullptr : &pem_key_cert_pair);
+  return WrapCredentials(c_creds);
+}
+
+// Builds credentials for use when running in GCE
+std::unique_ptr<Credentials> ComputeEngineCredentials() {
+  return WrapCredentials(grpc_compute_engine_credentials_create());
+}
+
+// Builds service account credentials.
+std::unique_ptr<Credentials> ServiceAccountCredentials(
+    const grpc::string& json_key, const grpc::string& scope,
+    std::chrono::seconds token_lifetime) {
+  gpr_timespec lifetime = gpr_time_from_seconds(
+      token_lifetime.count() > 0 ? token_lifetime.count() : 0);
+  return WrapCredentials(grpc_service_account_credentials_create(
+      json_key.c_str(), scope.c_str(), lifetime));
+}
+
+// Builds IAM credentials.
+std::unique_ptr<Credentials> IAMCredentials(
+    const grpc::string& authorization_token,
+    const grpc::string& authority_selector) {
+  return WrapCredentials(grpc_iam_credentials_create(
+      authorization_token.c_str(), authority_selector.c_str()));
+}
+
+// Combines two credentials objects into a composite credentials.
+std::unique_ptr<Credentials> CompositeCredentials(
+    const std::unique_ptr<Credentials>& creds1,
+    const std::unique_ptr<Credentials>& creds2) {
+  // Note that we are not saving unique_ptrs to the two credentials
+  // passed in here. This is OK because the underlying C objects (i.e.,
+  // creds1 and creds2) into grpc_composite_credentials_create will see their
+  // refcounts incremented.
+  SecureCredentials* s1 = creds1->AsSecureCredentials();
+  SecureCredentials* s2 = creds2->AsSecureCredentials();
+  if (s1 && s2) {
+    return WrapCredentials(grpc_composite_credentials_create(
+        s1->GetRawCreds(), s2->GetRawCreds()));
+  }
+  return nullptr;
+}
+
+}  // namespace grpc
diff --git a/src/core/surface/lame_client.h b/src/cpp/server/insecure_server_credentials.cc
similarity index 74%
rename from src/core/surface/lame_client.h
rename to src/cpp/server/insecure_server_credentials.cc
index b13e8cb6efe690d437c60effc5667d9d809c305e..f5e4732f73050bcf9db1b78655db2ed7a6c68cc4 100644
--- a/src/core/surface/lame_client.h
+++ b/src/cpp/server/insecure_server_credentials.cc
@@ -31,12 +31,22 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SURFACE_LAME_CLIENT_H
-#define GRPC_INTERNAL_CORE_SURFACE_LAME_CLIENT_H
+#include <grpc/grpc_security.h>
+#include <grpc++/server_credentials.h>
 
-#include <grpc/grpc.h>
+namespace grpc {
+namespace {
+class InsecureServerCredentialsImpl GRPC_FINAL : public ServerCredentials {
+ public:
+  int AddPortToServer(const grpc::string& addr,
+                      grpc_server* server) GRPC_OVERRIDE {
+    return grpc_server_add_http2_port(server, addr.c_str());
+  }
+};
+}  // namespace
 
-/* Create a lame client: this client fails every operation attempted on it. */
-grpc_channel *grpc_lame_client_channel_create(void);
+std::shared_ptr<ServerCredentials> InsecureServerCredentials() {
+  return std::shared_ptr<ServerCredentials>(new InsecureServerCredentialsImpl());
+}
 
-#endif  /* GRPC_INTERNAL_CORE_SURFACE_LAME_CLIENT_H */
+}  // namespace grpc
diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ff356385034e7a4a10a43b8134e151abf115ad1d
--- /dev/null
+++ b/src/cpp/server/secure_server_credentials.cc
@@ -0,0 +1,71 @@
+/*
+ *
+ * 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 <grpc/grpc_security.h>
+
+#include <grpc++/server_credentials.h>
+
+namespace grpc {
+
+namespace {
+class SecureServerCredentials GRPC_FINAL : public ServerCredentials {
+ public:
+  explicit SecureServerCredentials(grpc_server_credentials* creds) : creds_(creds) {}
+  ~SecureServerCredentials() GRPC_OVERRIDE {
+    grpc_server_credentials_release(creds_);
+  }
+
+  int AddPortToServer(const grpc::string& addr,
+                      grpc_server* server) GRPC_OVERRIDE {
+    return grpc_server_add_secure_http2_port(server, addr.c_str(), creds_);
+  }
+
+ private:
+  grpc_server_credentials* const creds_;
+};
+}  // namespace
+
+std::shared_ptr<ServerCredentials> SslServerCredentials(
+    const SslServerCredentialsOptions &options) {
+  std::vector<grpc_ssl_pem_key_cert_pair> pem_key_cert_pairs;
+  for (const auto &key_cert_pair : options.pem_key_cert_pairs) {
+    pem_key_cert_pairs.push_back(
+        {key_cert_pair.private_key.c_str(), key_cert_pair.cert_chain.c_str()});
+  }
+  grpc_server_credentials *c_creds = grpc_ssl_server_credentials_create(
+      options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(),
+      &pem_key_cert_pairs[0], pem_key_cert_pairs.size());
+  return std::shared_ptr<ServerCredentials>(new SecureServerCredentials(c_creds));
+}
+
+}  // namespace grpc
diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc
index 2a5a7fe5ebdaffa77923961b0e29a25c84ba2f0b..e69032a657d27f4c200c69bf422ae50f692aac47 100644
--- a/src/cpp/server/server.cc
+++ b/src/cpp/server/server.cc
@@ -170,26 +170,13 @@ class Server::SyncRequest GRPC_FINAL : public CompletionQueueTag {
   grpc_completion_queue* cq_;
 };
 
-Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned,
-               ServerCredentials* creds)
+Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned)
     : started_(false),
       shutdown_(false),
       num_running_cb_(0),
+      server_(grpc_server_create(cq_.cq(), nullptr)),
       thread_pool_(thread_pool),
-      thread_pool_owned_(thread_pool_owned),
-      secure_(creds != nullptr) {
-  if (creds) {
-    server_ =
-        grpc_secure_server_create(creds->GetRawCreds(), cq_.cq(), nullptr);
-  } else {
-    server_ = grpc_server_create(cq_.cq(), nullptr);
-  }
-}
-
-Server::Server() {
-  // Should not be called.
-  GPR_ASSERT(false);
-}
+      thread_pool_owned_(thread_pool_owned) {}
 
 Server::~Server() {
   std::unique_lock<std::mutex> lock(mu_);
@@ -239,13 +226,9 @@ bool Server::RegisterAsyncService(AsynchronousService* service) {
   return true;
 }
 
-int Server::AddPort(const grpc::string& addr) {
+int Server::AddPort(const grpc::string& addr, ServerCredentials* creds) {
   GPR_ASSERT(!started_);
-  if (secure_) {
-    return grpc_server_add_secure_http2_port(server_, addr.c_str());
-  } else {
-    return grpc_server_add_http2_port(server_, addr.c_str());
-  }
+  return creds->AddPortToServer(addr, server_);
 }
 
 bool Server::Start() {
diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc
index ae60f3d8b6743b0fdaec55b144aad75321d748e8..5de592334d76c66ddeaf5dc759e8869486ac1e63 100644
--- a/src/cpp/server/server_builder.cc
+++ b/src/cpp/server/server_builder.cc
@@ -51,14 +51,10 @@ void ServerBuilder::RegisterAsyncService(AsynchronousService* service) {
   async_services_.push_back(service);
 }
 
-void ServerBuilder::AddPort(const grpc::string& addr) {
-  ports_.push_back(addr);
-}
-
-void ServerBuilder::SetCredentials(
-    const std::shared_ptr<ServerCredentials>& creds) {
-  GPR_ASSERT(!creds_);
-  creds_ = creds;
+void ServerBuilder::AddPort(const grpc::string& addr,
+                            std::shared_ptr<ServerCredentials> creds,
+                            int* selected_port) {
+  ports_.push_back(Port{addr, creds, selected_port});
 }
 
 void ServerBuilder::SetThreadPool(ThreadPoolInterface* thread_pool) {
@@ -71,14 +67,13 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
     gpr_log(GPR_ERROR, "Mixing async and sync services is unsupported for now");
     return nullptr;
   }
-  if (!thread_pool_ && services_.size()) {
+  if (!thread_pool_ && !services_.empty()) {
     int cores = gpr_cpu_num_cores();
     if (!cores) cores = 4;
     thread_pool_ = new ThreadPool(cores);
     thread_pool_owned = true;
   }
-  std::unique_ptr<Server> server(
-      new Server(thread_pool_, thread_pool_owned, creds_.get()));
+  std::unique_ptr<Server> server(new Server(thread_pool_, thread_pool_owned));
   for (auto* service : services_) {
     if (!server->RegisterService(service)) {
       return nullptr;
@@ -90,8 +85,10 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
     }
   }
   for (auto& port : ports_) {
-    if (!server->AddPort(port)) {
-      return nullptr;
+    int r = server->AddPort(port.addr, port.creds.get());
+    if (!r) return nullptr;
+    if (port.selected_port != nullptr) {
+      *port.selected_port = r;
     }
   }
   if (!server->Start()) {
diff --git a/src/cpp/server/server_credentials.cc b/src/cpp/server/server_credentials.cc
index 69ad000ccc69f2d433910c52dc421466b6e193f4..6bdb465baaa5cd4e3b808f3ea3724c84eb6f7922 100644
--- a/src/cpp/server/server_credentials.cc
+++ b/src/cpp/server/server_credentials.cc
@@ -37,26 +37,6 @@
 
 namespace grpc {
 
-ServerCredentials::ServerCredentials(grpc_server_credentials *c_creds)
-    : creds_(c_creds) {}
-
-ServerCredentials::~ServerCredentials() {
-  grpc_server_credentials_release(creds_);
-}
-
-grpc_server_credentials *ServerCredentials::GetRawCreds() { return creds_; }
-
-std::shared_ptr<ServerCredentials> ServerCredentialsFactory::SslCredentials(
-    const SslServerCredentialsOptions &options) {
-  std::vector<grpc_ssl_pem_key_cert_pair> pem_key_cert_pairs;
-  for (const auto &key_cert_pair : options.pem_key_cert_pairs) {
-    pem_key_cert_pairs.push_back(
-        {key_cert_pair.private_key.c_str(), key_cert_pair.cert_chain.c_str()});
-  }
-  grpc_server_credentials *c_creds = grpc_ssl_server_credentials_create(
-      options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(),
-      &pem_key_cert_pairs[0], pem_key_cert_pairs.size());
-  return std::shared_ptr<ServerCredentials>(new ServerCredentials(c_creds));
-}
+ServerCredentials::~ServerCredentials() {}
 
 }  // namespace grpc
diff --git a/src/node/ext/server.cc b/src/node/ext/server.cc
index 5050042daa7c9dfdb2ed1556af45193e443d21ef..e47bac833bd24c31cb58e965d700f2ccfb20faaf 100644
--- a/src/node/ext/server.cc
+++ b/src/node/ext/server.cc
@@ -165,19 +165,7 @@ NAN_METHOD(Server::New) {
   if (args[0]->IsUndefined()) {
     wrapped_server = grpc_server_create(queue, NULL);
   } else if (args[0]->IsObject()) {
-    grpc_server_credentials *creds = NULL;
-    Handle<Object> args_hash(args[0]->ToObject()->Clone());
-    if (args_hash->HasOwnProperty(NanNew("credentials"))) {
-      Handle<Value> creds_value = args_hash->Get(NanNew("credentials"));
-      if (!ServerCredentials::HasInstance(creds_value)) {
-        return NanThrowTypeError(
-            "credentials arg must be a ServerCredentials object");
-      }
-      ServerCredentials *creds_object =
-          ObjectWrap::Unwrap<ServerCredentials>(creds_value->ToObject());
-      creds = creds_object->GetWrappedServerCredentials();
-      args_hash->Delete(NanNew("credentials"));
-    }
+    Handle<Object> args_hash(args[0]->ToObject());
     Handle<Array> keys(args_hash->GetOwnPropertyNames());
     grpc_channel_args channel_args;
     channel_args.num_args = keys->Length();
@@ -204,11 +192,7 @@ NAN_METHOD(Server::New) {
         return NanThrowTypeError("Arg values must be strings");
       }
     }
-    if (creds == NULL) {
-      wrapped_server = grpc_server_create(queue, &channel_args);
-    } else {
-      wrapped_server = grpc_secure_server_create(creds, queue, &channel_args);
-    }
+    wrapped_server = grpc_server_create(queue, &channel_args);
     free(channel_args.args);
   } else {
     return NanThrowTypeError("Server expects an object");
@@ -259,11 +243,19 @@ NAN_METHOD(Server::AddSecureHttp2Port) {
         "addSecureHttp2Port can only be called on a Server");
   }
   if (!args[0]->IsString()) {
-    return NanThrowTypeError("addSecureHttp2Port's argument must be a String");
+    return NanThrowTypeError(
+        "addSecureHttp2Port's first argument must be a String");
+  }
+  if (!ServerCredentials::HasInstance(args[1])) {
+    return NanThrowTypeError(
+        "addSecureHttp2Port's second argument must be ServerCredentials");
   }
   Server *server = ObjectWrap::Unwrap<Server>(args.This());
+  ServerCredentials *creds = ObjectWrap::Unwrap<ServerCredentials>(
+      args[1]->ToObject());
   NanReturnValue(NanNew<Number>(grpc_server_add_secure_http2_port(
-      server->wrapped_server, *NanUtf8String(args[0]))));
+      server->wrapped_server, *NanUtf8String(args[0]),
+      creds->GetWrappedServerCredentials())));
 }
 
 NAN_METHOD(Server::Start) {
diff --git a/src/node/interop/interop_server.js b/src/node/interop/interop_server.js
index 125ede174642f05bb0ee5f3d0831f5b69b797d7c..8e5c03666fa3b7ddcfb02ae9bd77a9856af52351 100644
--- a/src/node/interop/interop_server.js
+++ b/src/node/interop/interop_server.js
@@ -165,16 +165,16 @@ function handleHalfDuplex(call) {
 function getServer(port, tls) {
   // TODO(mlumish): enable TLS functionality
   var options = {};
+  var server_creds = null;
   if (tls) {
     var key_path = path.join(__dirname, '../test/data/server1.key');
     var pem_path = path.join(__dirname, '../test/data/server1.pem');
 
     var key_data = fs.readFileSync(key_path);
     var pem_data = fs.readFileSync(pem_path);
-    var server_creds = grpc.ServerCredentials.createSsl(null,
-                                                        key_data,
-                                                        pem_data);
-    options.credentials = server_creds;
+    server_creds = grpc.ServerCredentials.createSsl(null,
+                                                    key_data,
+                                                    pem_data);
   }
   var server = new Server({
     'grpc.testing.TestService' : {
@@ -186,7 +186,7 @@ function getServer(port, tls) {
       halfDuplexCall: handleHalfDuplex
     }
   }, null, options);
-  var port_num = server.bind('0.0.0.0:' + port, tls);
+  var port_num = server.bind('0.0.0.0:' + port, server_creds);
   return {server: server, port: port_num};
 }
 
diff --git a/src/node/src/server.js b/src/node/src/server.js
index 91dde0225181cc9341fd454bbab111723493c313..b72d110666e833518ec60d889a2c6805b8c1a36c 100644
--- a/src/node/src/server.js
+++ b/src/node/src/server.js
@@ -517,14 +517,15 @@ Server.prototype.register = function(name, handler, serialize, deserialize,
 };
 
 /**
- * Binds the server to the given port, with SSL enabled if secure is specified
+ * Binds the server to the given port, with SSL enabled if creds is given
  * @param {string} port The port that the server should bind on, in the format
  *     "address:port"
- * @param {boolean=} secure Whether the server should open a secure port
+ * @param {boolean=} creds Server credential object to be used for SSL. Pass
+ *     nothing for an insecure port
  */
-Server.prototype.bind = function(port, secure) {
-  if (secure) {
-    return this._server.addSecureHttp2Port(port);
+Server.prototype.bind = function(port, creds) {
+  if (creds) {
+    return this._server.addSecureHttp2Port(port, creds);
   } else {
     return this._server.addHttp2Port(port);
   }
@@ -604,14 +605,14 @@ function makeServerConstructor(services) {
   }
 
   /**
-   * Binds the server to the given port, with SSL enabled if secure is specified
+   * Binds the server to the given port, with SSL enabled if creds is supplied
    * @param {string} port The port that the server should bind on, in the format
    *     "address:port"
-   * @param {boolean=} secure Whether the server should open a secure port
+   * @param {boolean=} creds Credentials to use for SSL
    * @return {SurfaceServer} this
    */
-  SurfaceServer.prototype.bind = function(port, secure) {
-    return this.inner_server.bind(port, secure);
+  SurfaceServer.prototype.bind = function(port, creds) {
+    return this.inner_server.bind(port, creds);
   };
 
   /**
diff --git a/src/php/ext/grpc/server.c b/src/php/ext/grpc/server.c
index 32cc19775c0c76b2d9348a240615755490bec198..00d08c6ecf0976d1c336e33bc86145e8a137f1ee 100644
--- a/src/php/ext/grpc/server.c
+++ b/src/php/ext/grpc/server.c
@@ -96,9 +96,6 @@ PHP_METHOD(Server, __construct) {
   zval *queue_obj;
   zval *args_array = NULL;
   grpc_channel_args args;
-  HashTable *array_hash;
-  zval **creds_obj = NULL;
-  wrapped_grpc_server_credentials *creds = NULL;
   /* "O|a" == 1 Object, 1 optional array */
   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|a", &queue_obj,
                             grpc_ce_completion_queue, &args_array) == FAILURE) {
@@ -114,28 +111,8 @@ PHP_METHOD(Server, __construct) {
   if (args_array == NULL) {
     server->wrapped = grpc_server_create(queue->wrapped, NULL);
   } else {
-    array_hash = Z_ARRVAL_P(args_array);
-    if (zend_hash_find(array_hash, "credentials", sizeof("credentials"),
-                       (void **)&creds_obj) == SUCCESS) {
-      if (zend_get_class_entry(*creds_obj TSRMLS_CC) !=
-          grpc_ce_server_credentials) {
-        zend_throw_exception(spl_ce_InvalidArgumentException,
-                             "credentials must be a ServerCredentials object",
-                             1 TSRMLS_CC);
-        return;
-      }
-      creds = (wrapped_grpc_server_credentials *)zend_object_store_get_object(
-          *creds_obj TSRMLS_CC);
-      zend_hash_del(array_hash, "credentials", sizeof("credentials"));
-    }
     php_grpc_read_args_array(args_array, &args);
-    if (creds == NULL) {
-      server->wrapped = grpc_server_create(queue->wrapped, &args);
-    } else {
-      gpr_log(GPR_DEBUG, "Initialized secure server");
-      server->wrapped =
-          grpc_secure_server_create(creds->wrapped, queue->wrapped, &args);
-    }
+    server->wrapped = grpc_server_create(queue->wrapped, &args);
     efree(args.args);
   }
 }
@@ -187,14 +164,21 @@ PHP_METHOD(Server, add_secure_http2_port) {
       (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC);
   const char *addr;
   int addr_len;
-  /* "s" == 1 string */
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &addr, &addr_len) ==
+  zval *creds_obj;
+  /* "sO" == 1 string, 1 object */
+  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &addr, &addr_len,
+                            &creds_obj, grpc_ce_server_credentials) ==
       FAILURE) {
-    zend_throw_exception(spl_ce_InvalidArgumentException,
-                         "add_http2_port expects a string", 1 TSRMLS_CC);
+    zend_throw_exception(
+        spl_ce_InvalidArgumentException,
+        "add_http2_port expects a string and a ServerCredentials", 1 TSRMLS_CC);
     return;
   }
-  RETURN_LONG(grpc_server_add_secure_http2_port(server->wrapped, addr));
+  wrapped_grpc_server_credentials *creds =
+      (wrapped_grpc_server_credentials *)zend_object_store_get_object(
+          creds_obj TSRMLS_CC);
+  RETURN_LONG(grpc_server_add_secure_http2_port(server->wrapped, addr,
+                                                creds->wrapped));
 }
 
 /**
diff --git a/src/php/tests/unit_tests/SecureEndToEndTest.php b/src/php/tests/unit_tests/SecureEndToEndTest.php
index c23dd791acf979aba0d2fdf798166dfc87a4b6ca..896afeac49ad7fa656eb3f8e7f9dfa221bf0ce25 100755
--- a/src/php/tests/unit_tests/SecureEndToEndTest.php
+++ b/src/php/tests/unit_tests/SecureEndToEndTest.php
@@ -41,9 +41,9 @@ class SecureEndToEndTest extends PHPUnit_Framework_TestCase{
         null,
         file_get_contents(dirname(__FILE__) . '/../data/server1.key'),
         file_get_contents(dirname(__FILE__) . '/../data/server1.pem'));
-    $this->server = new Grpc\Server($this->server_queue,
-                                    ['credentials' => $server_credentials]);
-    $port = $this->server->add_secure_http2_port('0.0.0.0:0');
+    $this->server = new Grpc\Server($this->server_queue);
+    $port = $this->server->add_secure_http2_port('0.0.0.0:0',
+                                                 $server_credentials);
     $this->channel = new Grpc\Channel(
         'localhost:' . $port,
         [
diff --git a/src/python/README.md b/src/python/README.md
index 490a229d1d776a6f24c924f29a3d0759b3233e9a..c8057be38b380a86956d6fb8fc8819ebaf7eb4ed 100644
--- a/src/python/README.md
+++ b/src/python/README.md
@@ -46,7 +46,7 @@ Installing
 
 - Install gRPC Python's dependencies
 ```
-$ pip install -r requirements.txt
+$ pip install -r src/python/requirements.txt
 ```
 
 - Install gRPC Python
diff --git a/src/python/interop/interop/_insecure_interop_test.py b/src/python/interop/interop/_insecure_interop_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..1fa6b8b3f8f80a177dad0685dd2f4023351a4a9e
--- /dev/null
+++ b/src/python/interop/interop/_insecure_interop_test.py
@@ -0,0 +1,56 @@
+# 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.
+
+"""Insecure client-server interoperability as a unit test."""
+
+import unittest
+
+from grpc.early_adopter import implementations
+
+from interop import _interop_test_case
+from interop import methods
+
+
+class InsecureInteropTest(
+    _interop_test_case.InteropTestCase,
+    unittest.TestCase):
+
+  def setUp(self):
+    self.server = implementations.insecure_server(methods.SERVER_METHODS, 0)
+    self.server.start()
+    port = self.server.port()
+    self.stub = implementations.insecure_stub(
+        methods.CLIENT_METHODS, 'localhost', port)
+
+  def tearDown(self):
+    self.server.stop()
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/src/python/interop/interop/_interop_test_case.py b/src/python/interop/interop/_interop_test_case.py
new file mode 100644
index 0000000000000000000000000000000000000000..fec8f1915d53972d5abe126900636f776275ffe9
--- /dev/null
+++ b/src/python/interop/interop/_interop_test_case.py
@@ -0,0 +1,55 @@
+# 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.
+
+"""Common code for unit tests of the interoperability test code."""
+
+from interop import methods
+
+
+class InteropTestCase(object):
+  """Unit test methods.
+
+  This class must be mixed in with unittest.TestCase and a class that defines
+  setUp and tearDown methods that manage a stub attribute.
+  """
+
+  def testEmptyUnary(self):
+    methods.TestCase.EMPTY_UNARY.test_interoperability(self.stub)
+
+  def testLargeUnary(self):
+    methods.TestCase.LARGE_UNARY.test_interoperability(self.stub)
+
+  def testServerStreaming(self):
+    methods.TestCase.SERVER_STREAMING.test_interoperability(self.stub)
+
+  def testClientStreaming(self):
+    methods.TestCase.CLIENT_STREAMING.test_interoperability(self.stub)
+
+  def testPingPong(self):
+    methods.TestCase.PING_PONG.test_interoperability(self.stub)
diff --git a/src/python/interop/interop/_secure_interop_test.py b/src/python/interop/interop/_secure_interop_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..cc9e93821ad1693e8b72d8e4f1aa21608761a70a
--- /dev/null
+++ b/src/python/interop/interop/_secure_interop_test.py
@@ -0,0 +1,63 @@
+# 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.
+
+"""Secure client-server interoperability as a unit test."""
+
+import unittest
+
+from grpc.early_adopter import implementations
+
+from interop import _interop_test_case
+from interop import methods
+from interop import resources
+
+_SERVER_HOST_OVERRIDE = 'foo.test.google.fr'
+
+
+class SecureInteropTest(
+    _interop_test_case.InteropTestCase,
+    unittest.TestCase):
+
+  def setUp(self):
+    self.server = implementations.secure_server(
+        methods.SERVER_METHODS, 0, resources.private_key(),
+        resources.certificate_chain())
+    self.server.start()
+    port = self.server.port()
+    self.stub = implementations.secure_stub(
+        methods.CLIENT_METHODS, 'localhost', port,
+        resources.test_root_certificates(), None, None,
+        server_host_override=_SERVER_HOST_OVERRIDE)
+
+  def tearDown(self):
+    self.server.stop()
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/src/python/interop/interop/client.py b/src/python/interop/interop/client.py
index f4a449ef9e7ebab13c904289cc77965112979d56..b674a64f9d8583b9c5a435747c6f90ac0a6c98ff 100644
--- a/src/python/interop/interop/client.py
+++ b/src/python/interop/interop/client.py
@@ -65,21 +65,30 @@ def _stub(args):
       root_certificates = resources.test_root_certificates()
     else:
       root_certificates = resources.prod_root_certificates()
-    # TODO(nathaniel): server host override.
 
     stub = implementations.secure_stub(
         methods.CLIENT_METHODS, args.server_host, args.server_port,
-        root_certificates, None, None)
+        root_certificates, None, None,
+        server_host_override=args.server_host_override)
   else:
     stub = implementations.insecure_stub(
         methods.CLIENT_METHODS, args.server_host, args.server_port)
   return stub
 
 
+def _test_case_from_arg(test_case_arg):
+  for test_case in methods.TestCase:
+    if test_case_arg == test_case.value:
+      return test_case
+  else:
+    raise ValueError('No test case "%s"!' % test_case_arg)
+
+
 def _test_interoperability():
   args = _args()
   stub = _stub(args)
-  methods.test_interoperability(args.test_case, stub)
+  test_case = _test_case_from_arg(args.test_case)
+  test_case.test_interoperability(stub)
 
 
 if __name__ == '__main__':
diff --git a/src/python/interop/interop/methods.py b/src/python/interop/interop/methods.py
index 4da28ee7759b83e07d7653da717cdb38a49d3fec..2e15fac91573052ca385d2de1e9e1a9c6094948f 100644
--- a/src/python/interop/interop/methods.py
+++ b/src/python/interop/interop/methods.py
@@ -29,6 +29,7 @@
 
 """Implementations of interoperability test methods."""
 
+import enum
 import threading
 
 from grpc.early_adopter import utilities
@@ -265,16 +266,24 @@ def _ping_pong(stub):
     pipe.close()
 
 
-def test_interoperability(test_case, stub):
-  if test_case == 'empty_unary':
-    _empty_unary(stub)
-  elif test_case == 'large_unary':
-    _large_unary(stub)
-  elif test_case == 'server_streaming':
-    _server_streaming(stub)
-  elif test_case == 'client_streaming':
-    _client_streaming(stub)
-  elif test_case == 'ping_pong':
-    _ping_pong(stub)
-  else:
-    raise NotImplementedError('Test case "%s" not implemented!')
+@enum.unique
+class TestCase(enum.Enum):
+  EMPTY_UNARY = 'empty_unary'
+  LARGE_UNARY = 'large_unary'
+  SERVER_STREAMING = 'server_streaming'
+  CLIENT_STREAMING = 'client_streaming'
+  PING_PONG = 'ping_pong'
+
+  def test_interoperability(self, stub):
+    if self is TestCase.EMPTY_UNARY:
+      _empty_unary(stub)
+    elif self is TestCase.LARGE_UNARY:
+      _large_unary(stub)
+    elif self is TestCase.SERVER_STREAMING:
+      _server_streaming(stub)
+    elif self is TestCase.CLIENT_STREAMING:
+      _client_streaming(stub)
+    elif self is TestCase.PING_PONG:
+      _ping_pong(stub)
+    else:
+      raise NotImplementedError('Test case "%s" not implemented!' % self.name)
diff --git a/src/python/src/grpc/_adapter/_c_test.py b/src/python/src/grpc/_adapter/_c_test.py
index d81c63e3469643bcc1da143c97b1836ddf8e89c5..437a6730cd294560d483fed26b38aacbde97f7b9 100644
--- a/src/python/src/grpc/_adapter/_c_test.py
+++ b/src/python/src/grpc/_adapter/_c_test.py
@@ -70,7 +70,8 @@ class _CTest(unittest.TestCase):
   def testChannel(self):
     _c.init()
 
-    channel = _c.Channel('test host:12345', None)
+    channel = _c.Channel(
+        'test host:12345', None, server_host_override='ignored')
     del channel
 
     _c.shut_down()
@@ -92,7 +93,7 @@ class _CTest(unittest.TestCase):
     _c.init()
 
     completion_queue = _c.CompletionQueue()
-    server = _c.Server(completion_queue, None)
+    server = _c.Server(completion_queue)
     server.add_http2_addr('[::]:0')
     server.start()
     server.stop()
@@ -102,7 +103,7 @@ class _CTest(unittest.TestCase):
 
     service_tag = object()
     completion_queue = _c.CompletionQueue()
-    server = _c.Server(completion_queue, None)
+    server = _c.Server(completion_queue)
     server.add_http2_addr('[::]:0')
     server.start()
     server.service(service_tag)
@@ -119,7 +120,7 @@ class _CTest(unittest.TestCase):
     del completion_queue
 
     completion_queue = _c.CompletionQueue()
-    server = _c.Server(completion_queue, None)
+    server = _c.Server(completion_queue)
     server.add_http2_addr('[::]:0')
     server.start()
     thread = threading.Thread(target=completion_queue.get, args=(_FUTURE,))
diff --git a/src/python/src/grpc/_adapter/_channel.c b/src/python/src/grpc/_adapter/_channel.c
index 9cf580bcfb591e123f1571856d3c6cddd2ec5c1c..6be8f1c364330b56ab3a7988684c59427a9bdaf3 100644
--- a/src/python/src/grpc/_adapter/_channel.c
+++ b/src/python/src/grpc/_adapter/_channel.c
@@ -42,19 +42,35 @@
 static int pygrpc_channel_init(Channel *self, PyObject *args, PyObject *kwds) {
   const char *hostport;
   PyObject *client_credentials;
-  static char *kwlist[] = {"hostport", "client_credentials", NULL};
+  char *server_host_override = NULL;
+  static char *kwlist[] = {"hostport", "client_credentials",
+                           "server_host_override", NULL};
+  grpc_arg server_host_override_arg;
+  grpc_channel_args channel_args;
 
-  if (!(PyArg_ParseTupleAndKeywords(args, kwds, "sO:Channel", kwlist,
-                                    &hostport, &client_credentials))) {
+  if (!(PyArg_ParseTupleAndKeywords(args, kwds, "sO|z:Channel", kwlist,
+                                    &hostport, &client_credentials,
+                                    &server_host_override))) {
     return -1;
   }
   if (client_credentials == Py_None) {
     self->c_channel = grpc_channel_create(hostport, NULL);
     return 0;
   } else {
-    self->c_channel = grpc_secure_channel_create(
-        ((ClientCredentials *)client_credentials)->c_client_credentials,
-        hostport, NULL);
+    if (server_host_override == NULL) {
+      self->c_channel = grpc_secure_channel_create(
+	  ((ClientCredentials *)client_credentials)->c_client_credentials,
+          hostport, NULL);
+    } else {
+      server_host_override_arg.type = GRPC_ARG_STRING;
+      server_host_override_arg.key = GRPC_SSL_TARGET_NAME_OVERRIDE_ARG;
+      server_host_override_arg.value.string = server_host_override;
+      channel_args.num_args = 1;
+      channel_args.args = &server_host_override_arg;
+      self->c_channel = grpc_secure_channel_create(
+          ((ClientCredentials *)client_credentials)->c_client_credentials,
+          hostport, &channel_args);
+    }
     return 0;
   }
 }
diff --git a/src/python/src/grpc/_adapter/_face_test_case.py b/src/python/src/grpc/_adapter/_face_test_case.py
index 475d780c950d1913e0671247f61f5239717315f8..2542eb6da4d794e5b4636e4e8723e130a3e2ca44 100644
--- a/src/python/src/grpc/_adapter/_face_test_case.py
+++ b/src/python/src/grpc/_adapter/_face_test_case.py
@@ -50,31 +50,12 @@ class FaceTestCase(test_case.FaceTestCase, coverage.BlockingCoverage):
   """Provides abstract Face-layer tests a GRPC-backed implementation."""
 
   def set_up_implementation(
-      self,
-      name,
-      methods,
-      inline_value_in_value_out_methods,
-      inline_value_in_stream_out_methods,
-      inline_stream_in_value_out_methods,
-      inline_stream_in_stream_out_methods,
-      event_value_in_value_out_methods,
-      event_value_in_stream_out_methods,
-      event_stream_in_value_out_methods,
-      event_stream_in_stream_out_methods,
-      multi_method):
+      self, name, methods, method_implementations,
+      multi_method_implementation):
     pool = logging_pool.pool(_MAXIMUM_POOL_SIZE)
 
     servicer = face_implementations.servicer(
-        pool,
-        inline_value_in_value_out_methods=inline_value_in_value_out_methods,
-        inline_value_in_stream_out_methods=inline_value_in_stream_out_methods,
-        inline_stream_in_value_out_methods=inline_stream_in_value_out_methods,
-        inline_stream_in_stream_out_methods=inline_stream_in_stream_out_methods,
-        event_value_in_value_out_methods=event_value_in_value_out_methods,
-        event_value_in_stream_out_methods=event_value_in_stream_out_methods,
-        event_stream_in_value_out_methods=event_stream_in_value_out_methods,
-        event_stream_in_stream_out_methods=event_stream_in_stream_out_methods,
-        multi_method=multi_method)
+        pool, method_implementations, multi_method_implementation)
 
     serialization = serial.serialization(methods)
 
@@ -96,9 +77,8 @@ class FaceTestCase(test_case.FaceTestCase, coverage.BlockingCoverage):
     rear_link.join_fore_link(front)
     front.join_rear_link(rear_link)
 
-    server = face_implementations.server()
-    stub = face_implementations.stub(front, pool)
-    return server, stub, (rear_link, fore_link, front, back)
+    stub = face_implementations.generic_stub(front, pool)
+    return stub, (rear_link, fore_link, front, back)
 
   def tear_down_implementation(self, memo):
     rear_link, fore_link, front, back = memo
diff --git a/src/python/src/grpc/_adapter/_low_test.py b/src/python/src/grpc/_adapter/_low_test.py
index 03e3f473a3ec0cfd708581386b93e1b7eb43d757..b04ac1c95098a0cf23b89ce304223ccb3ebec89d 100644
--- a/src/python/src/grpc/_adapter/_low_test.py
+++ b/src/python/src/grpc/_adapter/_low_test.py
@@ -82,7 +82,7 @@ class EchoTest(unittest.TestCase):
     self.host = 'localhost'
 
     self.server_completion_queue = _low.CompletionQueue()
-    self.server = _low.Server(self.server_completion_queue, None)
+    self.server = _low.Server(self.server_completion_queue)
     port = self.server.add_http2_addr('[::]:0')
     self.server.start()
 
@@ -260,7 +260,7 @@ class CancellationTest(unittest.TestCase):
     self.host = 'localhost'
 
     self.server_completion_queue = _low.CompletionQueue()
-    self.server = _low.Server(self.server_completion_queue, None)
+    self.server = _low.Server(self.server_completion_queue)
     port = self.server.add_http2_addr('[::]:0')
     self.server.start()
 
diff --git a/src/python/src/grpc/_adapter/_server.c b/src/python/src/grpc/_adapter/_server.c
index ae7ae5b5d23e9e99c7be78d4da4345fe682614ca..181b6c21fcf1470cb56ae4168ab74e5c0cadaea2 100644
--- a/src/python/src/grpc/_adapter/_server.c
+++ b/src/python/src/grpc/_adapter/_server.c
@@ -42,30 +42,16 @@
 
 static int pygrpc_server_init(Server *self, PyObject *args, PyObject *kwds) {
   const PyObject *completion_queue;
-  PyObject *server_credentials;
-  static char *kwlist[] = {"completion_queue", "server_credentials", NULL};
+  static char *kwlist[] = {"completion_queue", NULL};
 
-  if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O:Server", kwlist,
+  if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!:Server", kwlist,
                                    &pygrpc_CompletionQueueType,
-                                   &completion_queue, &server_credentials)) {
-    return -1;
-  }
-  if (server_credentials == Py_None) {
-    self->c_server = grpc_server_create(
-        ((CompletionQueue *)completion_queue)->c_completion_queue, NULL);
-    return 0;
-  } else if (PyObject_TypeCheck(server_credentials,
-                                &pygrpc_ServerCredentialsType)) {
-    self->c_server = grpc_secure_server_create(
-        ((ServerCredentials *)server_credentials)->c_server_credentials,
-        ((CompletionQueue *)completion_queue)->c_completion_queue, NULL);
-    return 0;
-  } else {
-    PyErr_Format(PyExc_TypeError,
-                 "server_credentials must be _grpc.ServerCredentials, not %s",
-                 Py_TYPE(server_credentials)->tp_name);
+                                   &completion_queue)) {
     return -1;
   }
+  self->c_server = grpc_server_create(
+      ((CompletionQueue *)completion_queue)->c_completion_queue, NULL);
+  return 0;
 }
 
 static void pygrpc_server_dealloc(Server *self) {
@@ -92,13 +78,21 @@ static PyObject *pygrpc_server_add_http2_addr(Server *self, PyObject *args) {
 }
 
 static PyObject *pygrpc_server_add_secure_http2_addr(Server *self,
-                                                     PyObject *args) {
+                                                     PyObject *args,
+                                                     PyObject *kwargs) {
   const char *addr;
+  PyObject *server_credentials;
+  static char *kwlist[] = {"addr", "server_credentials", NULL};
   int port;
-  if (!PyArg_ParseTuple(args, "s:add_secure_http2_addr", &addr)) {
+
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO!:add_secure_http2_addr",
+                                   kwlist, &addr, &pygrpc_ServerCredentialsType,
+                                   &server_credentials)) {
     return NULL;
   }
-  port = grpc_server_add_secure_http2_port(self->c_server, addr);
+  port = grpc_server_add_secure_http2_port(
+      self->c_server, addr,
+      ((ServerCredentials *)server_credentials)->c_server_credentials);
   if (port == 0) {
     PyErr_SetString(PyExc_RuntimeError, "Couldn't add port to server!");
     return NULL;
@@ -138,8 +132,7 @@ static PyMethodDef methods[] = {
      METH_VARARGS, "Add a secure HTTP2 address."},
     {"start", (PyCFunction)pygrpc_server_start, METH_NOARGS,
      "Starts the server."},
-    {"service", (PyCFunction)pygrpc_server_service, METH_O,
-     "Services a call."},
+    {"service", (PyCFunction)pygrpc_server_service, METH_O, "Services a call."},
     {"stop", (PyCFunction)pygrpc_server_stop, METH_NOARGS, "Stops the server."},
     {NULL}};
 
diff --git a/src/python/src/grpc/_adapter/fore.py b/src/python/src/grpc/_adapter/fore.py
index b08b9f48bc6b891ae2452b7a3ab9981093e347f7..6ef9e6000626299c1c4b0bf7af98d380b0468e85 100644
--- a/src/python/src/grpc/_adapter/fore.py
+++ b/src/python/src/grpc/_adapter/fore.py
@@ -280,13 +280,14 @@ class ForeLink(ticket_interfaces.ForeLink, activated.Activated):
           0 if self._requested_port is None else self._requested_port)
       self._completion_queue = _low.CompletionQueue()
       if self._root_certificates is None and not self._key_chain_pairs:
-        self._server = _low.Server(self._completion_queue, None)
+        self._server = _low.Server(self._completion_queue)
         self._port = self._server.add_http2_addr(address)
       else:
         server_credentials = _low.ServerCredentials(
           self._root_certificates, self._key_chain_pairs)
-        self._server = _low.Server(self._completion_queue, server_credentials)
-        self._port = self._server.add_secure_http2_addr(address)
+        self._server = _low.Server(self._completion_queue)
+        self._port = self._server.add_secure_http2_addr(
+            address, server_credentials)
       self._server.start()
 
       self._server.service(None)
diff --git a/src/python/src/grpc/_adapter/rear.py b/src/python/src/grpc/_adapter/rear.py
index bfde5f5c577571208de1e722aab78d6e44896dca..fc71bf0a6c668a61cc823400d550760b12b288a7 100644
--- a/src/python/src/grpc/_adapter/rear.py
+++ b/src/python/src/grpc/_adapter/rear.py
@@ -93,7 +93,8 @@ class RearLink(ticket_interfaces.RearLink, activated.Activated):
 
   def __init__(
       self, host, port, pool, request_serializers, response_deserializers,
-      secure, root_certificates, private_key, certificate_chain):
+      secure, root_certificates, private_key, certificate_chain,
+      server_host_override=None):
     """Constructor.
 
     Args:
@@ -111,6 +112,8 @@ class RearLink(ticket_interfaces.RearLink, activated.Activated):
         key should be used.
       certificate_chain: The PEM-encoded certificate chain to use or None if
         no certificate chain should be used.
+      server_host_override: (For testing only) the target name used for SSL
+        host name checking.
     """
     self._condition = threading.Condition()
     self._host = host
@@ -132,6 +135,7 @@ class RearLink(ticket_interfaces.RearLink, activated.Activated):
     self._root_certificates = root_certificates
     self._private_key = private_key
     self._certificate_chain = certificate_chain
+    self._server_host_override = server_host_override
 
   def _on_write_event(self, operation_id, event, rpc_state):
     if event.write_accepted:
@@ -327,7 +331,8 @@ class RearLink(ticket_interfaces.RearLink, activated.Activated):
     with self._condition:
       self._completion_queue = _low.CompletionQueue()
       self._channel = _low.Channel(
-          '%s:%d' % (self._host, self._port), self._client_credentials)
+          '%s:%d' % (self._host, self._port), self._client_credentials,
+          server_host_override=self._server_host_override)
     return self
 
   def _stop(self):
@@ -388,7 +393,8 @@ class _ActivatedRearLink(ticket_interfaces.RearLink, activated.Activated):
 
   def __init__(
       self, host, port, request_serializers, response_deserializers, secure,
-      root_certificates, private_key, certificate_chain):
+      root_certificates, private_key, certificate_chain,
+      server_host_override=None):
     self._host = host
     self._port = port
     self._request_serializers = request_serializers
@@ -397,6 +403,7 @@ class _ActivatedRearLink(ticket_interfaces.RearLink, activated.Activated):
     self._root_certificates = root_certificates
     self._private_key = private_key
     self._certificate_chain = certificate_chain
+    self._server_host_override = server_host_override
 
     self._lock = threading.Lock()
     self._pool = None
@@ -415,7 +422,8 @@ class _ActivatedRearLink(ticket_interfaces.RearLink, activated.Activated):
       self._rear_link = RearLink(
           self._host, self._port, self._pool, self._request_serializers,
           self._response_deserializers, self._secure, self._root_certificates,
-          self._private_key, self._certificate_chain)
+          self._private_key, self._certificate_chain,
+          server_host_override=self._server_host_override)
       self._rear_link.join_fore_link(self._fore_link)
       self._rear_link.start()
     return self
@@ -477,7 +485,7 @@ def activated_rear_link(
 
 def secure_activated_rear_link(
     host, port, request_serializers, response_deserializers, root_certificates,
-    private_key, certificate_chain):
+    private_key, certificate_chain, server_host_override=None):
   """Creates a RearLink that is also an activated.Activated.
 
   The returned object is only valid for use between calls to its start and stop
@@ -496,7 +504,10 @@ def secure_activated_rear_link(
       should be used.
     certificate_chain: The PEM-encoded certificate chain to use or None if no
       certificate chain should be used.
+    server_host_override: (For testing only) the target name used for SSL
+      host name checking.
   """
   return _ActivatedRearLink(
       host, port, request_serializers, response_deserializers, True,
-      root_certificates, private_key, certificate_chain)
+      root_certificates, private_key, certificate_chain,
+      server_host_override=server_host_override)
diff --git a/src/python/src/grpc/early_adopter/_assembly_utilities.py b/src/python/src/grpc/early_adopter/_face_utilities.py
similarity index 76%
rename from src/python/src/grpc/early_adopter/_assembly_utilities.py
rename to src/python/src/grpc/early_adopter/_face_utilities.py
index facfc2bf0e647a6fa581da08caeb89e4b217a72a..2cf576018d4cf521db7ad78555b35b78d19a234e 100644
--- a/src/python/src/grpc/early_adopter/_assembly_utilities.py
+++ b/src/python/src/grpc/early_adopter/_face_utilities.py
@@ -30,23 +30,20 @@
 import abc
 import collections
 
-# assembly_interfaces is referenced from specification in this module.
-from grpc.framework.assembly import interfaces as assembly_interfaces  # pylint: disable=unused-import
-from grpc.framework.assembly import utilities as assembly_utilities
+# face_interfaces is referenced from specification in this module.
+from grpc.framework.common import cardinality
+from grpc.framework.face import interfaces as face_interfaces  # pylint: disable=unused-import
+from grpc.framework.face import utilities as face_utilities
 from grpc.early_adopter import _reexport
 from grpc.early_adopter import interfaces
 
 
-# TODO(issue 726): Kill the "implementations" attribute of this in favor
-# of the same-information-less-bogusly-represented "cardinalities".
 class InvocationBreakdown(object):
   """An intermediate representation of invocation-side views of RPC methods.
 
   Attributes:
     cardinalities: A dictionary from RPC method name to interfaces.Cardinality
       value.
-    implementations: A dictionary from RPC method name to
-      assembly_interfaces.MethodImplementation describing the method.
     request_serializers: A dictionary from RPC method name to callable
       behavior to be used serializing request values for the RPC.
     response_deserializers: A dictionary from RPC method name to callable
@@ -59,8 +56,7 @@ class _EasyInvocationBreakdown(
     InvocationBreakdown,
     collections.namedtuple(
         '_EasyInvocationBreakdown',
-        ('cardinalities', 'implementations', 'request_serializers',
-         'response_deserializers'))):
+        ('cardinalities', 'request_serializers', 'response_deserializers'))):
   pass
 
 
@@ -68,8 +64,8 @@ class ServiceBreakdown(object):
   """An intermediate representation of service-side views of RPC methods.
 
   Attributes:
-    implementations: A dictionary from RPC method name
-      assembly_interfaces.MethodImplementation implementing the RPC method.
+    implementations: A dictionary from RPC method name to
+      face_interfaces.MethodImplementation implementing the RPC method.
     request_deserializers: A dictionary from RPC method name to callable
       behavior to be used deserializing request values for the RPC.
     response_serializers: A dictionary from RPC method name to callable
@@ -97,25 +93,14 @@ def break_down_invocation(method_descriptions):
     An InvocationBreakdown corresponding to the given method descriptions.
   """
   cardinalities = {}
-  implementations = {}
   request_serializers = {}
   response_deserializers = {}
   for name, method_description in method_descriptions.iteritems():
-    cardinality = method_description.cardinality()
-    cardinalities[name] = cardinality
-    if cardinality is interfaces.Cardinality.UNARY_UNARY:
-      implementations[name] = assembly_utilities.unary_unary_inline(None)
-    elif cardinality is interfaces.Cardinality.UNARY_STREAM:
-      implementations[name] = assembly_utilities.unary_stream_inline(None)
-    elif cardinality is interfaces.Cardinality.STREAM_UNARY:
-      implementations[name] = assembly_utilities.stream_unary_inline(None)
-    elif cardinality is interfaces.Cardinality.STREAM_STREAM:
-      implementations[name] = assembly_utilities.stream_stream_inline(None)
+    cardinalities[name] = method_description.cardinality()
     request_serializers[name] = method_description.serialize_request
     response_deserializers[name] = method_description.deserialize_response
   return _EasyInvocationBreakdown(
-      cardinalities, implementations, request_serializers,
-      response_deserializers)
+      cardinalities, request_serializers, response_deserializers)
 
 
 def break_down_service(method_descriptions):
@@ -139,28 +124,28 @@ def break_down_service(method_descriptions):
           service_behavior=method_description.service_unary_unary):
         return service_behavior(
             request, _reexport.rpc_context(face_rpc_context))
-      implementations[name] = assembly_utilities.unary_unary_inline(service)
+      implementations[name] = face_utilities.unary_unary_inline(service)
     elif cardinality is interfaces.Cardinality.UNARY_STREAM:
       def service(
           request, face_rpc_context,
           service_behavior=method_description.service_unary_stream):
         return service_behavior(
             request, _reexport.rpc_context(face_rpc_context))
-      implementations[name] = assembly_utilities.unary_stream_inline(service)
+      implementations[name] = face_utilities.unary_stream_inline(service)
     elif cardinality is interfaces.Cardinality.STREAM_UNARY:
       def service(
           request_iterator, face_rpc_context,
           service_behavior=method_description.service_stream_unary):
         return service_behavior(
             request_iterator, _reexport.rpc_context(face_rpc_context))
-      implementations[name] = assembly_utilities.stream_unary_inline(service)
+      implementations[name] = face_utilities.stream_unary_inline(service)
     elif cardinality is interfaces.Cardinality.STREAM_STREAM:
       def service(
           request_iterator, face_rpc_context,
           service_behavior=method_description.service_stream_stream):
         return service_behavior(
             request_iterator, _reexport.rpc_context(face_rpc_context))
-      implementations[name] = assembly_utilities.stream_stream_inline(service)
+      implementations[name] = face_utilities.stream_stream_inline(service)
     request_deserializers[name] = method_description.deserialize_request
     response_serializers[name] = method_description.serialize_response
 
diff --git a/src/python/src/grpc/early_adopter/_reexport.py b/src/python/src/grpc/early_adopter/_reexport.py
index 35f4e85a7287bf94d88be6230a829d953a5a4ea0..3fed8099f6f5dc41062f1624f80778da1f946d4e 100644
--- a/src/python/src/grpc/early_adopter/_reexport.py
+++ b/src/python/src/grpc/early_adopter/_reexport.py
@@ -27,12 +27,20 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+from grpc.framework.common import cardinality
 from grpc.framework.face import exceptions as face_exceptions
 from grpc.framework.face import interfaces as face_interfaces
 from grpc.framework.foundation import future
 from grpc.early_adopter import exceptions
 from grpc.early_adopter import interfaces
 
+_EARLY_ADOPTER_CARDINALITY_TO_COMMON_CARDINALITY = {
+    interfaces.Cardinality.UNARY_UNARY: cardinality.Cardinality.UNARY_UNARY,
+    interfaces.Cardinality.UNARY_STREAM: cardinality.Cardinality.UNARY_STREAM,
+    interfaces.Cardinality.STREAM_UNARY: cardinality.Cardinality.STREAM_UNARY,
+    interfaces.Cardinality.STREAM_STREAM: cardinality.Cardinality.STREAM_STREAM,
+}
+
 _ABORTION_REEXPORT = {
     face_interfaces.Abortion.CANCELLED: interfaces.Abortion.CANCELLED,
     face_interfaces.Abortion.EXPIRED: interfaces.Abortion.EXPIRED,
@@ -142,28 +150,28 @@ class _RpcContext(interfaces.RpcContext):
 
 class _UnaryUnarySyncAsync(interfaces.UnaryUnarySyncAsync):
 
-  def __init__(self, face_unary_unary_sync_async):
-    self._underlying = face_unary_unary_sync_async
+  def __init__(self, face_unary_unary_multi_callable):
+    self._underlying = face_unary_unary_multi_callable
 
   def __call__(self, request, timeout):
     return _call_reexporting_errors(
         self._underlying, request, timeout)
 
   def async(self, request, timeout):
-    return _ReexportedFuture(self._underlying.async(request, timeout))
+    return _ReexportedFuture(self._underlying.future(request, timeout))
 
 
 class _StreamUnarySyncAsync(interfaces.StreamUnarySyncAsync):
 
-  def __init__(self, face_stream_unary_sync_async):
-    self._underlying = face_stream_unary_sync_async
+  def __init__(self, face_stream_unary_multi_callable):
+    self._underlying = face_stream_unary_multi_callable
 
   def __call__(self, request_iterator, timeout):
     return _call_reexporting_errors(
         self._underlying, request_iterator, timeout)
 
   def async(self, request_iterator, timeout):
-    return _ReexportedFuture(self._underlying.async(request_iterator, timeout))
+    return _ReexportedFuture(self._underlying.future(request_iterator, timeout))
 
 
 class _Stub(interfaces.Stub):
@@ -182,31 +190,40 @@ class _Stub(interfaces.Stub):
 
   def __getattr__(self, attr):
     underlying_attr = self._assembly_stub.__getattr__(attr)
-    cardinality = self._cardinalities.get(attr)
+    method_cardinality = self._cardinalities.get(attr)
     # TODO(nathaniel): unify this trick with its other occurrence in the code.
-    if cardinality is None:
-      for name, cardinality in self._cardinalities.iteritems():
+    if method_cardinality is None:
+      for name, method_cardinality in self._cardinalities.iteritems():
         last_slash_index = name.rfind('/')
         if 0 <= last_slash_index and name[last_slash_index + 1:] == attr:
           break
       else:
         raise AttributeError(attr)
-    if cardinality is interfaces.Cardinality.UNARY_UNARY:
+    if method_cardinality is interfaces.Cardinality.UNARY_UNARY:
       return _UnaryUnarySyncAsync(underlying_attr)
-    elif cardinality is interfaces.Cardinality.UNARY_STREAM:
+    elif method_cardinality is interfaces.Cardinality.UNARY_STREAM:
       return lambda request, timeout: _CancellableIterator(
           underlying_attr(request, timeout))
-    elif cardinality is interfaces.Cardinality.STREAM_UNARY:
+    elif method_cardinality is interfaces.Cardinality.STREAM_UNARY:
       return _StreamUnarySyncAsync(underlying_attr)
-    elif cardinality is interfaces.Cardinality.STREAM_STREAM:
+    elif method_cardinality is interfaces.Cardinality.STREAM_STREAM:
       return lambda request_iterator, timeout: _CancellableIterator(
           underlying_attr(request_iterator, timeout))
     else:
       raise AttributeError(attr)
 
+
+def common_cardinalities(early_adopter_cardinalities):
+  common_cardinalities = {}
+  for name, early_adopter_cardinality in early_adopter_cardinalities.iteritems():
+    common_cardinalities[name] = _EARLY_ADOPTER_CARDINALITY_TO_COMMON_CARDINALITY[
+        early_adopter_cardinality]
+  return common_cardinalities
+
+
 def rpc_context(face_rpc_context):
   return _RpcContext(face_rpc_context)
 
 
-def stub(assembly_stub, cardinalities):
-  return _Stub(assembly_stub, cardinalities)
+def stub(face_stub, cardinalities):
+  return _Stub(face_stub, cardinalities)
diff --git a/src/python/src/grpc/early_adopter/implementations.py b/src/python/src/grpc/early_adopter/implementations.py
index 619595862400bd731b52b915704ae3321dd01447..b46f94e9fbfbfaea92c090584391403d8c6dc8a6 100644
--- a/src/python/src/grpc/early_adopter/implementations.py
+++ b/src/python/src/grpc/early_adopter/implementations.py
@@ -33,7 +33,7 @@ import threading
 
 from grpc._adapter import fore as _fore
 from grpc._adapter import rear as _rear
-from grpc.early_adopter import _assembly_utilities
+from grpc.early_adopter import _face_utilities
 from grpc.early_adopter import _reexport
 from grpc.early_adopter import interfaces
 from grpc.framework.assembly import implementations as _assembly_implementations
@@ -95,12 +95,13 @@ class _Server(interfaces.Server):
 
 def _build_stub(breakdown, activated_rear_link):
   assembly_stub = _assembly_implementations.assemble_dynamic_inline_stub(
-      breakdown.implementations, activated_rear_link)
+      _reexport.common_cardinalities(breakdown.cardinalities),
+      activated_rear_link)
   return _reexport.stub(assembly_stub, breakdown.cardinalities)
 
 
 def _build_server(methods, port, private_key, certificate_chain):
-  breakdown = _assembly_utilities.break_down_service(methods)
+  breakdown = _face_utilities.break_down_service(methods)
   return _Server(breakdown, port, private_key, certificate_chain)
 
 
@@ -117,7 +118,7 @@ def insecure_stub(methods, host, port):
   Returns:
     An interfaces.Stub affording RPC invocation.
   """
-  breakdown = _assembly_utilities.break_down_invocation(methods)
+  breakdown = _face_utilities.break_down_invocation(methods)
   activated_rear_link = _rear.activated_rear_link(
       host, port, breakdown.request_serializers,
       breakdown.response_deserializers)
@@ -125,7 +126,8 @@ def insecure_stub(methods, host, port):
 
 
 def secure_stub(
-    methods, host, port, root_certificates, private_key, certificate_chain):
+    methods, host, port, root_certificates, private_key, certificate_chain,
+    server_host_override=None):
   """Constructs an insecure interfaces.Stub.
 
   Args:
@@ -140,15 +142,17 @@ def secure_stub(
       should be used.
     certificate_chain: The PEM-encoded certificate chain to use or None if no
       certificate chain should be used.
+    server_host_override: (For testing only) the target name used for SSL
+      host name checking.
 
   Returns:
     An interfaces.Stub affording RPC invocation.
   """
-  breakdown = _assembly_utilities.break_down_invocation(methods)
+  breakdown = _face_utilities.break_down_invocation(methods)
   activated_rear_link = _rear.secure_activated_rear_link(
       host, port, breakdown.request_serializers,
       breakdown.response_deserializers, root_certificates, private_key,
-      certificate_chain)
+      certificate_chain, server_host_override=server_host_override)
   return _build_stub(breakdown, activated_rear_link)
 
 
diff --git a/src/python/src/grpc/framework/assembly/implementations.py b/src/python/src/grpc/framework/assembly/implementations.py
index f7166ed99d1178bc1af8dfbf95b904d906ba4586..24afcbeb6d6c84d7d1831044b937ee18f08ba49c 100644
--- a/src/python/src/grpc/framework/assembly/implementations.py
+++ b/src/python/src/grpc/framework/assembly/implementations.py
@@ -66,7 +66,7 @@ class _FaceStub(object):
       self._rear_link.start()
       self._rear_link.join_fore_link(self._front)
       self._front.join_rear_link(self._rear_link)
-      self._under_stub = face_implementations.stub(self._front, self._pool)
+      self._under_stub = face_implementations.generic_stub(self._front, self._pool)
 
   def __exit__(self, exc_type, exc_val, exc_tb):
     with self._lock:
@@ -86,18 +86,18 @@ class _FaceStub(object):
         return getattr(self._under_stub, attr)
 
 
-def _behaviors(implementations, front, pool):
+def _behaviors(method_cardinalities, front, pool):
   behaviors = {}
-  stub = face_implementations.stub(front, pool)
-  for name, implementation in implementations.iteritems():
-    if implementation.cardinality is cardinality.Cardinality.UNARY_UNARY:
-      behaviors[name] = stub.unary_unary_sync_async(name)
-    elif implementation.cardinality is cardinality.Cardinality.UNARY_STREAM:
+  stub = face_implementations.generic_stub(front, pool)
+  for name, method_cardinality in method_cardinalities.iteritems():
+    if method_cardinality is cardinality.Cardinality.UNARY_UNARY:
+      behaviors[name] = stub.unary_unary_multi_callable(name)
+    elif method_cardinality is cardinality.Cardinality.UNARY_STREAM:
       behaviors[name] = lambda request, context, bound_name=name: (
           stub.inline_value_in_stream_out(bound_name, request, context))
-    elif implementation.cardinality is cardinality.Cardinality.STREAM_UNARY:
-      behaviors[name] = stub.stream_unary_sync_async(name)
-    elif implementation.cardinality is cardinality.Cardinality.STREAM_STREAM:
+    elif method_cardinality is cardinality.Cardinality.STREAM_UNARY:
+      behaviors[name] = stub.stream_unary_multi_callable(name)
+    elif method_cardinality is cardinality.Cardinality.STREAM_STREAM:
       behaviors[name] = lambda request_iterator, context, bound_name=name: (
           stub.inline_stream_in_stream_out(
               bound_name, request_iterator, context))
@@ -106,8 +106,8 @@ def _behaviors(implementations, front, pool):
 
 class _DynamicInlineStub(object):
 
-  def __init__(self, implementations, rear_link):
-    self._implementations = implementations
+  def __init__(self, cardinalities, rear_link):
+    self._cardinalities = cardinalities
     self._rear_link = rear_link
     self._lock = threading.Lock()
     self._pool = None
@@ -123,7 +123,7 @@ class _DynamicInlineStub(object):
       self._rear_link.join_fore_link(self._front)
       self._front.join_rear_link(self._rear_link)
       self._behaviors = _behaviors(
-          self._implementations, self._front, self._pool)
+          self._cardinalities, self._front, self._pool)
       return self
 
   def __exit__(self, exc_type, exc_val, exc_tb):
@@ -151,58 +151,6 @@ class _DynamicInlineStub(object):
         return behavior
 
 
-def _servicer(implementations, pool):
-  inline_value_in_value_out_methods = {}
-  inline_value_in_stream_out_methods = {}
-  inline_stream_in_value_out_methods = {}
-  inline_stream_in_stream_out_methods = {}
-  event_value_in_value_out_methods = {}
-  event_value_in_stream_out_methods = {}
-  event_stream_in_value_out_methods = {}
-  event_stream_in_stream_out_methods = {}
-
-  for name, implementation in implementations.iteritems():
-    if implementation.cardinality is cardinality.Cardinality.UNARY_UNARY:
-      if implementation.style is style.Service.INLINE:
-        inline_value_in_value_out_methods[name] = (
-            face_utilities.inline_unary_unary_method(implementation.unary_unary_inline))
-      elif implementation.style is style.Service.EVENT:
-        event_value_in_value_out_methods[name] = (
-            face_utilities.event_unary_unary_method(implementation.unary_unary_event))
-    elif implementation.cardinality is cardinality.Cardinality.UNARY_STREAM:
-      if implementation.style is style.Service.INLINE:
-        inline_value_in_stream_out_methods[name] = (
-            face_utilities.inline_unary_stream_method(implementation.unary_stream_inline))
-      elif implementation.style is style.Service.EVENT:
-        event_value_in_stream_out_methods[name] = (
-            face_utilities.event_unary_stream_method(implementation.unary_stream_event))
-    if implementation.cardinality is cardinality.Cardinality.STREAM_UNARY:
-      if implementation.style is style.Service.INLINE:
-        inline_stream_in_value_out_methods[name] = (
-            face_utilities.inline_stream_unary_method(implementation.stream_unary_inline))
-      elif implementation.style is style.Service.EVENT:
-        event_stream_in_value_out_methods[name] = (
-            face_utilities.event_stream_unary_method(implementation.stream_unary_event))
-    elif implementation.cardinality is cardinality.Cardinality.STREAM_STREAM:
-      if implementation.style is style.Service.INLINE:
-        inline_stream_in_stream_out_methods[name] = (
-            face_utilities.inline_stream_stream_method(implementation.stream_stream_inline))
-      elif implementation.style is style.Service.EVENT:
-        event_stream_in_stream_out_methods[name] = (
-            face_utilities.event_stream_stream_method(implementation.stream_stream_event))
-
-  return face_implementations.servicer(
-      pool,
-      inline_value_in_value_out_methods=inline_value_in_value_out_methods,
-      inline_value_in_stream_out_methods=inline_value_in_stream_out_methods,
-      inline_stream_in_value_out_methods=inline_stream_in_value_out_methods,
-      inline_stream_in_stream_out_methods=inline_stream_in_stream_out_methods,
-      event_value_in_value_out_methods=event_value_in_value_out_methods,
-      event_value_in_stream_out_methods=event_value_in_stream_out_methods,
-      event_stream_in_value_out_methods=event_stream_in_value_out_methods,
-      event_stream_in_stream_out_methods=event_stream_in_stream_out_methods)
-
-
 class _ServiceAssembly(interfaces.Server):
 
   def __init__(self, implementations, fore_link):
@@ -215,7 +163,8 @@ class _ServiceAssembly(interfaces.Server):
   def _start(self):
     with self._lock:
       self._pool = logging_pool.pool(_THREAD_POOL_SIZE)
-      servicer = _servicer(self._implementations, self._pool)
+      servicer = face_implementations.servicer(
+          self._pool, self._implementations, None)
       self._back = tickets_implementations.back(
           servicer, self._pool, self._pool, self._pool, _ONE_DAY_IN_SECONDS,
           _ONE_DAY_IN_SECONDS)
@@ -251,7 +200,7 @@ class _ServiceAssembly(interfaces.Server):
 
 
 def assemble_face_stub(activated_rear_link):
-  """Assembles a face_interfaces.Stub.
+  """Assembles a face_interfaces.GenericStub.
 
   The returned object is a context manager and may only be used in context to
   invoke RPCs.
@@ -262,12 +211,12 @@ def assemble_face_stub(activated_rear_link):
       when passed to this method.
 
   Returns:
-    A face_interfaces.Stub on which, in context, RPCs can be invoked.
+    A face_interfaces.GenericStub on which, in context, RPCs can be invoked.
   """
   return _FaceStub(activated_rear_link)
 
 
-def assemble_dynamic_inline_stub(implementations, activated_rear_link):
+def assemble_dynamic_inline_stub(cardinalities, activated_rear_link):
   """Assembles a stub with method names for attributes.
 
   The returned object is a context manager and may only be used in context to
@@ -276,29 +225,27 @@ def assemble_dynamic_inline_stub(implementations, activated_rear_link):
   The returned object, when used in context, will respond to attribute access
   as follows: if the requested attribute is the name of a unary-unary RPC
   method, the value of the attribute will be a
-  face_interfaces.UnaryUnarySyncAsync with which to invoke the RPC method. If
-  the requested attribute is the name of a unary-stream RPC method, the value
-  of the attribute will be a callable with the semantics of
-  face_interfaces.Stub.inline_value_in_stream_out, minus the "name" parameter,
+  face_interfaces.UnaryUnaryMultiCallable with which to invoke the RPC method.
+  If the requested attribute is the name of a unary-stream RPC method, the
+  value of the attribute will be a face_interfaces.UnaryStreamMultiCallable
   with which to invoke the RPC method. If the requested attribute is the name
   of a stream-unary RPC method, the value of the attribute will be a
-  face_interfaces.StreamUnarySyncAsync with which to invoke the RPC method. If
-  the requested attribute is the name of a stream-stream RPC method, the value
-  of the attribute will be a callable with the semantics of
-  face_interfaces.Stub.inline_stream_in_stream_out, minus the "name" parameter,
+  face_interfaces.StreamUnaryMultiCallable with which to invoke the RPC method.
+  If the requested attribute is the name of a stream-stream RPC method, the
+  value of the attribute will be a face_interfaces.StreamStreamMultiCallable
   with which to invoke the RPC method.
 
   Args:
-    implementations: A dictionary from RPC method name to
-      interfaces.MethodImplementation.
+    cardinalities: A dictionary from RPC method name to cardinality.Cardinality
+      value identifying the cardinality of the named RPC method.
     activated_rear_link: An object that is both a tickets_interfaces.RearLink
       and an activated.Activated. The object should be in the inactive state
       when passed to this method.
 
   Returns:
-    A stub on which, in context, RPCs can be invoked.
+    A face_interfaces.DynamicStub on which, in context, RPCs can be invoked.
   """
-  return _DynamicInlineStub(implementations, activated_rear_link)
+  return _DynamicInlineStub(cardinalities, activated_rear_link)
 
 
 def assemble_service(implementations, activated_fore_link):
@@ -306,7 +253,7 @@ def assemble_service(implementations, activated_fore_link):
 
   Args:
     implementations: A dictionary from RPC method name to
-      interfaces.MethodImplementation.
+      face_interfaces.MethodImplementation.
     activated_fore_link: An object that is both a tickets_interfaces.ForeLink
       and an activated.Activated. The object should be in the inactive state
       when passed to this method.
diff --git a/src/python/src/grpc/framework/assembly/implementations_test.py b/src/python/src/grpc/framework/assembly/implementations_test.py
index 74dc02ed83ddba887111be86668e193f8c1ea638..5540edff7ad38127907933d0d19501a14ea0fd3c 100644
--- a/src/python/src/grpc/framework/assembly/implementations_test.py
+++ b/src/python/src/grpc/framework/assembly/implementations_test.py
@@ -35,11 +35,11 @@ import threading
 import unittest
 
 from grpc.framework.assembly import implementations
-from grpc.framework.assembly import utilities
 from grpc.framework.base import interfaces
 from grpc.framework.base.packets import packets as tickets
 from grpc.framework.base.packets import interfaces as tickets_interfaces
 from grpc.framework.base.packets import null
+from grpc.framework.face import utilities as face_utilities
 from grpc.framework.foundation import logging_pool
 from grpc._junkdrawer import math_pb2
 
@@ -81,12 +81,16 @@ def _sum(request_iterator, unused_context):
 
 
 _IMPLEMENTATIONS = {
-    DIV: utilities.unary_unary_inline(_div),
-    DIV_MANY: utilities.stream_stream_inline(_div_many),
-    FIB: utilities.unary_stream_inline(_fib),
-    SUM: utilities.stream_unary_inline(_sum),
+    DIV: face_utilities.unary_unary_inline(_div),
+    DIV_MANY: face_utilities.stream_stream_inline(_div_many),
+    FIB: face_utilities.unary_stream_inline(_fib),
+    SUM: face_utilities.stream_unary_inline(_sum),
 }
 
+_CARDINALITIES = {
+    name: implementation.cardinality
+    for name, implementation in _IMPLEMENTATIONS.iteritems()}
+
 _TIMEOUT = 10
 
 
@@ -170,8 +174,8 @@ class FaceStubTest(unittest.TestCase):
     face_stub = implementations.assemble_face_stub(pipe)
 
     with service, face_stub:
-      sync_async = face_stub.stream_unary_sync_async(SUM)
-      response_future = sync_async.async(
+      multi_callable = face_stub.stream_unary_multi_callable(SUM)
+      response_future = multi_callable.future(
           (math_pb2.Num(num=index) for index in range(stream_length)),
           _TIMEOUT)
       self.assertEqual(
@@ -214,7 +218,7 @@ class DynamicInlineStubTest(unittest.TestCase):
     pipe = PipeLink()
     service = implementations.assemble_service(_IMPLEMENTATIONS, pipe)
     dynamic_stub = implementations.assemble_dynamic_inline_stub(
-        _IMPLEMENTATIONS, pipe)
+        _CARDINALITIES, pipe)
 
     service.start()
     with dynamic_stub:
@@ -229,7 +233,7 @@ class DynamicInlineStubTest(unittest.TestCase):
     pipe = PipeLink()
     service = implementations.assemble_service(_IMPLEMENTATIONS, pipe)
     dynamic_stub = implementations.assemble_dynamic_inline_stub(
-        _IMPLEMENTATIONS, pipe)
+        _CARDINALITIES, pipe)
 
     with service, dynamic_stub:
       response_iterator = dynamic_stub.Fib(
@@ -244,10 +248,10 @@ class DynamicInlineStubTest(unittest.TestCase):
     pipe = PipeLink()
     service = implementations.assemble_service(_IMPLEMENTATIONS, pipe)
     dynamic_stub = implementations.assemble_dynamic_inline_stub(
-        _IMPLEMENTATIONS, pipe)
+        _CARDINALITIES, pipe)
 
     with service, dynamic_stub:
-      response_future = dynamic_stub.Sum.async(
+      response_future = dynamic_stub.Sum.future(
           (math_pb2.Num(num=index) for index in range(stream_length)),
           _TIMEOUT)
       self.assertEqual(
@@ -261,7 +265,7 @@ class DynamicInlineStubTest(unittest.TestCase):
     pipe = PipeLink()
     service = implementations.assemble_service(_IMPLEMENTATIONS, pipe)
     dynamic_stub = implementations.assemble_dynamic_inline_stub(
-        _IMPLEMENTATIONS, pipe)
+        _CARDINALITIES, pipe)
 
     with service, dynamic_stub:
       response_iterator = dynamic_stub.DivMany(
diff --git a/src/python/src/grpc/framework/assembly/interfaces.py b/src/python/src/grpc/framework/assembly/interfaces.py
index d1a6aad29e767e07f03795c6b3bc2f6abaab666e..c469dc4fd2b10cf94cd60b1f36f65b8517cd2fad 100644
--- a/src/python/src/grpc/framework/assembly/interfaces.py
+++ b/src/python/src/grpc/framework/assembly/interfaces.py
@@ -33,63 +33,7 @@
 
 import abc
 
-# cardinality, style, and stream are referenced from specification in this
-# module.
-from grpc.framework.common import cardinality  # pylint: disable=unused-import
-from grpc.framework.common import style  # pylint: disable=unused-import
 from grpc.framework.foundation import activated
-from grpc.framework.foundation import stream  # pylint: disable=unused-import
-
-
-class MethodImplementation(object):
-  """A sum type that describes an RPC method implementation.
-
-  Attributes:
-    cardinality: A cardinality.Cardinality value.
-    style: A style.Service value.
-    unary_unary_inline: The implementation of the RPC method as a callable
-      value that takes a request value and a face_interfaces.RpcContext object
-      and returns a response value. Only non-None if cardinality is
-      cardinality.Cardinality.UNARY_UNARY and style is style.Service.INLINE.
-    unary_stream_inline: The implementation of the RPC method as a callable
-      value that takes a request value and a face_interfaces.RpcContext object
-      and returns an iterator of response values. Only non-None if cardinality
-      is cardinality.Cardinality.UNARY_STREAM and style is
-      style.Service.INLINE.
-    stream_unary_inline: The implementation of the RPC method as a callable
-      value that takes an iterator of request values and a
-      face_interfaces.RpcContext object and returns a response value. Only
-      non-None if cardinality is cardinality.Cardinality.STREAM_UNARY and style
-      is style.Service.INLINE.
-    stream_stream_inline: The implementation of the RPC method as a callable
-      value that takes an iterator of request values and a
-      face_interfaces.RpcContext object and returns an iterator of response
-      values. Only non-None if cardinality is
-      cardinality.Cardinality.STREAM_STREAM and style is style.Service.INLINE.
-    unary_unary_event: The implementation of the RPC method as a callable value
-      that takes a request value, a response callback to which to pass the
-      response value of the RPC, and a face_interfaces.RpcContext. Only
-      non-None if cardinality is cardinality.Cardinality.UNARY_UNARY and style
-      is style.Service.EVENT.
-    unary_stream_event: The implementation of the RPC method as a callable
-      value that takes a request value, a stream.Consumer to which to pass the
-      the response values of the RPC, and a face_interfaces.RpcContext. Only
-      non-None if cardinality is cardinality.Cardinality.UNARY_STREAM and style
-      is style.Service.EVENT.
-    stream_unary_event: The implementation of the RPC method as a callable
-      value that takes a response callback to which to pass the response value
-      of the RPC and a face_interfaces.RpcContext and returns a stream.Consumer
-      to which the request values of the RPC should be passed. Only non-None if
-      cardinality is cardinality.Cardinality.STREAM_UNARY and style is
-      style.Service.EVENT.
-    stream_stream_event: The implementation of the RPC method as a callable
-      value that takes a stream.Consumer to which to pass the response values
-      of the RPC and a face_interfaces.RpcContext and returns a stream.Consumer
-      to which the request values of the RPC should be passed. Only non-None if
-      cardinality is cardinality.Cardinality.STREAM_STREAM and style is
-      style.Service.EVENT.
-  """
-  __metaclass__ = abc.ABCMeta
 
 
 class Server(activated.Activated):
diff --git a/src/python/src/grpc/framework/assembly/utilities.py b/src/python/src/grpc/framework/assembly/utilities.py
deleted file mode 100644
index 80e7f59c03c5f8b49696f2fffefe2827b2803f86..0000000000000000000000000000000000000000
--- a/src/python/src/grpc/framework/assembly/utilities.py
+++ /dev/null
@@ -1,179 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-"""Utilities for assembling RPC framework values."""
-
-import collections
-
-from grpc.framework.assembly import interfaces
-from grpc.framework.common import cardinality
-from grpc.framework.common import style
-from grpc.framework.face import interfaces as face_interfaces
-from grpc.framework.foundation import stream
-
-
-class _MethodImplementation(
-    interfaces.MethodImplementation,
-    collections.namedtuple(
-        '_MethodImplementation',
-        ['cardinality', 'style', 'unary_unary_inline', 'unary_stream_inline',
-         'stream_unary_inline', 'stream_stream_inline', 'unary_unary_event',
-         'unary_stream_event', 'stream_unary_event', 'stream_stream_event',])):
-  pass
-
-
-def unary_unary_inline(behavior):
-  """Creates an interfaces.MethodImplementation for the given behavior.
-
-  Args:
-    behavior: The implementation of a unary-unary RPC method as a callable value
-      that takes a request value and a face_interfaces.RpcContext object and
-      returns a response value.
-
-  Returns:
-    An interfaces.MethodImplementation derived from the given behavior.
-  """
-  return _MethodImplementation(
-      cardinality.Cardinality.UNARY_UNARY, style.Service.INLINE, behavior,
-      None, None, None, None, None, None, None)
-
-
-def unary_stream_inline(behavior):
-  """Creates an interfaces.MethodImplementation for the given behavior.
-
-  Args:
-    behavior: The implementation of a unary-stream RPC method as a callable
-      value that takes a request value and a face_interfaces.RpcContext object
-      and returns an iterator of response values.
-
-  Returns:
-    An interfaces.MethodImplementation derived from the given behavior.
-  """
-  return _MethodImplementation(
-      cardinality.Cardinality.UNARY_STREAM, style.Service.INLINE, None,
-      behavior, None, None, None, None, None, None)
-
-
-def stream_unary_inline(behavior):
-  """Creates an interfaces.MethodImplementation for the given behavior.
-
-  Args:
-    behavior: The implementation of a stream-unary RPC method as a callable
-      value that takes an iterator of request values and a
-      face_interfaces.RpcContext object and returns a response value.
-
-  Returns:
-    An interfaces.MethodImplementation derived from the given behavior.
-  """
-  return _MethodImplementation(
-      cardinality.Cardinality.STREAM_UNARY, style.Service.INLINE, None, None,
-      behavior, None, None, None, None, None)
-
-
-def stream_stream_inline(behavior):
-  """Creates an interfaces.MethodImplementation for the given behavior.
-
-  Args:
-    behavior: The implementation of a stream-stream RPC method as a callable
-      value that takes an iterator of request values and a
-      face_interfaces.RpcContext object and returns an iterator of response
-      values.
-
-  Returns:
-    An interfaces.MethodImplementation derived from the given behavior.
-  """
-  return _MethodImplementation(
-      cardinality.Cardinality.STREAM_STREAM, style.Service.INLINE, None, None,
-      None, behavior, None, None, None, None)
-
-
-def unary_unary_event(behavior):
-  """Creates an interfaces.MethodImplementation for the given behavior.
-
-  Args:
-    behavior: The implementation of a unary-unary RPC method as a callable
-      value that takes a request value, a response callback to which to pass
-      the response value of the RPC, and a face_interfaces.RpcContext.
-
-  Returns:
-    An interfaces.MethodImplementation derived from the given behavior.
-  """
-  return _MethodImplementation(
-      cardinality.Cardinality.UNARY_UNARY, style.Service.EVENT, None, None,
-      None, None, behavior, None, None, None)
-
-
-def unary_stream_event(behavior):
-  """Creates an interfaces.MethodImplementation for the given behavior.
-
-  Args:
-    behavior: The implementation of a unary-stream RPC method as a callable
-      value that takes a request value, a stream.Consumer to which to pass the
-      the response values of the RPC, and a face_interfaces.RpcContext.
-
-  Returns:
-    An interfaces.MethodImplementation derived from the given behavior.
-  """
-  return _MethodImplementation(
-      cardinality.Cardinality.UNARY_STREAM, style.Service.EVENT, None, None,
-      None, None, None, behavior, None, None)
-
-
-def stream_unary_event(behavior):
-  """Creates an interfaces.MethodImplementation for the given behavior.
-
-  Args:
-    behavior: The implementation of a stream-unary RPC method as a callable
-      value that takes a response callback to which to pass the response value
-      of the RPC and a face_interfaces.RpcContext and returns a stream.Consumer
-      to which the request values of the RPC should be passed.
-
-  Returns:
-    An interfaces.MethodImplementation derived from the given behavior.
-  """
-  return _MethodImplementation(
-      cardinality.Cardinality.STREAM_UNARY, style.Service.EVENT, None, None,
-      None, None, None, None, behavior, None)
-
-
-def stream_stream_event(behavior):
-  """Creates an interfaces.MethodImplementation for the given behavior.
-
-  Args:
-    behavior: The implementation of a stream-stream RPC method as a callable
-      value that takes a stream.Consumer to which to pass the response values
-      of the RPC and a face_interfaces.RpcContext and returns a stream.Consumer
-      to which the request values of the RPC should be passed.
-
-  Returns:
-    An interfaces.MethodImplementation derived from the given behavior.
-  """
-  return _MethodImplementation(
-      cardinality.Cardinality.STREAM_STREAM, style.Service.EVENT, None, None,
-      None, None, None, None, None, behavior)
diff --git a/src/python/src/grpc/framework/face/_service.py b/src/python/src/grpc/framework/face/_service.py
index 26bde129687a5b48b6bb7ad849665b10ab19e722..cdf413356ad716e33bd45cdc9accda28202d50a6 100644
--- a/src/python/src/grpc/framework/face/_service.py
+++ b/src/python/src/grpc/framework/face/_service.py
@@ -105,15 +105,14 @@ def adapt_inline_value_in_value_out(method):
   def adaptation(response_consumer, operation_context):
     rpc_context = _control.RpcContext(operation_context)
     return stream_util.TransformingConsumer(
-        lambda request: method.service(request, rpc_context), response_consumer)
+        lambda request: method(request, rpc_context), response_consumer)
   return adaptation
 
 
 def adapt_inline_value_in_stream_out(method):
   def adaptation(response_consumer, operation_context):
     rpc_context = _control.RpcContext(operation_context)
-    return _ValueInStreamOutConsumer(
-        method.service, rpc_context, response_consumer)
+    return _ValueInStreamOutConsumer(method, rpc_context, response_consumer)
   return adaptation
 
 
@@ -123,7 +122,7 @@ def adapt_inline_stream_in_value_out(method, pool):
     operation_context.add_termination_callback(rendezvous.set_outcome)
     def in_pool_thread():
       response_consumer.consume_and_terminate(
-          method.service(rendezvous, _control.RpcContext(operation_context)))
+          method(rendezvous, _control.RpcContext(operation_context)))
     pool.submit(_pool_wrap(in_pool_thread, operation_context))
     return rendezvous
   return adaptation
@@ -149,7 +148,7 @@ def adapt_inline_stream_in_stream_out(method, pool):
     operation_context.add_termination_callback(rendezvous.set_outcome)
     def in_pool_thread():
       _control.pipe_iterator_to_consumer(
-          method.service(rendezvous, _control.RpcContext(operation_context)),
+          method(rendezvous, _control.RpcContext(operation_context)),
           response_consumer, operation_context.is_active, True)
     pool.submit(_pool_wrap(in_pool_thread, operation_context))
     return rendezvous
@@ -159,7 +158,7 @@ def adapt_inline_stream_in_stream_out(method, pool):
 def adapt_event_value_in_value_out(method):
   def adaptation(response_consumer, operation_context):
     def on_payload(payload):
-      method.service(
+      method(
           payload, response_consumer.consume_and_terminate,
           _control.RpcContext(operation_context))
     return _control.UnaryConsumer(on_payload)
@@ -169,7 +168,7 @@ def adapt_event_value_in_value_out(method):
 def adapt_event_value_in_stream_out(method):
   def adaptation(response_consumer, operation_context):
     def on_payload(payload):
-      method.service(
+      method(
           payload, response_consumer, _control.RpcContext(operation_context))
     return _control.UnaryConsumer(on_payload)
   return adaptation
@@ -178,12 +177,11 @@ def adapt_event_value_in_stream_out(method):
 def adapt_event_stream_in_value_out(method):
   def adaptation(response_consumer, operation_context):
     rpc_context = _control.RpcContext(operation_context)
-    return method.service(response_consumer.consume_and_terminate, rpc_context)
+    return method(response_consumer.consume_and_terminate, rpc_context)
   return adaptation
 
 
 def adapt_event_stream_in_stream_out(method):
   def adaptation(response_consumer, operation_context):
-    return method.service(
-        response_consumer, _control.RpcContext(operation_context))
+    return method(response_consumer, _control.RpcContext(operation_context))
   return adaptation
diff --git a/src/python/src/grpc/framework/face/_test_case.py b/src/python/src/grpc/framework/face/_test_case.py
index a4e17c464ce75bcca7e81f792aa34a2022f3e12d..b3a012db001ef44046ff13ee6247129f1bf7a62f 100644
--- a/src/python/src/grpc/framework/face/_test_case.py
+++ b/src/python/src/grpc/framework/face/_test_case.py
@@ -42,37 +42,17 @@ class FaceTestCase(test_case.FaceTestCase):
   """Provides abstract Face-layer tests an in-memory implementation."""
 
   def set_up_implementation(
-      self,
-      name,
-      methods,
-      inline_value_in_value_out_methods,
-      inline_value_in_stream_out_methods,
-      inline_stream_in_value_out_methods,
-      inline_stream_in_stream_out_methods,
-      event_value_in_value_out_methods,
-      event_value_in_stream_out_methods,
-      event_stream_in_value_out_methods,
-      event_stream_in_stream_out_methods,
-      multi_method):
+      self, name, methods, method_implementations,
+      multi_method_implementation):
     servicer_pool = logging_pool.pool(_MAXIMUM_POOL_SIZE)
     stub_pool = logging_pool.pool(_MAXIMUM_POOL_SIZE)
 
     servicer = implementations.servicer(
-        servicer_pool,
-        inline_value_in_value_out_methods=inline_value_in_value_out_methods,
-        inline_value_in_stream_out_methods=inline_value_in_stream_out_methods,
-        inline_stream_in_value_out_methods=inline_stream_in_value_out_methods,
-        inline_stream_in_stream_out_methods=inline_stream_in_stream_out_methods,
-        event_value_in_value_out_methods=event_value_in_value_out_methods,
-        event_value_in_stream_out_methods=event_value_in_stream_out_methods,
-        event_stream_in_value_out_methods=event_stream_in_value_out_methods,
-        event_stream_in_stream_out_methods=event_stream_in_stream_out_methods,
-        multi_method=multi_method)
+        servicer_pool, method_implementations, multi_method_implementation)
 
     linked_pair = base_util.linked_pair(servicer, _TIMEOUT)
-    server = implementations.server()
-    stub = implementations.stub(linked_pair.front, stub_pool)
-    return server, stub, (servicer_pool, stub_pool, linked_pair)
+    stub = implementations.generic_stub(linked_pair.front, stub_pool)
+    return stub, (servicer_pool, stub_pool, linked_pair)
 
   def tear_down_implementation(self, memo):
     servicer_pool, stub_pool, linked_pair = memo
diff --git a/src/python/src/grpc/framework/face/implementations.py b/src/python/src/grpc/framework/face/implementations.py
index 86948b386faf6f8d62bbb4fc88cf7ca6bfca244e..e8d91a3c91cce1279e0c4f20d55e24058a21348b 100644
--- a/src/python/src/grpc/framework/face/implementations.py
+++ b/src/python/src/grpc/framework/face/implementations.py
@@ -29,6 +29,8 @@
 
 """Entry points into the Face layer of RPC Framework."""
 
+from grpc.framework.common import cardinality
+from grpc.framework.common import style
 from grpc.framework.base import exceptions as _base_exceptions
 from grpc.framework.base import interfaces as base_interfaces
 from grpc.framework.face import _calls
@@ -56,7 +58,7 @@ class _BaseServicer(base_interfaces.Servicer):
       raise _base_exceptions.NoSuchMethodError()
 
 
-class _UnaryUnarySyncAsync(interfaces.UnaryUnarySyncAsync):
+class _UnaryUnaryMultiCallable(interfaces.UnaryUnaryMultiCallable):
 
   def __init__(self, front, name):
     self._front = front
@@ -66,12 +68,33 @@ class _UnaryUnarySyncAsync(interfaces.UnaryUnarySyncAsync):
     return _calls.blocking_value_in_value_out(
         self._front, self._name, request, timeout, 'unused trace ID')
 
-  def async(self, request, timeout):
+  def future(self, request, timeout):
     return _calls.future_value_in_value_out(
         self._front, self._name, request, timeout, 'unused trace ID')
 
+  def event(self, request, response_callback, abortion_callback, timeout):
+    return _calls.event_value_in_value_out(
+        self._front, self._name, request, response_callback, abortion_callback,
+        timeout, 'unused trace ID')
+
+
+class _UnaryStreamMultiCallable(interfaces.UnaryStreamMultiCallable):
+
+  def __init__(self, front, name):
+    self._front = front
+    self._name = name
 
-class _StreamUnarySyncAsync(interfaces.StreamUnarySyncAsync):
+  def __call__(self, request, timeout):
+    return _calls.inline_value_in_stream_out(
+        self._front, self._name, request, timeout, 'unused trace ID')
+
+  def event(self, request, response_consumer, abortion_callback, timeout):
+    return _calls.event_value_in_stream_out(
+        self._front, self._name, request, response_consumer, abortion_callback,
+        timeout, 'unused trace ID')
+
+
+class _StreamUnaryMultiCallable(interfaces.StreamUnaryMultiCallable):
 
   def __init__(self, front, name, pool):
     self._front = front
@@ -82,18 +105,37 @@ class _StreamUnarySyncAsync(interfaces.StreamUnarySyncAsync):
     return _calls.blocking_stream_in_value_out(
         self._front, self._name, request_iterator, timeout, 'unused trace ID')
 
-  def async(self, request_iterator, timeout):
+  def future(self, request_iterator, timeout):
     return _calls.future_stream_in_value_out(
         self._front, self._name, request_iterator, timeout, 'unused trace ID',
         self._pool)
 
+  def event(self, response_callback, abortion_callback, timeout):
+    return _calls.event_stream_in_value_out(
+        self._front, self._name, response_callback, abortion_callback, timeout,
+        'unused trace ID')
 
-class _Server(interfaces.Server):
-  """An interfaces.Server implementation."""
 
+class _StreamStreamMultiCallable(interfaces.StreamStreamMultiCallable):
 
-class _Stub(interfaces.Stub):
-  """An interfaces.Stub implementation."""
+  def __init__(self, front, name, pool):
+    self._front = front
+    self._name = name
+    self._pool = pool
+
+  def __call__(self, request_iterator, timeout):
+    return _calls.inline_stream_in_stream_out(
+        self._front, self._name, request_iterator, timeout, 'unused trace ID',
+        self._pool)
+
+  def event(self, response_consumer, abortion_callback, timeout):
+    return _calls.event_stream_in_stream_out(
+        self._front, self._name, response_consumer, abortion_callback, timeout,
+        'unused trace ID')
+
+
+class _GenericStub(interfaces.GenericStub):
+  """An interfaces.GenericStub implementation."""
 
   def __init__(self, front, pool):
     self._front = front
@@ -149,136 +191,128 @@ class _Stub(interfaces.Stub):
         self._front, name, response_consumer, abortion_callback, timeout,
         'unused trace ID')
 
-  def unary_unary_sync_async(self, name):
-    return _UnaryUnarySyncAsync(self._front, name)
-
-  def stream_unary_sync_async(self, name):
-    return _StreamUnarySyncAsync(self._front, name, self._pool)
-
-
-def _aggregate_methods(
-    pool,
-    inline_value_in_value_out_methods,
-    inline_value_in_stream_out_methods,
-    inline_stream_in_value_out_methods,
-    inline_stream_in_stream_out_methods,
-    event_value_in_value_out_methods,
-    event_value_in_stream_out_methods,
-    event_stream_in_value_out_methods,
-    event_stream_in_stream_out_methods):
-  """Aggregates methods coded in according to different interfaces."""
-  methods = {}
-
-  def adapt_unpooled_methods(adapted_methods, unadapted_methods, adaptation):
-    if unadapted_methods is not None:
-      for name, unadapted_method in unadapted_methods.iteritems():
-        adapted_methods[name] = adaptation(unadapted_method)
-
-  def adapt_pooled_methods(adapted_methods, unadapted_methods, adaptation):
-    if unadapted_methods is not None:
-      for name, unadapted_method in unadapted_methods.iteritems():
-        adapted_methods[name] = adaptation(unadapted_method, pool)
-
-  adapt_unpooled_methods(
-      methods, inline_value_in_value_out_methods,
-      _service.adapt_inline_value_in_value_out)
-  adapt_unpooled_methods(
-      methods, inline_value_in_stream_out_methods,
-      _service.adapt_inline_value_in_stream_out)
-  adapt_pooled_methods(
-      methods, inline_stream_in_value_out_methods,
-      _service.adapt_inline_stream_in_value_out)
-  adapt_pooled_methods(
-      methods, inline_stream_in_stream_out_methods,
-      _service.adapt_inline_stream_in_stream_out)
-  adapt_unpooled_methods(
-      methods, event_value_in_value_out_methods,
-      _service.adapt_event_value_in_value_out)
-  adapt_unpooled_methods(
-      methods, event_value_in_stream_out_methods,
-      _service.adapt_event_value_in_stream_out)
-  adapt_unpooled_methods(
-      methods, event_stream_in_value_out_methods,
-      _service.adapt_event_stream_in_value_out)
-  adapt_unpooled_methods(
-      methods, event_stream_in_stream_out_methods,
-      _service.adapt_event_stream_in_stream_out)
-
-  return methods
-
-
-def servicer(
-    pool,
-    inline_value_in_value_out_methods=None,
-    inline_value_in_stream_out_methods=None,
-    inline_stream_in_value_out_methods=None,
-    inline_stream_in_stream_out_methods=None,
-    event_value_in_value_out_methods=None,
-    event_value_in_stream_out_methods=None,
-    event_stream_in_value_out_methods=None,
-    event_stream_in_stream_out_methods=None,
-    multi_method=None):
+  def unary_unary_multi_callable(self, name):
+    return _UnaryUnaryMultiCallable(self._front, name)
+
+  def unary_stream_multi_callable(self, name):
+    return _UnaryStreamMultiCallable(self._front, name)
+
+  def stream_unary_multi_callable(self, name):
+    return _StreamUnaryMultiCallable(self._front, name, self._pool)
+
+  def stream_stream_multi_callable(self, name):
+    return _StreamStreamMultiCallable(self._front, name, self._pool)
+
+
+class _DynamicStub(interfaces.DynamicStub):
+  """An interfaces.DynamicStub implementation."""
+
+  def __init__(self, cardinalities, front, pool):
+    self._cardinalities = cardinalities
+    self._front = front
+    self._pool = pool
+
+  def __getattr__(self, attr):
+    cardinality = self._cardinalities.get(attr)
+    if cardinality is cardinality.Cardinality.UNARY_UNARY:
+      return _UnaryUnaryMultiCallable(self._front, attr)
+    elif cardinality is cardinality.Cardinality.UNARY_STREAM:
+      return _UnaryStreamMultiCallable(self._front, attr)
+    elif cardinality is cardinality.Cardinality.STREAM_UNARY:
+      return _StreamUnaryMultiCallable(self._front, attr, self._pool)
+    elif cardinality is cardinality.Cardinality.STREAM_STREAM:
+      return _StreamStreamMultiCallable(self._front, attr, self._pool)
+    else:
+      raise AttributeError('_DynamicStub object has no attribute "%s"!' % attr)
+
+
+def _adapt_method_implementations(method_implementations, pool):
+  adapted_implementations = {}
+  for name, method_implementation in method_implementations.iteritems():
+    if method_implementation.style is style.Service.INLINE:
+      if method_implementation.cardinality is cardinality.Cardinality.UNARY_UNARY:
+        adapted_implementations[name] = _service.adapt_inline_value_in_value_out(
+            method_implementation.unary_unary_inline)
+      elif method_implementation.cardinality is cardinality.Cardinality.UNARY_STREAM:
+        adapted_implementations[name] = _service.adapt_inline_value_in_stream_out(
+            method_implementation.unary_stream_inline)
+      elif method_implementation.cardinality is cardinality.Cardinality.STREAM_UNARY:
+        adapted_implementations[name] = _service.adapt_inline_stream_in_value_out(
+            method_implementation.stream_unary_inline, pool)
+      elif method_implementation.cardinality is cardinality.Cardinality.STREAM_STREAM:
+        adapted_implementations[name] = _service.adapt_inline_stream_in_stream_out(
+            method_implementation.stream_stream_inline, pool)
+    elif method_implementation.style is style.Service.EVENT:
+      if method_implementation.cardinality is cardinality.Cardinality.UNARY_UNARY:
+        adapted_implementations[name] = _service.adapt_event_value_in_value_out(
+            method_implementation.unary_unary_event)
+      elif method_implementation.cardinality is cardinality.Cardinality.UNARY_STREAM:
+        adapted_implementations[name] = _service.adapt_event_value_in_stream_out(
+            method_implementation.unary_stream_event)
+      elif method_implementation.cardinality is cardinality.Cardinality.STREAM_UNARY:
+        adapted_implementations[name] = _service.adapt_event_stream_in_value_out(
+            method_implementation.stream_unary_event)
+      elif method_implementation.cardinality is cardinality.Cardinality.STREAM_STREAM:
+        adapted_implementations[name] = _service.adapt_event_stream_in_stream_out(
+            method_implementation.stream_stream_event)
+  return adapted_implementations
+
+
+def servicer(pool, method_implementations, multi_method_implementation):
   """Creates a base_interfaces.Servicer.
 
-  The key sets of the passed dictionaries must be disjoint. It is guaranteed
-  that any passed MultiMethod implementation will only be called to service an
-  RPC if the RPC method name is not present in the key sets of the passed
-  dictionaries.
+  It is guaranteed that any passed interfaces.MultiMethodImplementation will
+  only be called to service an RPC if there is no
+  interfaces.MethodImplementation for the RPC method in the passed
+  method_implementations dictionary.
 
   Args:
     pool: A thread pool.
-    inline_value_in_value_out_methods: A dictionary mapping method names to
-      interfaces.InlineValueInValueOutMethod implementations.
-    inline_value_in_stream_out_methods: A dictionary mapping method names to
-      interfaces.InlineValueInStreamOutMethod implementations.
-    inline_stream_in_value_out_methods: A dictionary mapping method names to
-      interfaces.InlineStreamInValueOutMethod implementations.
-    inline_stream_in_stream_out_methods: A dictionary mapping method names to
-      interfaces.InlineStreamInStreamOutMethod implementations.
-    event_value_in_value_out_methods: A dictionary mapping method names to
-      interfaces.EventValueInValueOutMethod implementations.
-    event_value_in_stream_out_methods: A dictionary mapping method names to
-      interfaces.EventValueInStreamOutMethod implementations.
-    event_stream_in_value_out_methods: A dictionary mapping method names to
-      interfaces.EventStreamInValueOutMethod implementations.
-    event_stream_in_stream_out_methods: A dictionary mapping method names to
-      interfaces.EventStreamInStreamOutMethod implementations.
-    multi_method: An implementation of interfaces.MultiMethod.
+    method_implementations: A dictionary from RPC method name to
+      interfaces.MethodImplementation object to be used to service the named
+      RPC method.
+    multi_method_implementation: An interfaces.MultiMethodImplementation to be
+      used to service any RPCs not serviced by the
+      interfaces.MethodImplementations given in the method_implementations
+      dictionary, or None.
 
   Returns:
     A base_interfaces.Servicer that services RPCs via the given implementations.
   """
-  methods = _aggregate_methods(
-      pool,
-      inline_value_in_value_out_methods,
-      inline_value_in_stream_out_methods,
-      inline_stream_in_value_out_methods,
-      inline_stream_in_stream_out_methods,
-      event_value_in_value_out_methods,
-      event_value_in_stream_out_methods,
-      event_stream_in_value_out_methods,
-      event_stream_in_stream_out_methods)
+  adapted_implementations = _adapt_method_implementations(
+      method_implementations, pool)
+  return _BaseServicer(adapted_implementations, multi_method_implementation)
 
-  return _BaseServicer(methods, multi_method)
 
+def generic_stub(front, pool):
+  """Creates an interfaces.GenericStub.
 
-def server():
-  """Creates an interfaces.Server.
+  Args:
+    front: A base_interfaces.Front.
+    pool: A futures.ThreadPoolExecutor.
 
   Returns:
-    An interfaces.Server.
+    An interfaces.GenericStub that performs RPCs via the given
+      base_interfaces.Front.
   """
-  return _Server()
+  return _GenericStub(front, pool)
 
 
-def stub(front, pool):
-  """Creates an interfaces.Stub.
+def dynamic_stub(cardinalities, front, pool, prefix):
+  """Creates an interfaces.DynamicStub.
 
   Args:
+    cardinalities: A dict from RPC method name to cardinality.Cardinality
+      value identifying the cardinality of every RPC method to be supported by
+      the created interfaces.DynamicStub.
     front: A base_interfaces.Front.
     pool: A futures.ThreadPoolExecutor.
+    prefix: A string to prepend when mapping requested attribute name to RPC
+      method name during attribute access on the created
+      interfaces.DynamicStub.
 
   Returns:
-    An interfaces.Stub that performs RPCs via the given base_interfaces.Front.
+    An interfaces.DynamicStub that performs RPCs via the given
+      base_interfaces.Front.
   """
-  return _Stub(front, pool)
+  return _DynamicStub(cardinalities, front, pool, prefix)
diff --git a/src/python/src/grpc/framework/face/interfaces.py b/src/python/src/grpc/framework/face/interfaces.py
index 9e19106e6f342f1e93060a4ca439d9ae56c81a75..b7cc4c1169ab9e87ca29511105f8a227699c870f 100644
--- a/src/python/src/grpc/framework/face/interfaces.py
+++ b/src/python/src/grpc/framework/face/interfaces.py
@@ -32,11 +32,24 @@
 import abc
 import enum
 
-# exceptions, abandonment, and future are referenced from specification in this
-# module.
+# cardinality, style, exceptions, abandonment, future, and stream are
+# referenced from specification in this module.
+from grpc.framework.common import cardinality  # pylint: disable=unused-import
+from grpc.framework.common import style  # pylint: disable=unused-import
 from grpc.framework.face import exceptions  # pylint: disable=unused-import
 from grpc.framework.foundation import abandonment  # pylint: disable=unused-import
 from grpc.framework.foundation import future  # pylint: disable=unused-import
+from grpc.framework.foundation import stream  # pylint: disable=unused-import
+
+
+@enum.unique
+class Abortion(enum.Enum):
+  """Categories of RPC abortion."""
+  CANCELLED = 'cancelled'
+  EXPIRED = 'expired'
+  NETWORK_FAILURE = 'network failure'
+  SERVICED_FAILURE = 'serviced failure'
+  SERVICER_FAILURE = 'servicer failure'
 
 
 class CancellableIterator(object):
@@ -59,69 +72,61 @@ class CancellableIterator(object):
     raise NotImplementedError()
 
 
-class UnaryUnarySyncAsync(object):
-  """Affords invoking a unary-unary RPC synchronously or asynchronously.
-
-  Values implementing this interface are directly callable and present an
-  "async" method. Both calls take a request value and a numeric timeout.
-  Direct invocation of a value of this type invokes its associated RPC and
-  blocks until the RPC's response is available. Calling the "async" method
-  of a value of this type invokes its associated RPC and immediately returns a
-  future.Future bound to the asynchronous execution of the RPC.
-  """
+class RpcContext(object):
+  """Provides RPC-related information and action."""
   __metaclass__ = abc.ABCMeta
 
   @abc.abstractmethod
-  def __call__(self, request, timeout):
-    """Synchronously invokes the underlying RPC.
+  def is_active(self):
+    """Describes whether the RPC is active or has terminated."""
+    raise NotImplementedError()
 
-    Args:
-      request: The request value for the RPC.
-      timeout: A duration of time in seconds to allow for the RPC.
+  @abc.abstractmethod
+  def time_remaining(self):
+    """Describes the length of allowed time remaining for the RPC.
 
     Returns:
-      The response value for the RPC.
-
-    Raises:
-      exceptions.RpcError: Indicating that the RPC was aborted.
+      A nonnegative float indicating the length of allowed time in seconds
+      remaining for the RPC to complete before it is considered to have timed
+      out.
     """
     raise NotImplementedError()
 
   @abc.abstractmethod
-  def async(self, request, timeout):
-    """Asynchronously invokes the underlying RPC.
+  def add_abortion_callback(self, abortion_callback):
+    """Registers a callback to be called if the RPC is aborted.
 
     Args:
-      request: The request value for the RPC.
-      timeout: A duration of time in seconds to allow for the RPC.
-
-    Returns:
-      A future.Future representing the RPC. In the event of RPC completion, the
-        returned Future's result value will be the response value of the RPC.
-        In the event of RPC abortion, the returned Future's exception value
-        will be an exceptions.RpcError.
+      abortion_callback: A callable to be called and passed an Abortion value
+        in the event of RPC abortion.
     """
     raise NotImplementedError()
 
 
-class StreamUnarySyncAsync(object):
-  """Affords invoking a stream-unary RPC synchronously or asynchronously.
+class Call(object):
+  """Invocation-side representation of an RPC.
 
-  Values implementing this interface are directly callable and present an
-  "async" method. Both calls take an iterator of request values and a numeric
-  timeout. Direct invocation of a value of this type invokes its associated RPC
-  and blocks until the RPC's response is available. Calling the "async" method
-  of a value of this type invokes its associated RPC and immediately returns a
-  future.Future bound to the asynchronous execution of the RPC.
+  Attributes:
+    context: An RpcContext affording information about the RPC.
   """
   __metaclass__ = abc.ABCMeta
 
   @abc.abstractmethod
-  def __call__(self, request_iterator, timeout):
+  def cancel(self):
+    """Requests cancellation of the RPC."""
+    raise NotImplementedError()
+
+
+class UnaryUnaryMultiCallable(object):
+  """Affords invoking a unary-unary RPC in any call style."""
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def __call__(self, request, timeout):
     """Synchronously invokes the underlying RPC.
 
     Args:
-      request_iterator: An iterator that yields request values for the RPC.
+      request: The request value for the RPC.
       timeout: A duration of time in seconds to allow for the RPC.
 
     Returns:
@@ -133,11 +138,11 @@ class StreamUnarySyncAsync(object):
     raise NotImplementedError()
 
   @abc.abstractmethod
-  def async(self, request, timeout):
+  def future(self, request, timeout):
     """Asynchronously invokes the underlying RPC.
 
     Args:
-      request_iterator: An iterator that yields request values for the RPC.
+      request: The request value for the RPC.
       timeout: A duration of time in seconds to allow for the RPC.
 
     Returns:
@@ -148,248 +153,204 @@ class StreamUnarySyncAsync(object):
     """
     raise NotImplementedError()
 
-
-@enum.unique
-class Abortion(enum.Enum):
-  """Categories of RPC abortion."""
-
-  CANCELLED = 'cancelled'
-  EXPIRED = 'expired'
-  NETWORK_FAILURE = 'network failure'
-  SERVICED_FAILURE = 'serviced failure'
-  SERVICER_FAILURE = 'servicer failure'
-
-
-class RpcContext(object):
-  """Provides RPC-related information and action."""
-  __metaclass__ = abc.ABCMeta
-
-  @abc.abstractmethod
-  def is_active(self):
-    """Describes whether the RPC is active or has terminated."""
-    raise NotImplementedError()
-
-  @abc.abstractmethod
-  def time_remaining(self):
-    """Describes the length of allowed time remaining for the RPC.
-
-    Returns:
-      A nonnegative float indicating the length of allowed time in seconds
-      remaining for the RPC to complete before it is considered to have timed
-      out.
-    """
-    raise NotImplementedError()
-
   @abc.abstractmethod
-  def add_abortion_callback(self, abortion_callback):
-    """Registers a callback to be called if the RPC is aborted.
+  def event(self, request, response_callback, abortion_callback, timeout):
+    """Asynchronously invokes the underlying RPC.
 
     Args:
-      abortion_callback: A callable to be called and passed an Abortion value
+      request: The request value for the RPC.
+      response_callback: A callback to be called to accept the restponse value
+        of the RPC.
+      abortion_callback: A callback to be called and passed an Abortion value
         in the event of RPC abortion.
-    """
-    raise NotImplementedError()
-
-
-class InlineValueInValueOutMethod(object):
-  """A type for inline unary-request-unary-response RPC methods."""
-  __metaclass__ = abc.ABCMeta
-
-  @abc.abstractmethod
-  def service(self, request, context):
-    """Services an RPC that accepts one value and produces one value.
-
-    Args:
-      request: The single request value for the RPC.
-      context: An RpcContext object.
+      timeout: A duration of time in seconds to allow for the RPC.
 
     Returns:
-      The single response value for the RPC.
-
-    Raises:
-      abandonment.Abandoned: If no response is necessary because the RPC has
-        been aborted.
+      A Call object for the RPC.
     """
     raise NotImplementedError()
 
 
-class InlineValueInStreamOutMethod(object):
-  """A type for inline unary-request-stream-response RPC methods."""
+class UnaryStreamMultiCallable(object):
+  """Affords invoking a unary-stream RPC in any call style."""
   __metaclass__ = abc.ABCMeta
 
   @abc.abstractmethod
-  def service(self, request, context):
-    """Services an RPC that accepts one value and produces a stream of values.
+  def __call__(self, request, timeout):
+    """Synchronously invokes the underlying RPC.
 
     Args:
-      request: The single request value for the RPC.
-      context: An RpcContext object.
-
-    Yields:
-      The values that comprise the response stream of the RPC.
+      request: The request value for the RPC.
+      timeout: A duration of time in seconds to allow for the RPC.
 
-    Raises:
-      abandonment.Abandoned: If completing the response stream is not necessary
-        because the RPC has been aborted.
+    Returns:
+      A CancellableIterator that yields the response values of the RPC and
+        affords RPC cancellation. Drawing response values from the returned
+        CancellableIterator may raise exceptions.RpcError indicating abortion
+        of the RPC.
     """
     raise NotImplementedError()
 
-
-class InlineStreamInValueOutMethod(object):
-  """A type for inline stream-request-unary-response RPC methods."""
-  __metaclass__ = abc.ABCMeta
-
   @abc.abstractmethod
-  def service(self, request_iterator, context):
-    """Services an RPC that accepts a stream of values and produces one value.
+  def event(self, request, response_consumer, abortion_callback, timeout):
+    """Asynchronously invokes the underlying RPC.
 
     Args:
-      request_iterator: An iterator that yields the request values of the RPC.
-        Drawing values from this iterator may also raise exceptions.RpcError to
-        indicate abortion of the RPC.
-      context: An RpcContext object.
-
-    Yields:
-      The values that comprise the response stream of the RPC.
+      request: The request value for the RPC.
+      response_consumer: A stream.Consumer to be called to accept the restponse
+        values of the RPC.
+      abortion_callback: A callback to be called and passed an Abortion value
+        in the event of RPC abortion.
+      timeout: A duration of time in seconds to allow for the RPC.
 
-    Raises:
-      abandonment.Abandoned: If no response is necessary because the RPC has
-        been aborted.
-      exceptions.RpcError: Implementations of this method must not deliberately
-        raise exceptions.RpcError but may allow such errors raised by the
-        request_iterator passed to them to propagate through their bodies
-        uncaught.
+    Returns:
+      A Call object for the RPC.
     """
     raise NotImplementedError()
 
 
-class InlineStreamInStreamOutMethod(object):
-  """A type for inline stream-request-stream-response RPC methods."""
+class StreamUnaryMultiCallable(object):
+  """Affords invoking a stream-unary RPC in any call style."""
   __metaclass__ = abc.ABCMeta
 
   @abc.abstractmethod
-  def service(self, request_iterator, context):
-    """Services an RPC that accepts and produces streams of values.
+  def __call__(self, request_iterator, timeout):
+    """Synchronously invokes the underlying RPC.
 
     Args:
-      request_iterator: An iterator that yields the request values of the RPC.
-        Drawing values from this iterator may also raise exceptions.RpcError to
-        indicate abortion of the RPC.
-      context: An RpcContext object.
+      request_iterator: An iterator that yields request values for the RPC.
+      timeout: A duration of time in seconds to allow for the RPC.
 
-    Yields:
-      The values that comprise the response stream of the RPC.
+    Returns:
+      The response value for the RPC.
 
     Raises:
-      abandonment.Abandoned: If completing the response stream is not necessary
-        because the RPC has been aborted.
-      exceptions.RpcError: Implementations of this method must not deliberately
-        raise exceptions.RpcError but may allow such errors raised by the
-        request_iterator passed to them to propagate through their bodies
-        uncaught.
+      exceptions.RpcError: Indicating that the RPC was aborted.
     """
     raise NotImplementedError()
 
-
-class EventValueInValueOutMethod(object):
-  """A type for event-driven unary-request-unary-response RPC methods."""
-  __metaclass__ = abc.ABCMeta
-
   @abc.abstractmethod
-  def service(self, request, response_callback, context):
-    """Services an RPC that accepts one value and produces one value.
+  def future(self, request_iterator, timeout):
+    """Asynchronously invokes the underlying RPC.
 
     Args:
-      request: The single request value for the RPC.
-      response_callback: A callback to be called to accept the response value of
-        the RPC.
-      context: An RpcContext object.
+      request_iterator: An iterator that yields request values for the RPC.
+      timeout: A duration of time in seconds to allow for the RPC.
 
-    Raises:
-      abandonment.Abandoned: May or may not be raised when the RPC has been
-        aborted.
+    Returns:
+      A future.Future representing the RPC. In the event of RPC completion, the
+        returned Future's result value will be the response value of the RPC.
+        In the event of RPC abortion, the returned Future's exception value
+        will be an exceptions.RpcError.
     """
     raise NotImplementedError()
 
-
-class EventValueInStreamOutMethod(object):
-  """A type for event-driven unary-request-stream-response RPC methods."""
-  __metaclass__ = abc.ABCMeta
-
   @abc.abstractmethod
-  def service(self, request, response_consumer, context):
-    """Services an RPC that accepts one value and produces a stream of values.
+  def event(self, response_callback, abortion_callback, timeout):
+    """Asynchronously invokes the underlying RPC.
 
     Args:
-      request: The single request value for the RPC.
-      response_consumer: A stream.Consumer to be called to accept the response
-        values of the RPC.
-      context: An RpcContext object.
+      request: The request value for the RPC.
+      response_callback: A callback to be called to accept the restponse value
+        of the RPC.
+      abortion_callback: A callback to be called and passed an Abortion value
+        in the event of RPC abortion.
+      timeout: A duration of time in seconds to allow for the RPC.
 
-    Raises:
-      abandonment.Abandoned: May or may not be raised when the RPC has been
-        aborted.
+    Returns:
+      A pair of a Call object for the RPC and a stream.Consumer to which the
+        request values of the RPC should be passed.
     """
     raise NotImplementedError()
 
 
-class EventStreamInValueOutMethod(object):
-  """A type for event-driven stream-request-unary-response RPC methods."""
+class StreamStreamMultiCallable(object):
+  """Affords invoking a stream-stream RPC in any call style."""
   __metaclass__ = abc.ABCMeta
 
   @abc.abstractmethod
-  def service(self, response_callback, context):
-    """Services an RPC that accepts a stream of values and produces one value.
+  def __call__(self, request_iterator, timeout):
+    """Synchronously invokes the underlying RPC.
 
     Args:
-      response_callback: A callback to be called to accept the response value of
-        the RPC.
-      context: An RpcContext object.
+      request_iterator: An iterator that yields request values for the RPC.
+      timeout: A duration of time in seconds to allow for the RPC.
 
     Returns:
-      A stream.Consumer with which to accept the request values of the RPC. The
-        consumer returned from this method may or may not be invoked to
-        completion: in the case of RPC abortion, RPC Framework will simply stop
-        passing values to this object. Implementations must not assume that this
-        object will be called to completion of the request stream or even called
-        at all.
-
-    Raises:
-      abandonment.Abandoned: May or may not be raised when the RPC has been
-        aborted.
+      A CancellableIterator that yields the response values of the RPC and
+        affords RPC cancellation. Drawing response values from the returned
+        CancellableIterator may raise exceptions.RpcError indicating abortion
+        of the RPC.
     """
     raise NotImplementedError()
 
-
-class EventStreamInStreamOutMethod(object):
-  """A type for event-driven stream-request-stream-response RPC methods."""
-  __metaclass__ = abc.ABCMeta
-
   @abc.abstractmethod
-  def service(self, response_consumer, context):
-    """Services an RPC that accepts and produces streams of values.
+  def event(self, response_consumer, abortion_callback, timeout):
+    """Asynchronously invokes the underlying RPC.
 
-    Args:
-      response_consumer: A stream.Consumer to be called to accept the response
+l    Args:
+      response_consumer: A stream.Consumer to be called to accept the restponse
         values of the RPC.
-      context: An RpcContext object.
+      abortion_callback: A callback to be called and passed an Abortion value
+        in the event of RPC abortion.
+      timeout: A duration of time in seconds to allow for the RPC.
 
     Returns:
-      A stream.Consumer with which to accept the request values of the RPC. The
-        consumer returned from this method may or may not be invoked to
-        completion: in the case of RPC abortion, RPC Framework will simply stop
-        passing values to this object. Implementations must not assume that this
-        object will be called to completion of the request stream or even called
-        at all.
-
-    Raises:
-      abandonment.Abandoned: May or may not be raised when the RPC has been
-        aborted.
+      A pair of a Call object for the RPC and a stream.Consumer to which the
+        request values of the RPC should be passed.
     """
     raise NotImplementedError()
 
 
-class MultiMethod(object):
+class MethodImplementation(object):
+  """A sum type that describes an RPC method implementation.
+
+  Attributes:
+    cardinality: A cardinality.Cardinality value.
+    style: A style.Service value.
+    unary_unary_inline: The implementation of the RPC method as a callable
+      value that takes a request value and an RpcContext object and returns a
+      response value. Only non-None if cardinality is
+      cardinality.Cardinality.UNARY_UNARY and style is style.Service.INLINE.
+    unary_stream_inline: The implementation of the RPC method as a callable
+      value that takes a request value and an RpcContext object and returns an
+      iterator of response values. Only non-None if cardinality is
+      cardinality.Cardinality.UNARY_STREAM and style is style.Service.INLINE.
+    stream_unary_inline: The implementation of the RPC method as a callable
+      value that takes an iterator of request values and an RpcContext object
+      and returns a response value. Only non-None if cardinality is
+      cardinality.Cardinality.STREAM_UNARY and style is style.Service.INLINE.
+    stream_stream_inline: The implementation of the RPC method as a callable
+      value that takes an iterator of request values and an RpcContext object
+      and returns an iterator of response values. Only non-None if cardinality
+      is cardinality.Cardinality.STREAM_STREAM and style is
+      style.Service.INLINE.
+    unary_unary_event: The implementation of the RPC method as a callable value
+      that takes a request value, a response callback to which to pass the
+      response value of the RPC, and an RpcContext. Only non-None if
+      cardinality is cardinality.Cardinality.UNARY_UNARY and style is
+      style.Service.EVENT.
+    unary_stream_event: The implementation of the RPC method as a callable
+      value that takes a request value, a stream.Consumer to which to pass the
+      the response values of the RPC, and an RpcContext. Only non-None if
+      cardinality is cardinality.Cardinality.UNARY_STREAM and style is
+      style.Service.EVENT.
+    stream_unary_event: The implementation of the RPC method as a callable
+      value that takes a response callback to which to pass the response value
+      of the RPC and an RpcContext and returns a stream.Consumer to which the
+      request values of the RPC should be passed. Only non-None if cardinality
+      is cardinality.Cardinality.STREAM_UNARY and style is style.Service.EVENT.
+    stream_stream_event: The implementation of the RPC method as a callable
+      value that takes a stream.Consumer to which to pass the response values
+      of the RPC and an RpcContext and returns a stream.Consumer to which the
+      request values of the RPC should be passed. Only non-None if cardinality
+      is cardinality.Cardinality.STREAM_STREAM and style is
+      style.Service.EVENT.
+  """
+  __metaclass__ = abc.ABCMeta
+
+
+class MultiMethodImplementation(object):
   """A general type able to service many RPC methods."""
   __metaclass__ = abc.ABCMeta
 
@@ -420,26 +381,7 @@ class MultiMethod(object):
     raise NotImplementedError()
 
 
-class Server(object):
-  """Specification of a running server that services RPCs."""
-  __metaclass__ = abc.ABCMeta
-
-
-class Call(object):
-  """Invocation-side representation of an RPC.
-
-  Attributes:
-    context: An RpcContext affording information about the RPC.
-  """
-  __metaclass__ = abc.ABCMeta
-
-  @abc.abstractmethod
-  def cancel(self):
-    """Requests cancellation of the RPC."""
-    raise NotImplementedError()
-
-
-class Stub(object):
+class GenericStub(object):
   """Affords RPC methods to callers."""
   __metaclass__ = abc.ABCMeta
 
@@ -632,25 +574,67 @@ class Stub(object):
     raise NotImplementedError()
 
   @abc.abstractmethod
-  def unary_unary_sync_async(self, name):
-    """Creates a UnaryUnarySyncAsync value for a unary-unary RPC method.
+  def unary_unary_multi_callable(self, name):
+    """Creates a UnaryUnaryMultiCallable for a unary-unary RPC method.
+
+    Args:
+      name: The RPC method name.
+
+    Returns:
+      A UnaryUnaryMultiCallable value for the named unary-unary RPC method.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def unary_stream_multi_callable(self, name):
+    """Creates a UnaryStreamMultiCallable for a unary-stream RPC method.
 
     Args:
       name: The RPC method name.
 
     Returns:
-      A UnaryUnarySyncAsync value for the named unary-unary RPC method.
+      A UnaryStreamMultiCallable value for the name unary-stream RPC method.
     """
     raise NotImplementedError()
 
   @abc.abstractmethod
-  def stream_unary_sync_async(self, name):
-    """Creates a StreamUnarySyncAsync value for a stream-unary RPC method.
+  def stream_unary_multi_callable(self, name):
+    """Creates a StreamUnaryMultiCallable for a stream-unary RPC method.
 
     Args:
       name: The RPC method name.
 
     Returns:
-      A StreamUnarySyncAsync value for the named stream-unary RPC method.
+      A StreamUnaryMultiCallable value for the named stream-unary RPC method.
     """
     raise NotImplementedError()
+
+  @abc.abstractmethod
+  def stream_stream_multi_callable(self, name):
+    """Creates a StreamStreamMultiCallable for a stream-stream RPC method.
+
+    Args:
+      name: The RPC method name.
+
+    Returns:
+      A StreamStreamMultiCallable value for the named stream-stream RPC method.
+    """
+    raise NotImplementedError()
+
+
+class DynamicStub(object):
+  """A stub with RPC-method-bound multi-callable attributes.
+
+  Instances of this type responsd to attribute access as follows: if the
+  requested attribute is the name of a unary-unary RPC method, the value of the
+  attribute will be a UnaryUnaryMultiCallable with which to invoke the RPC
+  method; if the requested attribute is the name of a unary-stream RPC method,
+  the value of the attribute will be a UnaryStreamMultiCallable with which to
+  invoke the RPC method; if the requested attribute is the name of a
+  stream-unary RPC method, the value of the attribute will be a
+  StreamUnaryMultiCallable with which to invoke the RPC method; and if the
+  requested attribute is the name of a stream-stream RPC method, the value of
+  the attribute will be a StreamStreamMultiCallable with which to invoke the
+  RPC method.
+  """
+  __metaclass__ = abc.ABCMeta
diff --git a/src/python/src/grpc/framework/face/testing/blocking_invocation_inline_service_test_case.py b/src/python/src/grpc/framework/face/testing/blocking_invocation_inline_service_test_case.py
index 233486f2110368ca95f56f00dabb4e05965f0729..e57ee001045a487b0359e2401c2ffe83724ade2f 100644
--- a/src/python/src/grpc/framework/face/testing/blocking_invocation_inline_service_test_case.py
+++ b/src/python/src/grpc/framework/face/testing/blocking_invocation_inline_service_test_case.py
@@ -61,13 +61,9 @@ class BlockingInvocationInlineServiceTestCase(
     self.digest = digest.digest(
         stock_service.STOCK_TEST_SERVICE, self.control, None)
 
-    self.server, self.stub, self.memo = self.set_up_implementation(
+    self.stub, self.memo = self.set_up_implementation(
         self.digest.name, self.digest.methods,
-        self.digest.inline_unary_unary_methods,
-        self.digest.inline_unary_stream_methods,
-        self.digest.inline_stream_unary_methods,
-        self.digest.inline_stream_stream_methods,
-        {}, {}, {}, {}, None)
+        self.digest.inline_method_implementations, None)
 
   def tearDown(self):
     """See unittest.TestCase.tearDown for full specification.
@@ -147,8 +143,8 @@ class BlockingInvocationInlineServiceTestCase(
 
         with self.control.pause(), self.assertRaises(
             exceptions.ExpirationError):
-          sync_async = self.stub.unary_unary_sync_async(name)
-          sync_async(request, _TIMEOUT)
+          multi_callable = self.stub.unary_unary_multi_callable(name)
+          multi_callable(request, _TIMEOUT)
 
   def testExpiredUnaryRequestStreamResponse(self):
     for name, test_messages_sequence in (
@@ -170,8 +166,8 @@ class BlockingInvocationInlineServiceTestCase(
 
         with self.control.pause(), self.assertRaises(
             exceptions.ExpirationError):
-          sync_async = self.stub.stream_unary_sync_async(name)
-          sync_async(iter(requests), _TIMEOUT)
+          multi_callable = self.stub.stream_unary_multi_callable(name)
+          multi_callable(iter(requests), _TIMEOUT)
 
   def testExpiredStreamRequestStreamResponse(self):
     for name, test_messages_sequence in (
diff --git a/src/python/src/grpc/framework/face/testing/digest.py b/src/python/src/grpc/framework/face/testing/digest.py
index b8fb573301370e0e5556065bde548ed071169662..db8fcbb0184efaca4d239a1436b788d49712e9d2 100644
--- a/src/python/src/grpc/framework/face/testing/digest.py
+++ b/src/python/src/grpc/framework/face/testing/digest.py
@@ -34,6 +34,8 @@ import threading
 
 # testing_control, interfaces, and testing_service are referenced from
 # specification in this module.
+from grpc.framework.common import cardinality
+from grpc.framework.common import style
 from grpc.framework.face import exceptions
 from grpc.framework.face import interfaces as face_interfaces
 from grpc.framework.face.testing import control as testing_control  # pylint: disable=unused-import
@@ -50,15 +52,9 @@ class TestServiceDigest(
         'TestServiceDigest',
         ['name',
          'methods',
-         'inline_unary_unary_methods',
-         'inline_unary_stream_methods',
-         'inline_stream_unary_methods',
-         'inline_stream_stream_methods',
-         'event_unary_unary_methods',
-         'event_unary_stream_methods',
-         'event_stream_unary_methods',
-         'event_stream_stream_methods',
-         'multi_method',
+         'inline_method_implementations',
+         'event_method_implementations',
+         'multi_method_implementation',
          'unary_unary_messages_sequences',
          'unary_stream_messages_sequences',
          'stream_unary_messages_sequences',
@@ -69,32 +65,14 @@ class TestServiceDigest(
     name: The RPC service name to be used in the test.
     methods: A sequence of interfaces.Method objects describing the RPC
       methods that will be called during the test.
-    inline_unary_unary_methods: A dict from method name to
-      face_interfaces.InlineValueInValueOutMethod object to be used in tests of
+    inline_method_implementations: A dict from RPC method name to
+      face_interfaces.MethodImplementation object to be used in tests of
       in-line calls to behaviors under test.
-    inline_unary_stream_methods: A dict from method name to
-      face_interfaces.InlineValueInStreamOutMethod object to be used in tests of
-      in-line calls to behaviors under test.
-    inline_stream_unary_methods: A dict from method name to
-      face_interfaces.InlineStreamInValueOutMethod object to be used in tests of
-      in-line calls to behaviors under test.
-    inline_stream_stream_methods: A dict from method name to
-      face_interfaces.InlineStreamInStreamOutMethod object to be used in tests
-      of in-line calls to behaviors under test.
-    event_unary_unary_methods: A dict from method name to
-      face_interfaces.EventValueInValueOutMethod object to be used in tests of
-      event-driven calls to behaviors under test.
-    event_unary_stream_methods: A dict from method name to
-      face_interfaces.EventValueInStreamOutMethod object to be used in tests of
-      event-driven calls to behaviors under test.
-    event_stream_unary_methods: A dict from method name to
-      face_interfaces.EventStreamInValueOutMethod object to be used in tests of
+    event_method_implementations: A dict from RPC method name to
+      face_interfaces.MethodImplementation object to be used in tests of
       event-driven calls to behaviors under test.
-    event_stream_stream_methods: A dict from method name to
-      face_interfaces.EventStreamInStreamOutMethod object to be used in tests of
-      event-driven calls to behaviors under test.
-    multi_method: A face_interfaces.MultiMethod to be used in tests of generic
-      calls to behaviors under test.
+    multi_method_implementation: A face_interfaces.MultiMethodImplementation to
+      be used in tests of generic calls to behaviors under test.
     unary_unary_messages_sequences: A dict from method name to sequence of
       service.UnaryUnaryTestMessages objects to be used to test the method
       with the given name.
@@ -130,27 +108,33 @@ class _BufferingConsumer(stream.Consumer):
     self.terminated = True
 
 
-class _InlineUnaryUnaryMethod(face_interfaces.InlineValueInValueOutMethod):
+class _InlineUnaryUnaryMethod(face_interfaces.MethodImplementation):
 
   def __init__(self, unary_unary_test_method, control):
     self._test_method = unary_unary_test_method
     self._control = control
 
-  def service(self, request, context):
+    self.cardinality = cardinality.Cardinality.UNARY_UNARY
+    self.style = style.Service.INLINE
+
+  def unary_unary_inline(self, request, context):
     response_list = []
     self._test_method.service(
         request, response_list.append, context, self._control)
     return response_list.pop(0)
 
 
-class _EventUnaryUnaryMethod(face_interfaces.EventValueInValueOutMethod):
+class _EventUnaryUnaryMethod(face_interfaces.MethodImplementation):
 
   def __init__(self, unary_unary_test_method, control, pool):
     self._test_method = unary_unary_test_method
     self._control = control
     self._pool = pool
 
-  def service(self, request, response_callback, context):
+    self.cardinality = cardinality.Cardinality.UNARY_UNARY
+    self.style = style.Service.EVENT
+
+  def unary_unary_event(self, request, response_callback, context):
     if self._pool is None:
       self._test_method.service(
           request, response_callback, context, self._control)
@@ -160,13 +144,16 @@ class _EventUnaryUnaryMethod(face_interfaces.EventValueInValueOutMethod):
           self._control)
 
 
-class _InlineUnaryStreamMethod(face_interfaces.InlineValueInStreamOutMethod):
+class _InlineUnaryStreamMethod(face_interfaces.MethodImplementation):
 
   def __init__(self, unary_stream_test_method, control):
     self._test_method = unary_stream_test_method
     self._control = control
 
-  def service(self, request, context):
+    self.cardinality = cardinality.Cardinality.UNARY_STREAM
+    self.style = style.Service.INLINE
+
+  def unary_stream_inline(self, request, context):
     response_consumer = _BufferingConsumer()
     self._test_method.service(
         request, response_consumer, context, self._control)
@@ -174,14 +161,17 @@ class _InlineUnaryStreamMethod(face_interfaces.InlineValueInStreamOutMethod):
       yield response
 
 
-class _EventUnaryStreamMethod(face_interfaces.EventValueInStreamOutMethod):
+class _EventUnaryStreamMethod(face_interfaces.MethodImplementation):
 
   def __init__(self, unary_stream_test_method, control, pool):
     self._test_method = unary_stream_test_method
     self._control = control
     self._pool = pool
 
-  def service(self, request, response_consumer, context):
+    self.cardinality = cardinality.Cardinality.UNARY_STREAM
+    self.style = style.Service.EVENT
+
+  def unary_stream_event(self, request, response_consumer, context):
     if self._pool is None:
       self._test_method.service(
           request, response_consumer, context, self._control)
@@ -191,13 +181,16 @@ class _EventUnaryStreamMethod(face_interfaces.EventValueInStreamOutMethod):
           self._control)
 
 
-class _InlineStreamUnaryMethod(face_interfaces.InlineStreamInValueOutMethod):
+class _InlineStreamUnaryMethod(face_interfaces.MethodImplementation):
 
   def __init__(self, stream_unary_test_method, control):
     self._test_method = stream_unary_test_method
     self._control = control
 
-  def service(self, request_iterator, context):
+    self.cardinality = cardinality.Cardinality.STREAM_UNARY
+    self.style = style.Service.INLINE
+
+  def stream_unary_inline(self, request_iterator, context):
     response_list = []
     request_consumer = self._test_method.service(
         response_list.append, context, self._control)
@@ -207,14 +200,17 @@ class _InlineStreamUnaryMethod(face_interfaces.InlineStreamInValueOutMethod):
     return response_list.pop(0)
 
 
-class _EventStreamUnaryMethod(face_interfaces.EventStreamInValueOutMethod):
+class _EventStreamUnaryMethod(face_interfaces.MethodImplementation):
 
   def __init__(self, stream_unary_test_method, control, pool):
     self._test_method = stream_unary_test_method
     self._control = control
     self._pool = pool
 
-  def service(self, response_callback, context):
+    self.cardinality = cardinality.Cardinality.STREAM_UNARY
+    self.style = style.Service.EVENT
+
+  def stream_unary_event(self, response_callback, context):
     request_consumer = self._test_method.service(
         response_callback, context, self._control)
     if self._pool is None:
@@ -223,13 +219,16 @@ class _EventStreamUnaryMethod(face_interfaces.EventStreamInValueOutMethod):
       return stream_util.ThreadSwitchingConsumer(request_consumer, self._pool)
 
 
-class _InlineStreamStreamMethod(face_interfaces.InlineStreamInStreamOutMethod):
+class _InlineStreamStreamMethod(face_interfaces.MethodImplementation):
 
   def __init__(self, stream_stream_test_method, control):
     self._test_method = stream_stream_test_method
     self._control = control
 
-  def service(self, request_iterator, context):
+    self.cardinality = cardinality.Cardinality.STREAM_STREAM
+    self.style = style.Service.INLINE
+
+  def stream_stream_inline(self, request_iterator, context):
     response_consumer = _BufferingConsumer()
     request_consumer = self._test_method.service(
         response_consumer, context, self._control)
@@ -241,14 +240,17 @@ class _InlineStreamStreamMethod(face_interfaces.InlineStreamInStreamOutMethod):
     response_consumer.terminate()
 
 
-class _EventStreamStreamMethod(face_interfaces.EventStreamInStreamOutMethod):
+class _EventStreamStreamMethod(face_interfaces.MethodImplementation):
 
   def __init__(self, stream_stream_test_method, control, pool):
     self._test_method = stream_stream_test_method
     self._control = control
     self._pool = pool
 
-  def service(self, response_consumer, context):
+    self.cardinality = cardinality.Cardinality.STREAM_STREAM
+    self.style = style.Service.EVENT
+
+  def stream_stream_event(self, response_consumer, context):
     request_consumer = self._test_method.service(
         response_consumer, context, self._control)
     if self._pool is None:
@@ -332,7 +334,7 @@ class _StreamUnaryAdaptation(object):
         response_consumer.consume_and_terminate, context, control)
 
 
-class _MultiMethod(face_interfaces.MultiMethod):
+class _MultiMethodImplementation(face_interfaces.MultiMethodImplementation):
 
   def __init__(self, methods, control, pool):
     self._methods = methods
@@ -427,19 +429,21 @@ def digest(service, control, pool):
   adaptations.update(unary_stream.adaptations)
   adaptations.update(stream_unary.adaptations)
   adaptations.update(stream_stream.adaptations)
+  inlines = dict(unary_unary.inlines)
+  inlines.update(unary_stream.inlines)
+  inlines.update(stream_unary.inlines)
+  inlines.update(stream_stream.inlines)
+  events = dict(unary_unary.events)
+  events.update(unary_stream.events)
+  events.update(stream_unary.events)
+  events.update(stream_stream.events)
 
   return TestServiceDigest(
       service.name(),
       methods,
-      unary_unary.inlines,
-      unary_stream.inlines,
-      stream_unary.inlines,
-      stream_stream.inlines,
-      unary_unary.events,
-      unary_stream.events,
-      stream_unary.events,
-      stream_stream.events,
-      _MultiMethod(adaptations, control, pool),
+      inlines,
+      events,
+      _MultiMethodImplementation(adaptations, control, pool),
       unary_unary.messages,
       unary_stream.messages,
       stream_unary.messages,
diff --git a/src/python/src/grpc/framework/face/testing/event_invocation_synchronous_event_service_test_case.py b/src/python/src/grpc/framework/face/testing/event_invocation_synchronous_event_service_test_case.py
index 21e669b9080fb138101718c0e7ffebdda96c4566..0f0b0e3d5232a7014fc8be7e6861a516750d7485 100644
--- a/src/python/src/grpc/framework/face/testing/event_invocation_synchronous_event_service_test_case.py
+++ b/src/python/src/grpc/framework/face/testing/event_invocation_synchronous_event_service_test_case.py
@@ -60,14 +60,9 @@ class EventInvocationSynchronousEventServiceTestCase(
     self.digest = digest.digest(
         stock_service.STOCK_TEST_SERVICE, self.control, None)
 
-    self.server, self.stub, self.memo = self.set_up_implementation(
+    self.stub, self.memo = self.set_up_implementation(
         self.digest.name, self.digest.methods,
-        {}, {}, {}, {},
-        self.digest.event_unary_unary_methods,
-        self.digest.event_unary_stream_methods,
-        self.digest.event_stream_unary_methods,
-        self.digest.event_stream_stream_methods,
-        None)
+        self.digest.event_method_implementations, None)
 
   def tearDown(self):
     """See unittest.TestCase.tearDown for full specification.
diff --git a/src/python/src/grpc/framework/face/testing/future_invocation_asynchronous_event_service_test_case.py b/src/python/src/grpc/framework/face/testing/future_invocation_asynchronous_event_service_test_case.py
index c87846f2ef67280aab8c1cc243d75a7c260c8076..0d51b64f1b3b51f4ac0275b83967a68be9e57edf 100644
--- a/src/python/src/grpc/framework/face/testing/future_invocation_asynchronous_event_service_test_case.py
+++ b/src/python/src/grpc/framework/face/testing/future_invocation_asynchronous_event_service_test_case.py
@@ -91,14 +91,9 @@ class FutureInvocationAsynchronousEventServiceTestCase(
     self.digest = digest.digest(
         stock_service.STOCK_TEST_SERVICE, self.control, self.digest_pool)
 
-    self.server, self.stub, self.memo = self.set_up_implementation(
+    self.stub, self.memo = self.set_up_implementation(
         self.digest.name, self.digest.methods,
-        {}, {}, {}, {},
-        self.digest.event_unary_unary_methods,
-        self.digest.event_unary_stream_methods,
-        self.digest.event_stream_unary_methods,
-        self.digest.event_stream_stream_methods,
-        None)
+        self.digest.event_method_implementations, None)
 
   def tearDown(self):
     """See unittest.TestCase.tearDown for full specification.
@@ -190,8 +185,8 @@ class FutureInvocationAsynchronousEventServiceTestCase(
         request = test_messages.request()
 
         with self.control.pause():
-          sync_async = self.stub.unary_unary_sync_async(name)
-          response_future = sync_async.async(request, _TIMEOUT)
+          multi_callable = self.stub.unary_unary_multi_callable(name)
+          response_future = multi_callable.future(request, _TIMEOUT)
           self.assertIsInstance(
               response_future.exception(), exceptions.ExpirationError)
           with self.assertRaises(exceptions.ExpirationError):
@@ -216,8 +211,8 @@ class FutureInvocationAsynchronousEventServiceTestCase(
         requests = test_messages.requests()
 
         with self.control.pause():
-          sync_async = self.stub.stream_unary_sync_async(name)
-          response_future = sync_async.async(iter(requests), _TIMEOUT)
+          multi_callable = self.stub.stream_unary_multi_callable(name)
+          response_future = multi_callable.future(iter(requests), _TIMEOUT)
           self.assertIsInstance(
               response_future.exception(), exceptions.ExpirationError)
           with self.assertRaises(exceptions.ExpirationError):
diff --git a/src/python/src/grpc/framework/face/testing/service.py b/src/python/src/grpc/framework/face/testing/service.py
index a58e2ee42e41ed30be3f88e972942e85fa74f7d1..bf54d41d6643f66222c884419e50b2ca9066d440 100644
--- a/src/python/src/grpc/framework/face/testing/service.py
+++ b/src/python/src/grpc/framework/face/testing/service.py
@@ -36,8 +36,8 @@ from grpc.framework.face import interfaces as face_interfaces  # pylint: disable
 from grpc.framework.face.testing import interfaces
 
 
-class UnaryUnaryTestMethod(interfaces.Method):
-  """Like face_interfaces.EventValueInValueOutMethod but with a control."""
+class UnaryUnaryTestMethodImplementation(interfaces.Method):
+  """A controllable implementation of a unary-unary RPC method."""
 
   __metaclass__ = abc.ABCMeta
 
@@ -93,8 +93,8 @@ class UnaryUnaryTestMessages(object):
     raise NotImplementedError()
 
 
-class UnaryStreamTestMethod(interfaces.Method):
-  """Like face_interfaces.EventValueInStreamOutMethod but with a control."""
+class UnaryStreamTestMethodImplementation(interfaces.Method):
+  """A controllable implementation of a unary-stream RPC method."""
 
   __metaclass__ = abc.ABCMeta
 
@@ -106,7 +106,7 @@ class UnaryStreamTestMethod(interfaces.Method):
       request: The single request message for the RPC.
       response_consumer: A stream.Consumer to be called to accept the response
         messages of the RPC.
-      context: An RpcContext object.
+      context: A face_interfaces.RpcContext object.
       control: A test_control.Control to control execution of this method.
 
     Raises:
@@ -150,8 +150,8 @@ class UnaryStreamTestMessages(object):
     raise NotImplementedError()
 
 
-class StreamUnaryTestMethod(interfaces.Method):
-  """Like face_interfaces.EventStreamInValueOutMethod but with a control."""
+class StreamUnaryTestMethodImplementation(interfaces.Method):
+  """A controllable implementation of a stream-unary RPC method."""
 
   __metaclass__ = abc.ABCMeta
 
@@ -162,7 +162,7 @@ class StreamUnaryTestMethod(interfaces.Method):
     Args:
       response_callback: A callback to be called to accept the response message
         of the RPC.
-      context: An RpcContext object.
+      context: A face_interfaces.RpcContext object.
       control: A test_control.Control to control execution of this method.
 
     Returns:
@@ -214,8 +214,8 @@ class StreamUnaryTestMessages(object):
     raise NotImplementedError()
 
 
-class StreamStreamTestMethod(interfaces.Method):
-  """Like face_interfaces.EventStreamInStreamOutMethod but with a control."""
+class StreamStreamTestMethodImplementation(interfaces.Method):
+  """A controllable implementation of a stream-stream RPC method."""
 
   __metaclass__ = abc.ABCMeta
 
@@ -226,7 +226,7 @@ class StreamStreamTestMethod(interfaces.Method):
     Args:
       response_consumer: A stream.Consumer to be called to accept the response
         messages of the RPC.
-      context: An RpcContext object.
+      context: A face_interfaces.RpcContext object.
       control: A test_control.Control to control execution of this method.
 
     Returns:
@@ -298,8 +298,8 @@ class TestService(object):
 
     Returns:
       A dict from method name to pair. The first element of the pair
-        is a UnaryUnaryTestMethod object and the second element is a sequence
-        of UnaryUnaryTestMethodMessages objects.
+        is a UnaryUnaryTestMethodImplementation object and the second element
+        is a sequence of UnaryUnaryTestMethodMessages objects.
     """
     raise NotImplementedError()
 
@@ -309,8 +309,8 @@ class TestService(object):
 
     Returns:
       A dict from method name to pair. The first element of the pair is a
-        UnaryStreamTestMethod object and the second element is a sequence of
-        UnaryStreamTestMethodMessages objects.
+        UnaryStreamTestMethodImplementation object and the second element is a
+        sequence of UnaryStreamTestMethodMessages objects.
     """
     raise NotImplementedError()
 
@@ -320,8 +320,8 @@ class TestService(object):
 
     Returns:
       A dict from method name to pair. The first element of the pair is a
-        StreamUnaryTestMethod object and the second element is a sequence of
-        StreamUnaryTestMethodMessages objects.
+        StreamUnaryTestMethodImplementation object and the second element is a
+        sequence of StreamUnaryTestMethodMessages objects.
     """
     raise NotImplementedError()
 
@@ -331,7 +331,7 @@ class TestService(object):
 
     Returns:
       A dict from method name to pair. The first element of the pair is a
-        StreamStreamTestMethod object and the second element is a sequence of
-        StreamStreamTestMethodMessages objects.
+        StreamStreamTestMethodImplementation object and the second element is a
+        sequence of StreamStreamTestMethodMessages objects.
     """
     raise NotImplementedError()
diff --git a/src/python/src/grpc/framework/face/testing/stock_service.py b/src/python/src/grpc/framework/face/testing/stock_service.py
index 83c9418b074a3eadeaf3980487a2dc380a77b7f3..61aaf444a00fd42232053276f4da819b00ef297e 100644
--- a/src/python/src/grpc/framework/face/testing/stock_service.py
+++ b/src/python/src/grpc/framework/face/testing/stock_service.py
@@ -139,7 +139,7 @@ def _get_highest_trade_price(stock_reply_callback, control, active):
   return StockRequestConsumer()
 
 
-class GetLastTradePrice(service.UnaryUnaryTestMethod):
+class GetLastTradePrice(service.UnaryUnaryTestMethodImplementation):
   """GetLastTradePrice for use in tests."""
 
   def name(self):
@@ -186,7 +186,7 @@ class GetLastTradePriceMessages(service.UnaryUnaryTestMessages):
     test_case.assertEqual(_price(request.symbol), response.price)
 
 
-class GetLastTradePriceMultiple(service.StreamStreamTestMethod):
+class GetLastTradePriceMultiple(service.StreamStreamTestMethodImplementation):
   """GetLastTradePriceMultiple for use in tests."""
 
   def name(self):
@@ -238,7 +238,7 @@ class GetLastTradePriceMultipleMessages(service.StreamStreamTestMessages):
       test_case.assertEqual(_price(stock_request.symbol), stock_reply.price)
 
 
-class WatchFutureTrades(service.UnaryStreamTestMethod):
+class WatchFutureTrades(service.UnaryStreamTestMethodImplementation):
   """WatchFutureTrades for use in tests."""
 
   def name(self):
@@ -288,7 +288,7 @@ class WatchFutureTradesMessages(service.UnaryStreamTestMessages):
       test_case.assertEqual(base_price + index, response.price)
 
 
-class GetHighestTradePrice(service.StreamUnaryTestMethod):
+class GetHighestTradePrice(service.StreamUnaryTestMethodImplementation):
   """GetHighestTradePrice for use in tests."""
 
   def name(self):
diff --git a/src/python/src/grpc/framework/face/testing/test_case.py b/src/python/src/grpc/framework/face/testing/test_case.py
index 218a2a8549bebd91b90825b16faebff79f4d98bb..e60e3d1d405c2960f1423bf88132dc71376dad49 100644
--- a/src/python/src/grpc/framework/face/testing/test_case.py
+++ b/src/python/src/grpc/framework/face/testing/test_case.py
@@ -46,55 +46,24 @@ class FaceTestCase(object):
 
   @abc.abstractmethod
   def set_up_implementation(
-      self,
-      name,
-      methods,
-      inline_value_in_value_out_methods,
-      inline_value_in_stream_out_methods,
-      inline_stream_in_value_out_methods,
-      inline_stream_in_stream_out_methods,
-      event_value_in_value_out_methods,
-      event_value_in_stream_out_methods,
-      event_stream_in_value_out_methods,
-      event_stream_in_stream_out_methods,
-      multi_method):
+      self, name, methods, method_implementations,
+      multi_method_implementation):
     """Instantiates the Face Layer implementation under test.
 
     Args:
       name: The service name to be used in the test.
       methods: A sequence of interfaces.Method objects describing the RPC
         methods that will be called during the test.
-      inline_value_in_value_out_methods: A dictionary from string method names
-        to face_interfaces.InlineValueInValueOutMethod implementations of those
-        methods.
-      inline_value_in_stream_out_methods: A dictionary from string method names
-        to face_interfaces.InlineValueInStreamOutMethod implementations of those
-        methods.
-      inline_stream_in_value_out_methods: A dictionary from string method names
-        to face_interfaces.InlineStreamInValueOutMethod implementations of those
-        methods.
-      inline_stream_in_stream_out_methods: A dictionary from string method names
-        to face_interfaces.InlineStreamInStreamOutMethod implementations of
-        those methods.
-      event_value_in_value_out_methods: A dictionary from string method names
-        to face_interfaces.EventValueInValueOutMethod implementations of those
-        methods.
-      event_value_in_stream_out_methods: A dictionary from string method names
-        to face_interfaces.EventValueInStreamOutMethod implementations of those
-        methods.
-      event_stream_in_value_out_methods: A dictionary from string method names
-        to face_interfaces.EventStreamInValueOutMethod implementations of those
-        methods.
-      event_stream_in_stream_out_methods: A dictionary from string method names
-        to face_interfaces.EventStreamInStreamOutMethod implementations of those
-        methods.
-      multi_method: An face_interfaces.MultiMethod, or None.
+      method_implementations: A dictionary from string RPC method name to
+        face_interfaces.MethodImplementation object specifying
+        implementation of an RPC method.
+      multi_method_implementation: An face_interfaces.MultiMethodImplementation
+        or None.
 
     Returns:
-      A sequence of length three the first element of which is a
-        face_interfaces.Server, the second element of which is a
-        face_interfaces.Stub, (both of which are backed by the given method
-        implementations), and the third element of which is an arbitrary memo
+      A sequence of length two the first element of which is a
+        face_interfaces.GenericStub (backed by the given method
+        implementations), and the second element of which is an arbitrary memo
         object to be kept and passed to tearDownImplementation at the conclusion
         of the test.
     """
@@ -105,7 +74,7 @@ class FaceTestCase(object):
     """Destroys the Face layer implementation under test.
 
     Args:
-      memo: The object from the third position of the return value of
+      memo: The object from the second position of the return value of
         set_up_implementation.
     """
     raise NotImplementedError()
diff --git a/src/python/src/grpc/framework/face/utilities.py b/src/python/src/grpc/framework/face/utilities.py
index 5e34be37da7a5e9c537db9f280b609bd6d649ece..a63fe8c60dfbb9d365625168a1b5a4075881edf2 100644
--- a/src/python/src/grpc/framework/face/utilities.py
+++ b/src/python/src/grpc/framework/face/utilities.py
@@ -27,101 +27,44 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-"""Utilities for the face layer of RPC Framework."""
+"""Utilities for RPC framework's face layer."""
 
-# stream is referenced from specification in this module.
-from grpc.framework.face import interfaces
-from grpc.framework.foundation import stream  # pylint: disable=unused-import
-
-
-class _InlineUnaryUnaryMethod(interfaces.InlineValueInValueOutMethod):
-
-  def __init__(self, behavior):
-    self._behavior = behavior
-
-  def service(self, request, context):
-    return self._behavior(request, context)
-
-
-class _InlineUnaryStreamMethod(interfaces.InlineValueInStreamOutMethod):
-
-  def __init__(self, behavior):
-    self._behavior = behavior
-
-  def service(self, request, context):
-    return self._behavior(request, context)
-
-
-class _InlineStreamUnaryMethod(interfaces.InlineStreamInValueOutMethod):
-
-  def __init__(self, behavior):
-    self._behavior = behavior
-
-  def service(self, request_iterator, context):
-    return self._behavior(request_iterator, context)
-
-
-class _InlineStreamStreamMethod(interfaces.InlineStreamInStreamOutMethod):
-
-  def __init__(self, behavior):
-    self._behavior = behavior
-
-  def service(self, request_iterator, context):
-    return self._behavior(request_iterator, context)
+import collections
 
+from grpc.framework.common import cardinality
+from grpc.framework.common import style
+from grpc.framework.face import interfaces
+from grpc.framework.foundation import stream
 
-class _EventUnaryUnaryMethod(interfaces.EventValueInValueOutMethod):
-
-  def __init__(self, behavior):
-    self._behavior = behavior
-
-  def service(self, request, response_callback, context):
-    return self._behavior(request, response_callback, context)
-
-
-class _EventUnaryStreamMethod(interfaces.EventValueInStreamOutMethod):
-
-  def __init__(self, behavior):
-    self._behavior = behavior
-
-  def service(self, request, response_consumer, context):
-    return self._behavior(request, response_consumer, context)
-
-
-class _EventStreamUnaryMethod(interfaces.EventStreamInValueOutMethod):
-
-  def __init__(self, behavior):
-    self._behavior = behavior
-
-  def service(self, response_callback, context):
-    return self._behavior(response_callback, context)
-
-
-class _EventStreamStreamMethod(interfaces.EventStreamInStreamOutMethod):
-
-  def __init__(self, behavior):
-    self._behavior = behavior
 
-  def service(self, response_consumer, context):
-    return self._behavior(response_consumer, context)
+class _MethodImplementation(
+    interfaces.MethodImplementation,
+    collections.namedtuple(
+        '_MethodImplementation',
+        ['cardinality', 'style', 'unary_unary_inline', 'unary_stream_inline',
+         'stream_unary_inline', 'stream_stream_inline', 'unary_unary_event',
+         'unary_stream_event', 'stream_unary_event', 'stream_stream_event',])):
+  pass
 
 
-def inline_unary_unary_method(behavior):
-  """Creates an interfaces.InlineValueInValueOutMethod from a behavior.
+def unary_unary_inline(behavior):
+  """Creates an interfaces.MethodImplementation for the given behavior.
 
   Args:
-    behavior: The implementation of a unary-unary RPC method as a callable
-      value that takes a request value and an interfaces.RpcContext object and
+    behavior: The implementation of a unary-unary RPC method as a callable value
+      that takes a request value and an interfaces.RpcContext object and
       returns a response value.
 
   Returns:
-    An interfaces.InlineValueInValueOutMethod derived from the given behavior.
+    An interfaces.MethodImplementation derived from the given behavior.
   """
-  return _InlineUnaryUnaryMethod(behavior)
+  return _MethodImplementation(
+      cardinality.Cardinality.UNARY_UNARY, style.Service.INLINE, behavior,
+      None, None, None, None, None, None, None)
 
 
-def inline_unary_stream_method(behavior):
-  """Creates an interfaces.InlineValueInStreamOutMethod from a behavior.
+def unary_stream_inline(behavior):
+  """Creates an interfaces.MethodImplementation for the given behavior.
 
   Args:
     behavior: The implementation of a unary-stream RPC method as a callable
@@ -129,13 +72,15 @@ def inline_unary_stream_method(behavior):
       returns an iterator of response values.
 
   Returns:
-    An interfaces.InlineValueInStreamOutMethod derived from the given behavior.
+    An interfaces.MethodImplementation derived from the given behavior.
   """
-  return _InlineUnaryStreamMethod(behavior)
+  return _MethodImplementation(
+      cardinality.Cardinality.UNARY_STREAM, style.Service.INLINE, None,
+      behavior, None, None, None, None, None, None)
 
 
-def inline_stream_unary_method(behavior):
-  """Creates an interfaces.InlineStreamInValueOutMethod from a behavior.
+def stream_unary_inline(behavior):
+  """Creates an interfaces.MethodImplementation for the given behavior.
 
   Args:
     behavior: The implementation of a stream-unary RPC method as a callable
@@ -143,13 +88,15 @@ def inline_stream_unary_method(behavior):
       interfaces.RpcContext object and returns a response value.
 
   Returns:
-    An interfaces.InlineStreamInValueOutMethod derived from the given behavior.
+    An interfaces.MethodImplementation derived from the given behavior.
   """
-  return _InlineStreamUnaryMethod(behavior)
+  return _MethodImplementation(
+      cardinality.Cardinality.STREAM_UNARY, style.Service.INLINE, None, None,
+      behavior, None, None, None, None, None)
 
 
-def inline_stream_stream_method(behavior):
-  """Creates an interfaces.InlineStreamInStreamOutMethod from a behavior.
+def stream_stream_inline(behavior):
+  """Creates an interfaces.MethodImplementation for the given behavior.
 
   Args:
     behavior: The implementation of a stream-stream RPC method as a callable
@@ -157,14 +104,15 @@ def inline_stream_stream_method(behavior):
       interfaces.RpcContext object and returns an iterator of response values.
 
   Returns:
-    An interfaces.InlineStreamInStreamOutMethod derived from the given
-      behavior.
+    An interfaces.MethodImplementation derived from the given behavior.
   """
-  return _InlineStreamStreamMethod(behavior)
+  return _MethodImplementation(
+      cardinality.Cardinality.STREAM_STREAM, style.Service.INLINE, None, None,
+      None, behavior, None, None, None, None)
 
 
-def event_unary_unary_method(behavior):
-  """Creates an interfaces.EventValueInValueOutMethod from a behavior.
+def unary_unary_event(behavior):
+  """Creates an interfaces.MethodImplementation for the given behavior.
 
   Args:
     behavior: The implementation of a unary-unary RPC method as a callable
@@ -172,27 +120,31 @@ def event_unary_unary_method(behavior):
       the response value of the RPC, and an interfaces.RpcContext.
 
   Returns:
-    An interfaces.EventValueInValueOutMethod derived from the given behavior.
+    An interfaces.MethodImplementation derived from the given behavior.
   """
-  return _EventUnaryUnaryMethod(behavior)
+  return _MethodImplementation(
+      cardinality.Cardinality.UNARY_UNARY, style.Service.EVENT, None, None,
+      None, None, behavior, None, None, None)
 
 
-def event_unary_stream_method(behavior):
-  """Creates an interfaces.EventValueInStreamOutMethod from a behavior.
+def unary_stream_event(behavior):
+  """Creates an interfaces.MethodImplementation for the given behavior.
 
   Args:
     behavior: The implementation of a unary-stream RPC method as a callable
       value that takes a request value, a stream.Consumer to which to pass the
-      response values of the RPC, and an interfaces.RpcContext.
+      the response values of the RPC, and an interfaces.RpcContext.
 
   Returns:
-    An interfaces.EventValueInStreamOutMethod derived from the given behavior.
+    An interfaces.MethodImplementation derived from the given behavior.
   """
-  return _EventUnaryStreamMethod(behavior)
+  return _MethodImplementation(
+      cardinality.Cardinality.UNARY_STREAM, style.Service.EVENT, None, None,
+      None, None, None, behavior, None, None)
 
 
-def event_stream_unary_method(behavior):
-  """Creates an interfaces.EventStreamInValueOutMethod from a behavior.
+def stream_unary_event(behavior):
+  """Creates an interfaces.MethodImplementation for the given behavior.
 
   Args:
     behavior: The implementation of a stream-unary RPC method as a callable
@@ -201,13 +153,15 @@ def event_stream_unary_method(behavior):
       which the request values of the RPC should be passed.
 
   Returns:
-    An interfaces.EventStreamInValueOutMethod derived from the given behavior.
+    An interfaces.MethodImplementation derived from the given behavior.
   """
-  return _EventStreamUnaryMethod(behavior)
+  return _MethodImplementation(
+      cardinality.Cardinality.STREAM_UNARY, style.Service.EVENT, None, None,
+      None, None, None, None, behavior, None)
 
 
-def event_stream_stream_method(behavior):
-  """Creates an interfaces.EventStreamInStreamOutMethod from a behavior.
+def stream_stream_event(behavior):
+  """Creates an interfaces.MethodImplementation for the given behavior.
 
   Args:
     behavior: The implementation of a stream-stream RPC method as a callable
@@ -216,6 +170,8 @@ def event_stream_stream_method(behavior):
       which the request values of the RPC should be passed.
 
   Returns:
-    An interfaces.EventStreamInStreamOutMethod derived from the given behavior.
+    An interfaces.MethodImplementation derived from the given behavior.
   """
-  return _EventStreamStreamMethod(behavior)
+  return _MethodImplementation(
+      cardinality.Cardinality.STREAM_STREAM, style.Service.EVENT, None, None,
+      None, None, None, None, None, behavior)
diff --git a/src/ruby/bin/interop/interop_server.rb b/src/ruby/bin/interop/interop_server.rb
index b3b7d0c5a3a90f3eca27fac7ae34673f6197e6a6..0819ba9bbcc1d791091a7a9de38514e0e296d434 100755
--- a/src/ruby/bin/interop/interop_server.rb
+++ b/src/ruby/bin/interop/interop_server.rb
@@ -176,12 +176,11 @@ end
 def main
   opts = parse_options
   host = "0.0.0.0:#{opts['port']}"
+  s = GRPC::RpcServer.new
   if opts['secure']
-    s = GRPC::RpcServer.new(creds: test_server_creds)
-    s.add_http2_port(host, true)
+    s.add_http2_port(host, test_server_creds)
     logger.info("... running securely on #{host}")
   else
-    s = GRPC::RpcServer.new
     s.add_http2_port(host)
     logger.info("... running insecurely on #{host}")
   end
diff --git a/src/ruby/bin/math_server.rb b/src/ruby/bin/math_server.rb
index 93277e39320c4948cdd5fc46815da2feab4716ad..5cc76134893c225f12e5f22d9feb5f18da64a525 100755
--- a/src/ruby/bin/math_server.rb
+++ b/src/ruby/bin/math_server.rb
@@ -173,12 +173,11 @@ def main
     end
   end.parse!
 
+  s = GRPC::RpcServer.new
   if options['secure']
-    s = GRPC::RpcServer.new(creds: test_server_creds)
-    s.add_http2_port(options['host'], true)
+    s.add_http2_port(options['host'], test_server_creds)
     logger.info("... running securely on #{options['host']}")
   else
-    s = GRPC::RpcServer.new
     s.add_http2_port(options['host'])
     logger.info("... running insecurely on #{options['host']}")
   end
diff --git a/src/ruby/bin/noproto_server.rb b/src/ruby/bin/noproto_server.rb
index 435f8f4ebf495aec964d271a1a609a47fc532014..9979cb7ebbdd693e08f730d281f6213f316331b8 100755
--- a/src/ruby/bin/noproto_server.rb
+++ b/src/ruby/bin/noproto_server.rb
@@ -95,12 +95,11 @@ def main
     end
   end.parse!
 
+  s = GRPC::RpcServer.new
   if options['secure']
-    s = GRPC::RpcServer.new(creds: test_server_creds)
-    s.add_http2_port(options['host'], true)
+    s.add_http2_port(options['host'], test_server_creds)
     logger.info("... running securely on #{options['host']}")
   else
-    s = GRPC::RpcServer.new
     s.add_http2_port(options['host'])
     logger.info("... running insecurely on #{options['host']}")
   end
diff --git a/src/ruby/ext/grpc/rb_server.c b/src/ruby/ext/grpc/rb_server.c
index 5954e27d0249e8315f67553dc2aeadf4b0cf396a..c54f02e87afac11a2ea8f3c4a28406a460fe51dd 100644
--- a/src/ruby/ext/grpc/rb_server.c
+++ b/src/ruby/ext/grpc/rb_server.c
@@ -97,35 +97,19 @@ static VALUE grpc_rb_server_alloc(VALUE cls) {
 /*
   call-seq:
     cq = CompletionQueue.new
-    insecure_server = Server.new(cq, {'arg1': 'value1'})
-    server_creds = ...
-    secure_server = Server.new(cq, {'arg1': 'value1'}, server_creds)
+    server = Server.new(cq, {'arg1': 'value1'})
 
   Initializes server instances. */
-static VALUE grpc_rb_server_init(int argc, VALUE *argv, VALUE self) {
-  VALUE cqueue = Qnil;
-  VALUE credentials = Qnil;
-  VALUE channel_args = Qnil;
+static VALUE grpc_rb_server_init(VALUE self, VALUE cqueue, VALUE channel_args) {
   grpc_completion_queue *cq = NULL;
-  grpc_server_credentials *creds = NULL;
   grpc_rb_server *wrapper = NULL;
   grpc_server *srv = NULL;
   grpc_channel_args args;
   MEMZERO(&args, grpc_channel_args, 1);
-
-  /* "21" == 2 mandatory args, 1 (credentials) is optional */
-  rb_scan_args(argc, argv, "21", &cqueue, &channel_args, &credentials);
   cq = grpc_rb_get_wrapped_completion_queue(cqueue);
-
   Data_Get_Struct(self, grpc_rb_server, wrapper);
   grpc_rb_hash_convert_to_channel_args(channel_args, &args);
   srv = grpc_server_create(cq, &args);
-  if (credentials == Qnil) {
-    srv = grpc_server_create(cq, &args);
-  } else {
-    creds = grpc_rb_get_wrapped_server_credentials(credentials);
-    srv = grpc_secure_server_create(creds, cq, &args);
-  }
 
   if (args.args != NULL) {
     xfree(args.args); /* Allocated by grpc_rb_hash_convert_to_channel_args */
@@ -215,33 +199,36 @@ static VALUE grpc_rb_server_destroy(VALUE self) {
 
     // secure port
     server_creds = ...
-    secure_server = Server.new(cq, {'arg1': 'value1'}, creds)
-    secure_server.add_http_port('mydomain:7575', True)
+    secure_server = Server.new(cq, {'arg1': 'value1'})
+    secure_server.add_http_port('mydomain:7575', server_creds)
 
     Adds a http2 port to server */
 static VALUE grpc_rb_server_add_http2_port(int argc, VALUE *argv, VALUE self) {
   VALUE port = Qnil;
-  VALUE is_secure = Qnil;
+  VALUE rb_creds = Qnil;
   grpc_rb_server *s = NULL;
+  grpc_server_credentials *creds = NULL;
   int recvd_port = 0;
 
-  /* "11" == 1 mandatory args, 1 (is_secure) is optional */
-  rb_scan_args(argc, argv, "11", &port, &is_secure);
+  /* "11" == 1 mandatory args, 1 (rb_creds) is optional */
+  rb_scan_args(argc, argv, "11", &port, &rb_creds);
 
   Data_Get_Struct(self, grpc_rb_server, s);
   if (s->wrapped == NULL) {
     rb_raise(rb_eRuntimeError, "closed!");
     return Qnil;
-  } else if (is_secure == Qnil || TYPE(is_secure) != T_TRUE) {
+  } else if (rb_creds == Qnil) {
     recvd_port = grpc_server_add_http2_port(s->wrapped, StringValueCStr(port));
     if (recvd_port == 0) {
       rb_raise(rb_eRuntimeError,
                "could not add port %s to server, not sure why",
                StringValueCStr(port));
     }
-  } else if (TYPE(is_secure) != T_FALSE) {
+  } else {
+    creds = grpc_rb_get_wrapped_server_credentials(rb_creds);
     recvd_port =
-        grpc_server_add_secure_http2_port(s->wrapped, StringValueCStr(port));
+        grpc_server_add_secure_http2_port(s->wrapped, StringValueCStr(port),
+			                  creds);
     if (recvd_port == 0) {
       rb_raise(rb_eRuntimeError,
                "could not add secure port %s to server, not sure why",
@@ -258,7 +245,7 @@ void Init_grpc_server() {
   rb_define_alloc_func(rb_cServer, grpc_rb_server_alloc);
 
   /* Provides a ruby constructor and support for dup/clone. */
-  rb_define_method(rb_cServer, "initialize", grpc_rb_server_init, -1);
+  rb_define_method(rb_cServer, "initialize", grpc_rb_server_init, 2);
   rb_define_method(rb_cServer, "initialize_copy", grpc_rb_server_init_copy, 1);
 
   /* Add the server methods. */
diff --git a/src/ruby/grpc.gemspec b/src/ruby/grpc.gemspec
index ed26fef4a97a3e381d30cf9503dc62f2a240b34e..45cbacfeb04de3cf6ca43bbf2ee227cf1861e4e4 100755
--- a/src/ruby/grpc.gemspec
+++ b/src/ruby/grpc.gemspec
@@ -21,14 +21,10 @@ Gem::Specification.new do |s|
   s.require_paths = ['lib']
   s.platform      = Gem::Platform::RUBY
 
-  s.add_dependency 'faraday', '~> 0.9'
   s.add_dependency 'google-protobuf', '~> 3.0.0alpha.1.1'
   s.add_dependency 'googleauth', '~> 0.1'
   s.add_dependency 'logging', '~> 1.8'
-  s.add_dependency 'jwt', '~> 1.2.1'
   s.add_dependency 'minitest', '~> 5.4'  # reqd for interop tests
-  s.add_dependency 'multi_json', '1.10.1'
-  s.add_dependency 'signet', '~> 0.6.0'
   s.add_dependency 'xray', '~> 1.1'
 
   s.add_development_dependency 'bundler', '~> 1.7'
diff --git a/src/ruby/lib/grpc/generic/client_stub.rb b/src/ruby/lib/grpc/generic/client_stub.rb
index f234984eec3a4f4bde3d0d7cfe5528e56c1fcd65..01328d4a5bc68895716942b1f360ed0c9b911d7e 100644
--- a/src/ruby/lib/grpc/generic/client_stub.rb
+++ b/src/ruby/lib/grpc/generic/client_stub.rb
@@ -39,6 +39,25 @@ module GRPC
     # Default deadline is 5 seconds.
     DEFAULT_DEADLINE = 5
 
+    # setup_channel is used by #initialize to constuct a channel from its
+    # arguments.
+    def self.setup_channel(alt_chan, host, creds, **kw)
+      unless alt_chan.nil?
+        fail(TypeError, '!Channel') unless alt_chan.is_a?(Core::Channel)
+        return alt_chan
+      end
+      return Core::Channel.new(host, kw) if creds.nil?
+      fail(TypeError, '!Credentials') unless creds.is_a?(Core::Credentials)
+      Core::Channel.new(host, kw, creds)
+    end
+
+    # check_update_metadata is used by #initialize verify that it's a Proc.
+    def self.check_update_metadata(update_metadata)
+      return update_metadata if update_metadata.nil?
+      fail(TypeError, '!is_a?Proc') unless update_metadata.is_a?(Proc)
+      update_metadata
+    end
+
     # Creates a new ClientStub.
     #
     # Minimally, a stub is created with the just the host of the gRPC service
@@ -73,40 +92,17 @@ module GRPC
     # @param update_metadata a func that updates metadata as described above
     # @param kw [KeywordArgs]the channel arguments
     def initialize(host, q,
-                   channel_override:nil,
+                   channel_override: nil,
                    deadline: DEFAULT_DEADLINE,
                    creds: nil,
                    update_metadata: nil,
                    **kw)
-      unless q.is_a? Core::CompletionQueue
-        fail(ArgumentError, 'not a CompletionQueue')
-      end
+      fail(TypeError, '!CompletionQueue') unless q.is_a?(Core::CompletionQueue)
       @queue = q
-
-      # set the channel instance
-      if !channel_override.nil?
-        ch = channel_override
-        fail(ArgumentError, 'not a Channel') unless ch.is_a? Core::Channel
-      else
-        if creds.nil?
-          ch = Core::Channel.new(host, kw)
-        elsif !creds.is_a?(Core::Credentials)
-          fail(ArgumentError, 'not a Credentials')
-        else
-          ch = Core::Channel.new(host, kw, creds)
-        end
-      end
-      @ch = ch
-
-      @update_metadata = nil
-      unless update_metadata.nil?
-        unless update_metadata.is_a? Proc
-          fail(ArgumentError, 'update_metadata is not a Proc')
-        end
-        @update_metadata = update_metadata
-      end
-
-      @host = host
+      @ch = ClientStub.setup_channel(channel_override, host, creds, **kw)
+      @update_metadata = ClientStub.check_update_metadata(update_metadata)
+      alt_host = kw[Core::Channel::SSL_TARGET]
+      @host = alt_host.nil? ? host : alt_host
       @deadline = deadline
     end
 
@@ -400,12 +396,7 @@ module GRPC
     # @param deadline [TimeConst]
     def new_active_call(ch, marshal, unmarshal, deadline = nil)
       absolute_deadline = Core::TimeConsts.from_relative_time(deadline)
-      # It should be OK to to pass the hostname:port to create_call, but at
-      # the moment this fails a security check.  This will be corrected.
-      #
-      # TODO: # remove this after create_call is updated
-      host = @host.split(':')[0]
-      call = @ch.create_call(ch, host, absolute_deadline)
+      call = @ch.create_call(ch, @host, absolute_deadline)
       ActiveCall.new(call, @queue, marshal, unmarshal, absolute_deadline,
                      started: false)
     end
diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb
index 6938f718922cfc21b463b2cbf8aa70f12218d038..35e84023be952df4fa5e846a14a8d26d4c166e26 100644
--- a/src/ruby/lib/grpc/generic/rpc_server.rb
+++ b/src/ruby/lib/grpc/generic/rpc_server.rb
@@ -81,7 +81,6 @@ module GRPC
                    max_waiting_requests:DEFAULT_MAX_WAITING_REQUESTS,
                    poll_period:INFINITE_FUTURE,
                    completion_queue_override:nil,
-                   creds:nil,
                    server_override:nil,
                    **kw)
       if completion_queue_override.nil?
@@ -95,13 +94,7 @@ module GRPC
       @cq = cq
 
       if server_override.nil?
-        if creds.nil?
-          srv = Core::Server.new(@cq, kw)
-        elsif !creds.is_a? Core::ServerCredentials
-          fail(ArgumentError, 'not a ServerCredentials')
-        else
-          srv = Core::Server.new(@cq, kw, creds)
-        end
+        srv = Core::Server.new(@cq, kw)
       else
         srv = server_override
         fail(ArgumentError, 'not a Server') unless srv.is_a? Core::Server
diff --git a/src/ruby/spec/client_server_spec.rb b/src/ruby/spec/client_server_spec.rb
index 030ff328f217db820f857ed2619cc9da11a679ca..49a2d3bb4df9fd00b7f5955b3fb70f66bba77e6d 100644
--- a/src/ruby/spec/client_server_spec.rb
+++ b/src/ruby/spec/client_server_spec.rb
@@ -95,7 +95,7 @@ shared_context 'setup: tags' do
   end
 
   def new_client_call
-    @ch.create_call('/method', 'localhost', deadline)
+    @ch.create_call('/method', 'foo.test.google.fr', deadline)
   end
 end
 
@@ -346,12 +346,12 @@ end
 describe 'the secure http client/server' do
   before(:example) do
     certs = load_test_certs
-    server_host = 'localhost:0'
+    server_host = '0.0.0.0:0'
     @client_queue = GRPC::Core::CompletionQueue.new
     @server_queue = GRPC::Core::CompletionQueue.new
     server_creds = GRPC::Core::ServerCredentials.new(nil, certs[1], certs[2])
-    @server = GRPC::Core::Server.new(@server_queue, nil, server_creds)
-    server_port = @server.add_http2_port(server_host, true)
+    @server = GRPC::Core::Server.new(@server_queue, nil)
+    server_port = @server.add_http2_port(server_host, server_creds)
     @server.start
     args = { Channel::SSL_TARGET => 'foo.test.google.fr' }
     @ch = Channel.new("0.0.0.0:#{server_port}", args,
@@ -362,11 +362,9 @@ describe 'the secure http client/server' do
     @server.close
   end
 
-  # TODO: uncomment after updating the to the new c api
-  # it_behaves_like 'basic GRPC message delivery is OK' do
-  # end
+  it_behaves_like 'basic GRPC message delivery is OK' do
+  end
 
-  # TODO: uncomment after updating the to the new c api
-  # it_behaves_like 'GRPC metadata delivery works OK' do
-  # end
+  it_behaves_like 'GRPC metadata delivery works OK' do
+  end
 end
diff --git a/src/ruby/spec/generic/rpc_server_spec.rb b/src/ruby/spec/generic/rpc_server_spec.rb
index e8c706044617a7775d84ce65f5bb448438dc4b92..d5421d400c99c9f14ae2c6c0609760ee623abe45 100644
--- a/src/ruby/spec/generic/rpc_server_spec.rb
+++ b/src/ruby/spec/generic/rpc_server_spec.rb
@@ -164,19 +164,6 @@ describe GRPC::RpcServer do
       expect(&blk).to raise_error
     end
 
-    it 'can be created with the creds as valid ServerCedentials' do
-      certs = load_test_certs
-      server_creds = GRPC::Core::ServerCredentials.new(nil, certs[1], certs[2])
-      blk = proc do
-        opts = {
-          a_channel_arg: 'an_arg',
-          creds: server_creds
-        }
-        RpcServer.new(**opts)
-      end
-      expect(&blk).to_not raise_error
-    end
-
     it 'can be created with a server override' do
       opts = { a_channel_arg: 'an_arg', server_override: @server }
       blk = proc do
diff --git a/src/ruby/spec/server_spec.rb b/src/ruby/spec/server_spec.rb
index 5b81f195371d9b8a3b2301cc335b8bf160d7f63b..a47e484f9719c28c27fd4c6c485c74e08942bc45 100644
--- a/src/ruby/spec/server_spec.rb
+++ b/src/ruby/spec/server_spec.rb
@@ -118,10 +118,11 @@ describe Server do
     end
 
     describe 'for secure servers' do
+      let(:cert) { create_test_cert }
       it 'runs without failing' do
         blk = proc do
           s = Server.new(@cq, nil)
-          s.add_http2_port('localhost:0', true)
+          s.add_http2_port('localhost:0', cert)
           s.close
         end
         expect(&blk).to_not raise_error
@@ -130,7 +131,7 @@ describe Server do
       it 'fails if the server is closed' do
         s = Server.new(@cq, nil)
         s.close
-        blk = proc { s.add_http2_port('localhost:0', true) }
+        blk = proc { s.add_http2_port('localhost:0', cert) }
         expect(&blk).to raise_error(RuntimeError)
       end
     end
@@ -138,7 +139,7 @@ describe Server do
 
   shared_examples '#new' do
     it 'takes a completion queue with nil channel args' do
-      expect { Server.new(@cq, nil, create_test_cert) }.to_not raise_error
+      expect { Server.new(@cq, nil) }.to_not raise_error
     end
 
     it 'does not take a hash with bad keys as channel args' do
@@ -195,14 +196,6 @@ describe Server do
     it_behaves_like '#new'
   end
 
-  describe '#new with a secure channel' do
-    def construct_with_args(a)
-      proc { Server.new(@cq, a, create_test_cert) }
-    end
-
-    it_behaves_like '#new'
-  end
-
   def start_a_server
     s = Server.new(@cq, nil)
     s.add_http2_port('0.0.0.0:0')
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 24fd450dff58d3bad204d37e6980a53fade756d5..6573e03f7f55746d73cc48d8fdcd9e1fd4236ada 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -917,7 +917,7 @@ PUBLIC_HEADERS_C += \\
 LIB${lib.name.upper()}_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIB${lib.name.upper()}_SRC))))
 
 ## If the library requires OpenSSL with ALPN, let's add some restrictions.
-% if lib.get('secure', True):
+% if lib.get('secure', 'check') == 'yes' or lib.get('secure', 'check') == 'check':
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure libraries if you don't have OpenSSL with ALPN.
@@ -993,14 +993,14 @@ $(LIBDIR)/$(CONFIG)/lib${lib.name}.a: $(ZLIB_DEP)\
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/lib${lib.name}.a
 	$(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/lib${lib.name}.a $(LIB${lib.name.upper()}_OBJS)
 % if lib.get('baselib', False):
-% if lib.get('secure', True):
-	$(Q) rm -rf tmp-merge
-	$(Q) mkdir tmp-merge
-	$(Q) ( cd tmp-merge ; $(AR) x ../$(LIBDIR)/$(CONFIG)/lib${lib.name}.a )
-	$(Q) for l in $(OPENSSL_MERGE_LIBS) ; do ( cd tmp-merge ; <%text>ar x ../$${l}</%text> ) ; done
-	$(Q) rm -f $(LIBDIR)/$(CONFIG)/lib${lib.name}.a tmp-merge/__.SYMDEF*
-	$(Q) ar rcs $(LIBDIR)/$(CONFIG)/lib${lib.name}.a tmp-merge/*
-	$(Q) rm -rf tmp-merge
+% if lib.get('secure', 'check') == 'yes':
+	$(Q) rm -rf tmp-merge-${lib.name}
+	$(Q) mkdir tmp-merge-${lib.name}
+	$(Q) ( cd tmp-merge-${lib.name} ; $(AR) x ../$(LIBDIR)/$(CONFIG)/lib${lib.name}.a )
+	$(Q) for l in $(OPENSSL_MERGE_LIBS) ; do ( cd tmp-merge-${lib.name} ; <%text>ar x ../$${l}</%text> ) ; done
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/lib${lib.name}.a tmp-merge-${lib.name}/__.SYMDEF*
+	$(Q) ar rcs $(LIBDIR)/$(CONFIG)/lib${lib.name}.a tmp-merge-${lib.name}/*
+	$(Q) rm -rf tmp-merge-${lib.name}
 % endif
 % endif
 ifeq ($(SYSTEM),Darwin)
@@ -1028,8 +1028,10 @@ endif
     mingw_libs = mingw_libs + ' -l' + dep + '-imp'
     mingw_lib_deps = mingw_lib_deps + '$(LIBDIR)/$(CONFIG)/' + dep + '.$(SHARED_EXT)'
 
-  if lib.get('secure', True):
+  if lib.get('secure', 'check') == 'yes':
     common = common + ' $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS)'
+
+  if lib.get('secure', 'check') == 'yes' or lib.get('secure', 'check') == 'check':
     lib_deps = lib_deps + ' $(OPENSSL_DEP)'
     mingw_lib_deps = mingw_lib_deps + ' $(OPENSSL_DEP)'
 
@@ -1056,7 +1058,7 @@ else
 endif
 endif
 % endif
-% if lib.get('secure', True):
+% if lib.get('secure', 'check') == 'yes' or lib.get('secure', 'check') == 'check':
 ## If the lib was secure, we have to close the Makefile's if that tested
 ## the presence of an ALPN-capable OpenSSL.
 
@@ -1069,13 +1071,13 @@ endif
 endif
 % endif
 
-% if lib.get('secure', True):
+% if lib.get('secure', 'check') == 'yes' or lib.get('secure', 'check') == 'check':
 ifneq ($(NO_SECURE),true)
 % endif
 ifneq ($(NO_DEPS),true)
 -include $(LIB${lib.name.upper()}_OBJS:.o=.dep)
 endif
-% if lib.get('secure', True):
+% if lib.get('secure', 'check') == 'yes' or lib.get('secure', 'check') == 'check':
 endif
 % endif
 
@@ -1102,7 +1104,7 @@ ${tgt.name.upper()}_SRC = \\
 
 ${tgt.name.upper()}_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(${tgt.name.upper()}_SRC))))
 
-% if tgt.get('secure', True):
+% if tgt.get('secure', 'check') == 'yes' or tgt.get('secure', 'check') == 'check':
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL with ALPN.
@@ -1176,7 +1178,7 @@ $(BINDIR)/$(CONFIG)/${tgt.name}: $(${tgt.name.upper()}_OBJS)\
 % endif
 % if tgt.build == 'protoc':
  $(HOST_LDLIBS_PROTOC)\
-% elif tgt.get('secure', True):
+% elif tgt.get('secure', 'check') == 'yes' or tgt.get('secure', 'check') == 'check':
  $(LDLIBS_SECURE)\
 % endif
  -o $(BINDIR)/$(CONFIG)/${tgt.name}
@@ -1184,7 +1186,7 @@ $(BINDIR)/$(CONFIG)/${tgt.name}: $(${tgt.name.upper()}_OBJS)\
 
 endif
 % endif
-% if tgt.get('secure', True):
+% if tgt.get('secure', 'check') == 'yes' or tgt.get('secure', 'check') == 'check':
 
 endif
 % endif
@@ -1199,13 +1201,13 @@ $(OBJDIR)/$(CONFIG)/${os.path.splitext(src)[0]}.o: \
 
 deps_${tgt.name}: $(${tgt.name.upper()}_OBJS:.o=.dep)
 
-% if tgt.get('secure', True):
+% if tgt.get('secure', 'check') == 'yes' or tgt.get('secure', 'check') == 'check':
 ifneq ($(NO_SECURE),true)
 % endif
 ifneq ($(NO_DEPS),true)
 -include $(${tgt.name.upper()}_OBJS:.o=.dep)
 endif
-% if tgt.get('secure', True):
+% if tgt.get('secure', 'check') == 'yes' or tgt.get('secure', 'check') == 'check':
 endif
 % endif
 </%def>
diff --git a/test/core/echo/server.c b/test/core/echo/server.c
index bc84645a0405572d4a9a122a42c761095a614797..e888a0c8770984b2242d2ef1af9aa89f1a0908da 100644
--- a/test/core/echo/server.c
+++ b/test/core/echo/server.c
@@ -143,8 +143,8 @@ int main(int argc, char **argv) {
                                                     test_server1_cert};
     grpc_server_credentials *ssl_creds =
         grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1);
-    server = grpc_secure_server_create(ssl_creds, cq, &args);
-    GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr));
+    server = grpc_server_create(cq, &args);
+    GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, ssl_creds));
     grpc_server_credentials_release(ssl_creds);
   } else {
     server = grpc_server_create(cq, &args);
diff --git a/test/core/end2end/fixtures/chttp2_fake_security.c b/test/core/end2end/fixtures/chttp2_fake_security.c
index 247d1fd32232d2a2183e91764004e3c53d9051f6..047d482be340f75da8495a6941471f12c112240d 100644
--- a/test/core/end2end/fixtures/chttp2_fake_security.c
+++ b/test/core/end2end/fixtures/chttp2_fake_security.c
@@ -84,9 +84,9 @@ static void chttp2_init_server_secure_fullstack(
     grpc_server_destroy(f->server);
   }
   f->server =
-      grpc_secure_server_create(server_creds, f->server_cq, server_args);
+      grpc_server_create(f->server_cq, server_args);
+  GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds));
   grpc_server_credentials_release(server_creds);
-  GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr));
   grpc_server_start(f->server);
 }
 
diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
index 3df2e40806dcc2eeb04deae87a38fcaf469ed251..16433f5f87cdfee694bccf088c0b4865b05ef428 100644
--- a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
+++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
@@ -87,9 +87,9 @@ static void chttp2_init_server_secure_fullstack(
     grpc_server_destroy(f->server);
   }
   f->server =
-      grpc_secure_server_create(server_creds, f->server_cq, server_args);
+      grpc_server_create(f->server_cq, server_args);
+  GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds));
   grpc_server_credentials_release(server_creds);
-  GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr));
   grpc_server_start(f->server);
 }
 
diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
index 8d6c561d25d3a14e5b0fe7faccc1cf7eb67ef605..99031df8e5459b996314626607511e06d7982e2a 100644
--- a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
+++ b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
@@ -85,9 +85,9 @@ static void chttp2_init_server_secure_fullstack(
     grpc_server_destroy(f->server);
   }
   f->server =
-      grpc_secure_server_create(server_creds, f->server_cq, server_args);
+      grpc_server_create(f->server_cq, server_args);
+  GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds));
   grpc_server_credentials_release(server_creds);
-  GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr));
   grpc_server_start(f->server);
 }
 
diff --git a/test/core/end2end/gen_build_json.py b/test/core/end2end/gen_build_json.py
index 96d855579925f87e0261276ad7f28006f27a49fd..67fc0a6e539457c4a914d6a24b028b0db187c0ac 100755
--- a/test/core/end2end/gen_build_json.py
+++ b/test/core/end2end/gen_build_json.py
@@ -107,7 +107,7 @@ def main():
               'name': 'end2end_fixture_%s' % f,
               'build': 'private',
               'language': 'c',
-              'secure': True,
+              'secure': 'check',
               'src': ['test/core/end2end/fixtures/%s.c' % f]
           }
           for f in END2END_FIXTURES] + [
@@ -115,7 +115,7 @@ def main():
               'name': 'end2end_test_%s' % t,
               'build': 'private',
               'language': 'c',
-              'secure': False,
+              'secure': 'no',
               'src': ['test/core/end2end/tests/%s.c' % t],
               'headers': ['test/core/end2end/tests/cancel_test_helpers.h']
           }
diff --git a/test/core/fling/server.c b/test/core/fling/server.c
index 5c1ab14d03477cced84afb85cd07cc1d2408e73b..ca39cd84b13407d0d6c01c5b7a5f3d4737f26fd6 100644
--- a/test/core/fling/server.c
+++ b/test/core/fling/server.c
@@ -205,8 +205,8 @@ int main(int argc, char **argv) {
                                                     test_server1_cert};
     grpc_server_credentials *ssl_creds =
         grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1);
-    server = grpc_secure_server_create(ssl_creds, cq, NULL);
-    GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr));
+    server = grpc_server_create(cq, NULL);
+    GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, ssl_creds));
     grpc_server_credentials_release(ssl_creds);
   } else {
     server = grpc_server_create(cq, NULL);
diff --git a/test/core/network_benchmarks/low_level_ping_pong.c b/test/core/network_benchmarks/low_level_ping_pong.c
index a084c55a35bf8ae787a767d6ffaf2ff047a471cf..7d74d0e0781f015c8c219ee756eb23067251a762 100644
--- a/test/core/network_benchmarks/low_level_ping_pong.c
+++ b/test/core/network_benchmarks/low_level_ping_pong.c
@@ -654,7 +654,7 @@ int main(int argc, char **argv) {
   }
 
   for (i = 0; i < GPR_ARRAY_SIZE(test_strategies); ++i) {
-    if (!strcmp(test_strategies[i].name, read_strategy)) {
+    if (strcmp(test_strategies[i].name, read_strategy) == 0) {
       test_strategy = &test_strategies[i];
     }
   }
diff --git a/test/core/security/base64_test.c b/test/core/security/base64_test.c
index bfd5c4877728f5c363aef374d1976dea9ae50315..a922896bc3d59d2019706e623b2e050d7b4c0e03 100644
--- a/test/core/security/base64_test.c
+++ b/test/core/security/base64_test.c
@@ -58,8 +58,8 @@ static void test_simple_encode_decode_b64(int url_safe, int multiline) {
       grpc_base64_encode(hello, strlen(hello), url_safe, multiline);
   gpr_slice hello_slice = grpc_base64_decode(hello_b64, url_safe);
   GPR_ASSERT(GPR_SLICE_LENGTH(hello_slice) == strlen(hello));
-  GPR_ASSERT(!strncmp((const char *)GPR_SLICE_START_PTR(hello_slice), hello,
-                      GPR_SLICE_LENGTH(hello_slice)));
+  GPR_ASSERT(strncmp((const char *)GPR_SLICE_START_PTR(hello_slice), hello,
+                     GPR_SLICE_LENGTH(hello_slice)) == 0);
 
   gpr_slice_unref(hello_slice);
   gpr_free(hello_b64);
@@ -141,31 +141,31 @@ static void test_rfc4648_test_vectors(void) {
   char *b64;
 
   b64 = grpc_base64_encode("", 0, 0, 0);
-  GPR_ASSERT(!strcmp("", b64));
+  GPR_ASSERT(strcmp("", b64) == 0);
   gpr_free(b64);
 
   b64 = grpc_base64_encode("f", 1, 0, 0);
-  GPR_ASSERT(!strcmp("Zg==", b64));
+  GPR_ASSERT(strcmp("Zg==", b64) == 0);
   gpr_free(b64);
 
   b64 = grpc_base64_encode("fo", 2, 0, 0);
-  GPR_ASSERT(!strcmp("Zm8=", b64));
+  GPR_ASSERT(strcmp("Zm8=", b64) == 0);
   gpr_free(b64);
 
   b64 = grpc_base64_encode("foo", 3, 0, 0);
-  GPR_ASSERT(!strcmp("Zm9v", b64));
+  GPR_ASSERT(strcmp("Zm9v", b64) == 0);
   gpr_free(b64);
 
   b64 = grpc_base64_encode("foob", 4, 0, 0);
-  GPR_ASSERT(!strcmp("Zm9vYg==", b64));
+  GPR_ASSERT(strcmp("Zm9vYg==", b64) == 0);
   gpr_free(b64);
 
   b64 = grpc_base64_encode("fooba", 5, 0, 0);
-  GPR_ASSERT(!strcmp("Zm9vYmE=", b64));
+  GPR_ASSERT(strcmp("Zm9vYmE=", b64) == 0);
   gpr_free(b64);
 
   b64 = grpc_base64_encode("foobar", 6, 0, 0);
-  GPR_ASSERT(!strcmp("Zm9vYmFy", b64));
+  GPR_ASSERT(strcmp("Zm9vYmFy", b64) == 0);
   gpr_free(b64);
 }
 
diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c
index 50ef2d7657e3ee2a907e49e97dd0744ed2dfe40a..078462410ad6df115e3efc064e763561f7c3f818 100644
--- a/test/core/security/credentials_test.c
+++ b/test/core/security/credentials_test.c
@@ -143,9 +143,10 @@ static void test_oauth2_token_fetcher_creds_parsing_ok(void) {
              GRPC_CREDENTIALS_OK);
   GPR_ASSERT(token_lifetime.tv_sec == 3599);
   GPR_ASSERT(token_lifetime.tv_nsec == 0);
-  GPR_ASSERT(!strcmp(grpc_mdstr_as_c_string(token_elem->key), "Authorization"));
-  GPR_ASSERT(!strcmp(grpc_mdstr_as_c_string(token_elem->value),
-                     "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"));
+  GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(token_elem->key),
+                    "Authorization") == 0);
+  GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(token_elem->value),
+                    "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_") == 0);
   grpc_mdelem_unref(token_elem);
   grpc_mdctx_unref(ctx);
 }
@@ -294,15 +295,16 @@ static void test_ssl_oauth2_composite_creds(void) {
       grpc_composite_credentials_create(ssl_creds, oauth2_creds);
   grpc_credentials_unref(ssl_creds);
   grpc_credentials_unref(oauth2_creds);
-  GPR_ASSERT(!strcmp(composite_creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE));
+  GPR_ASSERT(strcmp(composite_creds->type,
+                    GRPC_CREDENTIALS_TYPE_COMPOSITE) == 0);
   GPR_ASSERT(grpc_credentials_has_request_metadata(composite_creds));
   GPR_ASSERT(!grpc_credentials_has_request_metadata_only(composite_creds));
   creds_array = grpc_composite_credentials_get_credentials(composite_creds);
   GPR_ASSERT(creds_array->num_creds == 2);
-  GPR_ASSERT(
-      !strcmp(creds_array->creds_array[0]->type, GRPC_CREDENTIALS_TYPE_SSL));
-  GPR_ASSERT(
-      !strcmp(creds_array->creds_array[1]->type, GRPC_CREDENTIALS_TYPE_OAUTH2));
+  GPR_ASSERT(strcmp(creds_array->creds_array[0]->type,
+                    GRPC_CREDENTIALS_TYPE_SSL) == 0);
+  GPR_ASSERT(strcmp(creds_array->creds_array[1]->type,
+                    GRPC_CREDENTIALS_TYPE_OAUTH2) == 0);
   grpc_credentials_get_request_metadata(composite_creds, test_service_url,
                                         check_ssl_oauth2_composite_metadata,
                                         composite_creds);
@@ -338,17 +340,18 @@ static void test_ssl_oauth2_iam_composite_creds(void) {
   grpc_credentials_unref(oauth2_creds);
   grpc_credentials_unref(aux_creds);
   grpc_credentials_unref(iam_creds);
-  GPR_ASSERT(!strcmp(composite_creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE));
+  GPR_ASSERT(strcmp(composite_creds->type,
+                    GRPC_CREDENTIALS_TYPE_COMPOSITE) == 0);
   GPR_ASSERT(grpc_credentials_has_request_metadata(composite_creds));
   GPR_ASSERT(!grpc_credentials_has_request_metadata_only(composite_creds));
   creds_array = grpc_composite_credentials_get_credentials(composite_creds);
   GPR_ASSERT(creds_array->num_creds == 3);
-  GPR_ASSERT(
-      !strcmp(creds_array->creds_array[0]->type, GRPC_CREDENTIALS_TYPE_SSL));
-  GPR_ASSERT(
-      !strcmp(creds_array->creds_array[1]->type, GRPC_CREDENTIALS_TYPE_OAUTH2));
-  GPR_ASSERT(
-      !strcmp(creds_array->creds_array[2]->type, GRPC_CREDENTIALS_TYPE_IAM));
+  GPR_ASSERT(strcmp(creds_array->creds_array[0]->type,
+                    GRPC_CREDENTIALS_TYPE_SSL) == 0);
+  GPR_ASSERT(strcmp(creds_array->creds_array[1]->type,
+                    GRPC_CREDENTIALS_TYPE_OAUTH2) == 0);
+  GPR_ASSERT(strcmp(creds_array->creds_array[2]->type,
+                    GRPC_CREDENTIALS_TYPE_IAM) == 0);
   grpc_credentials_get_request_metadata(composite_creds, test_service_url,
                                         check_ssl_oauth2_iam_composite_metadata,
                                         composite_creds);
@@ -359,12 +362,12 @@ static void on_oauth2_creds_get_metadata_success(
     grpc_credentials_status status) {
   GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
   GPR_ASSERT(num_md == 1);
-  GPR_ASSERT(
-      !strcmp(grpc_mdstr_as_c_string(md_elems[0]->key), "Authorization"));
-  GPR_ASSERT(!strcmp(grpc_mdstr_as_c_string(md_elems[0]->value),
-                     "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"));
+  GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(md_elems[0]->key),
+                    "Authorization") == 0);
+  GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(md_elems[0]->value),
+                    "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_") == 0);
   GPR_ASSERT(user_data != NULL);
-  GPR_ASSERT(!strcmp((const char *)user_data, test_user_data));
+  GPR_ASSERT(strcmp((const char *)user_data, test_user_data) == 0);
 }
 
 static void on_oauth2_creds_get_metadata_failure(
@@ -373,19 +376,19 @@ static void on_oauth2_creds_get_metadata_failure(
   GPR_ASSERT(status == GRPC_CREDENTIALS_ERROR);
   GPR_ASSERT(num_md == 0);
   GPR_ASSERT(user_data != NULL);
-  GPR_ASSERT(!strcmp((const char *)user_data, test_user_data));
+  GPR_ASSERT(strcmp((const char *)user_data, test_user_data) == 0);
 }
 
 static void validate_compute_engine_http_request(
     const grpc_httpcli_request *request) {
   GPR_ASSERT(!request->use_ssl);
-  GPR_ASSERT(!strcmp(request->host, "metadata"));
-  GPR_ASSERT(
-      !strcmp(request->path,
-              "/computeMetadata/v1/instance/service-accounts/default/token"));
+  GPR_ASSERT(strcmp(request->host, "metadata") == 0);
+  GPR_ASSERT(strcmp(request->path,
+             "/computeMetadata/v1/instance/service-accounts/default/token")
+             == 0);
   GPR_ASSERT(request->hdr_count == 1);
-  GPR_ASSERT(!strcmp(request->hdrs[0].key, "Metadata-Flavor"));
-  GPR_ASSERT(!strcmp(request->hdrs[0].value, "Google"));
+  GPR_ASSERT(strcmp(request->hdrs[0].key, "Metadata-Flavor") == 0);
+  GPR_ASSERT(strcmp(request->hdrs[0].value, "Google") == 0);
 }
 
 static int compute_engine_httpcli_get_success_override(
@@ -467,19 +470,19 @@ static void validate_jwt_encode_and_sign_params(
   GPR_ASSERT(json_key->private_key != NULL);
   GPR_ASSERT(RSA_check_key(json_key->private_key));
   GPR_ASSERT(json_key->type != NULL &&
-             !(strcmp(json_key->type, "service_account")));
+             strcmp(json_key->type, "service_account") == 0);
   GPR_ASSERT(json_key->private_key_id != NULL &&
-             !strcmp(json_key->private_key_id,
-                     "e6b5137873db8d2ef81e06a47289e6434ec8a165"));
+             strcmp(json_key->private_key_id,
+                    "e6b5137873db8d2ef81e06a47289e6434ec8a165") == 0);
   GPR_ASSERT(json_key->client_id != NULL &&
-             !strcmp(json_key->client_id,
-                     "777-abaslkan11hlb6nmim3bpspl31ud.apps."
-                     "googleusercontent.com"));
+             strcmp(json_key->client_id,
+                    "777-abaslkan11hlb6nmim3bpspl31ud.apps."
+                    "googleusercontent.com") == 0);
   GPR_ASSERT(json_key->client_email != NULL &&
-             !strcmp(json_key->client_email,
-                     "777-abaslkan11hlb6nmim3bpspl31ud@developer."
-                     "gserviceaccount.com"));
-  if (scope != NULL) GPR_ASSERT(!strcmp(scope, test_scope));
+             strcmp(json_key->client_email,
+                    "777-abaslkan11hlb6nmim3bpspl31ud@developer."
+                    "gserviceaccount.com") == 0);
+  if (scope != NULL) GPR_ASSERT(strcmp(scope, test_scope) == 0);
   GPR_ASSERT(!gpr_time_cmp(token_lifetime, grpc_max_auth_token_lifetime));
 }
 
@@ -517,12 +520,12 @@ static void validate_service_account_http_request(
   GPR_ASSERT(!memcmp(expected_body, body, body_size));
   gpr_free(expected_body);
   GPR_ASSERT(request->use_ssl);
-  GPR_ASSERT(!strcmp(request->host, "www.googleapis.com"));
-  GPR_ASSERT(!strcmp(request->path, "/oauth2/v3/token"));
+  GPR_ASSERT(strcmp(request->host, "www.googleapis.com") == 0);
+  GPR_ASSERT(strcmp(request->path, "/oauth2/v3/token") == 0);
   GPR_ASSERT(request->hdr_count == 1);
-  GPR_ASSERT(!strcmp(request->hdrs[0].key, "Content-Type"));
-  GPR_ASSERT(
-      !strcmp(request->hdrs[0].value, "application/x-www-form-urlencoded"));
+  GPR_ASSERT(strcmp(request->hdrs[0].key, "Content-Type") == 0);
+  GPR_ASSERT(strcmp(request->hdrs[0].value,
+                    "application/x-www-form-urlencoded") == 0);
 }
 
 static int service_account_httpcli_post_success(
@@ -626,12 +629,12 @@ static void on_jwt_creds_get_metadata_success(void *user_data,
   gpr_asprintf(&expected_md_value, "Bearer %s", test_signed_jwt);
   GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
   GPR_ASSERT(num_md == 1);
-  GPR_ASSERT(
-      !strcmp(grpc_mdstr_as_c_string(md_elems[0]->key), "Authorization"));
-  GPR_ASSERT(
-      !strcmp(grpc_mdstr_as_c_string(md_elems[0]->value), expected_md_value));
+  GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(md_elems[0]->key),
+                    "Authorization") == 0);
+  GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(md_elems[0]->value),
+                    expected_md_value) == 0);
   GPR_ASSERT(user_data != NULL);
-  GPR_ASSERT(!strcmp((const char *)user_data, test_user_data));
+  GPR_ASSERT(strcmp((const char *)user_data, test_user_data) == 0);
   gpr_free(expected_md_value);
 }
 
@@ -642,7 +645,7 @@ static void on_jwt_creds_get_metadata_failure(void *user_data,
   GPR_ASSERT(status == GRPC_CREDENTIALS_ERROR);
   GPR_ASSERT(num_md == 0);
   GPR_ASSERT(user_data != NULL);
-  GPR_ASSERT(!strcmp((const char *)user_data, test_user_data));
+  GPR_ASSERT(strcmp((const char *)user_data, test_user_data) == 0);
 }
 
 static void test_jwt_creds_success(void) {
diff --git a/test/core/security/json_token_test.c b/test/core/security/json_token_test.c
index fae911721adf8b6063ab13bc1441084628d7abf3..ca5b8891023e7e216e5aea9d5eccbd5ccdb68dda 100644
--- a/test/core/security/json_token_test.c
+++ b/test/core/security/json_token_test.c
@@ -102,18 +102,18 @@ static void test_parse_json_key_success(void) {
       grpc_auth_json_key_create_from_string(json_string);
   GPR_ASSERT(grpc_auth_json_key_is_valid(&json_key));
   GPR_ASSERT(json_key.type != NULL &&
-             !(strcmp(json_key.type, "service_account")));
+             strcmp(json_key.type, "service_account") == 0);
   GPR_ASSERT(json_key.private_key_id != NULL &&
-             !strcmp(json_key.private_key_id,
-                     "e6b5137873db8d2ef81e06a47289e6434ec8a165"));
+             strcmp(json_key.private_key_id,
+                    "e6b5137873db8d2ef81e06a47289e6434ec8a165") == 0);
   GPR_ASSERT(json_key.client_id != NULL &&
-             !strcmp(json_key.client_id,
-                     "777-abaslkan11hlb6nmim3bpspl31ud.apps."
-                     "googleusercontent.com"));
+             strcmp(json_key.client_id,
+                    "777-abaslkan11hlb6nmim3bpspl31ud.apps."
+                    "googleusercontent.com") == 0);
   GPR_ASSERT(json_key.client_email != NULL &&
-             !strcmp(json_key.client_email,
-                     "777-abaslkan11hlb6nmim3bpspl31ud@developer."
-                     "gserviceaccount.com"));
+             strcmp(json_key.client_email,
+                    "777-abaslkan11hlb6nmim3bpspl31ud@developer."
+                    "gserviceaccount.com") == 0);
   GPR_ASSERT(json_key.private_key != NULL);
   gpr_free(json_string);
   grpc_auth_json_key_destruct(&json_key);
@@ -248,15 +248,16 @@ static void check_jwt_header(grpc_json *header) {
   }
   GPR_ASSERT(alg != NULL);
   GPR_ASSERT(alg->type == GRPC_JSON_STRING);
-  GPR_ASSERT(!strcmp(alg->value, "RS256"));
+  GPR_ASSERT(strcmp(alg->value, "RS256") == 0);
 
   GPR_ASSERT(typ != NULL);
   GPR_ASSERT(typ->type == GRPC_JSON_STRING);
-  GPR_ASSERT(!strcmp(typ->value, "JWT"));
+  GPR_ASSERT(strcmp(typ->value, "JWT") == 0);
 
   GPR_ASSERT(kid != NULL);
   GPR_ASSERT(kid->type == GRPC_JSON_STRING);
-  GPR_ASSERT(!strcmp(kid->value, "e6b5137873db8d2ef81e06a47289e6434ec8a165"));
+  GPR_ASSERT(strcmp(kid->value,
+                    "e6b5137873db8d2ef81e06a47289e6434ec8a165") == 0);
 }
 
 static void check_jwt_claim(grpc_json *claim, const char *expected_audience,
@@ -290,27 +291,26 @@ static void check_jwt_claim(grpc_json *claim, const char *expected_audience,
 
   GPR_ASSERT(iss != NULL);
   GPR_ASSERT(iss->type == GRPC_JSON_STRING);
-  GPR_ASSERT(
-      !strcmp(
-          iss->value,
-          "777-abaslkan11hlb6nmim3bpspl31ud@developer.gserviceaccount.com"));
+  GPR_ASSERT(strcmp(iss->value,
+          "777-abaslkan11hlb6nmim3bpspl31ud@developer.gserviceaccount.com")
+             ==0);
 
   if (expected_scope != NULL) {
     GPR_ASSERT(scope != NULL);
     GPR_ASSERT(sub == NULL);
     GPR_ASSERT(scope->type == GRPC_JSON_STRING);
-    GPR_ASSERT(!strcmp(scope->value, expected_scope));
+    GPR_ASSERT(strcmp(scope->value, expected_scope) == 0);
   } else {
     /* Claims without scope must have a sub. */
     GPR_ASSERT(scope == NULL);
     GPR_ASSERT(sub != NULL);
     GPR_ASSERT(sub->type == GRPC_JSON_STRING);
-    GPR_ASSERT(!strcmp(iss->value, sub->value));
+    GPR_ASSERT(strcmp(iss->value, sub->value) == 0);
   }
 
   GPR_ASSERT(aud != NULL);
   GPR_ASSERT(aud->type == GRPC_JSON_STRING);
-  GPR_ASSERT(!strcmp(aud->value, expected_audience));
+  GPR_ASSERT(strcmp(aud->value, expected_audience) == 0);
 
   GPR_ASSERT(exp != NULL);
   GPR_ASSERT(exp->type == GRPC_JSON_NUMBER);
diff --git a/test/core/support/env_test.c b/test/core/support/env_test.c
index 1f16af87a5a6973ec01e58965404d5e9973b0596..aedf9313f3222f28e5ac7bc855ae1deba18cfa43 100644
--- a/test/core/support/env_test.c
+++ b/test/core/support/env_test.c
@@ -53,7 +53,7 @@ static void test_setenv_getenv(void) {
   gpr_setenv(name, value);
   retrieved_value = gpr_getenv(name);
   GPR_ASSERT(retrieved_value != NULL);
-  GPR_ASSERT(!strcmp(value, retrieved_value));
+  GPR_ASSERT(strcmp(value, retrieved_value) == 0);
   gpr_free(retrieved_value);
 }
 
diff --git a/test/core/surface/lame_client_test.c b/test/core/surface/lame_client_test.c
index 3653c5a1b0d48ba2a9298422fec8ade3e096a98e..f0420896eeb2754c7c89e2a1c1fdbc774ee8f790 100644
--- a/test/core/surface/lame_client_test.c
+++ b/test/core/surface/lame_client_test.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/surface/lame_client.h"
+#include <grpc/grpc.h>
 
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/util/test_config.h"
diff --git a/test/cpp/client/credentials_test.cc b/test/cpp/client/credentials_test.cc
index dc8d76d7eff5a920e4564120b982d79e9dafe21b..59ca33cc2979f33eb88a676ced1c305c99ba6c1e 100644
--- a/test/cpp/client/credentials_test.cc
+++ b/test/cpp/client/credentials_test.cc
@@ -47,8 +47,7 @@ class CredentialsTest : public ::testing::Test {
 
 TEST_F(CredentialsTest, InvalidServiceAccountCreds) {
   std::unique_ptr<Credentials> bad1 =
-      CredentialsFactory::ServiceAccountCredentials("", "",
-                                                    std::chrono::seconds(1));
+      ServiceAccountCredentials("", "", std::chrono::seconds(1));
   EXPECT_EQ(nullptr, bad1.get());
 }
 
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index 331a5ef8a02238692800fdb7075ea79121a5ccbb..70df9e14b21941206fa2cf92be65cf565c73e6d3 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -47,6 +47,7 @@
 #include <grpc++/server.h>
 #include <grpc++/server_builder.h>
 #include <grpc++/server_context.h>
+#include <grpc++/server_credentials.h>
 #include <grpc++/status.h>
 #include <grpc++/stream.h>
 #include "test/core/util/port.h"
@@ -84,7 +85,7 @@ class AsyncEnd2endTest : public ::testing::Test {
     server_address_ << "localhost:" << port;
     // Setup server
     ServerBuilder builder;
-    builder.AddPort(server_address_.str());
+    builder.AddPort(server_address_.str(), grpc::InsecureServerCredentials());
     builder.RegisterAsyncService(&service_);
     server_ = builder.BuildAndStart();
   }
@@ -102,8 +103,8 @@ class AsyncEnd2endTest : public ::testing::Test {
   }
 
   void ResetStub() {
-    std::shared_ptr<ChannelInterface> channel =
-        CreateChannelDeprecated(server_address_.str(), ChannelArguments());
+    std::shared_ptr<ChannelInterface> channel = CreateChannel(
+        server_address_.str(), InsecureCredentials(), ChannelArguments());
     stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel));
   }
 
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 1d5dfc4e34263c25a18c1476586717aa4b49f202..c586849349cbfa7237f5a1d373c0bb3eb5b74e16 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -47,6 +47,7 @@
 #include <grpc++/server.h>
 #include <grpc++/server_builder.h>
 #include <grpc++/server_context.h>
+#include <grpc++/server_credentials.h>
 #include <grpc++/status.h>
 #include <grpc++/stream.h>
 #include "test/core/util/port.h"
@@ -150,7 +151,7 @@ class End2endTest : public ::testing::Test {
     server_address_ << "localhost:" << port;
     // Setup server
     ServerBuilder builder;
-    builder.AddPort(server_address_.str());
+    builder.AddPort(server_address_.str(), InsecureServerCredentials());
     builder.RegisterService(&service_);
     builder.RegisterService(&dup_pkg_service_);
     builder.SetThreadPool(&thread_pool_);
@@ -160,8 +161,8 @@ class End2endTest : public ::testing::Test {
   void TearDown() GRPC_OVERRIDE { server_->Shutdown(); }
 
   void ResetStub() {
-    std::shared_ptr<ChannelInterface> channel =
-        CreateChannelDeprecated(server_address_.str(), ChannelArguments());
+    std::shared_ptr<ChannelInterface> channel = CreateChannel(
+        server_address_.str(), InsecureCredentials(), ChannelArguments());
     stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel));
   }
 
@@ -371,8 +372,8 @@ TEST_F(End2endTest, BidiStream) {
 // Talk to the two services with the same name but different package names.
 // The two stubs are created on the same channel.
 TEST_F(End2endTest, DiffPackageServices) {
-  std::shared_ptr<ChannelInterface> channel =
-      CreateChannelDeprecated(server_address_.str(), ChannelArguments());
+  std::shared_ptr<ChannelInterface> channel = CreateChannel(
+      server_address_.str(), InsecureCredentials(), ChannelArguments());
 
   EchoRequest request;
   EchoResponse response;
@@ -397,8 +398,7 @@ TEST_F(End2endTest, DiffPackageServices) {
 // rpc and stream should fail on bad credentials.
 TEST_F(End2endTest, BadCredentials) {
   std::unique_ptr<Credentials> bad_creds =
-      CredentialsFactory::ServiceAccountCredentials("", "",
-                                                    std::chrono::seconds(1));
+      ServiceAccountCredentials("", "", std::chrono::seconds(1));
   EXPECT_EQ(nullptr, bad_creds.get());
   std::shared_ptr<ChannelInterface> channel =
       CreateChannel(server_address_.str(), bad_creds, ChannelArguments());
diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc
index f7537c2d7b2ebaa53715364dfa21a797baaa1dc2..ae68f7a55649b79be08f46123f690c0058a98c8e 100644
--- a/test/cpp/interop/client.cc
+++ b/test/cpp/interop/client.cc
@@ -82,9 +82,10 @@ DEFINE_string(oauth_scope, "", "Scope for OAuth tokens.");
 
 using grpc::ChannelInterface;
 using grpc::ClientContext;
+using grpc::ComputeEngineCredentials;
 using grpc::CreateTestChannel;
 using grpc::Credentials;
-using grpc::CredentialsFactory;
+using grpc::ServiceAccountCredentials;
 using grpc::testing::ResponseParameters;
 using grpc::testing::SimpleRequest;
 using grpc::testing::SimpleResponse;
@@ -96,8 +97,8 @@ using grpc::testing::TestService;
 
 // 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 { }
+namespace google {}
+namespace gflags {}
 using namespace google;
 using namespace gflags;
 
@@ -135,14 +136,14 @@ std::shared_ptr<ChannelInterface> CreateChannelForTestCase(
     std::unique_ptr<Credentials> creds;
     GPR_ASSERT(FLAGS_enable_ssl);
     grpc::string json_key = GetServiceAccountJsonKey();
-    creds = CredentialsFactory::ServiceAccountCredentials(
-        json_key, FLAGS_oauth_scope, std::chrono::hours(1));
+    creds = ServiceAccountCredentials(json_key, FLAGS_oauth_scope,
+                                      std::chrono::hours(1));
     return CreateTestChannel(host_port, FLAGS_server_host_override,
                              FLAGS_enable_ssl, FLAGS_use_prod_roots, creds);
   } else if (test_case == "compute_engine_creds") {
     std::unique_ptr<Credentials> creds;
     GPR_ASSERT(FLAGS_enable_ssl);
-    creds = CredentialsFactory::ComputeEngineCredentials();
+    creds = ComputeEngineCredentials();
     return CreateTestChannel(host_port, FLAGS_server_host_override,
                              FLAGS_enable_ssl, FLAGS_use_prod_roots, creds);
   } else {
@@ -202,7 +203,7 @@ void DoComputeEngineCreds() {
   GPR_ASSERT(!response.username().empty());
   GPR_ASSERT(response.username().c_str() == FLAGS_default_service_account);
   GPR_ASSERT(!response.oauth_scope().empty());
-  const char *oauth_scope_str = response.oauth_scope().c_str();
+  const char* oauth_scope_str = response.oauth_scope().c_str();
   GPR_ASSERT(FLAGS_oauth_scope.find(oauth_scope_str) != grpc::string::npos);
   gpr_log(GPR_INFO, "Large unary with compute engine creds done.");
 }
@@ -221,7 +222,7 @@ void DoServiceAccountCreds() {
   GPR_ASSERT(!response.oauth_scope().empty());
   grpc::string json_key = GetServiceAccountJsonKey();
   GPR_ASSERT(json_key.find(response.username()) != grpc::string::npos);
-  const char *oauth_scope_str = response.oauth_scope().c_str();
+  const char* oauth_scope_str = response.oauth_scope().c_str();
   GPR_ASSERT(FLAGS_oauth_scope.find(oauth_scope_str) != grpc::string::npos);
   gpr_log(GPR_INFO, "Large unary with service account creds done.");
 }
diff --git a/test/cpp/interop/server.cc b/test/cpp/interop/server.cc
index 9810ff6622b2bb920ed09c1a98b2937c9b929ed7..743482e967103d291f151f391179ccab735152f3 100644
--- a/test/cpp/interop/server.cc
+++ b/test/cpp/interop/server.cc
@@ -60,7 +60,6 @@ using grpc::Server;
 using grpc::ServerBuilder;
 using grpc::ServerContext;
 using grpc::ServerCredentials;
-using grpc::ServerCredentialsFactory;
 using grpc::ServerReader;
 using grpc::ServerReaderWriter;
 using grpc::ServerWriter;
@@ -78,8 +77,8 @@ using grpc::Status;
 
 // 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 { }
+namespace google {}
+namespace gflags {}
 using namespace google;
 using namespace gflags;
 
@@ -211,15 +210,14 @@ void RunServer() {
   SimpleResponse response;
 
   ServerBuilder builder;
-  builder.AddPort(server_address.str());
   builder.RegisterService(&service);
+  std::shared_ptr<ServerCredentials> creds = grpc::InsecureServerCredentials();
   if (FLAGS_enable_ssl) {
     SslServerCredentialsOptions ssl_opts = {
         "", {{test_server1_key, test_server1_cert}}};
-    std::shared_ptr<ServerCredentials> creds =
-        ServerCredentialsFactory::SslCredentials(ssl_opts);
-    builder.SetCredentials(creds);
+    creds = grpc::SslServerCredentials(ssl_opts);
   }
+  builder.AddPort(server_address.str(), creds);
   std::unique_ptr<Server> server(builder.BuildAndStart());
   gpr_log(GPR_INFO, "Server listening on %s", server_address.str().c_str());
   while (!got_sigint) {
diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc
index 5eb9ff6521f77739f71002e7b1a5df058f18e29d..c6535bebf8856cb02fb5b89270f689f123114109 100644
--- a/test/cpp/qps/client_async.cc
+++ b/test/cpp/qps/client_async.cc
@@ -94,7 +94,7 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext {
     hist->Add((Timer::Now() - start_) * 1e9);
   }
 
-  void StartNewClone() {
+  void StartNewClone() GRPC_OVERRIDE {
     new ClientRpcContextUnaryImpl(stub_, req_, start_req_, callback_);
   }
 
@@ -175,7 +175,7 @@ class AsyncClient GRPC_FINAL : public Client {
     }
   }
 
-  void ThreadFunc(Histogram *histogram, size_t thread_idx) {
+  void ThreadFunc(Histogram *histogram, size_t thread_idx) GRPC_OVERRIDE {
     void *got_tag;
     bool ok;
     cli_cqs_[thread_idx]->Next(&got_tag, &ok);
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index 6d5df799a270439d8bb810d01a8c2243e4fa5db7..d29ca1de94776b60efc1b5502b9b373a78c98c25 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -103,7 +103,7 @@ ScenarioResult RunScenario(const ClientConfig& initial_client_config,
   for (size_t i = 0; i < num_servers; i++) {
     ServerData sd;
     sd.stub = std::move(Worker::NewStub(
-        CreateChannelDeprecated(workers[i], ChannelArguments())));
+        CreateChannel(workers[i], InsecureCredentials(), ChannelArguments())));
     ServerArgs args;
     *args.mutable_setup() = server_config;
     sd.stream = std::move(sd.stub->RunServer(alloc_context()));
@@ -131,8 +131,8 @@ ScenarioResult RunScenario(const ClientConfig& initial_client_config,
   vector<ClientData> clients;
   for (size_t i = 0; i < num_clients; i++) {
     ClientData cd;
-    cd.stub = std::move(Worker::NewStub(
-        CreateChannelDeprecated(workers[i + num_servers], ChannelArguments())));
+    cd.stub = std::move(Worker::NewStub(CreateChannel(
+        workers[i + num_servers], InsecureCredentials(), ChannelArguments())));
     ClientArgs args;
     *args.mutable_setup() = client_config;
     cd.stream = std::move(cd.stub->RunTest(alloc_context()));
diff --git a/test/cpp/qps/server.cc b/test/cpp/qps/server.cc
new file mode 100644
index 0000000000000000000000000000000000000000..005f0f9c5e2d78f440480a7e0440fdb94dc5d739
--- /dev/null
+++ b/test/cpp/qps/server.cc
@@ -0,0 +1,172 @@
+/*
+ *
+ * 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 <sys/time.h>
+#include <sys/resource.h>
+#include <sys/signal.h>
+#include <thread>
+
+#include <unistd.h>
+
+#include <gflags/gflags.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
+#include <grpc++/config.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+#include <grpc++/server_credentials.h>
+#include <grpc++/status.h>
+#include "src/cpp/server/thread_pool.h"
+#include "test/core/util/grpc_profiler.h"
+#include "test/cpp/qps/qpstest.pb.h"
+
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+
+DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls.");
+DEFINE_int32(port, 0, "Server port.");
+DEFINE_int32(server_threads, 4, "Number of server threads.");
+
+using grpc::Server;
+using grpc::ServerBuilder;
+using grpc::ServerContext;
+using grpc::ThreadPool;
+using grpc::testing::Payload;
+using grpc::testing::PayloadType;
+using grpc::testing::ServerStats;
+using grpc::testing::SimpleRequest;
+using grpc::testing::SimpleResponse;
+using grpc::testing::StatsRequest;
+using grpc::testing::TestService;
+using grpc::Status;
+
+// 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;
+
+static bool got_sigint = false;
+
+static void sigint_handler(int x) { got_sigint = 1; }
+
+static double time_double(struct timeval* tv) {
+  return tv->tv_sec + 1e-6 * tv->tv_usec;
+}
+
+static bool SetPayload(PayloadType type, int size, Payload* payload) {
+  PayloadType response_type = type;
+  // TODO(yangg): Support UNCOMPRESSABLE payload.
+  if (type != PayloadType::COMPRESSABLE) {
+    return false;
+  }
+  payload->set_type(response_type);
+  std::unique_ptr<char[]> body(new char[size]());
+  payload->set_body(body.get(), size);
+  return true;
+}
+
+namespace {
+
+class TestServiceImpl GRPC_FINAL : public TestService::Service {
+ public:
+  Status CollectServerStats(ServerContext* context, const StatsRequest*,
+                            ServerStats* response) {
+    struct rusage usage;
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    getrusage(RUSAGE_SELF, &usage);
+    response->set_time_now(time_double(&tv));
+    response->set_time_user(time_double(&usage.ru_utime));
+    response->set_time_system(time_double(&usage.ru_stime));
+    return Status::OK;
+  }
+  Status UnaryCall(ServerContext* context, const SimpleRequest* request,
+                   SimpleResponse* response) {
+    if (request->has_response_size() && request->response_size() > 0) {
+      if (!SetPayload(request->response_type(), request->response_size(),
+                      response->mutable_payload())) {
+        return Status(grpc::StatusCode::INTERNAL, "Error creating payload.");
+      }
+    }
+    return Status::OK;
+  }
+};
+
+}  // namespace
+
+static void RunServer() {
+  char* server_address = NULL;
+  gpr_join_host_port(&server_address, "::", FLAGS_port);
+
+  TestServiceImpl service;
+
+  SimpleRequest request;
+  SimpleResponse response;
+
+  ServerBuilder builder;
+  builder.AddPort(server_address, grpc::InsecureServerCredentials());
+  builder.RegisterService(&service);
+
+  std::unique_ptr<ThreadPool> pool(new ThreadPool(FLAGS_server_threads));
+  builder.SetThreadPool(pool.get());
+
+  std::unique_ptr<Server> server(builder.BuildAndStart());
+  gpr_log(GPR_INFO, "Server listening on %s\n", server_address);
+
+  grpc_profiler_start("qps_server.prof");
+
+  while (!got_sigint) {
+    sleep(5);
+  }
+
+  grpc_profiler_stop();
+
+  gpr_free(server_address);
+}
+
+int main(int argc, char** argv) {
+  grpc_init();
+  ParseCommandLineFlags(&argc, &argv, true);
+
+  signal(SIGINT, sigint_handler);
+
+  GPR_ASSERT(FLAGS_port != 0);
+  GPR_ASSERT(!FLAGS_enable_ssl);
+  RunServer();
+
+  grpc_shutdown();
+  return 0;
+}
diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc
index 64aca957e4cf8674bf566c90ff02890dbd09b4a3..19778e5a7cd09c6c231c17aa09d5e8c4458f59bc 100644
--- a/test/cpp/qps/server_async.cc
+++ b/test/cpp/qps/server_async.cc
@@ -46,6 +46,7 @@
 #include <grpc++/server.h>
 #include <grpc++/server_builder.h>
 #include <grpc++/server_context.h>
+#include <grpc++/server_credentials.h>
 #include <grpc++/status.h>
 #include <gtest/gtest.h>
 #include "src/cpp/server/thread_pool.h"
@@ -67,7 +68,7 @@ class AsyncQpsServerTest : public Server {
     gpr_join_host_port(&server_address, "::", port);
 
     ServerBuilder builder;
-    builder.AddPort(server_address);
+    builder.AddPort(server_address, InsecureServerCredentials());
     gpr_free(server_address);
 
     builder.RegisterAsyncService(&async_service_);
diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc
index beee688608e4f090e4f24d645943a08cd83f078d..5c6541989c6bd164b5a11a2c83af36461e1aaa5c 100644
--- a/test/cpp/qps/server_sync.cc
+++ b/test/cpp/qps/server_sync.cc
@@ -43,6 +43,7 @@
 #include <grpc++/server.h>
 #include <grpc++/server_builder.h>
 #include <grpc++/server_context.h>
+#include <grpc++/server_credentials.h>
 #include <grpc++/status.h>
 #include <grpc++/stream.h>
 #include "src/cpp/server/thread_pool.h"
@@ -83,7 +84,7 @@ class SynchronousServer GRPC_FINAL : public grpc::testing::Server {
 
     char* server_address = NULL;
     gpr_join_host_port(&server_address, "::", port);
-    builder.AddPort(server_address);
+    builder.AddPort(server_address, InsecureServerCredentials());
     gpr_free(server_address);
 
     builder.RegisterService(&service_);
diff --git a/test/cpp/qps/worker.cc b/test/cpp/qps/worker.cc
index 3a46a22665dd2a7be1fdc9ba902e405c4276437a..faabfd1147796149e127fcc4df0abc875f307a45 100644
--- a/test/cpp/qps/worker.cc
+++ b/test/cpp/qps/worker.cc
@@ -51,6 +51,7 @@
 #include <grpc++/status.h>
 #include <grpc++/server.h>
 #include <grpc++/server_builder.h>
+#include <grpc++/server_credentials.h>
 #include <grpc++/stream.h>
 #include "test/core/util/grpc_profiler.h"
 #include "test/cpp/util/create_test_channel.h"
@@ -209,7 +210,7 @@ static void RunServer() {
   WorkerImpl service;
 
   ServerBuilder builder;
-  builder.AddPort(server_address);
+  builder.AddPort(server_address, InsecureServerCredentials());
   builder.RegisterService(&service);
 
   gpr_free(server_address);
diff --git a/test/cpp/util/create_test_channel.cc b/test/cpp/util/create_test_channel.cc
index 745496f463013dac0b106192a9ba59f94e2cd599..d3b84b29653631133dbc2070d24a5d75f6620fd5 100644
--- a/test/cpp/util/create_test_channel.cc
+++ b/test/cpp/util/create_test_channel.cc
@@ -61,12 +61,10 @@ std::shared_ptr<ChannelInterface> CreateTestChannel(
     const std::unique_ptr<Credentials>& creds) {
   ChannelArguments channel_args;
   if (enable_ssl) {
-    const char* roots_certs =
-        use_prod_roots ? "" : test_root_cert;
+    const char* roots_certs = use_prod_roots ? "" : test_root_cert;
     SslCredentialsOptions ssl_opts = {roots_certs, "", ""};
 
-    std::unique_ptr<Credentials> channel_creds =
-        CredentialsFactory::SslCredentials(ssl_opts);
+    std::unique_ptr<Credentials> channel_creds = SslCredentials(ssl_opts);
 
     if (!server.empty() && !override_hostname.empty()) {
       channel_args.SetSslTargetNameOverride(override_hostname);
@@ -75,11 +73,11 @@ std::shared_ptr<ChannelInterface> CreateTestChannel(
         server.empty() ? override_hostname : server;
     if (creds.get()) {
       channel_creds =
-          CredentialsFactory::CompositeCredentials(creds, channel_creds);
+          CompositeCredentials(creds, channel_creds);
     }
     return CreateChannel(connect_to, channel_creds, channel_args);
   } else {
-    return CreateChannelDeprecated(server, channel_args);
+    return CreateChannel(server, InsecureCredentials(), channel_args);
   }
 }
 
diff --git a/tools/run_tests/build_python.sh b/tools/run_tests/build_python.sh
index de633083c352649acddb96e34e591f2003c106c4..0eba1c637798a4e17b0624a2810829eac03eaa69 100755
--- a/tools/run_tests/build_python.sh
+++ b/tools/run_tests/build_python.sh
@@ -39,3 +39,4 @@ virtualenv -p /usr/bin/python2.7 python2.7_virtual_environment
 source python2.7_virtual_environment/bin/activate
 pip install enum34==1.0.4 futures==2.2.0 protobuf==3.0.0-alpha-1
 CFLAGS=-I$root/include LDFLAGS=-L$root/libs/opt pip install src/python/src
+pip install src/python/interop
diff --git a/tools/run_tests/python_tests.json b/tools/run_tests/python_tests.json
index 4b43ee8357cc15b611ccb042d949390148193e4e..69022af12e1a5eef3de4c10c65b2ebede880960c 100755
--- a/tools/run_tests/python_tests.json
+++ b/tools/run_tests/python_tests.json
@@ -46,5 +46,11 @@
   },
   {
     "module": "grpc.framework.foundation._logging_pool_test"
+  },
+  {
+    "module": "interop._insecure_interop_test"
+  },
+  {
+    "module": "interop._secure_interop_test"
   }
 ]
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 12a45f3ad9a07c48530ff79bc0f93071a555a8a3..aee19cdc42d6ec9b106ce39d045dc679922584a7 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -379,7 +379,7 @@ test_cache.maybe_load()
 if forever:
   success = True
   while True:
-    dw = watch_dirs.DirWatcher(['src', 'include', 'test'])
+    dw = watch_dirs.DirWatcher(['src', 'include', 'test', 'examples'])
     initial_time = dw.most_recent_change()
     have_files_changed = lambda: dw.most_recent_change() != initial_time
     previous_success = success
diff --git a/vsprojects/vs2013/grpc.vcxproj b/vsprojects/vs2013/grpc.vcxproj
index 60dc98024204664be8b8776949deb42c01e05c38..9d0bcb327163f30a4e6899b08b7c7974763a4315 100644
--- a/vsprojects/vs2013/grpc.vcxproj
+++ b/vsprojects/vs2013/grpc.vcxproj
@@ -161,7 +161,6 @@
     <ClInclude Include="..\..\src\core\surface\completion_queue.h" />
     <ClInclude Include="..\..\src\core\surface\event_string.h" />
     <ClInclude Include="..\..\src\core\surface\init.h" />
-    <ClInclude Include="..\..\src\core\surface\lame_client.h" />
     <ClInclude Include="..\..\src\core\surface\server.h" />
     <ClInclude Include="..\..\src\core\surface\surface_trace.h" />
     <ClInclude Include="..\..\src\core\transport\chttp2\bin_encoder.h" />
@@ -224,8 +223,6 @@
     </ClCompile>
     <ClCompile Include="..\..\src\core\surface\secure_channel_create.c">
     </ClCompile>
-    <ClCompile Include="..\..\src\core\surface\secure_server_create.c">
-    </ClCompile>
     <ClCompile Include="..\..\src\core\tsi\fake_transport_security.c">
     </ClCompile>
     <ClCompile Include="..\..\src\core\tsi\ssl_transport_security.c">
diff --git a/vsprojects/vs2013/grpc.vcxproj.filters b/vsprojects/vs2013/grpc.vcxproj.filters
index 9fc70e74d9de6dbd3573a6984f14b83e384a9677..af38d8de35ad2d37df2b247db721290a646fb91b 100644
--- a/vsprojects/vs2013/grpc.vcxproj.filters
+++ b/vsprojects/vs2013/grpc.vcxproj.filters
@@ -55,9 +55,6 @@
     <ClCompile Include="..\..\src\core\surface\secure_channel_create.c">
       <Filter>src\core\surface</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\core\surface\secure_server_create.c">
-      <Filter>src\core\surface</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\src\core\tsi\fake_transport_security.c">
       <Filter>src\core\tsi</Filter>
     </ClCompile>
@@ -599,9 +596,6 @@
     <ClInclude Include="..\..\src\core\surface\init.h">
       <Filter>src\core\surface</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\core\surface\lame_client.h">
-      <Filter>src\core\surface</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\src\core\surface\server.h">
       <Filter>src\core\surface</Filter>
     </ClInclude>
diff --git a/vsprojects/vs2013/grpc_shared.vcxproj b/vsprojects/vs2013/grpc_shared.vcxproj
index 5c2e23b51398b81cd3a051c40813b376ecc8091c..f5575dc3f12db5abf050bdf6d44168443c848b47 100644
--- a/vsprojects/vs2013/grpc_shared.vcxproj
+++ b/vsprojects/vs2013/grpc_shared.vcxproj
@@ -165,7 +165,6 @@
     <ClInclude Include="..\..\src\core\surface\completion_queue.h" />
     <ClInclude Include="..\..\src\core\surface\event_string.h" />
     <ClInclude Include="..\..\src\core\surface\init.h" />
-    <ClInclude Include="..\..\src\core\surface\lame_client.h" />
     <ClInclude Include="..\..\src\core\surface\server.h" />
     <ClInclude Include="..\..\src\core\surface\surface_trace.h" />
     <ClInclude Include="..\..\src\core\transport\chttp2\bin_encoder.h" />
@@ -228,8 +227,6 @@
     </ClCompile>
     <ClCompile Include="..\..\src\core\surface\secure_channel_create.c">
     </ClCompile>
-    <ClCompile Include="..\..\src\core\surface\secure_server_create.c">
-    </ClCompile>
     <ClCompile Include="..\..\src\core\tsi\fake_transport_security.c">
     </ClCompile>
     <ClCompile Include="..\..\src\core\tsi\ssl_transport_security.c">
diff --git a/vsprojects/vs2013/grpc_shared.vcxproj.filters b/vsprojects/vs2013/grpc_shared.vcxproj.filters
index 9fc70e74d9de6dbd3573a6984f14b83e384a9677..af38d8de35ad2d37df2b247db721290a646fb91b 100644
--- a/vsprojects/vs2013/grpc_shared.vcxproj.filters
+++ b/vsprojects/vs2013/grpc_shared.vcxproj.filters
@@ -55,9 +55,6 @@
     <ClCompile Include="..\..\src\core\surface\secure_channel_create.c">
       <Filter>src\core\surface</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\core\surface\secure_server_create.c">
-      <Filter>src\core\surface</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\src\core\tsi\fake_transport_security.c">
       <Filter>src\core\tsi</Filter>
     </ClCompile>
@@ -599,9 +596,6 @@
     <ClInclude Include="..\..\src\core\surface\init.h">
       <Filter>src\core\surface</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\core\surface\lame_client.h">
-      <Filter>src\core\surface</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\src\core\surface\server.h">
       <Filter>src\core\surface</Filter>
     </ClInclude>
diff --git a/vsprojects/vs2013/grpc_unsecure.vcxproj b/vsprojects/vs2013/grpc_unsecure.vcxproj
index 9181db0b4e126f3e7d6caf919d45068ebfae4adc..ad7bf4762f57d451709e44349da6105c1276bef2 100644
--- a/vsprojects/vs2013/grpc_unsecure.vcxproj
+++ b/vsprojects/vs2013/grpc_unsecure.vcxproj
@@ -146,7 +146,6 @@
     <ClInclude Include="..\..\src\core\surface\completion_queue.h" />
     <ClInclude Include="..\..\src\core\surface\event_string.h" />
     <ClInclude Include="..\..\src\core\surface\init.h" />
-    <ClInclude Include="..\..\src\core\surface\lame_client.h" />
     <ClInclude Include="..\..\src\core\surface\server.h" />
     <ClInclude Include="..\..\src\core\surface\surface_trace.h" />
     <ClInclude Include="..\..\src\core\transport\chttp2\bin_encoder.h" />
diff --git a/vsprojects/vs2013/grpc_unsecure.vcxproj.filters b/vsprojects/vs2013/grpc_unsecure.vcxproj.filters
index 4583fa41eab8a2baeb584cde59c31e8162bfed42..205942a45099d7d05ab7db874c5f6ef7edf102f4 100644
--- a/vsprojects/vs2013/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vs2013/grpc_unsecure.vcxproj.filters
@@ -491,9 +491,6 @@
     <ClInclude Include="..\..\src\core\surface\init.h">
       <Filter>src\core\surface</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\core\surface\lame_client.h">
-      <Filter>src\core\surface</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\src\core\surface\server.h">
       <Filter>src\core\surface</Filter>
     </ClInclude>