diff --git a/lang/cs/GrpcCodeGeneration.targets b/lang/cs/GrpcCodeGeneration.targets
new file mode 100644
index 0000000..a63e693
--- /dev/null
+++ b/lang/cs/GrpcCodeGeneration.targets
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+-->
+<!-- GRPC CODE GENERATION TARGETS FOR MSBUILD -->
+<Project>
+  <UsingTask TaskName="GrpcToCSharp" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
+    <ParameterGroup>
+      <!-- The directory where the project is located. This is typically $(ProjectDir) -->
+      <OutputDirectory ParameterType="System.String" Required="true" />
+      <!-- This is the list of C# target files to be generaterd. This is typically @(Compile) -->
+      <SourceFileList ParameterType="System.String" Required="true" />
+      <!-- The directory where the .avsc schema files are located. -->
+      <GrpcSchemaDirectory ParameterType="System.String" Required="true" />
+      <!-- The where gRPC schema generator and dependent libraries are located. -->
+      <GrpcBinaryDirectory ParameterType="System.String" Required="true" />
+    </ParameterGroup>
+    <Task>
+      <Using Namespace="System" />
+      <Using Namespace="System.IO" />
+      <Using Namespace="System.Diagnostics" />
+      <Using Namespace="System.Threading" />
+      <Using Namespace="System.Threading.Tasks" />
+      <Code Type="Fragment" Language="cs"><![CDATA[
+          // Create a temporary working directory for the log file.
+          string tempDir = Path.GetFullPath(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()));
+          Directory.CreateDirectory(tempDir);
+
+          // Get the full path to the directory where the gRPC .proto files are located.
+          string grpcSrcFileDirectory = Path.GetFullPath(GrpcSchemaDirectory);
+          string grpcToolsDirectory = Path.GetFullPath(GrpcBinaryDirectory);
+          string grpcOutputDirectory = Path.GetFullPath(OutputDirectory);
+          string grpcPluginName = Path.Combine(GrpcBinaryDirectory, "grpc_csharp_plugin.exe");
+
+          // Get the list of names of .proto files
+          string[] sourceFiles = SourceFileList.Split(new char[]{';'});
+
+          string copyright = string.Join(Environment.NewLine,
+            "// Licensed to the Apache Software Foundation (ASF) under one",
+            "// or more contributor license agreements.  See the NOTICE file",
+            "// distributed with this work for additional information",
+            "// regarding copyright ownership.  The ASF licenses this file",
+            "// to you 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.");
+
+
+          // Setup the conversion process.
+          ProcessStartInfo rProcInfo = new ProcessStartInfo()
+          {
+              RedirectStandardOutput = true,
+              RedirectStandardError = true,
+              UseShellExecute = false,
+              CreateNoWindow = true,
+              FileName = Path.Combine(grpcToolsDirectory ,"protoc.exe")
+          };
+
+          bool conversionError = false;
+          using (StreamWriter logWriter = new StreamWriter(Path.Combine(tempDir, "GrpcCodeGeneration.log")))
+          {
+              foreach (string file in sourceFiles)
+              {
+                  logWriter.WriteLine("Processing file: {0}", file);
+
+                  string fullFileName = Path.Combine(grpcSrcFileDirectory, file);
+                  rProcInfo.Arguments = " -I" + grpcSrcFileDirectory + " --csharp_out " + tempDir
+                      + " " + fullFileName + " --grpc_out " + tempDir
+                      + " --plugin=protoc-gen-grpc=" + grpcPluginName;
+                  logWriter.WriteLine("Command: {0}", rProcInfo.Arguments);
+
+                  if (File.Exists(fullFileName))
+                  {
+                      StringBuilder stdOutBuilder = new StringBuilder();
+                      StringBuilder stdErrBuilder = new StringBuilder();
+
+                      // Start the conversion process
+                      using (Process rProc = Process.Start(rProcInfo))
+                      {
+                          // Read the standard out and error on separate threads
+                          // simultaneously to avoid deadlock when rProc fills one
+                          // of the buffers and waits for this process to read it.
+                          // Use fully qualified namespace to avoid conflict
+                          // with Task class defined in visual studio.
+                          var stdOutTask = System.Threading.Tasks.Task.Run(
+                              () => stdOutBuilder.Append(rProc.StandardOutput.ReadToEnd()));
+                          var stdErrTask = System.Threading.Tasks.Task.Run(
+                              () => stdErrBuilder.Append(rProc.StandardError.ReadToEnd()));
+
+                          rProc.WaitForExit();
+                          if (rProc.ExitCode != 0)
+                          {
+                              conversionError = true;
+                          }
+
+                          // Wait for std out and error readers.
+                          stdOutTask.Wait();
+                          stdErrTask.Wait();
+                      }
+                      logWriter.WriteLine("[StdOut]:");
+                      logWriter.WriteLine(stdOutBuilder.ToString());
+                      logWriter.WriteLine("[StdErr]:");
+                      logWriter.WriteLine(stdErrBuilder.ToString());
+                  }
+                  if (!conversionError)
+                  {
+                      // Get all of the generated C# files and copy to destination with copyright.
+                      var genFiles = Directory.EnumerateFiles(tempDir, "*.cs");
+                      foreach (string genFile in genFiles)
+                      {
+                          logWriter.WriteLine("Processing file {0}", genFile);
+                          using (StreamReader tmpReader = new StreamReader(genFile))
+                          {
+                              using (StreamWriter destWriter =
+                                  new StreamWriter(Path.Combine(grpcOutputDirectory, Path.GetFileName(genFile))))
+                             {
+                                 destWriter.WriteLine(copyright);
+                                 destWriter.Write(tmpReader.ReadToEnd());
+                             }
+                          }
+                          File.Delete(genFile);
+                      }
+                  }
+              }
+          }
+          if (!conversionError)
+          {
+              Directory.Delete(tempDir, recursive : true);
+          }
+      ]]></Code>
+    </Task>
+  </UsingTask>
+</Project>
diff --git a/lang/cs/Org.Apache.REEF.Bridge.Client/GrpcGeneratedCode/ClientProtocol.cs b/lang/cs/Org.Apache.REEF.Bridge.Client/GrpcGeneratedCode/ClientProtocol.cs
new file mode 100644
index 0000000..2bcafba
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Bridge.Client/GrpcGeneratedCode/ClientProtocol.cs
@@ -0,0 +1,1226 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: ClientProtocol.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Org.Apache.REEF.Bridge.Proto {
+
+  /// <summary>Holder for reflection information generated from ClientProtocol.proto</summary>
+  public static partial class ClientProtocolReflection {
+
+    #region Descriptor
+    /// <summary>File descriptor for ClientProtocol.proto</summary>
+    public static pbr::FileDescriptor Descriptor {
+      get { return descriptor; }
+    }
+    private static pbr::FileDescriptor descriptor;
+
+    static ClientProtocolReflection() {
+      byte[] descriptorData = global::System.Convert.FromBase64String(
+          string.Concat(
+            "ChRDbGllbnRQcm90b2NvbC5wcm90bxIMZHJpdmVyYnJpZGdlIoMBChZMb2Nh",
+            "bFJ1bnRpbWVQYXJhbWV0ZXJzEiAKGG1heF9udW1iZXJfb2ZfZXZhbHVhdG9y",
+            "cxgBIAEoDRIbChNydW50aW1lX3Jvb3RfZm9sZGVyGAIgASgJEhYKDmp2bV9o",
+            "ZWFwX3NsYWNrGAMgASgJEhIKCnJhY2tfbmFtZXMYBCADKAkiTwoVWWFyblJ1",
+            "bnRpbWVQYXJhbWV0ZXJzEg0KBXF1ZXVlGAEgASgJEicKH2pvYl9zdWJtaXNz",
+            "aW9uX2RpcmVjdG9yeV9wcmVmaXgYAiABKAkiHQobQXp1cmVCYXRjaFJ1bnRp",
+            "bWVQYXJhbWV0ZXJzIhgKFk1lc29zUnVudGltZVBhcmFtZXRlcnMiygcKGURy",
+            "aXZlckNsaWVudENvbmZpZ3VyYXRpb24SDQoFam9iaWQYASABKAkSEQoJY3B1",
+            "X2NvcmVzGAIgASgNEhEKCW1lbW9yeV9tYhgDIAEoDRI9Cg1sb2NhbF9ydW50",
+            "aW1lGAQgASgLMiQuZHJpdmVyYnJpZGdlLkxvY2FsUnVudGltZVBhcmFtZXRl",
+            "cnNIABI7Cgx5YXJuX3J1bnRpbWUYBSABKAsyIy5kcml2ZXJicmlkZ2UuWWFy",
+            "blJ1bnRpbWVQYXJhbWV0ZXJzSAASRAoPYXpiYXRjaF9ydW50aW1lGAYgASgL",
+            "MikuZHJpdmVyYnJpZGdlLkF6dXJlQmF0Y2hSdW50aW1lUGFyYW1ldGVyc0gA",
+            "Ej0KDW1lc29zX3J1bnRpbWUYByABKAsyJC5kcml2ZXJicmlkZ2UuTWVzb3NS",
+            "dW50aW1lUGFyYW1ldGVyc0gAEiQKHGRyaXZlcl9jbGllbnRfbGF1bmNoX2Nv",
+            "bW1hbmQYCiABKAkSQQoHaGFuZGxlchgLIAMoDjIwLmRyaXZlcmJyaWRnZS5E",
+            "cml2ZXJDbGllbnRDb25maWd1cmF0aW9uLkhhbmRsZXJzEhwKFHRjcF9wb3J0",
+            "X3JhbmdlX2JlZ2luGA8gASgNEhwKFHRjcF9wb3J0X3JhbmdlX2NvdW50GBAg",
+            "ASgNEiAKGHRjcF9wb3J0X3JhbmdlX3RyeV9jb3VudBgRIAEoDRIUCgxnbG9i",
+            "YWxfZmlsZXMYFCADKAkSEwoLbG9jYWxfZmlsZXMYFSADKAkSGAoQZ2xvYmFs",
+            "X2xpYnJhcmllcxgWIAMoCRIXCg9sb2NhbF9saWJyYXJpZXMYFyADKAkixgIK",
+            "CEhhbmRsZXJzEgkKBVNUQVJUEAASCAoEU1RPUBABEhcKE0VWQUxVQVRPUl9B",
+            "TExPQ0FURUQQBRIXChNFVkFMVUFUT1JfQ09NUExFVEVEEAYSFAoQRVZBTFVB",
+            "VE9SX0ZBSUxFRBAHEhIKDkNPTlRFWFRfQUNUSVZFEAoSEgoOQ09OVEVYVF9D",
+            "TE9TRUQQCxISCg5DT05URVhUX0ZBSUxFRBAMEhMKD0NPTlRFWFRfTUVTU0FH",
+            "RRANEhAKDFRBU0tfUlVOTklORxAPEg8KC1RBU0tfRkFJTEVEEBASEgoOVEFT",
+            "S19DT01QTEVURUQQERIQCgxUQVNLX01FU1NBR0UQEhISCg5DTElFTlRfTUVT",
+            "U0FHRRAUEhAKDENMSUVOVF9DTE9TRRAVEh0KGUNMSUVOVF9DTE9TRV9XSVRI",
+            "X01FU1NBR0UQFkIJCgdydW50aW1lQk0KHG9yZy5hcGFjaGUucmVlZi5icmlk",
+            "Z2UucHJvdG9CDkNsaWVudFByb3RvY29sqgIcT3JnLkFwYWNoZS5SRUVGLkJy",
+            "aWRnZS5Qcm90b2IGcHJvdG8z"));
+      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+          new pbr::FileDescriptor[] { },
+          new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+            new pbr::GeneratedClrTypeInfo(typeof(global::Org.Apache.REEF.Bridge.Proto.LocalRuntimeParameters), global::Org.Apache.REEF.Bridge.Proto.LocalRuntimeParameters.Parser, new[]{ "MaxNumberOfEvaluators", "RuntimeRootFolder", "JvmHeapSlack", "RackNames" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Org.Apache.REEF.Bridge.Proto.YarnRuntimeParameters), global::Org.Apache.REEF.Bridge.Proto.YarnRuntimeParameters.Parser, new[]{ "Queue", "JobSubmissionDirectoryPrefix" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Org.Apache.REEF.Bridge.Proto.AzureBatchRuntimeParameters), global::Org.Apache.REEF.Bridge.Proto.AzureBatchRuntimeParameters.Parser, null, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Org.Apache.REEF.Bridge.Proto.MesosRuntimeParameters), global::Org.Apache.REEF.Bridge.Proto.MesosRuntimeParameters.Parser, null, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Org.Apache.REEF.Bridge.Proto.DriverClientConfiguration), global::Org.Apache.REEF.Bridge.Proto.DriverClientConfiguration.Parser, new[]{ "Jobid", "CpuCores", "MemoryMb", "LocalRuntime", "YarnRuntime", "AzbatchRuntime", "MesosRuntime", "DriverClientLaunchCommand", "Handler", "TcpPortRangeBegin", "TcpPortRangeCount", "TcpPortRangeTryCount", "GlobalFiles", "LocalFiles", "GlobalLibraries", "LocalLibraries" }, new[]{ "Runtime" }, new[]{ typeof(global::Org.Apache.REEF.Bridge.Proto.DriverClientConfiguration.Types.Handlers) }, null)
+          }));
+    }
+    #endregion
+
+  }
+  #region Messages
+  public sealed partial class LocalRuntimeParameters : pb::IMessage<LocalRuntimeParameters> {
+    private static readonly pb::MessageParser<LocalRuntimeParameters> _parser = new pb::MessageParser<LocalRuntimeParameters>(() => new LocalRuntimeParameters());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<LocalRuntimeParameters> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Org.Apache.REEF.Bridge.Proto.ClientProtocolReflection.Descriptor.MessageTypes[0]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public LocalRuntimeParameters() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public LocalRuntimeParameters(LocalRuntimeParameters other) : this() {
+      maxNumberOfEvaluators_ = other.maxNumberOfEvaluators_;
+      runtimeRootFolder_ = other.runtimeRootFolder_;
+      jvmHeapSlack_ = other.jvmHeapSlack_;
+      rackNames_ = other.rackNames_.Clone();
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public LocalRuntimeParameters Clone() {
+      return new LocalRuntimeParameters(this);
+    }
+
+    /// <summary>Field number for the "max_number_of_evaluators" field.</summary>
+    public const int MaxNumberOfEvaluatorsFieldNumber = 1;
+    private uint maxNumberOfEvaluators_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public uint MaxNumberOfEvaluators {
+      get { return maxNumberOfEvaluators_; }
+      set {
+        maxNumberOfEvaluators_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "runtime_root_folder" field.</summary>
+    public const int RuntimeRootFolderFieldNumber = 2;
+    private string runtimeRootFolder_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string RuntimeRootFolder {
+      get { return runtimeRootFolder_; }
+      set {
+        runtimeRootFolder_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "jvm_heap_slack" field.</summary>
+    public const int JvmHeapSlackFieldNumber = 3;
+    private string jvmHeapSlack_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string JvmHeapSlack {
+      get { return jvmHeapSlack_; }
+      set {
+        jvmHeapSlack_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "rack_names" field.</summary>
+    public const int RackNamesFieldNumber = 4;
+    private static readonly pb::FieldCodec<string> _repeated_rackNames_codec
+        = pb::FieldCodec.ForString(34);
+    private readonly pbc::RepeatedField<string> rackNames_ = new pbc::RepeatedField<string>();
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pbc::RepeatedField<string> RackNames {
+      get { return rackNames_; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as LocalRuntimeParameters);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(LocalRuntimeParameters other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (MaxNumberOfEvaluators != other.MaxNumberOfEvaluators) return false;
+      if (RuntimeRootFolder != other.RuntimeRootFolder) return false;
+      if (JvmHeapSlack != other.JvmHeapSlack) return false;
+      if(!rackNames_.Equals(other.rackNames_)) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (MaxNumberOfEvaluators != 0) hash ^= MaxNumberOfEvaluators.GetHashCode();
+      if (RuntimeRootFolder.Length != 0) hash ^= RuntimeRootFolder.GetHashCode();
+      if (JvmHeapSlack.Length != 0) hash ^= JvmHeapSlack.GetHashCode();
+      hash ^= rackNames_.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (MaxNumberOfEvaluators != 0) {
+        output.WriteRawTag(8);
+        output.WriteUInt32(MaxNumberOfEvaluators);
+      }
+      if (RuntimeRootFolder.Length != 0) {
+        output.WriteRawTag(18);
+        output.WriteString(RuntimeRootFolder);
+      }
+      if (JvmHeapSlack.Length != 0) {
+        output.WriteRawTag(26);
+        output.WriteString(JvmHeapSlack);
+      }
+      rackNames_.WriteTo(output, _repeated_rackNames_codec);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (MaxNumberOfEvaluators != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeUInt32Size(MaxNumberOfEvaluators);
+      }
+      if (RuntimeRootFolder.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(RuntimeRootFolder);
+      }
+      if (JvmHeapSlack.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(JvmHeapSlack);
+      }
+      size += rackNames_.CalculateSize(_repeated_rackNames_codec);
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(LocalRuntimeParameters other) {
+      if (other == null) {
+        return;
+      }
+      if (other.MaxNumberOfEvaluators != 0) {
+        MaxNumberOfEvaluators = other.MaxNumberOfEvaluators;
+      }
+      if (other.RuntimeRootFolder.Length != 0) {
+        RuntimeRootFolder = other.RuntimeRootFolder;
+      }
+      if (other.JvmHeapSlack.Length != 0) {
+        JvmHeapSlack = other.JvmHeapSlack;
+      }
+      rackNames_.Add(other.rackNames_);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            MaxNumberOfEvaluators = input.ReadUInt32();
+            break;
+          }
+          case 18: {
+            RuntimeRootFolder = input.ReadString();
+            break;
+          }
+          case 26: {
+            JvmHeapSlack = input.ReadString();
+            break;
+          }
+          case 34: {
+            rackNames_.AddEntriesFrom(input, _repeated_rackNames_codec);
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  public sealed partial class YarnRuntimeParameters : pb::IMessage<YarnRuntimeParameters> {
+    private static readonly pb::MessageParser<YarnRuntimeParameters> _parser = new pb::MessageParser<YarnRuntimeParameters>(() => new YarnRuntimeParameters());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<YarnRuntimeParameters> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Org.Apache.REEF.Bridge.Proto.ClientProtocolReflection.Descriptor.MessageTypes[1]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public YarnRuntimeParameters() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public YarnRuntimeParameters(YarnRuntimeParameters other) : this() {
+      queue_ = other.queue_;
+      jobSubmissionDirectoryPrefix_ = other.jobSubmissionDirectoryPrefix_;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public YarnRuntimeParameters Clone() {
+      return new YarnRuntimeParameters(this);
+    }
+
+    /// <summary>Field number for the "queue" field.</summary>
+    public const int QueueFieldNumber = 1;
+    private string queue_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Queue {
+      get { return queue_; }
+      set {
+        queue_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "job_submission_directory_prefix" field.</summary>
+    public const int JobSubmissionDirectoryPrefixFieldNumber = 2;
+    private string jobSubmissionDirectoryPrefix_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string JobSubmissionDirectoryPrefix {
+      get { return jobSubmissionDirectoryPrefix_; }
+      set {
+        jobSubmissionDirectoryPrefix_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as YarnRuntimeParameters);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(YarnRuntimeParameters other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (Queue != other.Queue) return false;
+      if (JobSubmissionDirectoryPrefix != other.JobSubmissionDirectoryPrefix) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Queue.Length != 0) hash ^= Queue.GetHashCode();
+      if (JobSubmissionDirectoryPrefix.Length != 0) hash ^= JobSubmissionDirectoryPrefix.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Queue.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(Queue);
+      }
+      if (JobSubmissionDirectoryPrefix.Length != 0) {
+        output.WriteRawTag(18);
+        output.WriteString(JobSubmissionDirectoryPrefix);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (Queue.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Queue);
+      }
+      if (JobSubmissionDirectoryPrefix.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(JobSubmissionDirectoryPrefix);
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(YarnRuntimeParameters other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Queue.Length != 0) {
+        Queue = other.Queue;
+      }
+      if (other.JobSubmissionDirectoryPrefix.Length != 0) {
+        JobSubmissionDirectoryPrefix = other.JobSubmissionDirectoryPrefix;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            Queue = input.ReadString();
+            break;
+          }
+          case 18: {
+            JobSubmissionDirectoryPrefix = input.ReadString();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  public sealed partial class AzureBatchRuntimeParameters : pb::IMessage<AzureBatchRuntimeParameters> {
+    private static readonly pb::MessageParser<AzureBatchRuntimeParameters> _parser = new pb::MessageParser<AzureBatchRuntimeParameters>(() => new AzureBatchRuntimeParameters());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<AzureBatchRuntimeParameters> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Org.Apache.REEF.Bridge.Proto.ClientProtocolReflection.Descriptor.MessageTypes[2]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public AzureBatchRuntimeParameters() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public AzureBatchRuntimeParameters(AzureBatchRuntimeParameters other) : this() {
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public AzureBatchRuntimeParameters Clone() {
+      return new AzureBatchRuntimeParameters(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as AzureBatchRuntimeParameters);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(AzureBatchRuntimeParameters other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(AzureBatchRuntimeParameters other) {
+      if (other == null) {
+        return;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+        }
+      }
+    }
+
+  }
+
+  public sealed partial class MesosRuntimeParameters : pb::IMessage<MesosRuntimeParameters> {
+    private static readonly pb::MessageParser<MesosRuntimeParameters> _parser = new pb::MessageParser<MesosRuntimeParameters>(() => new MesosRuntimeParameters());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<MesosRuntimeParameters> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Org.Apache.REEF.Bridge.Proto.ClientProtocolReflection.Descriptor.MessageTypes[3]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public MesosRuntimeParameters() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public MesosRuntimeParameters(MesosRuntimeParameters other) : this() {
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public MesosRuntimeParameters Clone() {
+      return new MesosRuntimeParameters(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as MesosRuntimeParameters);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(MesosRuntimeParameters other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(MesosRuntimeParameters other) {
+      if (other == null) {
+        return;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+        }
+      }
+    }
+
+  }
+
+  public sealed partial class DriverClientConfiguration : pb::IMessage<DriverClientConfiguration> {
+    private static readonly pb::MessageParser<DriverClientConfiguration> _parser = new pb::MessageParser<DriverClientConfiguration>(() => new DriverClientConfiguration());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<DriverClientConfiguration> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Org.Apache.REEF.Bridge.Proto.ClientProtocolReflection.Descriptor.MessageTypes[4]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public DriverClientConfiguration() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public DriverClientConfiguration(DriverClientConfiguration other) : this() {
+      jobid_ = other.jobid_;
+      cpuCores_ = other.cpuCores_;
+      memoryMb_ = other.memoryMb_;
+      driverClientLaunchCommand_ = other.driverClientLaunchCommand_;
+      handler_ = other.handler_.Clone();
+      tcpPortRangeBegin_ = other.tcpPortRangeBegin_;
+      tcpPortRangeCount_ = other.tcpPortRangeCount_;
+      tcpPortRangeTryCount_ = other.tcpPortRangeTryCount_;
+      globalFiles_ = other.globalFiles_.Clone();
+      localFiles_ = other.localFiles_.Clone();
+      globalLibraries_ = other.globalLibraries_.Clone();
+      localLibraries_ = other.localLibraries_.Clone();
+      switch (other.RuntimeCase) {
+        case RuntimeOneofCase.LocalRuntime:
+          LocalRuntime = other.LocalRuntime.Clone();
+          break;
+        case RuntimeOneofCase.YarnRuntime:
+          YarnRuntime = other.YarnRuntime.Clone();
+          break;
+        case RuntimeOneofCase.AzbatchRuntime:
+          AzbatchRuntime = other.AzbatchRuntime.Clone();
+          break;
+        case RuntimeOneofCase.MesosRuntime:
+          MesosRuntime = other.MesosRuntime.Clone();
+          break;
+      }
+
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public DriverClientConfiguration Clone() {
+      return new DriverClientConfiguration(this);
+    }
+
+    /// <summary>Field number for the "jobid" field.</summary>
+    public const int JobidFieldNumber = 1;
+    private string jobid_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Jobid {
+      get { return jobid_; }
+      set {
+        jobid_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "cpu_cores" field.</summary>
+    public const int CpuCoresFieldNumber = 2;
+    private uint cpuCores_;
+    /// <summary>
+    /// driver machine resources
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public uint CpuCores {
+      get { return cpuCores_; }
+      set {
+        cpuCores_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "memory_mb" field.</summary>
+    public const int MemoryMbFieldNumber = 3;
+    private uint memoryMb_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public uint MemoryMb {
+      get { return memoryMb_; }
+      set {
+        memoryMb_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "local_runtime" field.</summary>
+    public const int LocalRuntimeFieldNumber = 4;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public global::Org.Apache.REEF.Bridge.Proto.LocalRuntimeParameters LocalRuntime {
+      get { return runtimeCase_ == RuntimeOneofCase.LocalRuntime ? (global::Org.Apache.REEF.Bridge.Proto.LocalRuntimeParameters) runtime_ : null; }
+      set {
+        runtime_ = value;
+        runtimeCase_ = value == null ? RuntimeOneofCase.None : RuntimeOneofCase.LocalRuntime;
+      }
+    }
+
+    /// <summary>Field number for the "yarn_runtime" field.</summary>
+    public const int YarnRuntimeFieldNumber = 5;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public global::Org.Apache.REEF.Bridge.Proto.YarnRuntimeParameters YarnRuntime {
+      get { return runtimeCase_ == RuntimeOneofCase.YarnRuntime ? (global::Org.Apache.REEF.Bridge.Proto.YarnRuntimeParameters) runtime_ : null; }
+      set {
+        runtime_ = value;
+        runtimeCase_ = value == null ? RuntimeOneofCase.None : RuntimeOneofCase.YarnRuntime;
+      }
+    }
+
+    /// <summary>Field number for the "azbatch_runtime" field.</summary>
+    public const int AzbatchRuntimeFieldNumber = 6;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public global::Org.Apache.REEF.Bridge.Proto.AzureBatchRuntimeParameters AzbatchRuntime {
+      get { return runtimeCase_ == RuntimeOneofCase.AzbatchRuntime ? (global::Org.Apache.REEF.Bridge.Proto.AzureBatchRuntimeParameters) runtime_ : null; }
+      set {
+        runtime_ = value;
+        runtimeCase_ = value == null ? RuntimeOneofCase.None : RuntimeOneofCase.AzbatchRuntime;
+      }
+    }
+
+    /// <summary>Field number for the "mesos_runtime" field.</summary>
+    public const int MesosRuntimeFieldNumber = 7;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public global::Org.Apache.REEF.Bridge.Proto.MesosRuntimeParameters MesosRuntime {
+      get { return runtimeCase_ == RuntimeOneofCase.MesosRuntime ? (global::Org.Apache.REEF.Bridge.Proto.MesosRuntimeParameters) runtime_ : null; }
+      set {
+        runtime_ = value;
+        runtimeCase_ = value == null ? RuntimeOneofCase.None : RuntimeOneofCase.MesosRuntime;
+      }
+    }
+
+    /// <summary>Field number for the "driver_client_launch_command" field.</summary>
+    public const int DriverClientLaunchCommandFieldNumber = 10;
+    private string driverClientLaunchCommand_ = "";
+    /// <summary>
+    /// The command to launch the driver client
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string DriverClientLaunchCommand {
+      get { return driverClientLaunchCommand_; }
+      set {
+        driverClientLaunchCommand_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "handler" field.</summary>
+    public const int HandlerFieldNumber = 11;
+    private static readonly pb::FieldCodec<global::Org.Apache.REEF.Bridge.Proto.DriverClientConfiguration.Types.Handlers> _repeated_handler_codec
+        = pb::FieldCodec.ForEnum(90, x => (int) x, x => (global::Org.Apache.REEF.Bridge.Proto.DriverClientConfiguration.Types.Handlers) x);
+    private readonly pbc::RepeatedField<global::Org.Apache.REEF.Bridge.Proto.DriverClientConfiguration.Types.Handlers> handler_ = new pbc::RepeatedField<global::Org.Apache.REEF.Bridge.Proto.DriverClientConfiguration.Types.Handlers>();
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pbc::RepeatedField<global::Org.Apache.REEF.Bridge.Proto.DriverClientConfiguration.Types.Handlers> Handler {
+      get { return handler_; }
+    }
+
+    /// <summary>Field number for the "tcp_port_range_begin" field.</summary>
+    public const int TcpPortRangeBeginFieldNumber = 15;
+    private uint tcpPortRangeBegin_;
+    /// <summary>
+    /// TCP port range
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public uint TcpPortRangeBegin {
+      get { return tcpPortRangeBegin_; }
+      set {
+        tcpPortRangeBegin_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "tcp_port_range_count" field.</summary>
+    public const int TcpPortRangeCountFieldNumber = 16;
+    private uint tcpPortRangeCount_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public uint TcpPortRangeCount {
+      get { return tcpPortRangeCount_; }
+      set {
+        tcpPortRangeCount_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "tcp_port_range_try_count" field.</summary>
+    public const int TcpPortRangeTryCountFieldNumber = 17;
+    private uint tcpPortRangeTryCount_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public uint TcpPortRangeTryCount {
+      get { return tcpPortRangeTryCount_; }
+      set {
+        tcpPortRangeTryCount_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "global_files" field.</summary>
+    public const int GlobalFilesFieldNumber = 20;
+    private static readonly pb::FieldCodec<string> _repeated_globalFiles_codec
+        = pb::FieldCodec.ForString(162);
+    private readonly pbc::RepeatedField<string> globalFiles_ = new pbc::RepeatedField<string>();
+    /// <summary>
+    /// file dependencies
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pbc::RepeatedField<string> GlobalFiles {
+      get { return globalFiles_; }
+    }
+
+    /// <summary>Field number for the "local_files" field.</summary>
+    public const int LocalFilesFieldNumber = 21;
+    private static readonly pb::FieldCodec<string> _repeated_localFiles_codec
+        = pb::FieldCodec.ForString(170);
+    private readonly pbc::RepeatedField<string> localFiles_ = new pbc::RepeatedField<string>();
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pbc::RepeatedField<string> LocalFiles {
+      get { return localFiles_; }
+    }
+
+    /// <summary>Field number for the "global_libraries" field.</summary>
+    public const int GlobalLibrariesFieldNumber = 22;
+    private static readonly pb::FieldCodec<string> _repeated_globalLibraries_codec
+        = pb::FieldCodec.ForString(178);
+    private readonly pbc::RepeatedField<string> globalLibraries_ = new pbc::RepeatedField<string>();
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pbc::RepeatedField<string> GlobalLibraries {
+      get { return globalLibraries_; }
+    }
+
+    /// <summary>Field number for the "local_libraries" field.</summary>
+    public const int LocalLibrariesFieldNumber = 23;
+    private static readonly pb::FieldCodec<string> _repeated_localLibraries_codec
+        = pb::FieldCodec.ForString(186);
+    private readonly pbc::RepeatedField<string> localLibraries_ = new pbc::RepeatedField<string>();
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pbc::RepeatedField<string> LocalLibraries {
+      get { return localLibraries_; }
+    }
+
+    private object runtime_;
+    /// <summary>Enum of possible cases for the "runtime" oneof.</summary>
+    public enum RuntimeOneofCase {
+      None = 0,
+      LocalRuntime = 4,
+      YarnRuntime = 5,
+      AzbatchRuntime = 6,
+      MesosRuntime = 7,
+    }
+    private RuntimeOneofCase runtimeCase_ = RuntimeOneofCase.None;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public RuntimeOneofCase RuntimeCase {
+      get { return runtimeCase_; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void ClearRuntime() {
+      runtimeCase_ = RuntimeOneofCase.None;
+      runtime_ = null;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as DriverClientConfiguration);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(DriverClientConfiguration other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (Jobid != other.Jobid) return false;
+      if (CpuCores != other.CpuCores) return false;
+      if (MemoryMb != other.MemoryMb) return false;
+      if (!object.Equals(LocalRuntime, other.LocalRuntime)) return false;
+      if (!object.Equals(YarnRuntime, other.YarnRuntime)) return false;
+      if (!object.Equals(AzbatchRuntime, other.AzbatchRuntime)) return false;
+      if (!object.Equals(MesosRuntime, other.MesosRuntime)) return false;
+      if (DriverClientLaunchCommand != other.DriverClientLaunchCommand) return false;
+      if(!handler_.Equals(other.handler_)) return false;
+      if (TcpPortRangeBegin != other.TcpPortRangeBegin) return false;
+      if (TcpPortRangeCount != other.TcpPortRangeCount) return false;
+      if (TcpPortRangeTryCount != other.TcpPortRangeTryCount) return false;
+      if(!globalFiles_.Equals(other.globalFiles_)) return false;
+      if(!localFiles_.Equals(other.localFiles_)) return false;
+      if(!globalLibraries_.Equals(other.globalLibraries_)) return false;
+      if(!localLibraries_.Equals(other.localLibraries_)) return false;
+      if (RuntimeCase != other.RuntimeCase) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Jobid.Length != 0) hash ^= Jobid.GetHashCode();
+      if (CpuCores != 0) hash ^= CpuCores.GetHashCode();
+      if (MemoryMb != 0) hash ^= MemoryMb.GetHashCode();
+      if (runtimeCase_ == RuntimeOneofCase.LocalRuntime) hash ^= LocalRuntime.GetHashCode();
+      if (runtimeCase_ == RuntimeOneofCase.YarnRuntime) hash ^= YarnRuntime.GetHashCode();
+      if (runtimeCase_ == RuntimeOneofCase.AzbatchRuntime) hash ^= AzbatchRuntime.GetHashCode();
+      if (runtimeCase_ == RuntimeOneofCase.MesosRuntime) hash ^= MesosRuntime.GetHashCode();
+      if (DriverClientLaunchCommand.Length != 0) hash ^= DriverClientLaunchCommand.GetHashCode();
+      hash ^= handler_.GetHashCode();
+      if (TcpPortRangeBegin != 0) hash ^= TcpPortRangeBegin.GetHashCode();
+      if (TcpPortRangeCount != 0) hash ^= TcpPortRangeCount.GetHashCode();
+      if (TcpPortRangeTryCount != 0) hash ^= TcpPortRangeTryCount.GetHashCode();
+      hash ^= globalFiles_.GetHashCode();
+      hash ^= localFiles_.GetHashCode();
+      hash ^= globalLibraries_.GetHashCode();
+      hash ^= localLibraries_.GetHashCode();
+      hash ^= (int) runtimeCase_;
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Jobid.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(Jobid);
+      }
+      if (CpuCores != 0) {
+        output.WriteRawTag(16);
+        output.WriteUInt32(CpuCores);
+      }
+      if (MemoryMb != 0) {
+        output.WriteRawTag(24);
+        output.WriteUInt32(MemoryMb);
+      }
+      if (runtimeCase_ == RuntimeOneofCase.LocalRuntime) {
+        output.WriteRawTag(34);
+        output.WriteMessage(LocalRuntime);
+      }
+      if (runtimeCase_ == RuntimeOneofCase.YarnRuntime) {
+        output.WriteRawTag(42);
+        output.WriteMessage(YarnRuntime);
+      }
+      if (runtimeCase_ == RuntimeOneofCase.AzbatchRuntime) {
+        output.WriteRawTag(50);
+        output.WriteMessage(AzbatchRuntime);
+      }
+      if (runtimeCase_ == RuntimeOneofCase.MesosRuntime) {
+        output.WriteRawTag(58);
+        output.WriteMessage(MesosRuntime);
+      }
+      if (DriverClientLaunchCommand.Length != 0) {
+        output.WriteRawTag(82);
+        output.WriteString(DriverClientLaunchCommand);
+      }
+      handler_.WriteTo(output, _repeated_handler_codec);
+      if (TcpPortRangeBegin != 0) {
+        output.WriteRawTag(120);
+        output.WriteUInt32(TcpPortRangeBegin);
+      }
+      if (TcpPortRangeCount != 0) {
+        output.WriteRawTag(128, 1);
+        output.WriteUInt32(TcpPortRangeCount);
+      }
+      if (TcpPortRangeTryCount != 0) {
+        output.WriteRawTag(136, 1);
+        output.WriteUInt32(TcpPortRangeTryCount);
+      }
+      globalFiles_.WriteTo(output, _repeated_globalFiles_codec);
+      localFiles_.WriteTo(output, _repeated_localFiles_codec);
+      globalLibraries_.WriteTo(output, _repeated_globalLibraries_codec);
+      localLibraries_.WriteTo(output, _repeated_localLibraries_codec);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (Jobid.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Jobid);
+      }
+      if (CpuCores != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeUInt32Size(CpuCores);
+      }
+      if (MemoryMb != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeUInt32Size(MemoryMb);
+      }
+      if (runtimeCase_ == RuntimeOneofCase.LocalRuntime) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(LocalRuntime);
+      }
+      if (runtimeCase_ == RuntimeOneofCase.YarnRuntime) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(YarnRuntime);
+      }
+      if (runtimeCase_ == RuntimeOneofCase.AzbatchRuntime) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(AzbatchRuntime);
+      }
+      if (runtimeCase_ == RuntimeOneofCase.MesosRuntime) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(MesosRuntime);
+      }
+      if (DriverClientLaunchCommand.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(DriverClientLaunchCommand);
+      }
+      size += handler_.CalculateSize(_repeated_handler_codec);
+      if (TcpPortRangeBegin != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeUInt32Size(TcpPortRangeBegin);
+      }
+      if (TcpPortRangeCount != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeUInt32Size(TcpPortRangeCount);
+      }
+      if (TcpPortRangeTryCount != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeUInt32Size(TcpPortRangeTryCount);
+      }
+      size += globalFiles_.CalculateSize(_repeated_globalFiles_codec);
+      size += localFiles_.CalculateSize(_repeated_localFiles_codec);
+      size += globalLibraries_.CalculateSize(_repeated_globalLibraries_codec);
+      size += localLibraries_.CalculateSize(_repeated_localLibraries_codec);
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(DriverClientConfiguration other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Jobid.Length != 0) {
+        Jobid = other.Jobid;
+      }
+      if (other.CpuCores != 0) {
+        CpuCores = other.CpuCores;
+      }
+      if (other.MemoryMb != 0) {
+        MemoryMb = other.MemoryMb;
+      }
+      if (other.DriverClientLaunchCommand.Length != 0) {
+        DriverClientLaunchCommand = other.DriverClientLaunchCommand;
+      }
+      handler_.Add(other.handler_);
+      if (other.TcpPortRangeBegin != 0) {
+        TcpPortRangeBegin = other.TcpPortRangeBegin;
+      }
+      if (other.TcpPortRangeCount != 0) {
+        TcpPortRangeCount = other.TcpPortRangeCount;
+      }
+      if (other.TcpPortRangeTryCount != 0) {
+        TcpPortRangeTryCount = other.TcpPortRangeTryCount;
+      }
+      globalFiles_.Add(other.globalFiles_);
+      localFiles_.Add(other.localFiles_);
+      globalLibraries_.Add(other.globalLibraries_);
+      localLibraries_.Add(other.localLibraries_);
+      switch (other.RuntimeCase) {
+        case RuntimeOneofCase.LocalRuntime:
+          if (LocalRuntime == null) {
+            LocalRuntime = new global::Org.Apache.REEF.Bridge.Proto.LocalRuntimeParameters();
+          }
+          LocalRuntime.MergeFrom(other.LocalRuntime);
+          break;
+        case RuntimeOneofCase.YarnRuntime:
+          if (YarnRuntime == null) {
+            YarnRuntime = new global::Org.Apache.REEF.Bridge.Proto.YarnRuntimeParameters();
+          }
+          YarnRuntime.MergeFrom(other.YarnRuntime);
+          break;
+        case RuntimeOneofCase.AzbatchRuntime:
+          if (AzbatchRuntime == null) {
+            AzbatchRuntime = new global::Org.Apache.REEF.Bridge.Proto.AzureBatchRuntimeParameters();
+          }
+          AzbatchRuntime.MergeFrom(other.AzbatchRuntime);
+          break;
+        case RuntimeOneofCase.MesosRuntime:
+          if (MesosRuntime == null) {
+            MesosRuntime = new global::Org.Apache.REEF.Bridge.Proto.MesosRuntimeParameters();
+          }
+          MesosRuntime.MergeFrom(other.MesosRuntime);
+          break;
+      }
+
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            Jobid = input.ReadString();
+            break;
+          }
+          case 16: {
+            CpuCores = input.ReadUInt32();
+            break;
+          }
+          case 24: {
+            MemoryMb = input.ReadUInt32();
+            break;
+          }
+          case 34: {
+            global::Org.Apache.REEF.Bridge.Proto.LocalRuntimeParameters subBuilder = new global::Org.Apache.REEF.Bridge.Proto.LocalRuntimeParameters();
+            if (runtimeCase_ == RuntimeOneofCase.LocalRuntime) {
+              subBuilder.MergeFrom(LocalRuntime);
+            }
+            input.ReadMessage(subBuilder);
+            LocalRuntime = subBuilder;
+            break;
+          }
+          case 42: {
+            global::Org.Apache.REEF.Bridge.Proto.YarnRuntimeParameters subBuilder = new global::Org.Apache.REEF.Bridge.Proto.YarnRuntimeParameters();
+            if (runtimeCase_ == RuntimeOneofCase.YarnRuntime) {
+              subBuilder.MergeFrom(YarnRuntime);
+            }
+            input.ReadMessage(subBuilder);
+            YarnRuntime = subBuilder;
+            break;
+          }
+          case 50: {
+            global::Org.Apache.REEF.Bridge.Proto.AzureBatchRuntimeParameters subBuilder = new global::Org.Apache.REEF.Bridge.Proto.AzureBatchRuntimeParameters();
+            if (runtimeCase_ == RuntimeOneofCase.AzbatchRuntime) {
+              subBuilder.MergeFrom(AzbatchRuntime);
+            }
+            input.ReadMessage(subBuilder);
+            AzbatchRuntime = subBuilder;
+            break;
+          }
+          case 58: {
+            global::Org.Apache.REEF.Bridge.Proto.MesosRuntimeParameters subBuilder = new global::Org.Apache.REEF.Bridge.Proto.MesosRuntimeParameters();
+            if (runtimeCase_ == RuntimeOneofCase.MesosRuntime) {
+              subBuilder.MergeFrom(MesosRuntime);
+            }
+            input.ReadMessage(subBuilder);
+            MesosRuntime = subBuilder;
+            break;
+          }
+          case 82: {
+            DriverClientLaunchCommand = input.ReadString();
+            break;
+          }
+          case 90:
+          case 88: {
+            handler_.AddEntriesFrom(input, _repeated_handler_codec);
+            break;
+          }
+          case 120: {
+            TcpPortRangeBegin = input.ReadUInt32();
+            break;
+          }
+          case 128: {
+            TcpPortRangeCount = input.ReadUInt32();
+            break;
+          }
+          case 136: {
+            TcpPortRangeTryCount = input.ReadUInt32();
+            break;
+          }
+          case 162: {
+            globalFiles_.AddEntriesFrom(input, _repeated_globalFiles_codec);
+            break;
+          }
+          case 170: {
+            localFiles_.AddEntriesFrom(input, _repeated_localFiles_codec);
+            break;
+          }
+          case 178: {
+            globalLibraries_.AddEntriesFrom(input, _repeated_globalLibraries_codec);
+            break;
+          }
+          case 186: {
+            localLibraries_.AddEntriesFrom(input, _repeated_localLibraries_codec);
+            break;
+          }
+        }
+      }
+    }
+
+    #region Nested types
+    /// <summary>Container for nested types declared in the DriverClientConfiguration message type.</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static partial class Types {
+      public enum Handlers {
+        /// <summary>
+        /// control events
+        /// </summary>
+        [pbr::OriginalName("START")] Start = 0,
+        [pbr::OriginalName("STOP")] Stop = 1,
+        /// <summary>
+        /// evaluator events
+        /// </summary>
+        [pbr::OriginalName("EVALUATOR_ALLOCATED")] EvaluatorAllocated = 5,
+        [pbr::OriginalName("EVALUATOR_COMPLETED")] EvaluatorCompleted = 6,
+        [pbr::OriginalName("EVALUATOR_FAILED")] EvaluatorFailed = 7,
+        /// <summary>
+        /// context events
+        /// </summary>
+        [pbr::OriginalName("CONTEXT_ACTIVE")] ContextActive = 10,
+        [pbr::OriginalName("CONTEXT_CLOSED")] ContextClosed = 11,
+        [pbr::OriginalName("CONTEXT_FAILED")] ContextFailed = 12,
+        [pbr::OriginalName("CONTEXT_MESSAGE")] ContextMessage = 13,
+        /// <summary>
+        /// task events
+        /// </summary>
+        [pbr::OriginalName("TASK_RUNNING")] TaskRunning = 15,
+        [pbr::OriginalName("TASK_FAILED")] TaskFailed = 16,
+        [pbr::OriginalName("TASK_COMPLETED")] TaskCompleted = 17,
+        [pbr::OriginalName("TASK_MESSAGE")] TaskMessage = 18,
+        /// <summary>
+        /// client events
+        /// </summary>
+        [pbr::OriginalName("CLIENT_MESSAGE")] ClientMessage = 20,
+        [pbr::OriginalName("CLIENT_CLOSE")] ClientClose = 21,
+        [pbr::OriginalName("CLIENT_CLOSE_WITH_MESSAGE")] ClientCloseWithMessage = 22,
+      }
+
+    }
+    #endregion
+
+  }
+
+  #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/lang/cs/Org.Apache.REEF.Bridge.Client/GrpcGeneratedCode/DriverClientProtocol.cs b/lang/cs/Org.Apache.REEF.Bridge.Client/GrpcGeneratedCode/DriverClientProtocol.cs
new file mode 100644
index 0000000..d9adc66
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Bridge.Client/GrpcGeneratedCode/DriverClientProtocol.cs
@@ -0,0 +1,2130 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: DriverClientProtocol.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Org.Apache.REEF.Bridge.Proto {
+
+  /// <summary>Holder for reflection information generated from DriverClientProtocol.proto</summary>
+  public static partial class DriverClientProtocolReflection {
+
+    #region Descriptor
+    /// <summary>File descriptor for DriverClientProtocol.proto</summary>
+    public static pbr::FileDescriptor Descriptor {
+      get { return descriptor; }
+    }
+    private static pbr::FileDescriptor descriptor;
+
+    static DriverClientProtocolReflection() {
+      byte[] descriptorData = global::System.Convert.FromBase64String(
+          string.Concat(
+            "ChpEcml2ZXJDbGllbnRQcm90b2NvbC5wcm90bxIMZHJpdmVyYnJpZGdlGhpE",
+            "cml2ZXJDb21tb25Qcm90b2NvbC5wcm90byItCgpJZGxlU3RhdHVzEg8KB2lz",
+            "X2lkbGUYASABKAgSDgoGcmVhc29uGAIgASgJIiMKDVN0YXJ0VGltZUluZm8S",
+            "EgoKc3RhcnRfdGltZRgBIAEoAyIhCgxTdG9wVGltZUluZm8SEQoJc3RvcF90",
+            "aW1lGAEgASgDIiQKEEFsYXJtVHJpZ2dlckluZm8SEAoIYWxhcm1faWQYASAB",
+            "KAkiTgoXRXZhbHVhdG9yRGVzY3JpcHRvckluZm8SDgoGbWVtb3J5GAEgASgF",
+            "Eg0KBWNvcmVzGAIgASgFEhQKDHJ1bnRpbWVfbmFtZRgDIAEoCSLtAQoNRXZh",
+            "bHVhdG9ySW5mbxIUCgxldmFsdWF0b3JfaWQYASABKAkSOAoHZmFpbHVyZRgC",
+            "IAEoCzInLmRyaXZlcmJyaWRnZS5FdmFsdWF0b3JJbmZvLkZhaWx1cmVJbmZv",
+            "Ej4KD2Rlc2NyaXB0b3JfaW5mbxgDIAEoCzIlLmRyaXZlcmJyaWRnZS5FdmFs",
+            "dWF0b3JEZXNjcmlwdG9ySW5mbxpMCgtGYWlsdXJlSW5mbxIPCgdtZXNzYWdl",
+            "GAEgASgJEhYKDmZhaWxlZENvbnRleHRzGAIgAygJEhQKDGZhaWxlZFRhc2tJ",
+            "ZBgDIAEoCSJ6CgtDb250ZXh0SW5mbxISCgpjb250ZXh0X2lkGAEgASgJEhQK",
+            "DGV2YWx1YXRvcl9pZBgCIAEoCRIRCglwYXJlbnRfaWQYAyABKAkSLgoJZXhj",
+            "ZXB0aW9uGAUgASgLMhsuZHJpdmVyYnJpZGdlLkV4Y2VwdGlvbkluZm8ibQoS",
+            "Q29udGV4dE1lc3NhZ2VJbmZvEhIKCmNvbnRleHRfaWQYASABKAkSDwoHcGF5",
+            "bG9hZBgCIAEoDBIXCg9zZXF1ZW5jZV9udW1iZXIYAyABKAMSGQoRbWVzc2Fn",
+            "ZV9zb3VyY2VfaWQYBCABKAkibwoIVGFza0luZm8SDwoHdGFza19pZBgBIAEo",
+            "CRISCgpjb250ZXh0X2lkGAIgASgJEg4KBnJlc3VsdBgDIAEoDBIuCglleGNl",
+            "cHRpb24YBSABKAsyGy5kcml2ZXJicmlkZ2UuRXhjZXB0aW9uSW5mbyJ7Cg9U",
+            "YXNrTWVzc2FnZUluZm8SDwoHdGFza19pZBgBIAEoCRIPCgdwYXlsb2FkGAIg",
+            "ASgMEhcKD3NlcXVlbmNlX251bWJlchgDIAEoAxISCgpjb250ZXh0X2lkGAQg",
+            "ASgJEhkKEW1lc3NhZ2Vfc291cmNlX2lkGAUgASgJIiQKEUNsaWVudE1lc3Nh",
+            "Z2VJbmZvEg8KB3BheWxvYWQYASABKAwy/goKDERyaXZlckNsaWVudBJGChRJ",
+            "ZGxlbmVzc0NoZWNrSGFuZGxlchISLmRyaXZlcmJyaWRnZS5Wb2lkGhguZHJp",
+            "dmVyYnJpZGdlLklkbGVTdGF0dXMiABJBCgxTdGFydEhhbmRsZXISGy5kcml2",
+            "ZXJicmlkZ2UuU3RhcnRUaW1lSW5mbxoSLmRyaXZlcmJyaWRnZS5Wb2lkIgAS",
+            "PwoLU3RvcEhhbmRsZXISGi5kcml2ZXJicmlkZ2UuU3RvcFRpbWVJbmZvGhIu",
+            "ZHJpdmVyYnJpZGdlLlZvaWQiABJECgxBbGFybVRyaWdnZXISHi5kcml2ZXJi",
+            "cmlkZ2UuQWxhcm1UcmlnZ2VySW5mbxoSLmRyaXZlcmJyaWRnZS5Wb2lkIgAS",
+            "TgoZQWxsb2NhdGVkRXZhbHVhdG9ySGFuZGxlchIbLmRyaXZlcmJyaWRnZS5F",
+            "dmFsdWF0b3JJbmZvGhIuZHJpdmVyYnJpZGdlLlZvaWQiABJOChlDb21wbGV0",
+            "ZWRFdmFsdWF0b3JIYW5kbGVyEhsuZHJpdmVyYnJpZGdlLkV2YWx1YXRvcklu",
+            "Zm8aEi5kcml2ZXJicmlkZ2UuVm9pZCIAEksKFkZhaWxlZEV2YWx1YXRvckhh",
+            "bmRsZXISGy5kcml2ZXJicmlkZ2UuRXZhbHVhdG9ySW5mbxoSLmRyaXZlcmJy",
+            "aWRnZS5Wb2lkIgASRwoUQWN0aXZlQ29udGV4dEhhbmRsZXISGS5kcml2ZXJi",
+            "cmlkZ2UuQ29udGV4dEluZm8aEi5kcml2ZXJicmlkZ2UuVm9pZCIAEkcKFENs",
+            "b3NlZENvbnRleHRIYW5kbGVyEhkuZHJpdmVyYnJpZGdlLkNvbnRleHRJbmZv",
+            "GhIuZHJpdmVyYnJpZGdlLlZvaWQiABJHChRGYWlsZWRDb250ZXh0SGFuZGxl",
+            "chIZLmRyaXZlcmJyaWRnZS5Db250ZXh0SW5mbxoSLmRyaXZlcmJyaWRnZS5W",
+            "b2lkIgASTwoVQ29udGV4dE1lc3NhZ2VIYW5kbGVyEiAuZHJpdmVyYnJpZGdl",
+            "LkNvbnRleHRNZXNzYWdlSW5mbxoSLmRyaXZlcmJyaWRnZS5Wb2lkIgASQgoS",
+            "UnVubmluZ1Rhc2tIYW5kbGVyEhYuZHJpdmVyYnJpZGdlLlRhc2tJbmZvGhIu",
+            "ZHJpdmVyYnJpZGdlLlZvaWQiABJBChFGYWlsZWRUYXNrSGFuZGxlchIWLmRy",
+            "aXZlcmJyaWRnZS5UYXNrSW5mbxoSLmRyaXZlcmJyaWRnZS5Wb2lkIgASRAoU",
+            "Q29tcGxldGVkVGFza0hhbmRsZXISFi5kcml2ZXJicmlkZ2UuVGFza0luZm8a",
+            "Ei5kcml2ZXJicmlkZ2UuVm9pZCIAEkQKFFN1c3BlbmRlZFRhc2tIYW5kbGVy",
+            "EhYuZHJpdmVyYnJpZGdlLlRhc2tJbmZvGhIuZHJpdmVyYnJpZGdlLlZvaWQi",
+            "ABJJChJUYXNrTWVzc2FnZUhhbmRsZXISHS5kcml2ZXJicmlkZ2UuVGFza01l",
+            "c3NhZ2VJbmZvGhIuZHJpdmVyYnJpZGdlLlZvaWQiABJNChRDbGllbnRNZXNz",
+            "YWdlSGFuZGxlchIfLmRyaXZlcmJyaWRnZS5DbGllbnRNZXNzYWdlSW5mbxoS",
+            "LmRyaXZlcmJyaWRnZS5Wb2lkIgASPgoSQ2xpZW50Q2xvc2VIYW5kbGVyEhIu",
+            "ZHJpdmVyYnJpZGdlLlZvaWQaEi5kcml2ZXJicmlkZ2UuVm9pZCIAElYKHUNs",
+            "aWVudENsb3NlV2l0aE1lc3NhZ2VIYW5kbGVyEh8uZHJpdmVyYnJpZGdlLkNs",
+            "aWVudE1lc3NhZ2VJbmZvGhIuZHJpdmVyYnJpZGdlLlZvaWQiAEJVChxvcmcu",
+            "YXBhY2hlLnJlZWYuYnJpZGdlLnByb3RvQhREcml2ZXJDbGllbnRQcm90b2Nv",
+            "bFABqgIcT3JnLkFwYWNoZS5SRUVGLkJyaWRnZS5Qcm90b2IGcHJvdG8z"));
+      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+          new pbr::FileDescriptor[] { global::Org.Apache.REEF.Bridge.Proto.DriverCommonProtocolReflection.Descriptor, },
+          new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+            new pbr::GeneratedClrTypeInfo(typeof(global::Org.Apache.REEF.Bridge.Proto.IdleStatus), global::Org.Apache.REEF.Bridge.Proto.IdleStatus.Parser, new[]{ "IsIdle", "Reason" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Org.Apache.REEF.Bridge.Proto.StartTimeInfo), global::Org.Apache.REEF.Bridge.Proto.StartTimeInfo.Parser, new[]{ "StartTime" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Org.Apache.REEF.Bridge.Proto.StopTimeInfo), global::Org.Apache.REEF.Bridge.Proto.StopTimeInfo.Parser, new[]{ "StopTime" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Org.Apache.REEF.Bridge.Proto.AlarmTriggerInfo), global::Org.Apache.REEF.Bridge.Proto.AlarmTriggerInfo.Parser, new[]{ "AlarmId" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Org.Apache.REEF.Bridge.Proto.EvaluatorDescriptorInfo), global::Org.Apache.REEF.Bridge.Proto.EvaluatorDescriptorInfo.Parser, new[]{ "Memory", "Cores", "RuntimeName" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo), global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo.Parser, new[]{ "EvaluatorId", "Failure", "DescriptorInfo" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo.Types.FailureInfo), global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo.Types.FailureInfo.Parser, new[]{ "Message", "FailedContexts", "FailedTaskId" }, null, null, null)}),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Org.Apache.REEF.Bridge.Proto.ContextInfo), global::Org.Apache.REEF.Bridge.Proto.ContextInfo.Parser, new[]{ "ContextId", "EvaluatorId", "ParentId", "Exception" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Org.Apache.REEF.Bridge.Proto.ContextMessageInfo), global::Org.Apache.REEF.Bridge.Proto.ContextMessageInfo.Parser, new[]{ "ContextId", "Payload", "SequenceNumber", "MessageSourceId" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Org.Apache.REEF.Bridge.Proto.TaskInfo), global::Org.Apache.REEF.Bridge.Proto.TaskInfo.Parser, new[]{ "TaskId", "ContextId", "Result", "Exception" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Org.Apache.REEF.Bridge.Proto.TaskMessageInfo), global::Org.Apache.REEF.Bridge.Proto.TaskMessageInfo.Parser, new[]{ "TaskId", "Payload", "SequenceNumber", "ContextId", "MessageSourceId" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Org.Apache.REEF.Bridge.Proto.ClientMessageInfo), global::Org.Apache.REEF.Bridge.Proto.ClientMessageInfo.Parser, new[]{ "Payload" }, null, null, null)
+          }));
+    }
+    #endregion
+
+  }
+  #region Messages
+  /// <summary>
+  /// IdleStatus response to idleness inquiry
+  /// </summary>
+  public sealed partial class IdleStatus : pb::IMessage<IdleStatus> {
+    private static readonly pb::MessageParser<IdleStatus> _parser = new pb::MessageParser<IdleStatus>(() => new IdleStatus());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<IdleStatus> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Org.Apache.REEF.Bridge.Proto.DriverClientProtocolReflection.Descriptor.MessageTypes[0]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public IdleStatus() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public IdleStatus(IdleStatus other) : this() {
+      isIdle_ = other.isIdle_;
+      reason_ = other.reason_;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public IdleStatus Clone() {
+      return new IdleStatus(this);
+    }
+
+    /// <summary>Field number for the "is_idle" field.</summary>
+    public const int IsIdleFieldNumber = 1;
+    private bool isIdle_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool IsIdle {
+      get { return isIdle_; }
+      set {
+        isIdle_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "reason" field.</summary>
+    public const int ReasonFieldNumber = 2;
+    private string reason_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Reason {
+      get { return reason_; }
+      set {
+        reason_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as IdleStatus);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(IdleStatus other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (IsIdle != other.IsIdle) return false;
+      if (Reason != other.Reason) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (IsIdle != false) hash ^= IsIdle.GetHashCode();
+      if (Reason.Length != 0) hash ^= Reason.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (IsIdle != false) {
+        output.WriteRawTag(8);
+        output.WriteBool(IsIdle);
+      }
+      if (Reason.Length != 0) {
+        output.WriteRawTag(18);
+        output.WriteString(Reason);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (IsIdle != false) {
+        size += 1 + 1;
+      }
+      if (Reason.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Reason);
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(IdleStatus other) {
+      if (other == null) {
+        return;
+      }
+      if (other.IsIdle != false) {
+        IsIdle = other.IsIdle;
+      }
+      if (other.Reason.Length != 0) {
+        Reason = other.Reason;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            IsIdle = input.ReadBool();
+            break;
+          }
+          case 18: {
+            Reason = input.ReadString();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  /// <summary>
+  /// The request message containing resource request.
+  /// </summary>
+  public sealed partial class StartTimeInfo : pb::IMessage<StartTimeInfo> {
+    private static readonly pb::MessageParser<StartTimeInfo> _parser = new pb::MessageParser<StartTimeInfo>(() => new StartTimeInfo());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<StartTimeInfo> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Org.Apache.REEF.Bridge.Proto.DriverClientProtocolReflection.Descriptor.MessageTypes[1]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public StartTimeInfo() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public StartTimeInfo(StartTimeInfo other) : this() {
+      startTime_ = other.startTime_;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public StartTimeInfo Clone() {
+      return new StartTimeInfo(this);
+    }
+
+    /// <summary>Field number for the "start_time" field.</summary>
+    public const int StartTimeFieldNumber = 1;
+    private long startTime_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public long StartTime {
+      get { return startTime_; }
+      set {
+        startTime_ = value;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as StartTimeInfo);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(StartTimeInfo other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (StartTime != other.StartTime) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (StartTime != 0L) hash ^= StartTime.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (StartTime != 0L) {
+        output.WriteRawTag(8);
+        output.WriteInt64(StartTime);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (StartTime != 0L) {
+        size += 1 + pb::CodedOutputStream.ComputeInt64Size(StartTime);
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(StartTimeInfo other) {
+      if (other == null) {
+        return;
+      }
+      if (other.StartTime != 0L) {
+        StartTime = other.StartTime;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            StartTime = input.ReadInt64();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  public sealed partial class StopTimeInfo : pb::IMessage<StopTimeInfo> {
+    private static readonly pb::MessageParser<StopTimeInfo> _parser = new pb::MessageParser<StopTimeInfo>(() => new StopTimeInfo());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<StopTimeInfo> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Org.Apache.REEF.Bridge.Proto.DriverClientProtocolReflection.Descriptor.MessageTypes[2]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public StopTimeInfo() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public StopTimeInfo(StopTimeInfo other) : this() {
+      stopTime_ = other.stopTime_;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public StopTimeInfo Clone() {
+      return new StopTimeInfo(this);
+    }
+
+    /// <summary>Field number for the "stop_time" field.</summary>
+    public const int StopTimeFieldNumber = 1;
+    private long stopTime_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public long StopTime {
+      get { return stopTime_; }
+      set {
+        stopTime_ = value;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as StopTimeInfo);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(StopTimeInfo other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (StopTime != other.StopTime) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (StopTime != 0L) hash ^= StopTime.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (StopTime != 0L) {
+        output.WriteRawTag(8);
+        output.WriteInt64(StopTime);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (StopTime != 0L) {
+        size += 1 + pb::CodedOutputStream.ComputeInt64Size(StopTime);
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(StopTimeInfo other) {
+      if (other == null) {
+        return;
+      }
+      if (other.StopTime != 0L) {
+        StopTime = other.StopTime;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            StopTime = input.ReadInt64();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  /// <summary>
+  /// Information associated with an alarm that was set.
+  /// </summary>
+  public sealed partial class AlarmTriggerInfo : pb::IMessage<AlarmTriggerInfo> {
+    private static readonly pb::MessageParser<AlarmTriggerInfo> _parser = new pb::MessageParser<AlarmTriggerInfo>(() => new AlarmTriggerInfo());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<AlarmTriggerInfo> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Org.Apache.REEF.Bridge.Proto.DriverClientProtocolReflection.Descriptor.MessageTypes[3]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public AlarmTriggerInfo() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public AlarmTriggerInfo(AlarmTriggerInfo other) : this() {
+      alarmId_ = other.alarmId_;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public AlarmTriggerInfo Clone() {
+      return new AlarmTriggerInfo(this);
+    }
+
+    /// <summary>Field number for the "alarm_id" field.</summary>
+    public const int AlarmIdFieldNumber = 1;
+    private string alarmId_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string AlarmId {
+      get { return alarmId_; }
+      set {
+        alarmId_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as AlarmTriggerInfo);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(AlarmTriggerInfo other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (AlarmId != other.AlarmId) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (AlarmId.Length != 0) hash ^= AlarmId.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (AlarmId.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(AlarmId);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (AlarmId.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(AlarmId);
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(AlarmTriggerInfo other) {
+      if (other == null) {
+        return;
+      }
+      if (other.AlarmId.Length != 0) {
+        AlarmId = other.AlarmId;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            AlarmId = input.ReadString();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  public sealed partial class EvaluatorDescriptorInfo : pb::IMessage<EvaluatorDescriptorInfo> {
+    private static readonly pb::MessageParser<EvaluatorDescriptorInfo> _parser = new pb::MessageParser<EvaluatorDescriptorInfo>(() => new EvaluatorDescriptorInfo());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<EvaluatorDescriptorInfo> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Org.Apache.REEF.Bridge.Proto.DriverClientProtocolReflection.Descriptor.MessageTypes[4]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public EvaluatorDescriptorInfo() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public EvaluatorDescriptorInfo(EvaluatorDescriptorInfo other) : this() {
+      memory_ = other.memory_;
+      cores_ = other.cores_;
+      runtimeName_ = other.runtimeName_;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public EvaluatorDescriptorInfo Clone() {
+      return new EvaluatorDescriptorInfo(this);
+    }
+
+    /// <summary>Field number for the "memory" field.</summary>
+    public const int MemoryFieldNumber = 1;
+    private int memory_;
+    /// <summary>
+    /// the amount of memory allocated
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Memory {
+      get { return memory_; }
+      set {
+        memory_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "cores" field.</summary>
+    public const int CoresFieldNumber = 2;
+    private int cores_;
+    /// <summary>
+    /// the number of virtual cores allocated
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Cores {
+      get { return cores_; }
+      set {
+        cores_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "runtime_name" field.</summary>
+    public const int RuntimeNameFieldNumber = 3;
+    private string runtimeName_ = "";
+    /// <summary>
+    /// name of the runtime
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string RuntimeName {
+      get { return runtimeName_; }
+      set {
+        runtimeName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as EvaluatorDescriptorInfo);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(EvaluatorDescriptorInfo other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (Memory != other.Memory) return false;
+      if (Cores != other.Cores) return false;
+      if (RuntimeName != other.RuntimeName) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Memory != 0) hash ^= Memory.GetHashCode();
+      if (Cores != 0) hash ^= Cores.GetHashCode();
+      if (RuntimeName.Length != 0) hash ^= RuntimeName.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Memory != 0) {
+        output.WriteRawTag(8);
+        output.WriteInt32(Memory);
+      }
+      if (Cores != 0) {
+        output.WriteRawTag(16);
+        output.WriteInt32(Cores);
+      }
+      if (RuntimeName.Length != 0) {
+        output.WriteRawTag(26);
+        output.WriteString(RuntimeName);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (Memory != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Memory);
+      }
+      if (Cores != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Cores);
+      }
+      if (RuntimeName.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(RuntimeName);
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(EvaluatorDescriptorInfo other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Memory != 0) {
+        Memory = other.Memory;
+      }
+      if (other.Cores != 0) {
+        Cores = other.Cores;
+      }
+      if (other.RuntimeName.Length != 0) {
+        RuntimeName = other.RuntimeName;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            Memory = input.ReadInt32();
+            break;
+          }
+          case 16: {
+            Cores = input.ReadInt32();
+            break;
+          }
+          case 26: {
+            RuntimeName = input.ReadString();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  public sealed partial class EvaluatorInfo : pb::IMessage<EvaluatorInfo> {
+    private static readonly pb::MessageParser<EvaluatorInfo> _parser = new pb::MessageParser<EvaluatorInfo>(() => new EvaluatorInfo());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<EvaluatorInfo> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Org.Apache.REEF.Bridge.Proto.DriverClientProtocolReflection.Descriptor.MessageTypes[5]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public EvaluatorInfo() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public EvaluatorInfo(EvaluatorInfo other) : this() {
+      evaluatorId_ = other.evaluatorId_;
+      Failure = other.failure_ != null ? other.Failure.Clone() : null;
+      DescriptorInfo = other.descriptorInfo_ != null ? other.DescriptorInfo.Clone() : null;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public EvaluatorInfo Clone() {
+      return new EvaluatorInfo(this);
+    }
+
+    /// <summary>Field number for the "evaluator_id" field.</summary>
+    public const int EvaluatorIdFieldNumber = 1;
+    private string evaluatorId_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string EvaluatorId {
+      get { return evaluatorId_; }
+      set {
+        evaluatorId_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "failure" field.</summary>
+    public const int FailureFieldNumber = 2;
+    private global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo.Types.FailureInfo failure_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo.Types.FailureInfo Failure {
+      get { return failure_; }
+      set {
+        failure_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "descriptor_info" field.</summary>
+    public const int DescriptorInfoFieldNumber = 3;
+    private global::Org.Apache.REEF.Bridge.Proto.EvaluatorDescriptorInfo descriptorInfo_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public global::Org.Apache.REEF.Bridge.Proto.EvaluatorDescriptorInfo DescriptorInfo {
+      get { return descriptorInfo_; }
+      set {
+        descriptorInfo_ = value;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as EvaluatorInfo);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(EvaluatorInfo other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (EvaluatorId != other.EvaluatorId) return false;
+      if (!object.Equals(Failure, other.Failure)) return false;
+      if (!object.Equals(DescriptorInfo, other.DescriptorInfo)) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (EvaluatorId.Length != 0) hash ^= EvaluatorId.GetHashCode();
+      if (failure_ != null) hash ^= Failure.GetHashCode();
+      if (descriptorInfo_ != null) hash ^= DescriptorInfo.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (EvaluatorId.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(EvaluatorId);
+      }
+      if (failure_ != null) {
+        output.WriteRawTag(18);
+        output.WriteMessage(Failure);
+      }
+      if (descriptorInfo_ != null) {
+        output.WriteRawTag(26);
+        output.WriteMessage(DescriptorInfo);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (EvaluatorId.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(EvaluatorId);
+      }
+      if (failure_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Failure);
+      }
+      if (descriptorInfo_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(DescriptorInfo);
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(EvaluatorInfo other) {
+      if (other == null) {
+        return;
+      }
+      if (other.EvaluatorId.Length != 0) {
+        EvaluatorId = other.EvaluatorId;
+      }
+      if (other.failure_ != null) {
+        if (failure_ == null) {
+          failure_ = new global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo.Types.FailureInfo();
+        }
+        Failure.MergeFrom(other.Failure);
+      }
+      if (other.descriptorInfo_ != null) {
+        if (descriptorInfo_ == null) {
+          descriptorInfo_ = new global::Org.Apache.REEF.Bridge.Proto.EvaluatorDescriptorInfo();
+        }
+        DescriptorInfo.MergeFrom(other.DescriptorInfo);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            EvaluatorId = input.ReadString();
+            break;
+          }
+          case 18: {
+            if (failure_ == null) {
+              failure_ = new global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo.Types.FailureInfo();
+            }
+            input.ReadMessage(failure_);
+            break;
+          }
+          case 26: {
+            if (descriptorInfo_ == null) {
+              descriptorInfo_ = new global::Org.Apache.REEF.Bridge.Proto.EvaluatorDescriptorInfo();
+            }
+            input.ReadMessage(descriptorInfo_);
+            break;
+          }
+        }
+      }
+    }
+
+    #region Nested types
+    /// <summary>Container for nested types declared in the EvaluatorInfo message type.</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static partial class Types {
+      public sealed partial class FailureInfo : pb::IMessage<FailureInfo> {
+        private static readonly pb::MessageParser<FailureInfo> _parser = new pb::MessageParser<FailureInfo>(() => new FailureInfo());
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public static pb::MessageParser<FailureInfo> Parser { get { return _parser; } }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public static pbr::MessageDescriptor Descriptor {
+          get { return global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo.Descriptor.NestedTypes[0]; }
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        pbr::MessageDescriptor pb::IMessage.Descriptor {
+          get { return Descriptor; }
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public FailureInfo() {
+          OnConstruction();
+        }
+
+        partial void OnConstruction();
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public FailureInfo(FailureInfo other) : this() {
+          message_ = other.message_;
+          failedContexts_ = other.failedContexts_.Clone();
+          failedTaskId_ = other.failedTaskId_;
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public FailureInfo Clone() {
+          return new FailureInfo(this);
+        }
+
+        /// <summary>Field number for the "message" field.</summary>
+        public const int MessageFieldNumber = 1;
+        private string message_ = "";
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public string Message {
+          get { return message_; }
+          set {
+            message_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+          }
+        }
+
+        /// <summary>Field number for the "failedContexts" field.</summary>
+        public const int FailedContextsFieldNumber = 2;
+        private static readonly pb::FieldCodec<string> _repeated_failedContexts_codec
+            = pb::FieldCodec.ForString(18);
+        private readonly pbc::RepeatedField<string> failedContexts_ = new pbc::RepeatedField<string>();
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public pbc::RepeatedField<string> FailedContexts {
+          get { return failedContexts_; }
+        }
+
+        /// <summary>Field number for the "failedTaskId" field.</summary>
+        public const int FailedTaskIdFieldNumber = 3;
+        private string failedTaskId_ = "";
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public string FailedTaskId {
+          get { return failedTaskId_; }
+          set {
+            failedTaskId_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+          }
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public override bool Equals(object other) {
+          return Equals(other as FailureInfo);
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public bool Equals(FailureInfo other) {
+          if (ReferenceEquals(other, null)) {
+            return false;
+          }
+          if (ReferenceEquals(other, this)) {
+            return true;
+          }
+          if (Message != other.Message) return false;
+          if(!failedContexts_.Equals(other.failedContexts_)) return false;
+          if (FailedTaskId != other.FailedTaskId) return false;
+          return true;
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public override int GetHashCode() {
+          int hash = 1;
+          if (Message.Length != 0) hash ^= Message.GetHashCode();
+          hash ^= failedContexts_.GetHashCode();
+          if (FailedTaskId.Length != 0) hash ^= FailedTaskId.GetHashCode();
+          return hash;
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public override string ToString() {
+          return pb::JsonFormatter.ToDiagnosticString(this);
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public void WriteTo(pb::CodedOutputStream output) {
+          if (Message.Length != 0) {
+            output.WriteRawTag(10);
+            output.WriteString(Message);
+          }
+          failedContexts_.WriteTo(output, _repeated_failedContexts_codec);
+          if (FailedTaskId.Length != 0) {
+            output.WriteRawTag(26);
+            output.WriteString(FailedTaskId);
+          }
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public int CalculateSize() {
+          int size = 0;
+          if (Message.Length != 0) {
+            size += 1 + pb::CodedOutputStream.ComputeStringSize(Message);
+          }
+          size += failedContexts_.CalculateSize(_repeated_failedContexts_codec);
+          if (FailedTaskId.Length != 0) {
+            size += 1 + pb::CodedOutputStream.ComputeStringSize(FailedTaskId);
+          }
+          return size;
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public void MergeFrom(FailureInfo other) {
+          if (other == null) {
+            return;
+          }
+          if (other.Message.Length != 0) {
+            Message = other.Message;
+          }
+          failedContexts_.Add(other.failedContexts_);
+          if (other.FailedTaskId.Length != 0) {
+            FailedTaskId = other.FailedTaskId;
+          }
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public void MergeFrom(pb::CodedInputStream input) {
+          uint tag;
+          while ((tag = input.ReadTag()) != 0) {
+            switch(tag) {
+              default:
+                input.SkipLastField();
+                break;
+              case 10: {
+                Message = input.ReadString();
+                break;
+              }
+              case 18: {
+                failedContexts_.AddEntriesFrom(input, _repeated_failedContexts_codec);
+                break;
+              }
+              case 26: {
+                FailedTaskId = input.ReadString();
+                break;
+              }
+            }
+          }
+        }
+
+      }
+
+    }
+    #endregion
+
+  }
+
+  public sealed partial class ContextInfo : pb::IMessage<ContextInfo> {
+    private static readonly pb::MessageParser<ContextInfo> _parser = new pb::MessageParser<ContextInfo>(() => new ContextInfo());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<ContextInfo> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Org.Apache.REEF.Bridge.Proto.DriverClientProtocolReflection.Descriptor.MessageTypes[6]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ContextInfo() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ContextInfo(ContextInfo other) : this() {
+      contextId_ = other.contextId_;
+      evaluatorId_ = other.evaluatorId_;
+      parentId_ = other.parentId_;
+      Exception = other.exception_ != null ? other.Exception.Clone() : null;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ContextInfo Clone() {
+      return new ContextInfo(this);
+    }
+
+    /// <summary>Field number for the "context_id" field.</summary>
+    public const int ContextIdFieldNumber = 1;
+    private string contextId_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string ContextId {
+      get { return contextId_; }
+      set {
+        contextId_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "evaluator_id" field.</summary>
+    public const int EvaluatorIdFieldNumber = 2;
+    private string evaluatorId_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string EvaluatorId {
+      get { return evaluatorId_; }
+      set {
+        evaluatorId_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "parent_id" field.</summary>
+    public const int ParentIdFieldNumber = 3;
+    private string parentId_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string ParentId {
+      get { return parentId_; }
+      set {
+        parentId_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "exception" field.</summary>
+    public const int ExceptionFieldNumber = 5;
+    private global::Org.Apache.REEF.Bridge.Proto.ExceptionInfo exception_;
+    /// <summary>
+    /// Optional exception information
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public global::Org.Apache.REEF.Bridge.Proto.ExceptionInfo Exception {
+      get { return exception_; }
+      set {
+        exception_ = value;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as ContextInfo);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(ContextInfo other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (ContextId != other.ContextId) return false;
+      if (EvaluatorId != other.EvaluatorId) return false;
+      if (ParentId != other.ParentId) return false;
+      if (!object.Equals(Exception, other.Exception)) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (ContextId.Length != 0) hash ^= ContextId.GetHashCode();
+      if (EvaluatorId.Length != 0) hash ^= EvaluatorId.GetHashCode();
+      if (ParentId.Length != 0) hash ^= ParentId.GetHashCode();
+      if (exception_ != null) hash ^= Exception.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (ContextId.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(ContextId);
+      }
+      if (EvaluatorId.Length != 0) {
+        output.WriteRawTag(18);
+        output.WriteString(EvaluatorId);
+      }
+      if (ParentId.Length != 0) {
+        output.WriteRawTag(26);
+        output.WriteString(ParentId);
+      }
+      if (exception_ != null) {
+        output.WriteRawTag(42);
+        output.WriteMessage(Exception);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (ContextId.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(ContextId);
+      }
+      if (EvaluatorId.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(EvaluatorId);
+      }
+      if (ParentId.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(ParentId);
+      }
+      if (exception_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Exception);
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(ContextInfo other) {
+      if (other == null) {
+        return;
+      }
+      if (other.ContextId.Length != 0) {
+        ContextId = other.ContextId;
+      }
+      if (other.EvaluatorId.Length != 0) {
+        EvaluatorId = other.EvaluatorId;
+      }
+      if (other.ParentId.Length != 0) {
+        ParentId = other.ParentId;
+      }
+      if (other.exception_ != null) {
+        if (exception_ == null) {
+          exception_ = new global::Org.Apache.REEF.Bridge.Proto.ExceptionInfo();
+        }
+        Exception.MergeFrom(other.Exception);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            ContextId = input.ReadString();
+            break;
+          }
+          case 18: {
+            EvaluatorId = input.ReadString();
+            break;
+          }
+          case 26: {
+            ParentId = input.ReadString();
+            break;
+          }
+          case 42: {
+            if (exception_ == null) {
+              exception_ = new global::Org.Apache.REEF.Bridge.Proto.ExceptionInfo();
+            }
+            input.ReadMessage(exception_);
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  public sealed partial class ContextMessageInfo : pb::IMessage<ContextMessageInfo> {
+    private static readonly pb::MessageParser<ContextMessageInfo> _parser = new pb::MessageParser<ContextMessageInfo>(() => new ContextMessageInfo());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<ContextMessageInfo> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Org.Apache.REEF.Bridge.Proto.DriverClientProtocolReflection.Descriptor.MessageTypes[7]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ContextMessageInfo() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ContextMessageInfo(ContextMessageInfo other) : this() {
+      contextId_ = other.contextId_;
+      payload_ = other.payload_;
+      sequenceNumber_ = other.sequenceNumber_;
+      messageSourceId_ = other.messageSourceId_;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ContextMessageInfo Clone() {
+      return new ContextMessageInfo(this);
+    }
+
+    /// <summary>Field number for the "context_id" field.</summary>
+    public const int ContextIdFieldNumber = 1;
+    private string contextId_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string ContextId {
+      get { return contextId_; }
+      set {
+        contextId_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "payload" field.</summary>
+    public const int PayloadFieldNumber = 2;
+    private pb::ByteString payload_ = pb::ByteString.Empty;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pb::ByteString Payload {
+      get { return payload_; }
+      set {
+        payload_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "sequence_number" field.</summary>
+    public const int SequenceNumberFieldNumber = 3;
+    private long sequenceNumber_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public long SequenceNumber {
+      get { return sequenceNumber_; }
+      set {
+        sequenceNumber_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "message_source_id" field.</summary>
+    public const int MessageSourceIdFieldNumber = 4;
+    private string messageSourceId_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string MessageSourceId {
+      get { return messageSourceId_; }
+      set {
+        messageSourceId_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as ContextMessageInfo);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(ContextMessageInfo other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (ContextId != other.ContextId) return false;
+      if (Payload != other.Payload) return false;
+      if (SequenceNumber != other.SequenceNumber) return false;
+      if (MessageSourceId != other.MessageSourceId) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (ContextId.Length != 0) hash ^= ContextId.GetHashCode();
+      if (Payload.Length != 0) hash ^= Payload.GetHashCode();
+      if (SequenceNumber != 0L) hash ^= SequenceNumber.GetHashCode();
+      if (MessageSourceId.Length != 0) hash ^= MessageSourceId.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (ContextId.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(ContextId);
+      }
+      if (Payload.Length != 0) {
+        output.WriteRawTag(18);
+        output.WriteBytes(Payload);
+      }
+      if (SequenceNumber != 0L) {
+        output.WriteRawTag(24);
+        output.WriteInt64(SequenceNumber);
+      }
+      if (MessageSourceId.Length != 0) {
+        output.WriteRawTag(34);
+        output.WriteString(MessageSourceId);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (ContextId.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(ContextId);
+      }
+      if (Payload.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeBytesSize(Payload);
+      }
+      if (SequenceNumber != 0L) {
+        size += 1 + pb::CodedOutputStream.ComputeInt64Size(SequenceNumber);
+      }
+      if (MessageSourceId.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(MessageSourceId);
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(ContextMessageInfo other) {
+      if (other == null) {
+        return;
+      }
+      if (other.ContextId.Length != 0) {
+        ContextId = other.ContextId;
+      }
+      if (other.Payload.Length != 0) {
+        Payload = other.Payload;
+      }
+      if (other.SequenceNumber != 0L) {
+        SequenceNumber = other.SequenceNumber;
+      }
+      if (other.MessageSourceId.Length != 0) {
+        MessageSourceId = other.MessageSourceId;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            ContextId = input.ReadString();
+            break;
+          }
+          case 18: {
+            Payload = input.ReadBytes();
+            break;
+          }
+          case 24: {
+            SequenceNumber = input.ReadInt64();
+            break;
+          }
+          case 34: {
+            MessageSourceId = input.ReadString();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  public sealed partial class TaskInfo : pb::IMessage<TaskInfo> {
+    private static readonly pb::MessageParser<TaskInfo> _parser = new pb::MessageParser<TaskInfo>(() => new TaskInfo());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<TaskInfo> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Org.Apache.REEF.Bridge.Proto.DriverClientProtocolReflection.Descriptor.MessageTypes[8]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public TaskInfo() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public TaskInfo(TaskInfo other) : this() {
+      taskId_ = other.taskId_;
+      contextId_ = other.contextId_;
+      result_ = other.result_;
+      Exception = other.exception_ != null ? other.Exception.Clone() : null;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public TaskInfo Clone() {
+      return new TaskInfo(this);
+    }
+
+    /// <summary>Field number for the "task_id" field.</summary>
+    public const int TaskIdFieldNumber = 1;
+    private string taskId_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string TaskId {
+      get { return taskId_; }
+      set {
+        taskId_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "context_id" field.</summary>
+    public const int ContextIdFieldNumber = 2;
+    private string contextId_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string ContextId {
+      get { return contextId_; }
+      set {
+        contextId_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "result" field.</summary>
+    public const int ResultFieldNumber = 3;
+    private pb::ByteString result_ = pb::ByteString.Empty;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pb::ByteString Result {
+      get { return result_; }
+      set {
+        result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "exception" field.</summary>
+    public const int ExceptionFieldNumber = 5;
+    private global::Org.Apache.REEF.Bridge.Proto.ExceptionInfo exception_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public global::Org.Apache.REEF.Bridge.Proto.ExceptionInfo Exception {
+      get { return exception_; }
+      set {
+        exception_ = value;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as TaskInfo);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(TaskInfo other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (TaskId != other.TaskId) return false;
+      if (ContextId != other.ContextId) return false;
+      if (Result != other.Result) return false;
+      if (!object.Equals(Exception, other.Exception)) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (TaskId.Length != 0) hash ^= TaskId.GetHashCode();
+      if (ContextId.Length != 0) hash ^= ContextId.GetHashCode();
+      if (Result.Length != 0) hash ^= Result.GetHashCode();
+      if (exception_ != null) hash ^= Exception.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (TaskId.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(TaskId);
+      }
+      if (ContextId.Length != 0) {
+        output.WriteRawTag(18);
+        output.WriteString(ContextId);
+      }
+      if (Result.Length != 0) {
+        output.WriteRawTag(26);
+        output.WriteBytes(Result);
+      }
+      if (exception_ != null) {
+        output.WriteRawTag(42);
+        output.WriteMessage(Exception);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (TaskId.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(TaskId);
+      }
+      if (ContextId.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(ContextId);
+      }
+      if (Result.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeBytesSize(Result);
+      }
+      if (exception_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Exception);
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(TaskInfo other) {
+      if (other == null) {
+        return;
+      }
+      if (other.TaskId.Length != 0) {
+        TaskId = other.TaskId;
+      }
+      if (other.ContextId.Length != 0) {
+        ContextId = other.ContextId;
+      }
+      if (other.Result.Length != 0) {
+        Result = other.Result;
+      }
+      if (other.exception_ != null) {
+        if (exception_ == null) {
+          exception_ = new global::Org.Apache.REEF.Bridge.Proto.ExceptionInfo();
+        }
+        Exception.MergeFrom(other.Exception);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            TaskId = input.ReadString();
+            break;
+          }
+          case 18: {
+            ContextId = input.ReadString();
+            break;
+          }
+          case 26: {
+            Result = input.ReadBytes();
+            break;
+          }
+          case 42: {
+            if (exception_ == null) {
+              exception_ = new global::Org.Apache.REEF.Bridge.Proto.ExceptionInfo();
+            }
+            input.ReadMessage(exception_);
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  public sealed partial class TaskMessageInfo : pb::IMessage<TaskMessageInfo> {
+    private static readonly pb::MessageParser<TaskMessageInfo> _parser = new pb::MessageParser<TaskMessageInfo>(() => new TaskMessageInfo());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<TaskMessageInfo> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Org.Apache.REEF.Bridge.Proto.DriverClientProtocolReflection.Descriptor.MessageTypes[9]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public TaskMessageInfo() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public TaskMessageInfo(TaskMessageInfo other) : this() {
+      taskId_ = other.taskId_;
+      payload_ = other.payload_;
+      sequenceNumber_ = other.sequenceNumber_;
+      contextId_ = other.contextId_;
+      messageSourceId_ = other.messageSourceId_;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public TaskMessageInfo Clone() {
+      return new TaskMessageInfo(this);
+    }
+
+    /// <summary>Field number for the "task_id" field.</summary>
+    public const int TaskIdFieldNumber = 1;
+    private string taskId_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string TaskId {
+      get { return taskId_; }
+      set {
+        taskId_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "payload" field.</summary>
+    public const int PayloadFieldNumber = 2;
+    private pb::ByteString payload_ = pb::ByteString.Empty;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pb::ByteString Payload {
+      get { return payload_; }
+      set {
+        payload_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "sequence_number" field.</summary>
+    public const int SequenceNumberFieldNumber = 3;
+    private long sequenceNumber_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public long SequenceNumber {
+      get { return sequenceNumber_; }
+      set {
+        sequenceNumber_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "context_id" field.</summary>
+    public const int ContextIdFieldNumber = 4;
+    private string contextId_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string ContextId {
+      get { return contextId_; }
+      set {
+        contextId_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "message_source_id" field.</summary>
+    public const int MessageSourceIdFieldNumber = 5;
+    private string messageSourceId_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string MessageSourceId {
+      get { return messageSourceId_; }
+      set {
+        messageSourceId_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as TaskMessageInfo);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(TaskMessageInfo other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (TaskId != other.TaskId) return false;
+      if (Payload != other.Payload) return false;
+      if (SequenceNumber != other.SequenceNumber) return false;
+      if (ContextId != other.ContextId) return false;
+      if (MessageSourceId != other.MessageSourceId) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (TaskId.Length != 0) hash ^= TaskId.GetHashCode();
+      if (Payload.Length != 0) hash ^= Payload.GetHashCode();
+      if (SequenceNumber != 0L) hash ^= SequenceNumber.GetHashCode();
+      if (ContextId.Length != 0) hash ^= ContextId.GetHashCode();
+      if (MessageSourceId.Length != 0) hash ^= MessageSourceId.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (TaskId.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(TaskId);
+      }
+      if (Payload.Length != 0) {
+        output.WriteRawTag(18);
+        output.WriteBytes(Payload);
+      }
+      if (SequenceNumber != 0L) {
+        output.WriteRawTag(24);
+        output.WriteInt64(SequenceNumber);
+      }
+      if (ContextId.Length != 0) {
+        output.WriteRawTag(34);
+        output.WriteString(ContextId);
+      }
+      if (MessageSourceId.Length != 0) {
+        output.WriteRawTag(42);
+        output.WriteString(MessageSourceId);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (TaskId.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(TaskId);
+      }
+      if (Payload.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeBytesSize(Payload);
+      }
+      if (SequenceNumber != 0L) {
+        size += 1 + pb::CodedOutputStream.ComputeInt64Size(SequenceNumber);
+      }
+      if (ContextId.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(ContextId);
+      }
+      if (MessageSourceId.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(MessageSourceId);
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(TaskMessageInfo other) {
+      if (other == null) {
+        return;
+      }
+      if (other.TaskId.Length != 0) {
+        TaskId = other.TaskId;
+      }
+      if (other.Payload.Length != 0) {
+        Payload = other.Payload;
+      }
+      if (other.SequenceNumber != 0L) {
+        SequenceNumber = other.SequenceNumber;
+      }
+      if (other.ContextId.Length != 0) {
+        ContextId = other.ContextId;
+      }
+      if (other.MessageSourceId.Length != 0) {
+        MessageSourceId = other.MessageSourceId;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            TaskId = input.ReadString();
+            break;
+          }
+          case 18: {
+            Payload = input.ReadBytes();
+            break;
+          }
+          case 24: {
+            SequenceNumber = input.ReadInt64();
+            break;
+          }
+          case 34: {
+            ContextId = input.ReadString();
+            break;
+          }
+          case 42: {
+            MessageSourceId = input.ReadString();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  public sealed partial class ClientMessageInfo : pb::IMessage<ClientMessageInfo> {
+    private static readonly pb::MessageParser<ClientMessageInfo> _parser = new pb::MessageParser<ClientMessageInfo>(() => new ClientMessageInfo());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<ClientMessageInfo> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Org.Apache.REEF.Bridge.Proto.DriverClientProtocolReflection.Descriptor.MessageTypes[10]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ClientMessageInfo() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ClientMessageInfo(ClientMessageInfo other) : this() {
+      payload_ = other.payload_;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ClientMessageInfo Clone() {
+      return new ClientMessageInfo(this);
+    }
+
+    /// <summary>Field number for the "payload" field.</summary>
+    public const int PayloadFieldNumber = 1;
+    private pb::ByteString payload_ = pb::ByteString.Empty;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pb::ByteString Payload {
+      get { return payload_; }
+      set {
+        payload_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as ClientMessageInfo);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(ClientMessageInfo other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (Payload != other.Payload) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Payload.Length != 0) hash ^= Payload.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Payload.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteBytes(Payload);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (Payload.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeBytesSize(Payload);
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(ClientMessageInfo other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Payload.Length != 0) {
+        Payload = other.Payload;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            Payload = input.ReadBytes();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/lang/cs/Org.Apache.REEF.Bridge.Client/GrpcGeneratedCode/DriverClientProtocolGrpc.cs b/lang/cs/Org.Apache.REEF.Bridge.Client/GrpcGeneratedCode/DriverClientProtocolGrpc.cs
new file mode 100644
index 0000000..d220993
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Bridge.Client/GrpcGeneratedCode/DriverClientProtocolGrpc.cs
@@ -0,0 +1,870 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+// <auto-generated>
+//     Generated by the protocol buffer compiler.  DO NOT EDIT!
+//     source: DriverClientProtocol.proto
+// </auto-generated>
+// Original file comments:
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+//
+#pragma warning disable 1591
+#region Designer generated code
+
+using grpc = global::Grpc.Core;
+
+namespace Org.Apache.REEF.Bridge.Proto {
+  /// <summary>
+  /// The java driver service definition.
+  /// </summary>
+  public static partial class DriverClient
+  {
+    static readonly string __ServiceName = "driverbridge.DriverClient";
+
+    static readonly grpc::Marshaller<global::Org.Apache.REEF.Bridge.Proto.Void> __Marshaller_Void = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Org.Apache.REEF.Bridge.Proto.Void.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Org.Apache.REEF.Bridge.Proto.IdleStatus> __Marshaller_IdleStatus = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Org.Apache.REEF.Bridge.Proto.IdleStatus.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Org.Apache.REEF.Bridge.Proto.StartTimeInfo> __Marshaller_StartTimeInfo = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Org.Apache.REEF.Bridge.Proto.StartTimeInfo.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Org.Apache.REEF.Bridge.Proto.StopTimeInfo> __Marshaller_StopTimeInfo = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Org.Apache.REEF.Bridge.Proto.StopTimeInfo.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Org.Apache.REEF.Bridge.Proto.AlarmTriggerInfo> __Marshaller_AlarmTriggerInfo = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Org.Apache.REEF.Bridge.Proto.AlarmTriggerInfo.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo> __Marshaller_EvaluatorInfo = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Org.Apache.REEF.Bridge.Proto.ContextInfo> __Marshaller_ContextInfo = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Org.Apache.REEF.Bridge.Proto.ContextInfo.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Org.Apache.REEF.Bridge.Proto.ContextMessageInfo> __Marshaller_ContextMessageInfo = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Org.Apache.REEF.Bridge.Proto.ContextMessageInfo.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Org.Apache.REEF.Bridge.Proto.TaskInfo> __Marshaller_TaskInfo = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Org.Apache.REEF.Bridge.Proto.TaskInfo.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Org.Apache.REEF.Bridge.Proto.TaskMessageInfo> __Marshaller_TaskMessageInfo = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Org.Apache.REEF.Bridge.Proto.TaskMessageInfo.Parser.ParseFrom);
+    static readonly grpc::Marshaller<global::Org.Apache.REEF.Bridge.Proto.ClientMessageInfo> __Marshaller_ClientMessageInfo = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Org.Apache.REEF.Bridge.Proto.ClientMessageInfo.Parser.ParseFrom);
+
+    static readonly grpc::Method<global::Org.Apache.REEF.Bridge.Proto.Void, global::Org.Apache.REEF.Bridge.Proto.IdleStatus> __Method_IdlenessCheckHandler = new grpc::Method<global::Org.Apache.REEF.Bridge.Proto.Void, global::Org.Apache.REEF.Bridge.Proto.IdleStatus>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "IdlenessCheckHandler",
+        __Marshaller_Void,
+        __Marshaller_IdleStatus);
+
+    static readonly grpc::Method<global::Org.Apache.REEF.Bridge.Proto.StartTimeInfo, global::Org.Apache.REEF.Bridge.Proto.Void> __Method_StartHandler = new grpc::Method<global::Org.Apache.REEF.Bridge.Proto.StartTimeInfo, global::Org.Apache.REEF.Bridge.Proto.Void>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "StartHandler",
+        __Marshaller_StartTimeInfo,
+        __Marshaller_Void);
+
+    static readonly grpc::Method<global::Org.Apache.REEF.Bridge.Proto.StopTimeInfo, global::Org.Apache.REEF.Bridge.Proto.Void> __Method_StopHandler = new grpc::Method<global::Org.Apache.REEF.Bridge.Proto.StopTimeInfo, global::Org.Apache.REEF.Bridge.Proto.Void>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "StopHandler",
+        __Marshaller_StopTimeInfo,
+        __Marshaller_Void);
+
+    static readonly grpc::Method<global::Org.Apache.REEF.Bridge.Proto.AlarmTriggerInfo, global::Org.Apache.REEF.Bridge.Proto.Void> __Method_AlarmTrigger = new grpc::Method<global::Org.Apache.REEF.Bridge.Proto.AlarmTriggerInfo, global::Org.Apache.REEF.Bridge.Proto.Void>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "AlarmTrigger",
+        __Marshaller_AlarmTriggerInfo,
+        __Marshaller_Void);
+
+    static readonly grpc::Method<global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo, global::Org.Apache.REEF.Bridge.Proto.Void> __Method_AllocatedEvaluatorHandler = new grpc::Method<global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo, global::Org.Apache.REEF.Bridge.Proto.Void>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "AllocatedEvaluatorHandler",
+        __Marshaller_EvaluatorInfo,
+        __Marshaller_Void);
+
+    static readonly grpc::Method<global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo, global::Org.Apache.REEF.Bridge.Proto.Void> __Method_CompletedEvaluatorHandler = new grpc::Method<global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo, global::Org.Apache.REEF.Bridge.Proto.Void>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "CompletedEvaluatorHandler",
+        __Marshaller_EvaluatorInfo,
+        __Marshaller_Void);
+
+    static readonly grpc::Method<global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo, global::Org.Apache.REEF.Bridge.Proto.Void> __Method_FailedEvaluatorHandler = new grpc::Method<global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo, global::Org.Apache.REEF.Bridge.Proto.Void>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "FailedEvaluatorHandler",
+        __Marshaller_EvaluatorInfo,
+        __Marshaller_Void);
+
+    static readonly grpc::Method<global::Org.Apache.REEF.Bridge.Proto.ContextInfo, global::Org.Apache.REEF.Bridge.Proto.Void> __Method_ActiveContextHandler = new grpc::Method<global::Org.Apache.REEF.Bridge.Proto.ContextInfo, global::Org.Apache.REEF.Bridge.Proto.Void>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "ActiveContextHandler",
+        __Marshaller_ContextInfo,
+        __Marshaller_Void);
+
+    static readonly grpc::Method<global::Org.Apache.REEF.Bridge.Proto.ContextInfo, global::Org.Apache.REEF.Bridge.Proto.Void> __Method_ClosedContextHandler = new grpc::Method<global::Org.Apache.REEF.Bridge.Proto.ContextInfo, global::Org.Apache.REEF.Bridge.Proto.Void>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "ClosedContextHandler",
+        __Marshaller_ContextInfo,
+        __Marshaller_Void);
+
+    static readonly grpc::Method<global::Org.Apache.REEF.Bridge.Proto.ContextInfo, global::Org.Apache.REEF.Bridge.Proto.Void> __Method_FailedContextHandler = new grpc::Method<global::Org.Apache.REEF.Bridge.Proto.ContextInfo, global::Org.Apache.REEF.Bridge.Proto.Void>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "FailedContextHandler",
+        __Marshaller_ContextInfo,
+        __Marshaller_Void);
+
+    static readonly grpc::Method<global::Org.Apache.REEF.Bridge.Proto.ContextMessageInfo, global::Org.Apache.REEF.Bridge.Proto.Void> __Method_ContextMessageHandler = new grpc::Method<global::Org.Apache.REEF.Bridge.Proto.ContextMessageInfo, global::Org.Apache.REEF.Bridge.Proto.Void>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "ContextMessageHandler",
+        __Marshaller_ContextMessageInfo,
+        __Marshaller_Void);
+
+    static readonly grpc::Method<global::Org.Apache.REEF.Bridge.Proto.TaskInfo, global::Org.Apache.REEF.Bridge.Proto.Void> __Method_RunningTaskHandler = new grpc::Method<global::Org.Apache.REEF.Bridge.Proto.TaskInfo, global::Org.Apache.REEF.Bridge.Proto.Void>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "RunningTaskHandler",
+        __Marshaller_TaskInfo,
+        __Marshaller_Void);
+
+    static readonly grpc::Method<global::Org.Apache.REEF.Bridge.Proto.TaskInfo, global::Org.Apache.REEF.Bridge.Proto.Void> __Method_FailedTaskHandler = new grpc::Method<global::Org.Apache.REEF.Bridge.Proto.TaskInfo, global::Org.Apache.REEF.Bridge.Proto.Void>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "FailedTaskHandler",
+        __Marshaller_TaskInfo,
+        __Marshaller_Void);
+
+    static readonly grpc::Method<global::Org.Apache.REEF.Bridge.Proto.TaskInfo, global::Org.Apache.REEF.Bridge.Proto.Void> __Method_CompletedTaskHandler = new grpc::Method<global::Org.Apache.REEF.Bridge.Proto.TaskInfo, global::Org.Apache.REEF.Bridge.Proto.Void>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "CompletedTaskHandler",
+        __Marshaller_TaskInfo,
+        __Marshaller_Void);
+
+    static readonly grpc::Method<global::Org.Apache.REEF.Bridge.Proto.TaskInfo, global::Org.Apache.REEF.Bridge.Proto.Void> __Method_SuspendedTaskHandler = new grpc::Method<global::Org.Apache.REEF.Bridge.Proto.TaskInfo, global::Org.Apache.REEF.Bridge.Proto.Void>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "SuspendedTaskHandler",
+        __Marshaller_TaskInfo,
+        __Marshaller_Void);
+
+    static readonly grpc::Method<global::Org.Apache.REEF.Bridge.Proto.TaskMessageInfo, global::Org.Apache.REEF.Bridge.Proto.Void> __Method_TaskMessageHandler = new grpc::Method<global::Org.Apache.REEF.Bridge.Proto.TaskMessageInfo, global::Org.Apache.REEF.Bridge.Proto.Void>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "TaskMessageHandler",
+        __Marshaller_TaskMessageInfo,
+        __Marshaller_Void);
+
+    static readonly grpc::Method<global::Org.Apache.REEF.Bridge.Proto.ClientMessageInfo, global::Org.Apache.REEF.Bridge.Proto.Void> __Method_ClientMessageHandler = new grpc::Method<global::Org.Apache.REEF.Bridge.Proto.ClientMessageInfo, global::Org.Apache.REEF.Bridge.Proto.Void>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "ClientMessageHandler",
+        __Marshaller_ClientMessageInfo,
+        __Marshaller_Void);
+
+    static readonly grpc::Method<global::Org.Apache.REEF.Bridge.Proto.Void, global::Org.Apache.REEF.Bridge.Proto.Void> __Method_ClientCloseHandler = new grpc::Method<global::Org.Apache.REEF.Bridge.Proto.Void, global::Org.Apache.REEF.Bridge.Proto.Void>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "ClientCloseHandler",
+        __Marshaller_Void,
+        __Marshaller_Void);
+
+    static readonly grpc::Method<global::Org.Apache.REEF.Bridge.Proto.ClientMessageInfo, global::Org.Apache.REEF.Bridge.Proto.Void> __Method_ClientCloseWithMessageHandler = new grpc::Method<global::Org.Apache.REEF.Bridge.Proto.ClientMessageInfo, global::Org.Apache.REEF.Bridge.Proto.Void>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "ClientCloseWithMessageHandler",
+        __Marshaller_ClientMessageInfo,
+        __Marshaller_Void);
+
+    /// <summary>Service descriptor</summary>
+    public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
+    {
+      get { return global::Org.Apache.REEF.Bridge.Proto.DriverClientProtocolReflection.Descriptor.Services[0]; }
+    }
+
+    /// <summary>Base class for server-side implementations of DriverClient</summary>
+    public abstract partial class DriverClientBase
+    {
+      /// <summary>
+      /// Inquire if idle
+      /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
+      public virtual global::System.Threading.Tasks.Task<global::Org.Apache.REEF.Bridge.Proto.IdleStatus> IdlenessCheckHandler(global::Org.Apache.REEF.Bridge.Proto.Void request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      /// <summary>
+      /// Request for resources
+      /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
+      public virtual global::System.Threading.Tasks.Task<global::Org.Apache.REEF.Bridge.Proto.Void> StartHandler(global::Org.Apache.REEF.Bridge.Proto.StartTimeInfo request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      public virtual global::System.Threading.Tasks.Task<global::Org.Apache.REEF.Bridge.Proto.Void> StopHandler(global::Org.Apache.REEF.Bridge.Proto.StopTimeInfo request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      public virtual global::System.Threading.Tasks.Task<global::Org.Apache.REEF.Bridge.Proto.Void> AlarmTrigger(global::Org.Apache.REEF.Bridge.Proto.AlarmTriggerInfo request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      /// <summary>
+      /// Evaluator handlers
+      /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
+      public virtual global::System.Threading.Tasks.Task<global::Org.Apache.REEF.Bridge.Proto.Void> AllocatedEvaluatorHandler(global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      public virtual global::System.Threading.Tasks.Task<global::Org.Apache.REEF.Bridge.Proto.Void> CompletedEvaluatorHandler(global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      public virtual global::System.Threading.Tasks.Task<global::Org.Apache.REEF.Bridge.Proto.Void> FailedEvaluatorHandler(global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      /// <summary>
+      /// Context handlers
+      /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
+      public virtual global::System.Threading.Tasks.Task<global::Org.Apache.REEF.Bridge.Proto.Void> ActiveContextHandler(global::Org.Apache.REEF.Bridge.Proto.ContextInfo request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      public virtual global::System.Threading.Tasks.Task<global::Org.Apache.REEF.Bridge.Proto.Void> ClosedContextHandler(global::Org.Apache.REEF.Bridge.Proto.ContextInfo request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      public virtual global::System.Threading.Tasks.Task<global::Org.Apache.REEF.Bridge.Proto.Void> FailedContextHandler(global::Org.Apache.REEF.Bridge.Proto.ContextInfo request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      public virtual global::System.Threading.Tasks.Task<global::Org.Apache.REEF.Bridge.Proto.Void> ContextMessageHandler(global::Org.Apache.REEF.Bridge.Proto.ContextMessageInfo request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      /// <summary>
+      /// Task handlers
+      /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
+      public virtual global::System.Threading.Tasks.Task<global::Org.Apache.REEF.Bridge.Proto.Void> RunningTaskHandler(global::Org.Apache.REEF.Bridge.Proto.TaskInfo request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      public virtual global::System.Threading.Tasks.Task<global::Org.Apache.REEF.Bridge.Proto.Void> FailedTaskHandler(global::Org.Apache.REEF.Bridge.Proto.TaskInfo request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      public virtual global::System.Threading.Tasks.Task<global::Org.Apache.REEF.Bridge.Proto.Void> CompletedTaskHandler(global::Org.Apache.REEF.Bridge.Proto.TaskInfo request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      public virtual global::System.Threading.Tasks.Task<global::Org.Apache.REEF.Bridge.Proto.Void> SuspendedTaskHandler(global::Org.Apache.REEF.Bridge.Proto.TaskInfo request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      public virtual global::System.Threading.Tasks.Task<global::Org.Apache.REEF.Bridge.Proto.Void> TaskMessageHandler(global::Org.Apache.REEF.Bridge.Proto.TaskMessageInfo request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      /// <summary>
+      /// Client Handlers
+      /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
+      public virtual global::System.Threading.Tasks.Task<global::Org.Apache.REEF.Bridge.Proto.Void> ClientMessageHandler(global::Org.Apache.REEF.Bridge.Proto.ClientMessageInfo request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      public virtual global::System.Threading.Tasks.Task<global::Org.Apache.REEF.Bridge.Proto.Void> ClientCloseHandler(global::Org.Apache.REEF.Bridge.Proto.Void request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+      public virtual global::System.Threading.Tasks.Task<global::Org.Apache.REEF.Bridge.Proto.Void> ClientCloseWithMessageHandler(global::Org.Apache.REEF.Bridge.Proto.ClientMessageInfo request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+    }
+
+    /// <summary>Client for DriverClient</summary>
+    public partial class DriverClientClient : grpc::ClientBase<DriverClientClient>
+    {
+      /// <summary>Creates a new client for DriverClient</summary>
+      /// <param name="channel">The channel to use to make remote calls.</param>
+      public DriverClientClient(grpc::Channel channel) : base(channel)
+      {
+      }
+      /// <summary>Creates a new client for DriverClient that uses a custom <c>CallInvoker</c>.</summary>
+      /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
+      public DriverClientClient(grpc::CallInvoker callInvoker) : base(callInvoker)
+      {
+      }
+      /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+      protected DriverClientClient() : base()
+      {
+      }
+      /// <summary>Protected constructor to allow creation of configured clients.</summary>
+      /// <param name="configuration">The client configuration.</param>
+      protected DriverClientClient(ClientBaseConfiguration configuration) : base(configuration)
+      {
+      }
+
+      /// <summary>
+      /// Inquire if idle
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Org.Apache.REEF.Bridge.Proto.IdleStatus IdlenessCheckHandler(global::Org.Apache.REEF.Bridge.Proto.Void request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return IdlenessCheckHandler(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Inquire if idle
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Org.Apache.REEF.Bridge.Proto.IdleStatus IdlenessCheckHandler(global::Org.Apache.REEF.Bridge.Proto.Void request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_IdlenessCheckHandler, null, options, request);
+      }
+      /// <summary>
+      /// Inquire if idle
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.IdleStatus> IdlenessCheckHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.Void request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return IdlenessCheckHandlerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Inquire if idle
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.IdleStatus> IdlenessCheckHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.Void request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_IdlenessCheckHandler, null, options, request);
+      }
+      /// <summary>
+      /// Request for resources
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void StartHandler(global::Org.Apache.REEF.Bridge.Proto.StartTimeInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return StartHandler(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Request for resources
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void StartHandler(global::Org.Apache.REEF.Bridge.Proto.StartTimeInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_StartHandler, null, options, request);
+      }
+      /// <summary>
+      /// Request for resources
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> StartHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.StartTimeInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return StartHandlerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Request for resources
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> StartHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.StartTimeInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_StartHandler, null, options, request);
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void StopHandler(global::Org.Apache.REEF.Bridge.Proto.StopTimeInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return StopHandler(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void StopHandler(global::Org.Apache.REEF.Bridge.Proto.StopTimeInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_StopHandler, null, options, request);
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> StopHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.StopTimeInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return StopHandlerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> StopHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.StopTimeInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_StopHandler, null, options, request);
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void AlarmTrigger(global::Org.Apache.REEF.Bridge.Proto.AlarmTriggerInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return AlarmTrigger(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void AlarmTrigger(global::Org.Apache.REEF.Bridge.Proto.AlarmTriggerInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_AlarmTrigger, null, options, request);
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> AlarmTriggerAsync(global::Org.Apache.REEF.Bridge.Proto.AlarmTriggerInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return AlarmTriggerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> AlarmTriggerAsync(global::Org.Apache.REEF.Bridge.Proto.AlarmTriggerInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_AlarmTrigger, null, options, request);
+      }
+      /// <summary>
+      /// Evaluator handlers
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void AllocatedEvaluatorHandler(global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return AllocatedEvaluatorHandler(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Evaluator handlers
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void AllocatedEvaluatorHandler(global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_AllocatedEvaluatorHandler, null, options, request);
+      }
+      /// <summary>
+      /// Evaluator handlers
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> AllocatedEvaluatorHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return AllocatedEvaluatorHandlerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Evaluator handlers
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> AllocatedEvaluatorHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_AllocatedEvaluatorHandler, null, options, request);
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void CompletedEvaluatorHandler(global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return CompletedEvaluatorHandler(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void CompletedEvaluatorHandler(global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_CompletedEvaluatorHandler, null, options, request);
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> CompletedEvaluatorHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return CompletedEvaluatorHandlerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> CompletedEvaluatorHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_CompletedEvaluatorHandler, null, options, request);
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void FailedEvaluatorHandler(global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return FailedEvaluatorHandler(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void FailedEvaluatorHandler(global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_FailedEvaluatorHandler, null, options, request);
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> FailedEvaluatorHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return FailedEvaluatorHandlerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> FailedEvaluatorHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.EvaluatorInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_FailedEvaluatorHandler, null, options, request);
+      }
+      /// <summary>
+      /// Context handlers
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void ActiveContextHandler(global::Org.Apache.REEF.Bridge.Proto.ContextInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return ActiveContextHandler(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Context handlers
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void ActiveContextHandler(global::Org.Apache.REEF.Bridge.Proto.ContextInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_ActiveContextHandler, null, options, request);
+      }
+      /// <summary>
+      /// Context handlers
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> ActiveContextHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.ContextInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return ActiveContextHandlerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Context handlers
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> ActiveContextHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.ContextInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_ActiveContextHandler, null, options, request);
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void ClosedContextHandler(global::Org.Apache.REEF.Bridge.Proto.ContextInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return ClosedContextHandler(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void ClosedContextHandler(global::Org.Apache.REEF.Bridge.Proto.ContextInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_ClosedContextHandler, null, options, request);
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> ClosedContextHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.ContextInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return ClosedContextHandlerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> ClosedContextHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.ContextInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_ClosedContextHandler, null, options, request);
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void FailedContextHandler(global::Org.Apache.REEF.Bridge.Proto.ContextInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return FailedContextHandler(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void FailedContextHandler(global::Org.Apache.REEF.Bridge.Proto.ContextInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_FailedContextHandler, null, options, request);
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> FailedContextHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.ContextInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return FailedContextHandlerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> FailedContextHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.ContextInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_FailedContextHandler, null, options, request);
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void ContextMessageHandler(global::Org.Apache.REEF.Bridge.Proto.ContextMessageInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return ContextMessageHandler(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void ContextMessageHandler(global::Org.Apache.REEF.Bridge.Proto.ContextMessageInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_ContextMessageHandler, null, options, request);
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> ContextMessageHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.ContextMessageInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return ContextMessageHandlerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> ContextMessageHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.ContextMessageInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_ContextMessageHandler, null, options, request);
+      }
+      /// <summary>
+      /// Task handlers
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void RunningTaskHandler(global::Org.Apache.REEF.Bridge.Proto.TaskInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return RunningTaskHandler(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Task handlers
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void RunningTaskHandler(global::Org.Apache.REEF.Bridge.Proto.TaskInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_RunningTaskHandler, null, options, request);
+      }
+      /// <summary>
+      /// Task handlers
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> RunningTaskHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.TaskInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return RunningTaskHandlerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Task handlers
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> RunningTaskHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.TaskInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_RunningTaskHandler, null, options, request);
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void FailedTaskHandler(global::Org.Apache.REEF.Bridge.Proto.TaskInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return FailedTaskHandler(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void FailedTaskHandler(global::Org.Apache.REEF.Bridge.Proto.TaskInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_FailedTaskHandler, null, options, request);
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> FailedTaskHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.TaskInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return FailedTaskHandlerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> FailedTaskHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.TaskInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_FailedTaskHandler, null, options, request);
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void CompletedTaskHandler(global::Org.Apache.REEF.Bridge.Proto.TaskInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return CompletedTaskHandler(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void CompletedTaskHandler(global::Org.Apache.REEF.Bridge.Proto.TaskInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_CompletedTaskHandler, null, options, request);
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> CompletedTaskHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.TaskInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return CompletedTaskHandlerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> CompletedTaskHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.TaskInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_CompletedTaskHandler, null, options, request);
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void SuspendedTaskHandler(global::Org.Apache.REEF.Bridge.Proto.TaskInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return SuspendedTaskHandler(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void SuspendedTaskHandler(global::Org.Apache.REEF.Bridge.Proto.TaskInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_SuspendedTaskHandler, null, options, request);
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> SuspendedTaskHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.TaskInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return SuspendedTaskHandlerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> SuspendedTaskHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.TaskInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_SuspendedTaskHandler, null, options, request);
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void TaskMessageHandler(global::Org.Apache.REEF.Bridge.Proto.TaskMessageInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return TaskMessageHandler(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void TaskMessageHandler(global::Org.Apache.REEF.Bridge.Proto.TaskMessageInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_TaskMessageHandler, null, options, request);
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> TaskMessageHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.TaskMessageInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return TaskMessageHandlerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> TaskMessageHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.TaskMessageInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_TaskMessageHandler, null, options, request);
+      }
+      /// <summary>
+      /// Client Handlers
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void ClientMessageHandler(global::Org.Apache.REEF.Bridge.Proto.ClientMessageInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return ClientMessageHandler(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Client Handlers
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void ClientMessageHandler(global::Org.Apache.REEF.Bridge.Proto.ClientMessageInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_ClientMessageHandler, null, options, request);
+      }
+      /// <summary>
+      /// Client Handlers
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> ClientMessageHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.ClientMessageInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return ClientMessageHandlerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Client Handlers
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> ClientMessageHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.ClientMessageInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_ClientMessageHandler, null, options, request);
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void ClientCloseHandler(global::Org.Apache.REEF.Bridge.Proto.Void request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return ClientCloseHandler(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void ClientCloseHandler(global::Org.Apache.REEF.Bridge.Proto.Void request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_ClientCloseHandler, null, options, request);
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> ClientCloseHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.Void request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return ClientCloseHandlerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> ClientCloseHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.Void request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_ClientCloseHandler, null, options, request);
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void ClientCloseWithMessageHandler(global::Org.Apache.REEF.Bridge.Proto.ClientMessageInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return ClientCloseWithMessageHandler(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual global::Org.Apache.REEF.Bridge.Proto.Void ClientCloseWithMessageHandler(global::Org.Apache.REEF.Bridge.Proto.ClientMessageInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_ClientCloseWithMessageHandler, null, options, request);
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> ClientCloseWithMessageHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.ClientMessageInfo request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return ClientCloseWithMessageHandlerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      public virtual grpc::AsyncUnaryCall<global::Org.Apache.REEF.Bridge.Proto.Void> ClientCloseWithMessageHandlerAsync(global::Org.Apache.REEF.Bridge.Proto.ClientMessageInfo request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_ClientCloseWithMessageHandler, null, options, request);
+      }
+      /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
+      protected override DriverClientClient NewInstance(ClientBaseConfiguration configuration)
+      {
+        return new DriverClientClient(configuration);
+      }
+    }
+
+    /// <summary>Creates service definition that can be registered with a server</summary>
+    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+    public static grpc::ServerServiceDefinition BindService(DriverClientBase serviceImpl)
+    {
+      return grpc::ServerServiceDefinition.CreateBuilder()
+          .AddMethod(__Method_IdlenessCheckHandler, serviceImpl.IdlenessCheckHandler)
+          .AddMethod(__Method_StartHandler, serviceImpl.StartHandler)
+          .AddMethod(__Method_StopHandler, serviceImpl.StopHandler)
+          .AddMethod(__Method_AlarmTrigger, serviceImpl.AlarmTrigger)
+          .AddMethod(__Method_AllocatedEvaluatorHandler, serviceImpl.AllocatedEvaluatorHandler)
+          .AddMethod(__Method_CompletedEvaluatorHandler, serviceImpl.CompletedEvaluatorHandler)
+          .AddMethod(__Method_FailedEvaluatorHandler, serviceImpl.FailedEvaluatorHandler)
+          .AddMethod(__Method_ActiveContextHandler, serviceImpl.ActiveContextHandler)
+          .AddMethod(__Method_ClosedContextHandler, serviceImpl.ClosedContextHandler)
+          .AddMethod(__Method_FailedContextHandler, serviceImpl.FailedContextHandler)
+          .AddMethod(__Method_ContextMessageHandler, serviceImpl.ContextMessageHandler)
+          .AddMethod(__Method_RunningTaskHandler, serviceImpl.RunningTaskHandler)
+          .AddMethod(__Method_FailedTaskHandler, serviceImpl.FailedTaskHandler)
+          .AddMethod(__Method_CompletedTaskHandler, serviceImpl.CompletedTaskHandler)
+          .AddMethod(__Method_SuspendedTaskHandler, serviceImpl.SuspendedTaskHandler)
+          .AddMethod(__Method_TaskMessageHandler, serviceImpl.TaskMessageHandler)
+          .AddMethod(__Method_ClientMessageHandler, serviceImpl.ClientMessageHandler)
+          .AddMethod(__Method_ClientCloseHandler, serviceImpl.ClientCloseHandler)
+          .AddMethod(__Method_ClientCloseWithMessageHandler, serviceImpl.ClientCloseWithMessageHandler).Build();
+    }
+
+  }
+}
+#endregion
diff --git a/lang/cs/Org.Apache.REEF.Bridge.Client/GrpcGeneratedCode/DriverCommonProtocol.cs b/lang/cs/Org.Apache.REEF.Bridge.Client/GrpcGeneratedCode/DriverCommonProtocol.cs
new file mode 100644
index 0000000..c4c890c
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Bridge.Client/GrpcGeneratedCode/DriverCommonProtocol.cs
@@ -0,0 +1,358 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: DriverCommonProtocol.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Org.Apache.REEF.Bridge.Proto {
+
+  /// <summary>Holder for reflection information generated from DriverCommonProtocol.proto</summary>
+  public static partial class DriverCommonProtocolReflection {
+
+    #region Descriptor
+    /// <summary>File descriptor for DriverCommonProtocol.proto</summary>
+    public static pbr::FileDescriptor Descriptor {
+      get { return descriptor; }
+    }
+    private static pbr::FileDescriptor descriptor;
+
+    static DriverCommonProtocolReflection() {
+      byte[] descriptorData = global::System.Convert.FromBase64String(
+          string.Concat(
+            "ChpEcml2ZXJDb21tb25Qcm90b2NvbC5wcm90bxIMZHJpdmVyYnJpZGdlIgYK",
+            "BFZvaWQiUQoNRXhjZXB0aW9uSW5mbxIMCgRuYW1lGAEgASgJEg8KB21lc3Nh",
+            "Z2UYAiABKAkSEwoLc3RhY2tfdHJhY2UYAyADKAkSDAoEZGF0YRgEIAEoDEI/",
+            "ChxvcmcuYXBhY2hlLnJlZWYuYnJpZGdlLnByb3RvUAGqAhxPcmcuQXBhY2hl",
+            "LlJFRUYuQnJpZGdlLlByb3RvYgZwcm90bzM="));
+      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+          new pbr::FileDescriptor[] { },
+          new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+            new pbr::GeneratedClrTypeInfo(typeof(global::Org.Apache.REEF.Bridge.Proto.Void), global::Org.Apache.REEF.Bridge.Proto.Void.Parser, null, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Org.Apache.REEF.Bridge.Proto.ExceptionInfo), global::Org.Apache.REEF.Bridge.Proto.ExceptionInfo.Parser, new[]{ "Name", "Message", "StackTrace", "Data" }, null, null, null)
+          }));
+    }
+    #endregion
+
+  }
+  #region Messages
+  /// <summary>
+  /// Void message type
+  /// </summary>
+  public sealed partial class Void : pb::IMessage<Void> {
+    private static readonly pb::MessageParser<Void> _parser = new pb::MessageParser<Void>(() => new Void());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<Void> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Org.Apache.REEF.Bridge.Proto.DriverCommonProtocolReflection.Descriptor.MessageTypes[0]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public Void() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public Void(Void other) : this() {
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public Void Clone() {
+      return new Void(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as Void);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(Void other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(Void other) {
+      if (other == null) {
+        return;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+        }
+      }
+    }
+
+  }
+
+  public sealed partial class ExceptionInfo : pb::IMessage<ExceptionInfo> {
+    private static readonly pb::MessageParser<ExceptionInfo> _parser = new pb::MessageParser<ExceptionInfo>(() => new ExceptionInfo());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<ExceptionInfo> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Org.Apache.REEF.Bridge.Proto.DriverCommonProtocolReflection.Descriptor.MessageTypes[1]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ExceptionInfo() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ExceptionInfo(ExceptionInfo other) : this() {
+      name_ = other.name_;
+      message_ = other.message_;
+      stackTrace_ = other.stackTrace_.Clone();
+      data_ = other.data_;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ExceptionInfo Clone() {
+      return new ExceptionInfo(this);
+    }
+
+    /// <summary>Field number for the "name" field.</summary>
+    public const int NameFieldNumber = 1;
+    private string name_ = "";
+    /// <summary>
+    /// Exception name/type
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Name {
+      get { return name_; }
+      set {
+        name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "message" field.</summary>
+    public const int MessageFieldNumber = 2;
+    private string message_ = "";
+    /// <summary>
+    /// Exception message
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Message {
+      get { return message_; }
+      set {
+        message_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "stack_trace" field.</summary>
+    public const int StackTraceFieldNumber = 3;
+    private static readonly pb::FieldCodec<string> _repeated_stackTrace_codec
+        = pb::FieldCodec.ForString(26);
+    private readonly pbc::RepeatedField<string> stackTrace_ = new pbc::RepeatedField<string>();
+    /// <summary>
+    /// Stack trace
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pbc::RepeatedField<string> StackTrace {
+      get { return stackTrace_; }
+    }
+
+    /// <summary>Field number for the "data" field.</summary>
+    public const int DataFieldNumber = 4;
+    private pb::ByteString data_ = pb::ByteString.Empty;
+    /// <summary>
+    /// Data associated with exception
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pb::ByteString Data {
+      get { return data_; }
+      set {
+        data_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as ExceptionInfo);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(ExceptionInfo other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (Name != other.Name) return false;
+      if (Message != other.Message) return false;
+      if(!stackTrace_.Equals(other.stackTrace_)) return false;
+      if (Data != other.Data) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Name.Length != 0) hash ^= Name.GetHashCode();
+      if (Message.Length != 0) hash ^= Message.GetHashCode();
+      hash ^= stackTrace_.GetHashCode();
+      if (Data.Length != 0) hash ^= Data.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Name.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(Name);
+      }
+      if (Message.Length != 0) {
+        output.WriteRawTag(18);
+        output.WriteString(Message);
+      }
+      stackTrace_.WriteTo(output, _repeated_stackTrace_codec);
+      if (Data.Length != 0) {
+        output.WriteRawTag(34);
+        output.WriteBytes(Data);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (Name.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
+      }
+      if (Message.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Message);
+      }
+      size += stackTrace_.CalculateSize(_repeated_stackTrace_codec);
+      if (Data.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeBytesSize(Data);
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(ExceptionInfo other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Name.Length != 0) {
+        Name = other.Name;
+      }
+      if (other.Message.Length != 0) {
+        Message = other.Message;
+      }
+      stackTrace_.Add(other.stackTrace_);
+      if (other.Data.Length != 0) {
+        Data = other.Data;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            Name = input.ReadString();
+            break;
+          }
+          case 18: {
+            Message = input.ReadString();
+            break;
+          }
+          case 26: {
+            stackTrace_.AddEntriesFrom(input, _repeated_stackTrace_codec);
+            break;
+          }
+          case 34: {
+            Data = input.ReadBytes();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/lang/cs/Org.Apache.REEF.Bridge.Client/Org.Apache.REEF.Bridge.Client.DotNet.csproj b/lang/cs/Org.Apache.REEF.Bridge.Client/Org.Apache.REEF.Bridge.Client.DotNet.csproj
new file mode 100644
index 0000000..dcdab87
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Bridge.Client/Org.Apache.REEF.Bridge.Client.DotNet.csproj
@@ -0,0 +1,63 @@
+<Project>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+-->
+  <PropertyGroup>
+    <AssemblyName>Org.Apache.REEF.Bridge.Client</AssemblyName>
+    <Description>Bridge CSharp Client for REEF.NET</Description>
+    <PackageTags>REEF Bridge CSharp Client</PackageTags>
+  </PropertyGroup>
+  <Import Project="..\build.DotNetApp.props" />
+  <ItemGroup>
+    <PackageReference Include="Grpc" Version="1.11.0-pre2" />
+    <PackageReference Include="Grpc.Tools" Version="1.11.0-pre2" />
+    <PackageReference Include="Google.Protobuf" Version="3.5.0.0" />
+  </ItemGroup>
+  <PropertyGroup>
+    <GrpcSchemaDirectory>..\..\common\proto\bridge</GrpcSchemaDirectory>
+    <GrpcToolsDirectory>$(PackagesDir)\grpc.tools\1.11.0-pre2\tools\windows_x64</GrpcToolsDirectory>
+    <GrpcToolsDirectory>$(PackagesDir)\grpc.tools\1.11.0-pre2\tools\windows_x64</GrpcToolsDirectory>
+    <GrpcLibraryDirectory>$(PackagesDir)\grpc.core\1.11.0-pre2\lib\net45</GrpcLibraryDirectory>
+  </PropertyGroup>
+  <!-- TODO[JIRA REEF-1888] This item group will not be needed when only .netcore is targeted. -->
+  <ItemGroup Condition="'$(TargetFramework)' == 'net452' Or '$(TargetFramework)' == 'net46'">
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Configuration" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="Grpc.Core">
+      <HintPath>$(GRrpcLibraryDirectory)\Grpc.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Protobuf">
+      <HintPath>$(PackagesDir)\Google.Protobuf.3.5.0\lib\net45\Google.Protobuf.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <ProjectReference Include="..\Org.Apache.REEF.Tang\Org.Apache.REEF.Tang.DotNet.csproj" />
+    <ProjectReference Include="..\Org.Apache.REEF.Utilities\Org.Apache.REEF.Utilities.DotNet.csproj" />
+    <ProjectReference Include="..\Org.Apache.REEF.Common\Org.Apache.REEF.Common.DotNet.csproj" />
+    <ProjectReference Include="..\Org.Apache.REEF.Driver\Org.Apache.REEF.Driver.DotNet.csproj" />
+    <ProjectReference Include="..\Org.Apache.REEF.Wake\Org.Apache.REEF.Wake.DotNet.csproj" />
+  </ItemGroup>
+  <Import Project="..\build.DotNet.targets" />
+  <Import Project="$(SolutionDir)\GrpcCodeGeneration.Targets" Condition="Exists('$(SolutionDir)\GrpcCodeGeneration.Targets')" />
+  <Target Name="CodeGeneration" DependsOnTargets="Restore" BeforeTargets="BeforeBuild">
+    <Message Text="Generating C# classes from gRPC proto files @(Compile)..." Importance="High" />
+    <GrpcToCSharp OUtputDirectory="$(ProjectDir)\GrpcGeneratedCode" SourceFileList="ClientProtocol.proto;DriverCommonProtocol.proto;DriverClientProtocol.proto" GrpcSchemaDirectory="$(GrpcSchemaDirectory)" GrpcBinaryDirectory="$(GrpcToolsDirectory)" />
+  </Target>
+</Project>
diff --git a/lang/cs/Org.Apache.REEF.Bridge.Client/Program.cs b/lang/cs/Org.Apache.REEF.Bridge.Client/Program.cs
new file mode 100644
index 0000000..18af573
--- /dev/null
+++ b/lang/cs/Org.Apache.REEF.Bridge.Client/Program.cs
@@ -0,0 +1,29 @@
+﻿// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+
+using System;
+
+namespace Org.Apache.REEF.Bridge.Client
+{
+    class Program
+    {
+        static void Main(string[] args)
+        {
+            Console.WriteLine("Hello World!");
+        }
+    }
+}
diff --git a/lang/cs/Org.Apache.REEF.DotNet.sln b/lang/cs/Org.Apache.REEF.DotNet.sln
index 3d612f1..eb352db 100644
--- a/lang/cs/Org.Apache.REEF.DotNet.sln
+++ b/lang/cs/Org.Apache.REEF.DotNet.sln
@@ -74,7 +74,9 @@
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Org.Apache.REEF.FatNuGet.DotNet", "Org.Apache.REEF.FatNuGet\Org.Apache.REEF.FatNuGet.DotNet.csproj", "{F7D5EAB5-65F8-45B5-9318-60EC311E08C6}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}}") = "Org.Apache.REEF.Bridge.CLR.DotNet", "Org.Apache.REEF.Bridge.CLR\Org.Apache.REEF.Bridge.CLR.DotNet.csproj", "{81575917-C673-4E6F-9CF1-0DD35FC5E717}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Org.Apache.REEF.Bridge.CLR.DotNet", "Org.Apache.REEF.Bridge.CLR\Org.Apache.REEF.Bridge.CLR.DotNet.csproj", "{81575917-C673-4E6F-9CF1-0DD35FC5E717}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Org.Apache.REEF.Bridge.Client.DotNet", "Org.Apache.REEF.Bridge.Client\Org.Apache.REEF.Bridge.Client.DotNet.csproj", "{77BE3864-C183-4E56-8E9E-FEBFC429FA85}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -214,6 +216,10 @@
 		{81575917-C673-4E6F-9CF1-0DD35FC5E717}.Debug|x64.Build.0 = Debug|x64
 		{81575917-C673-4E6F-9CF1-0DD35FC5E717}.Release|x64.ActiveCfg = Release|x64
 		{81575917-C673-4E6F-9CF1-0DD35FC5E717}.Release|x64.Build.0 = Release|x64
+		{77BE3864-C183-4E56-8E9E-FEBFC429FA85}.Debug|x64.ActiveCfg = Debug|x64
+		{77BE3864-C183-4E56-8E9E-FEBFC429FA85}.Debug|x64.Build.0 = Debug|x64
+		{77BE3864-C183-4E56-8E9E-FEBFC429FA85}.Release|x64.ActiveCfg = Release|x64
+		{77BE3864-C183-4E56-8E9E-FEBFC429FA85}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
