diff --git a/BUILD b/BUILD
index 0c91633b7fe0f385db913b9d291c9527db3ee041..542c43f6321620851ebdbbacaf33a656e86907a4 100644
--- a/BUILD
+++ b/BUILD
@@ -37,11 +37,12 @@ package(default_visibility = ["//visibility:public"])
 
 load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_proto_plugin")
 
-g_stands_for = "green"
+# This should be updated along with build.yaml
+g_stands_for = "gentle"
 
 core_version = "3.0.0-dev"
 
-version = "1.3.0-dev"
+version = "1.4.0-dev"
 
 grpc_cc_library(
     name = "gpr",
@@ -1039,11 +1040,11 @@ grpc_cc_library(
         "src/core/ext/transport/chttp2/transport/frame_ping.c",
         "src/core/ext/transport/chttp2/transport/frame_rst_stream.c",
         "src/core/ext/transport/chttp2/transport/frame_settings.c",
-        "src/core/ext/transport/chttp2/transport/http2_settings.c",
         "src/core/ext/transport/chttp2/transport/frame_window_update.c",
         "src/core/ext/transport/chttp2/transport/hpack_encoder.c",
         "src/core/ext/transport/chttp2/transport/hpack_parser.c",
         "src/core/ext/transport/chttp2/transport/hpack_table.c",
+        "src/core/ext/transport/chttp2/transport/http2_settings.c",
         "src/core/ext/transport/chttp2/transport/huffsyms.c",
         "src/core/ext/transport/chttp2/transport/incoming_metadata.c",
         "src/core/ext/transport/chttp2/transport/parsing.c",
@@ -1062,11 +1063,11 @@ grpc_cc_library(
         "src/core/ext/transport/chttp2/transport/frame_ping.h",
         "src/core/ext/transport/chttp2/transport/frame_rst_stream.h",
         "src/core/ext/transport/chttp2/transport/frame_settings.h",
-        "src/core/ext/transport/chttp2/transport/http2_settings.h",
         "src/core/ext/transport/chttp2/transport/frame_window_update.h",
         "src/core/ext/transport/chttp2/transport/hpack_encoder.h",
         "src/core/ext/transport/chttp2/transport/hpack_parser.h",
         "src/core/ext/transport/chttp2/transport/hpack_table.h",
+        "src/core/ext/transport/chttp2/transport/http2_settings.h",
         "src/core/ext/transport/chttp2/transport/huffsyms.h",
         "src/core/ext/transport/chttp2/transport/incoming_metadata.h",
         "src/core/ext/transport/chttp2/transport/internal.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6825c60b738b17cdb617561e68eb31aca725d33d..0dad894cc4ca70b3cc94944a866335acac9be141 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -39,7 +39,7 @@
 cmake_minimum_required(VERSION 2.8)
 
 set(PACKAGE_NAME      "grpc")
-set(PACKAGE_VERSION   "1.3.0-dev")
+set(PACKAGE_VERSION   "1.4.0-dev")
 set(PACKAGE_STRING    "${PACKAGE_NAME} ${PACKAGE_VERSION}")
 set(PACKAGE_TARNAME   "${PACKAGE_NAME}-${PACKAGE_VERSION}")
 set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
diff --git a/Makefile b/Makefile
index 4b3c4bcbb374934c890ff2840ea6eab7d745577d..a96d461cac07cbe60739f21a826d96d1a5b0cbe4 100644
--- a/Makefile
+++ b/Makefile
@@ -420,8 +420,8 @@ Q = @
 endif
 
 CORE_VERSION = 3.0.0-dev
-CPP_VERSION = 1.3.0-dev
-CSHARP_VERSION = 1.3.0-dev
+CPP_VERSION = 1.4.0-dev
+CSHARP_VERSION = 1.4.0-dev
 
 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
 CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@@ -4389,7 +4389,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC+
 ifeq ($(SYSTEM),Darwin)
 	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc -lgpr
 else
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc -lgpr
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc -lgpr
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).so.1
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).so
 endif
@@ -4789,7 +4789,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(L
 ifeq ($(SYSTEM),Darwin)
 	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr -lgrpc_cronet
 else
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_cronet.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr -lgrpc_cronet
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_cronet.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr -lgrpc_cronet
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).so.1
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).so
 endif
@@ -4859,7 +4859,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CP
 ifeq ($(SYSTEM),Darwin)
 	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++
 else
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_error_details.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_error_details.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).so.1
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).so
 endif
@@ -4983,7 +4983,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP):
 ifeq ($(SYSTEM),Darwin)
 	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++
 else
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_reflection.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_reflection.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).so.1
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).so
 endif
@@ -5474,7 +5474,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $
 ifeq ($(SYSTEM),Darwin)
 	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr -lgrpc_unsecure
 else
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr -lgrpc_unsecure
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgpr -lgrpc_unsecure
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).so.1
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).so
 endif
@@ -6065,7 +6065,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHA
 ifeq ($(SYSTEM),Darwin)
 	$(Q) $(LD) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBS)
 else
-	$(Q) $(LD) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBS)
+	$(Q) $(LD) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(LDLIBS)
 	$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).so.1
 	$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).so
 endif
diff --git a/build.yaml b/build.yaml
index 907e6ddb44b366fc8e914fffeefaa703af0d6f45..da5fe2f0cffee387c392f1f721f0333d8cf267a3 100644
--- a/build.yaml
+++ b/build.yaml
@@ -6,7 +6,7 @@ settings:
   '#02': ===
   '#03': Please update the 'g_stands_for' field periodically with a new g word
   '#04': not listed in doc/g_stands_for.md - and update that document to list the
-  '#05': new word.
+  '#05': new word. When doing so, please also update BUILD.
   '#06': ===
   '#07': Master always has a "-dev" suffix
   '#08': Use "-preN" suffixes to identify pre-release versions
@@ -14,7 +14,7 @@ settings:
   '#10': See the expand_version.py for all the quirks here
   core_version: 3.0.0-dev
   g_stands_for: gentle
-  version: 1.3.0-dev
+  version: 1.4.0-dev
 filegroups:
 - name: census
   public_headers:
diff --git a/doc/statuscodes.md b/doc/statuscodes.md
index 1cd72df30ad4cfec034b88f24cf02ec75e0482c4..f2df9e00dec423919be9df8a79927d30c775b6ee 100644
--- a/doc/statuscodes.md
+++ b/doc/statuscodes.md
@@ -1,9 +1,20 @@
 # Status codes and their use in gRPC
 
-gRPC uses a set of well defined status codes as part of the RPC API. All RPCs started at a client return  a `status` object composed of an integer `code` and a string `message`. The server-side can choose the status it returns for a given RPC.
+gRPC uses a set of well defined status codes as part of the RPC API. All
+RPCs started at a client return  a `status` object composed of an integer
+`code` and a string `message`. The server-side can choose the status it
+returns for a given RPC.
 
-The gRPC client and server-side implementations may also generate and return `status` on their own when errors happen.  
-Only a subset of the pre-defined status codes are generated by the gRPC libraries. The following table lists these codes and summarizes the situations in which they are generated, either by the client or the server-side library implementation.
+The gRPC client and server-side implementations may also generate and
+return `status` on their own when errors happen.  Only a subset of
+the pre-defined status codes are generated by the gRPC libraries.  This
+allows applications to be sure that any other code it sees was actually
+returned by the application (although it is also possible for the
+server-side to return one of the codes generated by the gRPC libraries).
+
+The following table lists the codes that may be returned by the gRPC
+libraries (on either the client-side or server-side) and summarizes the
+situations in which they are generated.
 
 | Case        | Code           | Generated at Client or Server  |
 | ------------- |:-------------| :-----:|
@@ -26,7 +37,7 @@ Only a subset of the pre-defined status codes are generated by the gRPC librarie
 | Response cardinality violation (method requires exactly one response but server sent some other number of responses) | UNIMPLEMENTED | Client|
 | Error parsing response proto	| INTERNAL | Client|
 | Error parsing request proto	| INTERNAL | Server|
-
+| Sent or received message was larger than configured limit | RESOURCE_EXHAUSTED | Both |
 
 The following status codes are never generated by the library:
 - INVALID_ARGUMENT
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index c0cd511d8209ebcac6a332619a5d398b5d4b32b5..4bd9cd9363ea6dc5a95b274b05a1df1ff538dffd 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -37,7 +37,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC-Core'
-  version = '1.3.0-dev'
+  version = '1.4.0-dev'
   s.version  = version
   s.summary  = 'Core cross-platform gRPC library, written in C'
   s.homepage = 'http://www.grpc.io'
diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec
index 1940015782eac50bed8010c957dda0237235ecb2..62cb0d11a1c9e8c55980f296153973dd32775fb7 100644
--- a/gRPC-ProtoRPC.podspec
+++ b/gRPC-ProtoRPC.podspec
@@ -36,7 +36,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC-ProtoRPC'
-  version = '1.3.0-dev'
+  version = '1.4.0-dev'
   s.version  = version
   s.summary  = 'RPC library for Protocol Buffers, based on gRPC'
   s.homepage = 'http://www.grpc.io'
diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec
index 841a85336333185e3f6a1fe9437e35c8cbe5b183..77ceb22123c5746df403ea3bcf233ec4ccb2c0ef 100644
--- a/gRPC-RxLibrary.podspec
+++ b/gRPC-RxLibrary.podspec
@@ -36,7 +36,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC-RxLibrary'
-  version = '1.3.0-dev'
+  version = '1.4.0-dev'
   s.version  = version
   s.summary  = 'Reactive Extensions library for iOS/OSX.'
   s.homepage = 'http://www.grpc.io'
diff --git a/gRPC.podspec b/gRPC.podspec
index 08ea79118d1a03a78301e367545f5b22d13e7793..10520bd3880edb2e05e9397d04f63f26c0bc62d2 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -35,7 +35,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC'
-  version = '1.3.0-dev'
+  version = '1.4.0-dev'
   s.version  = version
   s.summary  = 'gRPC client library for iOS/OSX'
   s.homepage = 'http://www.grpc.io'
diff --git a/include/grpc/support/alloc.h b/include/grpc/support/alloc.h
index 541433c68804783033f9b82130b7a3605f9ca6a8..017d75a3d0ebc257807317869e21e7f84bfd6b43 100644
--- a/include/grpc/support/alloc.h
+++ b/include/grpc/support/alloc.h
@@ -68,7 +68,8 @@ GPRAPI void gpr_free_aligned(void *ptr);
 
 /** Request the family of allocation functions in \a functions be used. NOTE
  * that this request will be honored in a *best effort* basis and that no
- * guarantees are made about the default functions (eg, malloc) being called. */
+ * guarantees are made about the default functions (eg, malloc) being called.
+ * The functions.free_fn implementation must be a no-op for NULL input. */
 GPRAPI void gpr_set_allocation_functions(gpr_allocation_functions functions);
 
 /** Return the family of allocation functions currently in effect. */
diff --git a/package.json b/package.json
index 7f242326d7ecd03feacb76126aa7defa87d18579..6a01ae23243f086981ee025cfbb73d5ca48009f7 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "grpc",
-  "version": "1.3.0-dev",
+  "version": "1.4.0-dev",
   "author": "Google Inc.",
   "description": "gRPC Library for Node",
   "homepage": "http://www.grpc.io/",
diff --git a/package.xml b/package.xml
index 108281746bde5fa33d14cda54f88d2e142e892bb..b128be672ea082f1bb2d1bcf9999dd872b197cdb 100644
--- a/package.xml
+++ b/package.xml
@@ -13,8 +13,8 @@
  <date>2017-03-01</date>
  <time>16:06:07</time>
  <version>
-  <release>1.3.0dev</release>
-  <api>1.3.0dev</api>
+  <release>1.4.0dev</release>
+  <api>1.4.0dev</api>
  </version>
  <stability>
   <release>beta</release>
diff --git a/src/core/ext/census/context.c b/src/core/ext/census/context.c
index 0dfc4ecbf1da6e31c0086dfc86fdb3d70d826fd1..4195cb1c9b3cdf1df6ec8efd9d550823eae0bd04 100644
--- a/src/core/ext/census/context.c
+++ b/src/core/ext/census/context.c
@@ -200,7 +200,7 @@ static bool tag_set_add_tag(struct tag_set *tags, const census_tag *tag,
     // allocate new memory if needed
     tags->kvm_size += 2 * CENSUS_MAX_TAG_KV_LEN + TAG_HEADER_SIZE;
     char *new_kvm = gpr_malloc(tags->kvm_size);
-    memcpy(new_kvm, tags->kvm, tags->kvm_used);
+    if (tags->kvm_used > 0) memcpy(new_kvm, tags->kvm, tags->kvm_used);
     gpr_free(tags->kvm);
     tags->kvm = new_kvm;
   }
diff --git a/src/core/ext/census/resource.c b/src/core/ext/census/resource.c
index ed44f004f91c2bf74ea726628afcf5e3f34aa8d7..26ea1a86720b17a7322cfd5be1b23f810b942fd7 100644
--- a/src/core/ext/census/resource.c
+++ b/src/core/ext/census/resource.c
@@ -223,7 +223,9 @@ size_t allocate_resource(void) {
   if (n_resources == n_defined_resources) {
     size_t new_n_resources = n_resources ? n_resources * 2 : 2;
     resource **new_resources = gpr_malloc(new_n_resources * sizeof(resource *));
-    memcpy(new_resources, resources, n_resources * sizeof(resource *));
+    if (n_resources != 0) {
+      memcpy(new_resources, resources, n_resources * sizeof(resource *));
+    }
     memset(new_resources + n_resources, 0,
            (new_n_resources - n_resources) * sizeof(resource *));
     gpr_free(resources);
diff --git a/src/core/ext/filters/http/client/http_client_filter.c b/src/core/ext/filters/http/client/http_client_filter.c
index 4b3d2833e22d46319fdd3d671a4b0019ecd65f1a..019f2ead1de27021f164e526b238da9458ce13fb 100644
--- a/src/core/ext/filters/http/client/http_client_filter.c
+++ b/src/core/ext/filters/http/client/http_client_filter.c
@@ -222,8 +222,10 @@ static void continue_send_message(grpc_exec_ctx *exec_ctx,
   while (grpc_byte_stream_next(
       exec_ctx, calld->send_op->payload->send_message.send_message,
       &calld->incoming_slice, ~(size_t)0, &calld->got_slice)) {
-    memcpy(wrptr, GRPC_SLICE_START_PTR(calld->incoming_slice),
-           GRPC_SLICE_LENGTH(calld->incoming_slice));
+    if (GRPC_SLICE_LENGTH(calld->incoming_slice) > 0) {
+      memcpy(wrptr, GRPC_SLICE_START_PTR(calld->incoming_slice),
+             GRPC_SLICE_LENGTH(calld->incoming_slice));
+    }
     wrptr += GRPC_SLICE_LENGTH(calld->incoming_slice);
     grpc_slice_buffer_add(&calld->slices, calld->incoming_slice);
     if (calld->send_length == calld->slices.length) {
diff --git a/src/core/ext/filters/message_size/message_size_filter.c b/src/core/ext/filters/message_size/message_size_filter.c
index 455958d57506aab01bedf9062e4776fe0e67c4e1..db0f0119053970d03c953ca02126f9e8ca45ab61 100644
--- a/src/core/ext/filters/message_size/message_size_filter.c
+++ b/src/core/ext/filters/message_size/message_size_filter.c
@@ -122,7 +122,7 @@ static void recv_message_ready(grpc_exec_ctx* exec_ctx, void* user_data,
                  (*calld->recv_message)->length, calld->limits.max_recv_size);
     grpc_error* new_error = grpc_error_set_int(
         GRPC_ERROR_CREATE_FROM_COPIED_STRING(message_string),
-        GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INVALID_ARGUMENT);
+        GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED);
     if (error == GRPC_ERROR_NONE) {
       error = new_error;
     } else {
@@ -152,7 +152,7 @@ static void start_transport_stream_op_batch(
         exec_ctx, op,
         grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(message_string),
                            GRPC_ERROR_INT_GRPC_STATUS,
-                           GRPC_STATUS_INVALID_ARGUMENT));
+                           GRPC_STATUS_RESOURCE_EXHAUSTED));
     gpr_free(message_string);
     return;
   }
diff --git a/src/core/lib/iomgr/closure.c b/src/core/lib/iomgr/closure.c
index 6633fb68ecf63b488e5976a98c5a4502bb80fef6..8ef0b210ad213fef162eb4742612920170265bc1 100644
--- a/src/core/lib/iomgr/closure.c
+++ b/src/core/lib/iomgr/closure.c
@@ -45,6 +45,9 @@ grpc_closure *grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb,
   closure->cb = cb;
   closure->cb_arg = cb_arg;
   closure->scheduler = scheduler;
+#ifndef NDEBUG
+  closure->scheduled = false;
+#endif
   return closure;
 }
 
@@ -137,6 +140,10 @@ void grpc_closure_sched(grpc_exec_ctx *exec_ctx, grpc_closure *c,
                         grpc_error *error) {
   GPR_TIMER_BEGIN("grpc_closure_sched", 0);
   if (c != NULL) {
+#ifndef NDEBUG
+    GPR_ASSERT(!c->scheduled);
+    c->scheduled = true;
+#endif
     assert(c->cb);
     c->scheduler->vtable->sched(exec_ctx, c, error);
   } else {
@@ -149,6 +156,10 @@ void grpc_closure_list_sched(grpc_exec_ctx *exec_ctx, grpc_closure_list *list) {
   grpc_closure *c = list->head;
   while (c != NULL) {
     grpc_closure *next = c->next_data.next;
+#ifndef NDEBUG
+    GPR_ASSERT(!c->scheduled);
+    c->scheduled = true;
+#endif
     assert(c->cb);
     c->scheduler->vtable->sched(exec_ctx, c, c->error_data.error);
     c = next;
diff --git a/src/core/lib/iomgr/closure.h b/src/core/lib/iomgr/closure.h
index 2510d50b428f37b697f7ed51bd416347e1aea2b2..2bedbf00d63c99ab871904f9a40619e21e0d3a93 100644
--- a/src/core/lib/iomgr/closure.h
+++ b/src/core/lib/iomgr/closure.h
@@ -99,6 +99,10 @@ struct grpc_closure {
     grpc_error *error;
     uintptr_t scratch;
   } error_data;
+
+#ifndef NDEBUG
+  bool scheduled;
+#endif
 };
 
 /** Initializes \a closure with \a cb and \a cb_arg. Returns \a closure. */
diff --git a/src/core/lib/iomgr/combiner.c b/src/core/lib/iomgr/combiner.c
index 2bc476bbef624a72aafd09049f58ffa30ef52a26..05cdbdad2b78e2bcc5ae9d4e3eab66dbae12767b 100644
--- a/src/core/lib/iomgr/combiner.c
+++ b/src/core/lib/iomgr/combiner.c
@@ -319,6 +319,9 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) {
     GPR_TIMER_BEGIN("combiner.exec1", 0);
     grpc_closure *cl = (grpc_closure *)n;
     error_data err = unpack_error_data(cl->error_data.scratch);
+#ifndef NDEBUG
+    cl->scheduled = false;
+#endif
     cl->cb(exec_ctx, cl->cb_arg, err.error);
     if (err.covered_by_poller) {
       gpr_atm_no_barrier_fetch_add(&lock->elements_covered_by_poller, -1);
@@ -337,6 +340,9 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) {
           gpr_log(GPR_DEBUG, "C:%p execute_final[%d] c=%p", lock, loops, c));
       grpc_closure *next = c->next_data.next;
       grpc_error *error = c->error_data.error;
+#ifndef NDEBUG
+      c->scheduled = false;
+#endif
       c->cb(exec_ctx, c->cb_arg, error);
       GRPC_ERROR_UNREF(error);
       c = next;
diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c
index 4a0f91391f2429011898a66a2ce02b39fe68684b..e603a755937286e80ab1d8d14cd51be6c3a9287e 100644
--- a/src/core/lib/iomgr/ev_epoll_linux.c
+++ b/src/core/lib/iomgr/ev_epoll_linux.c
@@ -1348,6 +1348,9 @@ static bool maybe_do_workqueue_work(grpc_exec_ctx *exec_ctx,
       }
       grpc_closure *c = (grpc_closure *)n;
       grpc_error *error = c->error_data.error;
+#ifndef NDEBUG
+      c->scheduled = false;
+#endif
       c->cb(exec_ctx, c->cb_arg, error);
       GRPC_ERROR_UNREF(error);
       return true;
diff --git a/src/core/lib/iomgr/exec_ctx.c b/src/core/lib/iomgr/exec_ctx.c
index 83bb436bd0ad426c6f4f7fdfd964c0ad39fd301f..2532a708e7b0ba9aa0f6caec3ddf90c18c3d3d12 100644
--- a/src/core/lib/iomgr/exec_ctx.c
+++ b/src/core/lib/iomgr/exec_ctx.c
@@ -73,6 +73,9 @@ bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) {
         grpc_closure *next = c->next_data.next;
         grpc_error *error = c->error_data.error;
         did_something = true;
+#ifndef NDEBUG
+        c->scheduled = false;
+#endif
         c->cb(exec_ctx, c->cb_arg, error);
         GRPC_ERROR_UNREF(error);
         c = next;
@@ -93,6 +96,9 @@ void grpc_exec_ctx_finish(grpc_exec_ctx *exec_ctx) {
 
 static void exec_ctx_run(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
                          grpc_error *error) {
+#ifndef NDEBUG
+  closure->scheduled = false;
+#endif
   closure->cb(exec_ctx, closure->cb_arg, error);
   GRPC_ERROR_UNREF(error);
 }
diff --git a/src/core/lib/iomgr/executor.c b/src/core/lib/iomgr/executor.c
index ae3e2eabc390a47e51256038aa21cd1eb650c3fc..75fd5b1c50c547575f6ade9fec301d61cfcb6bfd 100644
--- a/src/core/lib/iomgr/executor.c
+++ b/src/core/lib/iomgr/executor.c
@@ -83,6 +83,9 @@ static void closure_exec_thread_func(void *ignored) {
       while (c != NULL) {
         grpc_closure *next = c->next_data.next;
         grpc_error *error = c->error_data.error;
+#ifndef NDEBUG
+        c->scheduled = false;
+#endif
         c->cb(&exec_ctx, c->cb_arg, error);
         GRPC_ERROR_UNREF(error);
         c = next;
@@ -146,6 +149,9 @@ void grpc_executor_shutdown(grpc_exec_ctx *exec_ctx) {
   while (c != NULL) {
     grpc_closure *next = c->next_data.next;
     grpc_error *error = c->error_data.error;
+#ifndef NDEBUG
+    c->scheduled = false;
+#endif
     c->cb(exec_ctx, c->cb_arg, error);
     GRPC_ERROR_UNREF(error);
     c = next;
diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc
index f5a0e4131de418d88f6a06e26fec1e1c128a74fb..72a4c4cf94a2753f108835ba6cb35e5f400998f9 100644
--- a/src/cpp/common/version_cc.cc
+++ b/src/cpp/common/version_cc.cc
@@ -37,5 +37,5 @@
 #include <grpc++/grpc++.h>
 
 namespace grpc {
-grpc::string Version() { return "1.3.0-dev"; }
+grpc::string Version() { return "1.4.0-dev"; }
 }
diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include
index ce9d0d2d5d287f616bda2ccdee308683e301ee22..6af2af10bd00cc6d67c0ff88968acfc6b61c2d01 100755
--- a/src/csharp/Grpc.Core/Version.csproj.include
+++ b/src/csharp/Grpc.Core/Version.csproj.include
@@ -1,7 +1,7 @@
 <!-- This file is generated -->
 <Project>
   <PropertyGroup>
-    <GrpcCsharpVersion>1.3.0-dev</GrpcCsharpVersion>
+    <GrpcCsharpVersion>1.4.0-dev</GrpcCsharpVersion>
     <GoogleProtobufVersion>3.2.0</GoogleProtobufVersion>
   </PropertyGroup>
 </Project>
diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs
index 6012d904b69ee0697b2739ffe63e05faa27ef64d..2e55d9d80eb45365b732c8995efe181670d9b653 100644
--- a/src/csharp/Grpc.Core/VersionInfo.cs
+++ b/src/csharp/Grpc.Core/VersionInfo.cs
@@ -48,11 +48,11 @@ namespace Grpc.Core
         /// <summary>
         /// Current <c>AssemblyFileVersion</c> of gRPC C# assemblies
         /// </summary>
-        public const string CurrentAssemblyFileVersion = "1.3.0.0";
+        public const string CurrentAssemblyFileVersion = "1.4.0.0";
 
         /// <summary>
         /// Current version of gRPC C#
         /// </summary>
-        public const string CurrentVersion = "1.3.0-dev";
+        public const string CurrentVersion = "1.4.0-dev";
     }
 }
diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat
index 7558ca60c71794d4435a1a1b01464566b4f09a35..673642e3d8714710ea10993101f2145d97f41399 100755
--- a/src/csharp/build_packages_dotnetcli.bat
+++ b/src/csharp/build_packages_dotnetcli.bat
@@ -28,7 +28,7 @@
 @rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 @rem Current package versions
-set VERSION=1.3.0-dev
+set VERSION=1.4.0-dev
 
 @rem Adjust the location of nuget.exe
 set NUGET=C:\nuget\nuget.exe
diff --git a/src/csharp/build_packages_dotnetcli.sh b/src/csharp/build_packages_dotnetcli.sh
index 2186bd3c56805607343aa13cc753cab2be428658..ee923e3d870b5edeb7193eeb0ba787790fef0703 100755
--- a/src/csharp/build_packages_dotnetcli.sh
+++ b/src/csharp/build_packages_dotnetcli.sh
@@ -70,7 +70,7 @@ dotnet pack --configuration Release Grpc.Auth --output ../../../artifacts
 dotnet pack --configuration Release Grpc.HealthCheck --output ../../../artifacts
 dotnet pack --configuration Release Grpc.Reflection --output ../../../artifacts
 
-nuget pack Grpc.nuspec -Version "1.3.0-dev" -OutputDirectory ../../artifacts
-nuget pack Grpc.Tools.nuspec -Version "1.3.0-dev" -OutputDirectory ../../artifacts
+nuget pack Grpc.nuspec -Version "1.4.0-dev" -OutputDirectory ../../artifacts
+nuget pack Grpc.Tools.nuspec -Version "1.4.0-dev" -OutputDirectory ../../artifacts
 
 (cd ../../artifacts && zip csharp_nugets_dotnetcli.zip *.nupkg)
diff --git a/src/node/ext/call.cc b/src/node/ext/call.cc
index 5d573110dacd1cac3e01b05ca2e02477807c8e06..bd60775aad9f84d4ccf1dec910a1247b094a7c4f 100644
--- a/src/node/ext/call.cc
+++ b/src/node/ext/call.cc
@@ -217,6 +217,8 @@ class SendMetadataOp : public Op {
   bool IsFinalOp() {
     return false;
   }
+  void OnComplete(bool success) {
+  }
  protected:
   std::string GetTypeString() const {
     return "send_metadata";
@@ -260,6 +262,8 @@ class SendMessageOp : public Op {
   bool IsFinalOp() {
     return false;
   }
+  void OnComplete(bool success) {
+  }
  protected:
   std::string GetTypeString() const {
     return "send_message";
@@ -280,6 +284,8 @@ class SendClientCloseOp : public Op {
   bool IsFinalOp() {
     return false;
   }
+  void OnComplete(bool success) {
+  }
  protected:
   std::string GetTypeString() const {
     return "client_close";
@@ -349,6 +355,8 @@ class SendServerStatusOp : public Op {
   bool IsFinalOp() {
     return true;
   }
+  void OnComplete(bool success) {
+  }
  protected:
   std::string GetTypeString() const {
     return "send_status";
@@ -381,6 +389,8 @@ class GetMetadataOp : public Op {
   bool IsFinalOp() {
     return false;
   }
+  void OnComplete(bool success) {
+  }
 
  protected:
   std::string GetTypeString() const {
@@ -413,6 +423,8 @@ class ReadMessageOp : public Op {
   bool IsFinalOp() {
     return false;
   }
+  void OnComplete(bool success) {
+  }
 
  protected:
   std::string GetTypeString() const {
@@ -454,6 +466,8 @@ class ClientStatusOp : public Op {
   bool IsFinalOp() {
     return true;
   }
+  void OnComplete(bool success) {
+  }
  protected:
   std::string GetTypeString() const {
     return "status";
@@ -478,6 +492,8 @@ class ServerCloseResponseOp : public Op {
   bool IsFinalOp() {
     return false;
   }
+  void OnComplete(bool success) {
+  }
 
  protected:
   std::string GetTypeString() const {
@@ -499,36 +515,36 @@ tag::~tag() {
   delete ops;
 }
 
-Local<Value> GetTagNodeValue(void *tag) {
-  EscapableHandleScope scope;
+void CompleteTag(void *tag, const char *error_message) {
+  HandleScope scope;
   struct tag *tag_struct = reinterpret_cast<struct tag *>(tag);
-  Local<Object> tag_obj = Nan::New<Object>();
-  for (vector<unique_ptr<Op> >::iterator it = tag_struct->ops->begin();
-       it != tag_struct->ops->end(); ++it) {
-    Op *op_ptr = it->get();
-    Nan::Set(tag_obj, op_ptr->GetOpType(), op_ptr->GetNodeValue());
+  Callback *callback = tag_struct->callback;
+  if (error_message == NULL) {
+    Local<Object> tag_obj = Nan::New<Object>();
+    for (vector<unique_ptr<Op> >::iterator it = tag_struct->ops->begin();
+         it != tag_struct->ops->end(); ++it) {
+      Op *op_ptr = it->get();
+      Nan::Set(tag_obj, op_ptr->GetOpType(), op_ptr->GetNodeValue());
+    }
+    Local<Value> argv[] = {Nan::Null(), tag_obj};
+    callback->Call(2, argv);
+  } else {
+    Local<Value> argv[] = {Nan::Error(error_message)};
+    callback->Call(1, argv);
   }
-  return scope.Escape(tag_obj);
-}
-
-Callback *GetTagCallback(void *tag) {
-  struct tag *tag_struct = reinterpret_cast<struct tag *>(tag);
-  return tag_struct->callback;
-}
-
-void CompleteTag(void *tag) {
-  struct tag *tag_struct = reinterpret_cast<struct tag *>(tag);
+  bool success = (error_message == NULL);
   bool is_final_op = false;
-  if (tag_struct->call == NULL) {
-    return;
-  }
   for (vector<unique_ptr<Op> >::iterator it = tag_struct->ops->begin();
        it != tag_struct->ops->end(); ++it) {
     Op *op_ptr = it->get();
+    op_ptr->OnComplete(success);
     if (op_ptr->IsFinalOp()) {
       is_final_op = true;
     }
   }
+  if (tag_struct->call == NULL) {
+    return;
+  }
   tag_struct->call->CompleteBatch(is_final_op);
 }
 
diff --git a/src/node/ext/call.h b/src/node/ext/call.h
index 53a5e4ab67905c24c860afcad6f38136b971f116..340e32682b9f031b4fcc658e6015a85492332959 100644
--- a/src/node/ext/call.h
+++ b/src/node/ext/call.h
@@ -106,6 +106,7 @@ class Op {
   virtual ~Op();
   v8::Local<v8::Value> GetOpType() const;
   virtual bool IsFinalOp() = 0;
+  virtual void OnComplete(bool success) = 0;
 
  protected:
   virtual std::string GetTypeString() const = 0;
@@ -123,13 +124,9 @@ struct tag {
       call_persist;
 };
 
-v8::Local<v8::Value> GetTagNodeValue(void *tag);
-
-Nan::Callback *GetTagCallback(void *tag);
-
 void DestroyTag(void *tag);
 
-void CompleteTag(void *tag);
+void CompleteTag(void *tag, const char *error_message);
 
 }  // namespace node
 }  // namespace grpc
diff --git a/src/node/ext/completion_queue_threadpool.cc b/src/node/ext/completion_queue_threadpool.cc
index 1917074dc2dfe85ddd238513b6ae2199291b52ef..7b1bdda03341e14afbe70a03c6a684659b6a2ee3 100644
--- a/src/node/ext/completion_queue_threadpool.cc
+++ b/src/node/ext/completion_queue_threadpool.cc
@@ -148,9 +148,7 @@ void CompletionQueueAsyncWorker::HandleOKCallback() {
   Nan::HandleScope scope;
   current_threads -= 1;
   TryAddWorker();
-  Nan::Callback *callback = GetTagCallback(result.tag);
-  Local<Value> argv[] = {Nan::Null(), GetTagNodeValue(result.tag)};
-  callback->Call(2, argv);
+  CompleteTag(result.tag, NULL);
 
   DestroyTag(result.tag);
 }
@@ -159,10 +157,7 @@ void CompletionQueueAsyncWorker::HandleErrorCallback() {
   Nan::HandleScope scope;
   current_threads -= 1;
   TryAddWorker();
-  Nan::Callback *callback = GetTagCallback(result.tag);
-  Local<Value> argv[] = {Nan::Error(ErrorMessage())};
-
-  callback->Call(1, argv);
+  CompleteTag(result.tag, ErrorMessage());
 
   DestroyTag(result.tag);
 }
diff --git a/src/node/ext/completion_queue_uv.cc b/src/node/ext/completion_queue_uv.cc
index 615973a6c9b8f0e67fc02bc2a068bf74b4098906..0f6f7da46077a6129a1981f454f47122aa425e0b 100644
--- a/src/node/ext/completion_queue_uv.cc
+++ b/src/node/ext/completion_queue_uv.cc
@@ -61,17 +61,13 @@ void drain_completion_queue(uv_prepare_t *handle) {
         queue, gpr_inf_past(GPR_CLOCK_MONOTONIC), NULL);
 
     if (event.type == GRPC_OP_COMPLETE) {
-      Nan::Callback *callback = grpc::node::GetTagCallback(event.tag);
+      const char *error_message;
       if (event.success) {
-        Local<Value> argv[] = {Nan::Null(),
-                             grpc::node::GetTagNodeValue(event.tag)};
-        callback->Call(2, argv);
+        error_message = NULL;
       } else {
-        Local<Value> argv[] = {Nan::Error(
-            "The async function encountered an error")};
-        callback->Call(1, argv);
+        error_message = "The async function encountered an error";
       }
-      grpc::node::CompleteTag(event.tag);
+      CompleteTag(event.tag, error_message);
       grpc::node::DestroyTag(event.tag);
       pending_batches--;
       if (pending_batches == 0) {
diff --git a/src/node/ext/server.cc b/src/node/ext/server.cc
index f0920c842a3d50670880573d40411564ffcf6a2a..5384305631db0e0009c0e7c177a765682ba794fd 100644
--- a/src/node/ext/server.cc
+++ b/src/node/ext/server.cc
@@ -117,6 +117,8 @@ class NewCallOp : public Op {
   bool IsFinalOp() {
     return false;
   }
+  void OnComplete(bool success) {
+  }
 
   grpc_call *call;
   grpc_call_details details;
@@ -126,6 +128,34 @@ class NewCallOp : public Op {
   std::string GetTypeString() const { return "new_call"; }
 };
 
+class TryShutdownOp: public Op {
+ public:
+  TryShutdownOp(Server *server, Local<Value> server_value) : server(server) {
+    server_persist.Reset(server_value);
+  }
+  Local<Value> GetNodeValue() const {
+    EscapableHandleScope scope;
+    return scope.Escape(Nan::New(server_persist));
+  }
+  bool ParseOp(Local<Value> value, grpc_op *out) {
+    return true;
+  }
+  bool IsFinalOp() {
+    return false;
+  }
+  void OnComplete(bool success) {
+    if (success) {
+      server->DestroyWrappedServer();
+    }
+  }
+ protected:
+  std::string GetTypeString() const { return "try_shutdown"; }
+ private:
+  Server *server;
+  Nan::Persistent<v8::Value, Nan::CopyablePersistentTraits<v8::Value>>
+      server_persist;
+};
+
 void Server::Init(Local<Object> exports) {
   HandleScope scope;
   Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
@@ -147,6 +177,13 @@ bool Server::HasInstance(Local<Value> val) {
   return Nan::New(fun_tpl)->HasInstance(val);
 }
 
+void Server::DestroyWrappedServer() {
+  if (this->wrapped_server != NULL) {
+    grpc_server_destroy(this->wrapped_server);
+    this->wrapped_server = NULL;
+  }
+}
+
 NAN_METHOD(Server::New) {
   /* If this is not a constructor call, make a constructor call and return
      the result */
@@ -242,7 +279,15 @@ NAN_METHOD(Server::TryShutdown) {
     return Nan::ThrowTypeError("tryShutdown can only be called on a Server");
   }
   Server *server = ObjectWrap::Unwrap<Server>(info.This());
+  if (server->wrapped_server == NULL) {
+    // Server is already shut down. Call callback immediately.
+    Nan::Callback callback(info[0].As<Function>());
+    callback.Call(0, {});
+    return;
+  }
+  TryShutdownOp *op = new TryShutdownOp(server, info.This());
   unique_ptr<OpVec> ops(new OpVec());
+  ops->push_back(unique_ptr<Op>(op));
   grpc_server_shutdown_and_notify(
       server->wrapped_server, GetCompletionQueue(),
       new struct tag(new Nan::Callback(info[0].As<Function>()), ops.release(),
diff --git a/src/node/ext/server.h b/src/node/ext/server.h
index ab5fc210e8ace61e6021d197fc11577d166723cc..c0f2e86554b534ea03b34404b3d3892415bbe991 100644
--- a/src/node/ext/server.h
+++ b/src/node/ext/server.h
@@ -53,6 +53,8 @@ class Server : public Nan::ObjectWrap {
      JavaScript constructor */
   static bool HasInstance(v8::Local<v8::Value> val);
 
+  void DestroyWrappedServer();
+
  private:
   explicit Server(grpc_server *server);
   ~Server();
diff --git a/src/node/ext/server_uv.cc b/src/node/ext/server_uv.cc
index 82e7589fc870fb8b042ebd25539e54fd7ddbf5a6..789938318ebfd99bb8864b8b407fab2167335981 100644
--- a/src/node/ext/server_uv.cc
+++ b/src/node/ext/server_uv.cc
@@ -67,7 +67,7 @@ class ServerShutdownOp : public Op {
   }
 
   Local<Value> GetNodeValue() const {
-    return Nan::New<External>(reinterpret_cast<void *>(server));
+    return Nan::Null();
   }
 
   bool ParseOp(Local<Value> value, grpc_op *out) {
@@ -76,6 +76,11 @@ class ServerShutdownOp : public Op {
   bool IsFinalOp() {
     return false;
   }
+  void OnComplete(bool success) {
+    /* Because cancel_all_calls was called, we assume that shutdown_and_notify
+       completes successfully */
+    grpc_server_destroy(server);
+  }
 
   grpc_server *server;
 
@@ -94,16 +99,10 @@ NAN_METHOD(ServerShutdownCallback) {
   if (!info[0]->IsNull()) {
     return Nan::ThrowError("forceShutdown failed somehow");
   }
-  MaybeLocal<Object> maybe_result = Nan::To<Object>(info[1]);
-  Local<Object> result = maybe_result.ToLocalChecked();
-  Local<Value> server_val = Nan::Get(
-      result, Nan::New("shutdown").ToLocalChecked()).ToLocalChecked();
-  Local<External> server_extern = server_val.As<External>();
-  grpc_server *server = reinterpret_cast<grpc_server *>(server_extern->Value());
-  grpc_server_destroy(server);
 }
 
 void Server::ShutdownServer() {
+  Nan::HandleScope scope;
   if (this->wrapped_server != NULL) {
     if (shutdown_callback == NULL) {
       Local<FunctionTemplate>callback_tpl =
diff --git a/src/node/health_check/package.json b/src/node/health_check/package.json
index e218f5a4063dc34b46b4d9bd7c20544c55bd9b5c..37c9b7a54f5fd0f381937b860f16e54a77d32ae0 100644
--- a/src/node/health_check/package.json
+++ b/src/node/health_check/package.json
@@ -1,6 +1,6 @@
 {
   "name": "grpc-health-check",
-  "version": "1.3.0-dev",
+  "version": "1.4.0-dev",
   "author": "Google Inc.",
   "description": "Health check service for use with gRPC",
   "repository": {
@@ -15,7 +15,7 @@
     }
   ],
   "dependencies": {
-    "grpc": "^1.3.0-dev",
+    "grpc": "^1.4.0-dev",
     "lodash": "^3.9.3",
     "google-protobuf": "^3.0.0"
   },
diff --git a/src/node/test/test_messages.proto b/src/node/test/test_messages.proto
index ae70f6e152a5acc2141dd06db372776ccb2261d4..43c213dabb1fb87bca217f754e7d7f63f5963063 100644
--- a/src/node/test/test_messages.proto
+++ b/src/node/test/test_messages.proto
@@ -57,4 +57,4 @@ enum TestEnum {
 
 message EnumValues {
   TestEnum enum_value = 1;
-}
\ No newline at end of file
+}
diff --git a/src/node/tools/package.json b/src/node/tools/package.json
index 3096c6e42a8fcd6a0ffb442fbd8b9947baa108d4..a81aa87f4bb7708a6582fae4607a1c5b058f7e01 100644
--- a/src/node/tools/package.json
+++ b/src/node/tools/package.json
@@ -1,6 +1,6 @@
 {
   "name": "grpc-tools",
-  "version": "1.3.0-dev",
+  "version": "1.4.0-dev",
   "author": "Google Inc.",
   "description": "Tools for developing with gRPC on Node.js",
   "homepage": "http://www.grpc.io/",
diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
index 2f41ad196a651f50fb35544f8e23b8c73c2fef1a..2f29058b59d4b721e1a3958c7acca9723a2f7413 100644
--- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
+++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
@@ -42,7 +42,7 @@ Pod::Spec.new do |s|
   # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
   # before them.
   s.name     = '!ProtoCompiler-gRPCPlugin'
-  v = '1.3.0-dev'
+  v = '1.4.0-dev'
   s.version  = v
   s.summary  = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.'
   s.description = <<-DESC
diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h
index 09155ee4d40afab42c113e7c9f2270979b3719b2..c846f4214c968a4f67f75d38238b967d7338424c 100644
--- a/src/objective-c/GRPCClient/private/version.h
+++ b/src/objective-c/GRPCClient/private/version.h
@@ -38,4 +38,4 @@
 // `tools/buildgen/generate_projects.sh`.
 
 
-#define GRPC_OBJC_VERSION_STRING @"1.3.0-dev"
+#define GRPC_OBJC_VERSION_STRING @"1.4.0-dev"
diff --git a/src/php/composer.json b/src/php/composer.json
index 2b140077cc5ed9ddbb4e508d6bce036b8b161f6f..24c17c3b572dacf45772a44005d11a71a09cda1e 100644
--- a/src/php/composer.json
+++ b/src/php/composer.json
@@ -2,7 +2,7 @@
   "name": "grpc/grpc-dev",
   "description": "gRPC library for PHP - for Developement use only",
   "license": "BSD-3-Clause",
-  "version": "1.3.0",
+  "version": "1.4.0",
   "require": {
     "php": ">=5.5.0",
     "google/protobuf": "^v3.1.0"
diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py
index 267d848e74377e8d036915a7fb2122fbde598601..ea4bc7ba207d856818fc418a43d8488245d5f1f4 100644
--- a/src/python/grpcio/grpc_version.py
+++ b/src/python/grpcio/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!!
 
-VERSION='1.3.0.dev0'
+VERSION='1.4.0.dev0'
diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py
index 4ff5e266a1f4f1becb827368196562d2dcdaedff..26aa555e14cf9b2257214624a9f3bcb83c77a668 100644
--- a/src/python/grpcio_health_checking/grpc_version.py
+++ b/src/python/grpcio_health_checking/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!!
 
-VERSION='1.3.0.dev0'
+VERSION='1.4.0.dev0'
diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py
index 8ffc08c04b8f72ebbc771f7bb153fcc31b5f096e..978d6b4011f76ac41a5d3f17bb88c6680acb30dc 100644
--- a/src/python/grpcio_reflection/grpc_version.py
+++ b/src/python/grpcio_reflection/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!!
 
-VERSION='1.3.0.dev0'
+VERSION='1.4.0.dev0'
diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py
index ba82dce6f6d2ae8e168370aa4f4385606e54942a..5f0b084884649fea2bd4d0fee6d92d6bdda4e9c5 100644
--- a/src/python/grpcio_tests/grpc_version.py
+++ b/src/python/grpcio_tests/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!!
 
-VERSION='1.3.0.dev0'
+VERSION='1.4.0.dev0'
diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb
index 9901158e735daae3d90616247754933bdff569dc..f30dff335f1af4606a0b3cb37581beb67dcf9148 100644
--- a/src/ruby/lib/grpc/version.rb
+++ b/src/ruby/lib/grpc/version.rb
@@ -29,5 +29,5 @@
 
 # GRPC contains the General RPC module.
 module GRPC
-  VERSION = '1.3.0.dev'
+  VERSION = '1.4.0.dev'
 end
diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb
index 632c0100bd842cef6ddffb978e9c7ebb36d0e466..1f8d4afb95f2fcfe4da299292e1aaf1ef4af7501 100644
--- a/src/ruby/tools/version.rb
+++ b/src/ruby/tools/version.rb
@@ -29,6 +29,6 @@
 
 module GRPC
   module Tools
-    VERSION = '1.3.0.dev'
+    VERSION = '1.4.0.dev'
   end
 end
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 8f61a8b99078be244ce0bb68fa0da7fe5c74f1ed..1e6ca9337d732a9f6575d8788dbd806ff15dc155 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -1609,7 +1609,7 @@
   ifeq ($(SYSTEM),Darwin)
   	$(Q) ${ld} ${ldflags} -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) -dynamiclib -o ${out_libbase}.$(SHARED_EXT_${lang_to_var[lib.language]}) ${common}${link_libs}
   else
-  	$(Q) ${ld} ${ldflags} -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,lib${lib.name}.so.${settings.core_version.major} -o ${out_libbase}.$(SHARED_EXT_${lang_to_var[lib.language]}) ${common}${link_libs}
+  	$(Q) ${ld} ${ldflags} -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,lib${lib.name}.so.${settings.get(lang_to_var[lib.language].lower() + '_version').major} -o ${out_libbase}.$(SHARED_EXT_${lang_to_var[lib.language]}) ${common}${link_libs}
   	$(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) ${out_libbase}.so.${settings.get(lang_to_var[lib.language].lower() + '_version').major}
   	$(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) ${out_libbase}.so
   endif
diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c
index a0acf5bf6020b728b748a83a9d5213481abefabf..0ec5a23d5d2a32ad64b86ff53dfa04732654ff45 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.c
+++ b/test/core/end2end/fuzzers/api_fuzzer.c
@@ -967,7 +967,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
           break;
         }
         grpc_op *ops = gpr_malloc(sizeof(grpc_op) * num_ops);
-        memset(ops, 0, sizeof(grpc_op) * num_ops);
+        if (num_ops > 0) memset(ops, 0, sizeof(grpc_op) * num_ops);
         bool ok = true;
         size_t i;
         grpc_op *op;
diff --git a/test/core/end2end/tests/max_message_length.c b/test/core/end2end/tests/max_message_length.c
index ab58d9f9a62aae2f21384c2f64df3e0a5fa60aed..a8b6f1f79a9c25b78b67faad6d334b35f1fe0fff 100644
--- a/test/core/end2end/tests/max_message_length.c
+++ b/test/core/end2end/tests/max_message_length.c
@@ -272,7 +272,7 @@ static void test_max_message_length_on_request(grpc_end2end_test_config config,
   GPR_ASSERT(was_cancelled == 1);
 
 done:
-  GPR_ASSERT(status == GRPC_STATUS_INVALID_ARGUMENT);
+  GPR_ASSERT(status == GRPC_STATUS_RESOURCE_EXHAUSTED);
   GPR_ASSERT(
       grpc_slice_str_cmp(
           details, send_limit
@@ -466,7 +466,7 @@ static void test_max_message_length_on_response(grpc_end2end_test_config config,
   GPR_ASSERT(0 ==
              grpc_slice_str_cmp(call_details.host, "foo.test.google.fr:1234"));
 
-  GPR_ASSERT(status == GRPC_STATUS_INVALID_ARGUMENT);
+  GPR_ASSERT(status == GRPC_STATUS_RESOURCE_EXHAUSTED);
   GPR_ASSERT(
       grpc_slice_str_cmp(
           details, send_limit
diff --git a/test/core/support/spinlock_test.c b/test/core/support/spinlock_test.c
index c70e76c7ea1c729c8decf1116ecaea74c46ee9a5..96055e9bd785ebd5b5f4873e3dc5e195c69bee9e 100644
--- a/test/core/support/spinlock_test.c
+++ b/test/core/support/spinlock_test.c
@@ -109,7 +109,7 @@ static void test(const char *name, void (*body)(void *m), int timeout_s,
       start, gpr_time_from_micros((int64_t)timeout_s * 1000000, GPR_TIMESPAN));
   fprintf(stderr, "%s:", name);
   while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0) {
-    iterations <<= 1;
+    if (iterations < INT64_MAX / 2) iterations <<= 1;
     fprintf(stderr, " %ld", (long)iterations);
     m = test_new(10, iterations, incr_step);
     test_create_threads(m, body);
diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py
index ad35b90bad3743f0afc81df80abfd22732d3242d..1f2aa81c850aaa782cee069c0ceea02b7c12b463 100644
--- a/tools/distrib/python/grpcio_tools/grpc_version.py
+++ b/tools/distrib/python/grpcio_tools/grpc_version.py
@@ -29,4 +29,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!!
 
-VERSION='1.3.0.dev0'
+VERSION='1.4.0.dev0'
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 59e619749a88a24c24d63be365b1021f973a3a91..1864dd9e908404a8e66f8a9ffc05d51a545a9250 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -40,7 +40,7 @@ PROJECT_NAME           = "GRPC C++"
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 1.3.0-dev
+PROJECT_NUMBER         = 1.4.0-dev
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 48e9aca14cd30250623ee61ffb7d09b8bf410dae..ca3514bc61e7f30be3b0c95eb9225142cd79eebd 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -40,7 +40,7 @@ PROJECT_NAME           = "GRPC C++"
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 1.3.0-dev
+PROJECT_NUMBER         = 1.4.0-dev
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
diff --git a/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.sh b/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.sh
index c3bf79b1fb57b057f8fb3b9845f8e494c34692e9..47ccb26f878349232ad79ed07ae2b56de7620ff8 100755
--- a/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.sh
+++ b/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.sh
@@ -37,4 +37,4 @@ git submodule update --init
 
 # download docker images from dockerhub
 export DOCKERHUB_ORGANIZATION=grpctesting
-tools/run_tests/run_tests_matrix.py -f cpp asan
+tools/run_tests/run_tests_matrix.py -f c++ asan
diff --git a/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.sh b/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.sh
index c72a106c91af9a67be6c4130418ab30ea25ced94..ee3ec5ebb08023b6ec6a5a3aa4617639c44ed793 100755
--- a/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.sh
+++ b/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.sh
@@ -37,4 +37,4 @@ git submodule update --init
 
 # download docker images from dockerhub
 export DOCKERHUB_ORGANIZATION=grpctesting
-tools/run_tests/run_tests_matrix.py -f cpp tsan
+tools/run_tests/run_tests_matrix.py -f c++ tsan