// 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
