diff --git a/grpc/tests/GameFactory.java b/grpc/tests/GameFactory.java
new file mode 100644
index 0000000..520ae39
--- /dev/null
+++ b/grpc/tests/GameFactory.java
@@ -0,0 +1,42 @@
+import java.nio.ByteBuffer;
+import MyGame.Example.Monster;
+import MyGame.Example.Stat;
+import com.google.flatbuffers.FlatBufferBuilder;
+
+class GameFactory {
+  public static Monster createMonster(String monsterName, short nestedMonsterHp, short nestedMonsterMana) {
+    FlatBufferBuilder builder = new FlatBufferBuilder();
+
+    int name_offset = builder.createString(monsterName);
+    Monster.startMonster(builder);
+    Monster.addName(builder, name_offset);
+    Monster.addHp(builder, nestedMonsterHp);
+    Monster.addMana(builder, nestedMonsterMana);
+    int monster_offset = Monster.endMonster(builder);
+    Monster.finishMonsterBuffer(builder, monster_offset);
+
+    ByteBuffer buffer = builder.dataBuffer();
+    Monster monster = Monster.getRootAsMonster(buffer);
+    return monster;
+  }
+
+  public static Monster createMonsterFromStat(Stat stat, int seqNo) {
+    FlatBufferBuilder builder = new FlatBufferBuilder();
+    int name_offset = builder.createString(stat.id() + " No." + seqNo);
+    Monster.startMonster(builder);
+    Monster.addName(builder, name_offset);
+    int monster_offset = Monster.endMonster(builder);
+    Monster.finishMonsterBuffer(builder, monster_offset);
+    Monster monster = Monster.getRootAsMonster(builder.dataBuffer());
+    return monster;
+  }
+
+  public static Stat createStat(String greeting, long val, int count) { 
+    FlatBufferBuilder builder = new FlatBufferBuilder();
+    int statOffset = Stat.createStat(builder, builder.createString(greeting), val, count);
+    builder.finish(statOffset);
+    Stat stat = Stat.getRootAsStat(builder.dataBuffer());
+    return stat;
+  }
+
+}
diff --git a/grpc/tests/JavaGrpcTest.java b/grpc/tests/JavaGrpcTest.java
new file mode 100644
index 0000000..98a67b5
--- /dev/null
+++ b/grpc/tests/JavaGrpcTest.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import MyGame.Example.Monster;
+import MyGame.Example.MonsterStorageGrpc;
+import MyGame.Example.Stat;
+import com.google.flatbuffers.FlatBufferBuilder;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import io.grpc.Server;
+import io.grpc.ServerBuilder;
+import io.grpc.stub.StreamObserver;
+import org.junit.Assert;
+
+import java.io.IOException;
+import java.lang.InterruptedException;
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.CountDownLatch;
+
+
+/**
+ * Demonstrates basic client-server interaction using grpc-java over netty.
+ */
+public class JavaGrpcTest {
+    static final String BIG_MONSTER_NAME = "Cyberdemon";
+    static final short nestedMonsterHp = 600;
+    static final short nestedMonsterMana = 1024;
+    static final int numStreamedMsgs = 10;
+    static final int timeoutMs = 3000;
+    static Server server;
+    static ManagedChannel channel;
+    static MonsterStorageGrpc.MonsterStorageBlockingStub blockingStub;
+    static MonsterStorageGrpc.MonsterStorageStub asyncStub;
+
+    static class MyService extends MonsterStorageGrpc.MonsterStorageImplBase {
+        @Override
+        public void store(Monster request, io.grpc.stub.StreamObserver<Stat> responseObserver) {
+            Assert.assertEquals(request.name(), BIG_MONSTER_NAME);
+            Assert.assertEquals(request.hp(), nestedMonsterHp);
+            Assert.assertEquals(request.mana(), nestedMonsterMana);
+            System.out.println("Received store request from " + request.name());
+            // Create a response from the incoming request name.
+            Stat stat = GameFactory.createStat("Hello " + request.name(), 100, 10);
+            responseObserver.onNext(stat);
+            responseObserver.onCompleted();
+        }
+
+        @Override
+        public void retrieve(Stat request, io.grpc.stub.StreamObserver<Monster> responseObserver) {
+            // Create 10 monsters for streaming response.
+            for (int i=0; i<numStreamedMsgs; i++) {
+                Monster monster = GameFactory.createMonsterFromStat(request, i);
+                responseObserver.onNext(monster);
+            }
+            responseObserver.onCompleted();
+        }
+
+        @Override
+        public StreamObserver<Monster> getMaxHitPoint(final StreamObserver<Stat> responseObserver) {
+          return computeMinMax(responseObserver, false);
+        }
+
+        @Override
+        public StreamObserver<Monster> getMinMaxHitPoints(final StreamObserver<Stat> responseObserver) {
+          return computeMinMax(responseObserver, true);
+        }
+
+        private StreamObserver<Monster> computeMinMax(final StreamObserver<Stat> responseObserver, final boolean includeMin) {
+          final AtomicInteger maxHp = new AtomicInteger(Integer.MIN_VALUE);
+          final AtomicReference<String> maxHpMonsterName = new AtomicReference<String>();
+          final AtomicInteger maxHpCount = new AtomicInteger();
+
+          final AtomicInteger minHp = new AtomicInteger(Integer.MAX_VALUE);
+          final AtomicReference<String> minHpMonsterName = new AtomicReference<String>();
+          final AtomicInteger minHpCount = new AtomicInteger();
+
+          return new StreamObserver<Monster>() {
+            public void onNext(Monster monster) {
+              if (monster.hp() > maxHp.get()) {
+                // Found a monster of higher hit points.
+                maxHp.set(monster.hp());
+                maxHpMonsterName.set(monster.name()); 
+                maxHpCount.set(1);
+              }
+              else if (monster.hp() == maxHp.get()) {
+                // Count how many times we saw a monster of current max hit points.
+                maxHpCount.getAndIncrement();
+              }
+
+              if (monster.hp() < minHp.get()) {
+                // Found a monster of a lower hit points.
+                minHp.set(monster.hp());
+                minHpMonsterName.set(monster.name());
+                minHpCount.set(1);
+              }
+              else if (monster.hp() == minHp.get()) {
+                // Count how many times we saw a monster of current min hit points.
+                minHpCount.getAndIncrement();
+              }
+            }
+            public void onCompleted() {
+              Stat maxHpStat = GameFactory.createStat(maxHpMonsterName.get(), maxHp.get(), maxHpCount.get());
+              // Send max hit points first.
+              responseObserver.onNext(maxHpStat);
+              if (includeMin) {
+                // Send min hit points.
+                Stat minHpStat = GameFactory.createStat(minHpMonsterName.get(), minHp.get(), minHpCount.get());
+                responseObserver.onNext(minHpStat);
+              }
+              responseObserver.onCompleted();
+            }
+            public void onError(Throwable t) {
+              // Not expected
+              Assert.fail();
+            };
+          };
+        }
+    }
+
+    @org.junit.BeforeClass
+    public static void startServer() throws IOException {
+        server = ServerBuilder.forPort(0).addService(new MyService()).build().start();
+        int port = server.getPort();
+        channel = ManagedChannelBuilder.forAddress("localhost", port)
+                // Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
+                // needing certificates.
+                .usePlaintext(true)
+                .directExecutor()
+                .build();
+        blockingStub = MonsterStorageGrpc.newBlockingStub(channel);
+        asyncStub = MonsterStorageGrpc.newStub(channel);
+    }
+
+    @org.junit.Test
+    public void testUnary() throws IOException {
+        Monster monsterRequest = GameFactory.createMonster(BIG_MONSTER_NAME, nestedMonsterHp, nestedMonsterMana);
+        Stat stat = blockingStub.store(monsterRequest);
+        Assert.assertEquals(stat.id(), "Hello " + BIG_MONSTER_NAME);
+        System.out.println("Received stat response from service: " + stat.id());
+    }
+
+    @org.junit.Test
+    public void testServerStreaming() throws IOException {
+        Monster monsterRequest = GameFactory.createMonster(BIG_MONSTER_NAME, nestedMonsterHp, nestedMonsterMana);
+        Stat stat = blockingStub.store(monsterRequest);
+        Iterator<Monster> iterator = blockingStub.retrieve(stat);
+        int counter = 0;
+        while(iterator.hasNext()) {
+            Monster m = iterator.next();
+            System.out.println("Received monster " + m.name());
+            counter ++;
+        }
+        Assert.assertEquals(counter, numStreamedMsgs);
+        System.out.println("FlatBuffers GRPC client/server test: completed successfully");
+    }
+
+    @org.junit.Test
+    public void testClientStreaming() throws IOException, InterruptedException {
+      final AtomicReference<Stat> maxHitStat = new AtomicReference<Stat>();
+      final CountDownLatch streamAlive = new CountDownLatch(1);
+
+      StreamObserver<Stat> statObserver = new StreamObserver<Stat>() {
+        public void onCompleted() { 
+          streamAlive.countDown();
+        }
+        public void onError(Throwable ex) { }
+        public void onNext(Stat stat) {
+          maxHitStat.set(stat);
+        }
+      };
+      StreamObserver<Monster> monsterStream = asyncStub.getMaxHitPoint(statObserver);
+      short count = 10;
+      for (short i = 0;i < count; ++i) {
+        Monster monster = GameFactory.createMonster(BIG_MONSTER_NAME + i, (short) (nestedMonsterHp * i), nestedMonsterMana);
+        monsterStream.onNext(monster);
+      }
+      monsterStream.onCompleted();
+      // Wait a little bit for the server to send the stats of the monster with the max hit-points.
+      streamAlive.await(timeoutMs, TimeUnit.MILLISECONDS);
+      Assert.assertEquals(maxHitStat.get().id(), BIG_MONSTER_NAME + (count - 1));
+      Assert.assertEquals(maxHitStat.get().val(), nestedMonsterHp * (count - 1));
+      Assert.assertEquals(maxHitStat.get().count(), 1);
+    }
+
+    @org.junit.Test
+    public void testBiDiStreaming() throws IOException, InterruptedException {
+      final AtomicReference<Stat> maxHitStat = new AtomicReference<Stat>();
+      final AtomicReference<Stat> minHitStat = new AtomicReference<Stat>();
+      final CountDownLatch streamAlive = new CountDownLatch(1);
+
+      StreamObserver<Stat> statObserver = new StreamObserver<Stat>() {
+        public void onCompleted() {
+          streamAlive.countDown();
+        }
+        public void onError(Throwable ex) { }
+        public void onNext(Stat stat) {
+          // We expect the server to send the max stat first and then the min stat.
+          if (maxHitStat.get() == null) {
+            maxHitStat.set(stat);
+          }
+          else {
+            minHitStat.set(stat);
+          }
+        }
+      };
+      StreamObserver<Monster> monsterStream = asyncStub.getMinMaxHitPoints(statObserver);
+      short count = 10;
+      for (short i = 0;i < count; ++i) {
+        Monster monster = GameFactory.createMonster(BIG_MONSTER_NAME + i, (short) (nestedMonsterHp * i), nestedMonsterMana);
+        monsterStream.onNext(monster);
+      }
+      monsterStream.onCompleted();
+
+      // Wait a little bit for the server to send the stats of the monster with the max and min hit-points.
+      streamAlive.await(timeoutMs, TimeUnit.MILLISECONDS);
+
+      Assert.assertEquals(maxHitStat.get().id(), BIG_MONSTER_NAME + (count - 1));
+      Assert.assertEquals(maxHitStat.get().val(), nestedMonsterHp * (count - 1));
+      Assert.assertEquals(maxHitStat.get().count(), 1);
+
+      Assert.assertEquals(minHitStat.get().id(), BIG_MONSTER_NAME + 0);
+      Assert.assertEquals(minHitStat.get().val(), nestedMonsterHp * 0);
+      Assert.assertEquals(minHitStat.get().count(), 1);
+    }
+}
diff --git a/grpc/tests/go_test.go b/grpc/tests/go_test.go
new file mode 100644
index 0000000..288036b
--- /dev/null
+++ b/grpc/tests/go_test.go
@@ -0,0 +1,93 @@
+package testing
+
+import (
+	"../../tests/MyGame/Example"
+
+	"context"
+	"net"
+	"testing"
+
+	"google.golang.org/grpc"
+)
+
+type server struct{}
+
+// test used to send and receive in grpc methods
+var test = "Flatbuffers"
+var addr = "0.0.0.0:50051"
+
+// gRPC server store method
+func (s *server) Store(context context.Context, in *Example.Monster) (*flatbuffers.Builder, error) {
+	b := flatbuffers.NewBuilder(0)
+	i := b.CreateString(test)
+	Example.StatStart(b)
+	Example.StatAddId(b, i)
+	b.Finish(Example.StatEnd(b))
+	return b, nil
+
+}
+
+// gRPC server retrieve method
+func (s *server) Retrieve(context context.Context, in *Example.Stat) (*flatbuffers.Builder, error) {
+	b := flatbuffers.NewBuilder(0)
+	i := b.CreateString(test)
+	Example.MonsterStart(b)
+	Example.MonsterAddName(b, i)
+	b.Finish(Example.MonsterEnd(b))
+	return b, nil
+}
+
+func StoreClient(c Example.MonsterStorageClient, t *testing.T) {
+	b := flatbuffers.NewBuilder(0)
+	i := b.CreateString(test)
+	Example.MonsterStart(b)
+	Example.MonsterAddName(b, i)
+	b.Finish(Example.MonsterEnd(b))
+	out, err := c.Store(context.Background(), b)
+	if err != nil {
+		t.Fatalf("Store client failed: %v", err)
+	}
+	if string(out.Id()) != test {
+		t.Errorf("StoreClient failed: expected=%s, got=%s\n", test, out.Id())
+		t.Fail()
+	}
+}
+
+func RetrieveClient(c Example.MonsterStorageClient, t *testing.T) {
+	b := flatbuffers.NewBuilder(0)
+	i := b.CreateString(test)
+	Example.StatStart(b)
+	Example.StatAddId(b, i)
+	b.Finish(Example.StatEnd(b))
+	out, err := c.Retrieve(context.Background(), b)
+	if err != nil {
+		t.Fatalf("Retrieve client failed: %v", err)
+	}
+	if string(out.Name()) != test {
+		t.Errorf("RetrieveClient failed: expected=%s, got=%s\n", test, out.Name())
+		t.Fail()
+	}
+}
+
+func TestGRPC(t *testing.T) {
+	lis, err := net.Listen("tcp", addr)
+	if err != nil {
+		t.Fatalf("Failed to listen: %v", err)
+	}
+	ser := grpc.NewServer(grpc.CustomCodec(flatbuffers.FlatbuffersCodec{}))
+	Example.RegisterMonsterStorageServer(ser, &server{})
+	go func() {
+		if err := ser.Serve(lis); err != nil {
+			t.Fatalf("Failed to serve: %v", err)
+			t.FailNow()
+		}
+	}()
+	conn, err := grpc.Dial(addr, grpc.WithInsecure(), grpc.WithCodec(flatbuffers.FlatbuffersCodec{}))
+	if err != nil {
+		t.Fatalf("Failed to connect: %v", err)
+	}
+	defer conn.Close()
+	client := Example.NewMonsterStorageClient(conn)
+	StoreClient(client, t)
+	RetrieveClient(client, t)
+}
diff --git a/grpc/tests/grpctest.cpp b/grpc/tests/grpctest.cpp
new file mode 100644
index 0000000..7e5c6e6
--- /dev/null
+++ b/grpc/tests/grpctest.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <thread>
+
+#include <grpc++/grpc++.h>
+
+#include "monster_test.grpc.fb.h"
+#include "monster_test_generated.h"
+#include "test_assert.h"
+
+using namespace MyGame::Example;
+using flatbuffers::grpc::MessageBuilder;
+using flatbuffers::FlatBufferBuilder;
+
+void message_builder_tests();
+
+// The callback implementation of our server, that derives from the generated
+// code. It implements all rpcs specified in the FlatBuffers schema.
+class ServiceImpl final : public MyGame::Example::MonsterStorage::Service {
+  virtual ::grpc::Status Store(
+      ::grpc::ServerContext *context,
+      const flatbuffers::grpc::Message<Monster> *request,
+      flatbuffers::grpc::Message<Stat> *response) override {
+    // Create a response from the incoming request name.
+    fbb_.Clear();
+    auto stat_offset = CreateStat(
+        fbb_, fbb_.CreateString("Hello, " + request->GetRoot()->name()->str()));
+    fbb_.Finish(stat_offset);
+    // Transfer ownership of the message to gRPC
+    *response = fbb_.ReleaseMessage<Stat>();
+    return grpc::Status::OK;
+  }
+  virtual ::grpc::Status Retrieve(
+      ::grpc::ServerContext *context,
+      const flatbuffers::grpc::Message<Stat> *request,
+      ::grpc::ServerWriter<flatbuffers::grpc::Message<Monster>> *writer)
+      override {
+    for (int i = 0; i < 5; i++) {
+      fbb_.Clear();
+      // Create 5 monsters for resposne.
+      auto monster_offset =
+          CreateMonster(fbb_, 0, 0, 0,
+                        fbb_.CreateString(request->GetRoot()->id()->str() +
+                                          " No." + std::to_string(i)));
+      fbb_.Finish(monster_offset);
+
+      flatbuffers::grpc::Message<Monster> monster =
+          fbb_.ReleaseMessage<Monster>();
+
+      // Send monster to client using streaming.
+      writer->Write(monster);
+    }
+    return grpc::Status::OK;
+  }
+
+ private:
+  flatbuffers::grpc::MessageBuilder fbb_;
+};
+
+// Track the server instance, so we can terminate it later.
+grpc::Server *server_instance = nullptr;
+// Mutex to protec this variable.
+std::mutex wait_for_server;
+std::condition_variable server_instance_cv;
+
+// This function implements the server thread.
+void RunServer() {
+  auto server_address = "0.0.0.0:50051";
+  // Callback interface we implemented above.
+  ServiceImpl service;
+  grpc::ServerBuilder builder;
+  builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+  builder.RegisterService(&service);
+
+  // Start the server. Lock to change the variable we're changing.
+  wait_for_server.lock();
+  server_instance = builder.BuildAndStart().release();
+  wait_for_server.unlock();
+  server_instance_cv.notify_one();
+
+  std::cout << "Server listening on " << server_address << std::endl;
+  // This will block the thread and serve requests.
+  server_instance->Wait();
+}
+
+template <class Builder>
+void StoreRPC(MonsterStorage::Stub *stub) {
+  Builder fbb;
+  grpc::ClientContext context;
+  // Build a request with the name set.
+  auto monster_offset = CreateMonster(fbb, 0, 0, 0, fbb.CreateString("Fred"));
+  MessageBuilder mb(std::move(fbb));
+  mb.Finish(monster_offset);
+  auto request = mb.ReleaseMessage<Monster>();
+  flatbuffers::grpc::Message<Stat> response;
+
+  // The actual RPC.
+  auto status = stub->Store(&context, request, &response);
+
+  if (status.ok()) {
+    auto resp = response.GetRoot()->id();
+    std::cout << "RPC response: " << resp->str() << std::endl;
+  } else {
+    std::cout << "RPC failed" << std::endl;
+  }
+}
+
+template <class Builder>
+void RetrieveRPC(MonsterStorage::Stub *stub) {
+  Builder fbb;
+  grpc::ClientContext context;
+  fbb.Clear();
+  auto stat_offset = CreateStat(fbb, fbb.CreateString("Fred"));
+  fbb.Finish(stat_offset);
+  auto request = MessageBuilder(std::move(fbb)).ReleaseMessage<Stat>();
+
+  flatbuffers::grpc::Message<Monster> response;
+  auto stream = stub->Retrieve(&context, request);
+  while (stream->Read(&response)) {
+    auto resp = response.GetRoot()->name();
+    std::cout << "RPC Streaming response: " << resp->str() << std::endl;
+  }
+}
+
+int grpc_server_test() {
+  // Launch server.
+  std::thread server_thread(RunServer);
+
+  // wait for server to spin up.
+  std::unique_lock<std::mutex> lock(wait_for_server);
+  while (!server_instance) server_instance_cv.wait(lock);
+
+  // Now connect the client.
+  auto channel = grpc::CreateChannel("localhost:50051",
+                                     grpc::InsecureChannelCredentials());
+  auto stub = MyGame::Example::MonsterStorage::NewStub(channel);
+
+  StoreRPC<MessageBuilder>(stub.get());
+  StoreRPC<FlatBufferBuilder>(stub.get());
+
+  RetrieveRPC<MessageBuilder>(stub.get());
+  RetrieveRPC<FlatBufferBuilder>(stub.get());
+
+
+#if !FLATBUFFERS_GRPC_DISABLE_AUTO_VERIFICATION
+  {
+    // Test that an invalid request errors out correctly
+    grpc::ClientContext context;
+    flatbuffers::grpc::Message<Monster> request;  // simulate invalid message
+    flatbuffers::grpc::Message<Stat> response;
+    auto status = stub->Store(&context, request, &response);
+    // The rpc status should be INTERNAL to indicate a verification error. This
+    // matches the protobuf gRPC status code for an unparseable message.
+    assert(!status.ok());
+    assert(status.error_code() == ::grpc::StatusCode::INTERNAL);
+    assert(strcmp(status.error_message().c_str(),
+                  "Message verification failed") == 0);
+  }
+#endif
+
+  server_instance->Shutdown();
+
+  server_thread.join();
+
+  delete server_instance;
+
+  return 0;
+}
+
+int main(int /*argc*/, const char * /*argv*/ []) {
+  message_builder_tests();
+  grpc_server_test();
+
+  if (!testing_fails) {
+    TEST_OUTPUT_LINE("ALL TESTS PASSED");
+    return 0;
+  } else {
+    TEST_OUTPUT_LINE("%d FAILED TESTS", testing_fails);
+    return 1;
+  }
+}
+
diff --git a/grpc/tests/java-grpc-test.sh b/grpc/tests/java-grpc-test.sh
new file mode 100755
index 0000000..ec42960
--- /dev/null
+++ b/grpc/tests/java-grpc-test.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+# NOTE: make sure `mvn install` in /gprc is executed before running this test
+mvn test
diff --git a/grpc/tests/message_builder_test.cpp b/grpc/tests/message_builder_test.cpp
new file mode 100644
index 0000000..36f5bc2
--- /dev/null
+++ b/grpc/tests/message_builder_test.cpp
@@ -0,0 +1,340 @@
+#include "flatbuffers/grpc.h"
+#include "monster_test_generated.h"
+#include "test_assert.h"
+#include "test_builder.h"
+
+using MyGame::Example::Vec3;
+using MyGame::Example::CreateStat;
+using MyGame::Example::Any_NONE;
+
+bool verify(flatbuffers::grpc::Message<Monster> &msg, const std::string &expected_name, Color color) {
+  const Monster *monster = msg.GetRoot();
+  return (monster->name()->str() == expected_name) && (monster->color() == color);
+}
+
+bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb, const std::string &expected_name, Color color) {
+  flatbuffers::grpc::Message<Monster> msg = mbb.ReleaseMessage<Monster>();
+  const Monster *monster = msg.GetRoot();
+  return (monster->name()->str() == expected_name) && (monster->color() == color);
+}
+
+void builder_move_assign_after_releaseraw_test(flatbuffers::grpc::MessageBuilder dst) {
+  auto root_offset1 = populate1(dst);
+  dst.Finish(root_offset1);
+  size_t size, offset;
+  grpc_slice slice;
+  dst.ReleaseRaw(size, offset, slice);
+  flatbuffers::FlatBufferBuilder src;
+  auto root_offset2 = populate2(src);
+  src.Finish(root_offset2);
+  auto src_size = src.GetSize();
+  // Move into a released builder.
+  dst = std::move(src);
+  TEST_EQ(dst.GetSize(), src_size);
+  TEST_ASSERT(release_n_verify(dst, m2_name, m2_color));
+  TEST_EQ(src.GetSize(), 0);
+  grpc_slice_unref(slice);
+}
+
+template <class SrcBuilder>
+struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
+  static void builder_reusable_after_release_message_test(TestSelector selector) {
+    if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE)) {
+      return;
+    }
+
+    flatbuffers::grpc::MessageBuilder mb;
+    std::vector<flatbuffers::grpc::Message<Monster>> buffers;
+    for (int i = 0; i < 5; ++i) {
+      auto root_offset1 = populate1(mb);
+      mb.Finish(root_offset1);
+      buffers.push_back(mb.ReleaseMessage<Monster>());
+      TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
+    }
+  }
+
+  static void builder_reusable_after_release_test(TestSelector selector) {
+    if (!selector.count(REUSABLE_AFTER_RELEASE)) {
+      return;
+    }
+
+    // FIXME: Populate-Release loop fails assert(GRPC_SLICE_IS_EMPTY(slice_)) in SliceAllocator::allocate
+    // in the second iteration.
+
+    flatbuffers::grpc::MessageBuilder mb;
+    std::vector<flatbuffers::DetachedBuffer> buffers;
+    for (int i = 0; i < 2; ++i) {
+      auto root_offset1 = populate1(mb);
+      mb.Finish(root_offset1);
+      buffers.push_back(mb.Release());
+      TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
+    }
+  }
+
+  static void builder_reusable_after_releaseraw_test(TestSelector selector) {
+    if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) {
+      return;
+    }
+
+    flatbuffers::grpc::MessageBuilder mb;
+    for (int i = 0; i < 5; ++i) {
+      auto root_offset1 = populate1(mb);
+      mb.Finish(root_offset1);
+      size_t size, offset;
+      grpc_slice slice;
+      const uint8_t *buf = mb.ReleaseRaw(size, offset, slice);
+      TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
+      grpc_slice_unref(slice);
+    }
+  }
+
+  static void builder_reusable_after_release_and_move_assign_test(TestSelector selector) {
+    if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) {
+      return;
+    }
+
+    // FIXME: Release-move_assign loop fails assert(p == GRPC_SLICE_START_PTR(slice_))
+    // in DetachedBuffer destructor after all the iterations
+
+    flatbuffers::grpc::MessageBuilder dst;
+    std::vector<flatbuffers::DetachedBuffer> buffers;
+
+    for (int i = 0; i < 2; ++i) {
+      auto root_offset1 = populate1(dst);
+      dst.Finish(root_offset1);
+      buffers.push_back(dst.Release());
+      TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
+
+      // bring dst back to life.
+      SrcBuilder src;
+      dst = std::move(src);
+      TEST_EQ_FUNC(dst.GetSize(), 0);
+      TEST_EQ_FUNC(src.GetSize(), 0);
+    }
+  }
+
+  static void builder_reusable_after_release_message_and_move_assign_test(TestSelector selector) {
+    if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN)) {
+      return;
+    }
+
+    flatbuffers::grpc::MessageBuilder dst;
+    std::vector<flatbuffers::grpc::Message<Monster>> buffers;
+
+    for (int i = 0; i < 5; ++i) {
+      auto root_offset1 = populate1(dst);
+      dst.Finish(root_offset1);
+      buffers.push_back(dst.ReleaseMessage<Monster>());
+      TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
+
+      // bring dst back to life.
+      SrcBuilder src;
+      dst = std::move(src);
+      TEST_EQ_FUNC(dst.GetSize(), 0);
+      TEST_EQ_FUNC(src.GetSize(), 0);
+    }
+  }
+
+  static void builder_reusable_after_releaseraw_and_move_assign_test(TestSelector selector) {
+    if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) {
+      return;
+    }
+
+    flatbuffers::grpc::MessageBuilder dst;
+    for (int i = 0; i < 5; ++i) {
+      auto root_offset1 = populate1(dst);
+      dst.Finish(root_offset1);
+      size_t size, offset;
+      grpc_slice slice = grpc_empty_slice();
+      const uint8_t *buf = dst.ReleaseRaw(size, offset, slice);
+      TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
+      grpc_slice_unref(slice);
+
+      SrcBuilder src;
+      dst = std::move(src);
+      TEST_EQ_FUNC(dst.GetSize(), 0);
+      TEST_EQ_FUNC(src.GetSize(), 0);
+    }
+  }
+
+  static void run_tests(TestSelector selector) {
+    builder_reusable_after_release_test(selector);
+    builder_reusable_after_release_message_test(selector);
+    builder_reusable_after_releaseraw_test(selector);
+    builder_reusable_after_release_and_move_assign_test(selector);
+    builder_reusable_after_releaseraw_and_move_assign_test(selector);
+    builder_reusable_after_release_message_and_move_assign_test(selector);
+  }
+};
+
+void slice_allocator_tests() {
+  // move-construct no-delete test
+  {
+    size_t size = 2048;
+    flatbuffers::grpc::SliceAllocator sa1;
+    uint8_t *buf = sa1.allocate(size);
+    TEST_ASSERT_FUNC(buf != 0);
+    buf[0] = 100;
+    buf[size-1] = 200;
+    flatbuffers::grpc::SliceAllocator sa2(std::move(sa1));
+    // buf should not be deleted after move-construct
+    TEST_EQ_FUNC(buf[0], 100);
+    TEST_EQ_FUNC(buf[size-1], 200);
+    // buf is freed here
+  }
+
+  // move-assign test
+  {
+    flatbuffers::grpc::SliceAllocator sa1, sa2;
+    uint8_t *buf = sa1.allocate(2048);
+    sa1 = std::move(sa2);
+    // sa1 deletes previously allocated memory in move-assign.
+    // So buf is no longer usable here.
+    TEST_ASSERT_FUNC(buf != 0);
+  }
+}
+
+/// This function does not populate exactly the first half of the table. But it could.
+void populate_first_half(MyGame::Example::MonsterBuilder &wrapper, flatbuffers::Offset<flatbuffers::String> name_offset) {
+  wrapper.add_name(name_offset);
+  wrapper.add_color(m1_color);
+}
+
+/// This function does not populate exactly the second half of the table. But it could.
+void populate_second_half(MyGame::Example::MonsterBuilder &wrapper) {
+  wrapper.add_hp(77);
+  wrapper.add_mana(88);
+  Vec3 vec3;
+  wrapper.add_pos(&vec3);
+}
+
+/// This function is a hack to update the FlatBufferBuilder reference (fbb_) in the MonsterBuilder object.
+/// This function will break if fbb_ is not the first member in MonsterBuilder. In that case, some offset must be added.
+/// This function is used exclusively for testing correctness of move operations between FlatBufferBuilders.
+/// If MonsterBuilder had a fbb_ pointer, this hack would be unnecessary. That involves a code-generator change though.
+void test_only_hack_update_fbb_reference(MyGame::Example::MonsterBuilder &monsterBuilder,
+                                         flatbuffers::grpc::MessageBuilder &mb) {
+  *reinterpret_cast<flatbuffers::FlatBufferBuilder **>(&monsterBuilder) = &mb;
+}
+
+/// This test validates correctness of move conversion of FlatBufferBuilder to a MessageBuilder DURING
+/// a table construction. Half of the table is constructed using FlatBufferBuilder and the other half
+/// of the table is constructed using a MessageBuilder.
+void builder_move_ctor_conversion_before_finish_half_n_half_table_test() {
+  for (size_t initial_size = 4 ; initial_size <= 2048; initial_size *= 2) {
+    flatbuffers::FlatBufferBuilder fbb(initial_size);
+    auto name_offset = fbb.CreateString(m1_name);
+    MyGame::Example::MonsterBuilder monsterBuilder(fbb);     // starts a table in FlatBufferBuilder
+    populate_first_half(monsterBuilder, name_offset);
+    flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
+    test_only_hack_update_fbb_reference(monsterBuilder, mb); // hack
+    populate_second_half(monsterBuilder);
+    mb.Finish(monsterBuilder.Finish());                      // ends the table in MessageBuilder
+    TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
+    TEST_EQ_FUNC(fbb.GetSize(), 0);
+  }
+}
+
+/// This test populates a COMPLETE inner table before move conversion and later populates more members in the outer table.
+void builder_move_ctor_conversion_before_finish_test() {
+  for (size_t initial_size = 4 ; initial_size <= 2048; initial_size *= 2) {
+    flatbuffers::FlatBufferBuilder fbb(initial_size);
+    auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0);
+    flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
+    auto monster_offset = CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name), 0, m1_color, Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
+    mb.Finish(monster_offset);
+    TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
+    TEST_EQ_FUNC(fbb.GetSize(), 0);
+  }
+}
+
+/// This test validates correctness of move conversion of FlatBufferBuilder to a MessageBuilder DURING
+/// a table construction. Half of the table is constructed using FlatBufferBuilder and the other half
+/// of the table is constructed using a MessageBuilder.
+void builder_move_assign_conversion_before_finish_half_n_half_table_test() {
+  flatbuffers::FlatBufferBuilder fbb;
+  flatbuffers::grpc::MessageBuilder mb;
+
+  for (int i = 0;i < 5; ++i) {
+    flatbuffers::FlatBufferBuilder fbb;
+    auto name_offset = fbb.CreateString(m1_name);
+    MyGame::Example::MonsterBuilder monsterBuilder(fbb);     // starts a table in FlatBufferBuilder
+    populate_first_half(monsterBuilder, name_offset);
+    mb = std::move(fbb);
+    test_only_hack_update_fbb_reference(monsterBuilder, mb); // hack
+    populate_second_half(monsterBuilder);
+    mb.Finish(monsterBuilder.Finish());                      // ends the table in MessageBuilder
+    TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
+    TEST_EQ_FUNC(fbb.GetSize(), 0);
+  }
+}
+
+/// This test populates a COMPLETE inner table before move conversion and later populates more members in the outer table.
+void builder_move_assign_conversion_before_finish_test() {
+  flatbuffers::FlatBufferBuilder fbb;
+  flatbuffers::grpc::MessageBuilder mb;
+
+  for (int i = 0;i < 5; ++i) {
+    auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0);
+    mb = std::move(fbb);
+    auto monster_offset = CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name), 0, m1_color, Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
+    mb.Finish(monster_offset);
+    TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
+    TEST_EQ_FUNC(fbb.GetSize(), 0);
+  }
+}
+
+/// This test populates data, finishes the buffer, and does move conversion after.
+void builder_move_ctor_conversion_after_finish_test() {
+  flatbuffers::FlatBufferBuilder fbb;
+  fbb.Finish(populate1(fbb));
+  flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
+  TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
+  TEST_EQ_FUNC(fbb.GetSize(), 0);
+}
+
+/// This test populates data, finishes the buffer, and does move conversion after.
+void builder_move_assign_conversion_after_finish_test() {
+  flatbuffers::FlatBufferBuilder fbb;
+  flatbuffers::grpc::MessageBuilder mb;
+
+  for (int i = 0;i < 5; ++i) {
+    fbb.Finish(populate1(fbb));
+    mb = std::move(fbb);
+    TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
+    TEST_EQ_FUNC(fbb.GetSize(), 0);
+  }
+}
+
+void message_builder_tests() {
+  using flatbuffers::grpc::MessageBuilder;
+  using flatbuffers::FlatBufferBuilder;
+
+  slice_allocator_tests();
+
+#ifndef __APPLE__
+  builder_move_ctor_conversion_before_finish_half_n_half_table_test();
+  builder_move_assign_conversion_before_finish_half_n_half_table_test();
+#endif // __APPLE__
+  builder_move_ctor_conversion_before_finish_test();
+  builder_move_assign_conversion_before_finish_test();
+
+  builder_move_ctor_conversion_after_finish_test();
+  builder_move_assign_conversion_after_finish_test();
+
+  BuilderTests<MessageBuilder, MessageBuilder>::all_tests();
+  BuilderTests<MessageBuilder, FlatBufferBuilder>::all_tests();
+
+  BuilderReuseTestSelector tests[6] = {
+    //REUSABLE_AFTER_RELEASE,                 // Assertion failed: (GRPC_SLICE_IS_EMPTY(slice_))
+    //REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN, // Assertion failed: (p == GRPC_SLICE_START_PTR(slice_)
+
+    REUSABLE_AFTER_RELEASE_RAW,
+    REUSABLE_AFTER_RELEASE_MESSAGE,
+    REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN,
+    REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN
+  };
+
+  BuilderReuseTests<MessageBuilder, MessageBuilder>::run_tests(TestSelector(tests, tests+6));
+  BuilderReuseTests<MessageBuilder, FlatBufferBuilder>::run_tests(TestSelector(tests, tests+6));
+}
diff --git a/grpc/tests/pom.xml b/grpc/tests/pom.xml
new file mode 100644
index 0000000..addc9fa
--- /dev/null
+++ b/grpc/tests/pom.xml
@@ -0,0 +1,73 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.google.flatbuffers</groupId>
+        <artifactId>flatbuffers-parent</artifactId>
+        <version>1.11.1</version>
+    </parent>
+    <artifactId>grpc-test</artifactId>
+    <description>Example/Test project demonstrating usage of flatbuffers with GRPC-Java instead of protobufs
+    </description>
+    <properties>
+        <gRPC.version>1.11.1</gRPC.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>com.google.flatbuffers</groupId>
+            <artifactId>flatbuffers-java</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.flatbuffers</groupId>
+            <artifactId>flatbuffers-java-grpc</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+            <version>${gRPC.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-netty</artifactId>
+            <version>${gRPC.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>add-source</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>add-test-source</goal>
+                        </goals>
+                        <configuration>
+                            <sources>
+                                <source>${project.basedir}</source>
+				<source>${project.basedir}/../../tests</source>
+                            </sources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+        <!--<testSourceDirectory>${project.basedir}</testSourceDirectory>-->
+    </build>
+</project>
+
