/**
 * 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.
 */
/**
 * Autogenerated by Thrift Compiler (0.12.0)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.storm.generated;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.12.0)")
public class Supervisor {

  public interface Iface {

    /**
     * Send node specific assignments to supervisor
     * 
     * @param assignments
     */
    public void sendSupervisorAssignments(SupervisorAssignments assignments) throws AuthorizationException, org.apache.storm.thrift.TException;

    /**
     * Get local assignment for a storm
     * 
     * @param id
     */
    public Assignment getLocalAssignmentForStorm(java.lang.String id) throws NotAliveException, AuthorizationException, org.apache.storm.thrift.TException;

    /**
     * Send worker heartbeat to local supervisor
     * 
     * @param heartbeat
     */
    public void sendSupervisorWorkerHeartbeat(SupervisorWorkerHeartbeat heartbeat) throws AuthorizationException, org.apache.storm.thrift.TException;

  }

  public interface AsyncIface {

    public void sendSupervisorAssignments(SupervisorAssignments assignments, org.apache.storm.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.storm.thrift.TException;

    public void getLocalAssignmentForStorm(java.lang.String id, org.apache.storm.thrift.async.AsyncMethodCallback<Assignment> resultHandler) throws org.apache.storm.thrift.TException;

    public void sendSupervisorWorkerHeartbeat(SupervisorWorkerHeartbeat heartbeat, org.apache.storm.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.storm.thrift.TException;

  }

  public static class Client extends org.apache.storm.thrift.TServiceClient implements Iface {
    public static class Factory implements org.apache.storm.thrift.TServiceClientFactory<Client> {
      public Factory() {}
      public Client getClient(org.apache.storm.thrift.protocol.TProtocol prot) {
        return new Client(prot);
      }
      public Client getClient(org.apache.storm.thrift.protocol.TProtocol iprot, org.apache.storm.thrift.protocol.TProtocol oprot) {
        return new Client(iprot, oprot);
      }
    }

    public Client(org.apache.storm.thrift.protocol.TProtocol prot)
    {
      super(prot, prot);
    }

    public Client(org.apache.storm.thrift.protocol.TProtocol iprot, org.apache.storm.thrift.protocol.TProtocol oprot) {
      super(iprot, oprot);
    }

    public void sendSupervisorAssignments(SupervisorAssignments assignments) throws AuthorizationException, org.apache.storm.thrift.TException
    {
      send_sendSupervisorAssignments(assignments);
      recv_sendSupervisorAssignments();
    }

    public void send_sendSupervisorAssignments(SupervisorAssignments assignments) throws org.apache.storm.thrift.TException
    {
      sendSupervisorAssignments_args args = new sendSupervisorAssignments_args();
      args.set_assignments(assignments);
      sendBase("sendSupervisorAssignments", args);
    }

    public void recv_sendSupervisorAssignments() throws AuthorizationException, org.apache.storm.thrift.TException
    {
      sendSupervisorAssignments_result result = new sendSupervisorAssignments_result();
      receiveBase(result, "sendSupervisorAssignments");
      if (result.aze != null) {
        throw result.aze;
      }
      return;
    }

    public Assignment getLocalAssignmentForStorm(java.lang.String id) throws NotAliveException, AuthorizationException, org.apache.storm.thrift.TException
    {
      send_getLocalAssignmentForStorm(id);
      return recv_getLocalAssignmentForStorm();
    }

    public void send_getLocalAssignmentForStorm(java.lang.String id) throws org.apache.storm.thrift.TException
    {
      getLocalAssignmentForStorm_args args = new getLocalAssignmentForStorm_args();
      args.set_id(id);
      sendBase("getLocalAssignmentForStorm", args);
    }

    public Assignment recv_getLocalAssignmentForStorm() throws NotAliveException, AuthorizationException, org.apache.storm.thrift.TException
    {
      getLocalAssignmentForStorm_result result = new getLocalAssignmentForStorm_result();
      receiveBase(result, "getLocalAssignmentForStorm");
      if (result.is_set_success()) {
        return result.success;
      }
      if (result.e != null) {
        throw result.e;
      }
      if (result.aze != null) {
        throw result.aze;
      }
      throw new org.apache.storm.thrift.TApplicationException(org.apache.storm.thrift.TApplicationException.MISSING_RESULT, "getLocalAssignmentForStorm failed: unknown result");
    }

    public void sendSupervisorWorkerHeartbeat(SupervisorWorkerHeartbeat heartbeat) throws AuthorizationException, org.apache.storm.thrift.TException
    {
      send_sendSupervisorWorkerHeartbeat(heartbeat);
      recv_sendSupervisorWorkerHeartbeat();
    }

    public void send_sendSupervisorWorkerHeartbeat(SupervisorWorkerHeartbeat heartbeat) throws org.apache.storm.thrift.TException
    {
      sendSupervisorWorkerHeartbeat_args args = new sendSupervisorWorkerHeartbeat_args();
      args.set_heartbeat(heartbeat);
      sendBase("sendSupervisorWorkerHeartbeat", args);
    }

    public void recv_sendSupervisorWorkerHeartbeat() throws AuthorizationException, org.apache.storm.thrift.TException
    {
      sendSupervisorWorkerHeartbeat_result result = new sendSupervisorWorkerHeartbeat_result();
      receiveBase(result, "sendSupervisorWorkerHeartbeat");
      if (result.aze != null) {
        throw result.aze;
      }
      return;
    }

  }
  public static class AsyncClient extends org.apache.storm.thrift.async.TAsyncClient implements AsyncIface {
    public static class Factory implements org.apache.storm.thrift.async.TAsyncClientFactory<AsyncClient> {
      private org.apache.storm.thrift.async.TAsyncClientManager clientManager;
      private org.apache.storm.thrift.protocol.TProtocolFactory protocolFactory;
      public Factory(org.apache.storm.thrift.async.TAsyncClientManager clientManager, org.apache.storm.thrift.protocol.TProtocolFactory protocolFactory) {
        this.clientManager = clientManager;
        this.protocolFactory = protocolFactory;
      }
      public AsyncClient getAsyncClient(org.apache.storm.thrift.transport.TNonblockingTransport transport) {
        return new AsyncClient(protocolFactory, clientManager, transport);
      }
    }

    public AsyncClient(org.apache.storm.thrift.protocol.TProtocolFactory protocolFactory, org.apache.storm.thrift.async.TAsyncClientManager clientManager, org.apache.storm.thrift.transport.TNonblockingTransport transport) {
      super(protocolFactory, clientManager, transport);
    }

    public void sendSupervisorAssignments(SupervisorAssignments assignments, org.apache.storm.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.storm.thrift.TException {
      checkReady();
      sendSupervisorAssignments_call method_call = new sendSupervisorAssignments_call(assignments, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class sendSupervisorAssignments_call extends org.apache.storm.thrift.async.TAsyncMethodCall<Void> {
      private SupervisorAssignments assignments;
      public sendSupervisorAssignments_call(SupervisorAssignments assignments, org.apache.storm.thrift.async.AsyncMethodCallback<Void> resultHandler, org.apache.storm.thrift.async.TAsyncClient client, org.apache.storm.thrift.protocol.TProtocolFactory protocolFactory, org.apache.storm.thrift.transport.TNonblockingTransport transport) throws org.apache.storm.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.assignments = assignments;
      }

      public void write_args(org.apache.storm.thrift.protocol.TProtocol prot) throws org.apache.storm.thrift.TException {
        prot.writeMessageBegin(new org.apache.storm.thrift.protocol.TMessage("sendSupervisorAssignments", org.apache.storm.thrift.protocol.TMessageType.CALL, 0));
        sendSupervisorAssignments_args args = new sendSupervisorAssignments_args();
        args.set_assignments(assignments);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AuthorizationException, org.apache.storm.thrift.TException {
        if (getState() != org.apache.storm.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.storm.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.storm.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.storm.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return null;
      }
    }

    public void getLocalAssignmentForStorm(java.lang.String id, org.apache.storm.thrift.async.AsyncMethodCallback<Assignment> resultHandler) throws org.apache.storm.thrift.TException {
      checkReady();
      getLocalAssignmentForStorm_call method_call = new getLocalAssignmentForStorm_call(id, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getLocalAssignmentForStorm_call extends org.apache.storm.thrift.async.TAsyncMethodCall<Assignment> {
      private java.lang.String id;
      public getLocalAssignmentForStorm_call(java.lang.String id, org.apache.storm.thrift.async.AsyncMethodCallback<Assignment> resultHandler, org.apache.storm.thrift.async.TAsyncClient client, org.apache.storm.thrift.protocol.TProtocolFactory protocolFactory, org.apache.storm.thrift.transport.TNonblockingTransport transport) throws org.apache.storm.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.id = id;
      }

      public void write_args(org.apache.storm.thrift.protocol.TProtocol prot) throws org.apache.storm.thrift.TException {
        prot.writeMessageBegin(new org.apache.storm.thrift.protocol.TMessage("getLocalAssignmentForStorm", org.apache.storm.thrift.protocol.TMessageType.CALL, 0));
        getLocalAssignmentForStorm_args args = new getLocalAssignmentForStorm_args();
        args.set_id(id);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Assignment getResult() throws NotAliveException, AuthorizationException, org.apache.storm.thrift.TException {
        if (getState() != org.apache.storm.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.storm.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.storm.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.storm.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getLocalAssignmentForStorm();
      }
    }

    public void sendSupervisorWorkerHeartbeat(SupervisorWorkerHeartbeat heartbeat, org.apache.storm.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.storm.thrift.TException {
      checkReady();
      sendSupervisorWorkerHeartbeat_call method_call = new sendSupervisorWorkerHeartbeat_call(heartbeat, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class sendSupervisorWorkerHeartbeat_call extends org.apache.storm.thrift.async.TAsyncMethodCall<Void> {
      private SupervisorWorkerHeartbeat heartbeat;
      public sendSupervisorWorkerHeartbeat_call(SupervisorWorkerHeartbeat heartbeat, org.apache.storm.thrift.async.AsyncMethodCallback<Void> resultHandler, org.apache.storm.thrift.async.TAsyncClient client, org.apache.storm.thrift.protocol.TProtocolFactory protocolFactory, org.apache.storm.thrift.transport.TNonblockingTransport transport) throws org.apache.storm.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.heartbeat = heartbeat;
      }

      public void write_args(org.apache.storm.thrift.protocol.TProtocol prot) throws org.apache.storm.thrift.TException {
        prot.writeMessageBegin(new org.apache.storm.thrift.protocol.TMessage("sendSupervisorWorkerHeartbeat", org.apache.storm.thrift.protocol.TMessageType.CALL, 0));
        sendSupervisorWorkerHeartbeat_args args = new sendSupervisorWorkerHeartbeat_args();
        args.set_heartbeat(heartbeat);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws AuthorizationException, org.apache.storm.thrift.TException {
        if (getState() != org.apache.storm.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.storm.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.storm.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.storm.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return null;
      }
    }

  }

  public static class Processor<I extends Iface> extends org.apache.storm.thrift.TBaseProcessor<I> implements org.apache.storm.thrift.TProcessor {
    private static final org.slf4j.Logger _LOGGER = org.slf4j.LoggerFactory.getLogger(Processor.class.getName());
    public Processor(I iface) {
      super(iface, getProcessMap(new java.util.HashMap<java.lang.String, org.apache.storm.thrift.ProcessFunction<I, ? extends org.apache.storm.thrift.TBase>>()));
    }

    protected Processor(I iface, java.util.Map<java.lang.String, org.apache.storm.thrift.ProcessFunction<I, ? extends org.apache.storm.thrift.TBase>> processMap) {
      super(iface, getProcessMap(processMap));
    }

    private static <I extends Iface> java.util.Map<java.lang.String,  org.apache.storm.thrift.ProcessFunction<I, ? extends org.apache.storm.thrift.TBase>> getProcessMap(java.util.Map<java.lang.String, org.apache.storm.thrift.ProcessFunction<I, ? extends  org.apache.storm.thrift.TBase>> processMap) {
      processMap.put("sendSupervisorAssignments", new sendSupervisorAssignments());
      processMap.put("getLocalAssignmentForStorm", new getLocalAssignmentForStorm());
      processMap.put("sendSupervisorWorkerHeartbeat", new sendSupervisorWorkerHeartbeat());
      return processMap;
    }

    public static class sendSupervisorAssignments<I extends Iface> extends org.apache.storm.thrift.ProcessFunction<I, sendSupervisorAssignments_args> {
      public sendSupervisorAssignments() {
        super("sendSupervisorAssignments");
      }

      public sendSupervisorAssignments_args getEmptyArgsInstance() {
        return new sendSupervisorAssignments_args();
      }

      protected boolean isOneway() {
        return false;
      }

      @Override
      protected boolean rethrowUnhandledExceptions() {
        return false;
      }

      public sendSupervisorAssignments_result getResult(I iface, sendSupervisorAssignments_args args) throws org.apache.storm.thrift.TException {
        sendSupervisorAssignments_result result = new sendSupervisorAssignments_result();
        try {
          iface.sendSupervisorAssignments(args.assignments);
        } catch (AuthorizationException aze) {
          result.aze = aze;
        }
        return result;
      }
    }

    public static class getLocalAssignmentForStorm<I extends Iface> extends org.apache.storm.thrift.ProcessFunction<I, getLocalAssignmentForStorm_args> {
      public getLocalAssignmentForStorm() {
        super("getLocalAssignmentForStorm");
      }

      public getLocalAssignmentForStorm_args getEmptyArgsInstance() {
        return new getLocalAssignmentForStorm_args();
      }

      protected boolean isOneway() {
        return false;
      }

      @Override
      protected boolean rethrowUnhandledExceptions() {
        return false;
      }

      public getLocalAssignmentForStorm_result getResult(I iface, getLocalAssignmentForStorm_args args) throws org.apache.storm.thrift.TException {
        getLocalAssignmentForStorm_result result = new getLocalAssignmentForStorm_result();
        try {
          result.success = iface.getLocalAssignmentForStorm(args.id);
        } catch (NotAliveException e) {
          result.e = e;
        } catch (AuthorizationException aze) {
          result.aze = aze;
        }
        return result;
      }
    }

    public static class sendSupervisorWorkerHeartbeat<I extends Iface> extends org.apache.storm.thrift.ProcessFunction<I, sendSupervisorWorkerHeartbeat_args> {
      public sendSupervisorWorkerHeartbeat() {
        super("sendSupervisorWorkerHeartbeat");
      }

      public sendSupervisorWorkerHeartbeat_args getEmptyArgsInstance() {
        return new sendSupervisorWorkerHeartbeat_args();
      }

      protected boolean isOneway() {
        return false;
      }

      @Override
      protected boolean rethrowUnhandledExceptions() {
        return false;
      }

      public sendSupervisorWorkerHeartbeat_result getResult(I iface, sendSupervisorWorkerHeartbeat_args args) throws org.apache.storm.thrift.TException {
        sendSupervisorWorkerHeartbeat_result result = new sendSupervisorWorkerHeartbeat_result();
        try {
          iface.sendSupervisorWorkerHeartbeat(args.heartbeat);
        } catch (AuthorizationException aze) {
          result.aze = aze;
        }
        return result;
      }
    }

  }

  public static class AsyncProcessor<I extends AsyncIface> extends org.apache.storm.thrift.TBaseAsyncProcessor<I> {
    private static final org.slf4j.Logger _LOGGER = org.slf4j.LoggerFactory.getLogger(AsyncProcessor.class.getName());
    public AsyncProcessor(I iface) {
      super(iface, getProcessMap(new java.util.HashMap<java.lang.String, org.apache.storm.thrift.AsyncProcessFunction<I, ? extends org.apache.storm.thrift.TBase, ?>>()));
    }

    protected AsyncProcessor(I iface, java.util.Map<java.lang.String,  org.apache.storm.thrift.AsyncProcessFunction<I, ? extends  org.apache.storm.thrift.TBase, ?>> processMap) {
      super(iface, getProcessMap(processMap));
    }

    private static <I extends AsyncIface> java.util.Map<java.lang.String,  org.apache.storm.thrift.AsyncProcessFunction<I, ? extends  org.apache.storm.thrift.TBase,?>> getProcessMap(java.util.Map<java.lang.String,  org.apache.storm.thrift.AsyncProcessFunction<I, ? extends  org.apache.storm.thrift.TBase, ?>> processMap) {
      processMap.put("sendSupervisorAssignments", new sendSupervisorAssignments());
      processMap.put("getLocalAssignmentForStorm", new getLocalAssignmentForStorm());
      processMap.put("sendSupervisorWorkerHeartbeat", new sendSupervisorWorkerHeartbeat());
      return processMap;
    }

    public static class sendSupervisorAssignments<I extends AsyncIface> extends org.apache.storm.thrift.AsyncProcessFunction<I, sendSupervisorAssignments_args, Void> {
      public sendSupervisorAssignments() {
        super("sendSupervisorAssignments");
      }

      public sendSupervisorAssignments_args getEmptyArgsInstance() {
        return new sendSupervisorAssignments_args();
      }

      public org.apache.storm.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.storm.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.storm.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.storm.thrift.async.AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            sendSupervisorAssignments_result result = new sendSupervisorAssignments_result();
            try {
              fcall.sendResponse(fb, result, org.apache.storm.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.storm.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.storm.thrift.protocol.TMessageType.REPLY;
            org.apache.storm.thrift.TSerializable msg;
            sendSupervisorAssignments_result result = new sendSupervisorAssignments_result();
            if (e instanceof AuthorizationException) {
              result.aze = (AuthorizationException) e;
              result.set_aze_isSet(true);
              msg = result;
            } else if (e instanceof org.apache.storm.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.storm.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.storm.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.storm.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.storm.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.storm.thrift.TApplicationException(org.apache.storm.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, sendSupervisorAssignments_args args, org.apache.storm.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.storm.thrift.TException {
        iface.sendSupervisorAssignments(args.assignments,resultHandler);
      }
    }

    public static class getLocalAssignmentForStorm<I extends AsyncIface> extends org.apache.storm.thrift.AsyncProcessFunction<I, getLocalAssignmentForStorm_args, Assignment> {
      public getLocalAssignmentForStorm() {
        super("getLocalAssignmentForStorm");
      }

      public getLocalAssignmentForStorm_args getEmptyArgsInstance() {
        return new getLocalAssignmentForStorm_args();
      }

      public org.apache.storm.thrift.async.AsyncMethodCallback<Assignment> getResultHandler(final org.apache.storm.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.storm.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.storm.thrift.async.AsyncMethodCallback<Assignment>() { 
          public void onComplete(Assignment o) {
            getLocalAssignmentForStorm_result result = new getLocalAssignmentForStorm_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.storm.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.storm.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.storm.thrift.protocol.TMessageType.REPLY;
            org.apache.storm.thrift.TSerializable msg;
            getLocalAssignmentForStorm_result result = new getLocalAssignmentForStorm_result();
            if (e instanceof NotAliveException) {
              result.e = (NotAliveException) e;
              result.set_e_isSet(true);
              msg = result;
            } else if (e instanceof AuthorizationException) {
              result.aze = (AuthorizationException) e;
              result.set_aze_isSet(true);
              msg = result;
            } else if (e instanceof org.apache.storm.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.storm.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.storm.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.storm.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.storm.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.storm.thrift.TApplicationException(org.apache.storm.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getLocalAssignmentForStorm_args args, org.apache.storm.thrift.async.AsyncMethodCallback<Assignment> resultHandler) throws org.apache.storm.thrift.TException {
        iface.getLocalAssignmentForStorm(args.id,resultHandler);
      }
    }

    public static class sendSupervisorWorkerHeartbeat<I extends AsyncIface> extends org.apache.storm.thrift.AsyncProcessFunction<I, sendSupervisorWorkerHeartbeat_args, Void> {
      public sendSupervisorWorkerHeartbeat() {
        super("sendSupervisorWorkerHeartbeat");
      }

      public sendSupervisorWorkerHeartbeat_args getEmptyArgsInstance() {
        return new sendSupervisorWorkerHeartbeat_args();
      }

      public org.apache.storm.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.storm.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.storm.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.storm.thrift.async.AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            sendSupervisorWorkerHeartbeat_result result = new sendSupervisorWorkerHeartbeat_result();
            try {
              fcall.sendResponse(fb, result, org.apache.storm.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.storm.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.storm.thrift.protocol.TMessageType.REPLY;
            org.apache.storm.thrift.TSerializable msg;
            sendSupervisorWorkerHeartbeat_result result = new sendSupervisorWorkerHeartbeat_result();
            if (e instanceof AuthorizationException) {
              result.aze = (AuthorizationException) e;
              result.set_aze_isSet(true);
              msg = result;
            } else if (e instanceof org.apache.storm.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.storm.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.storm.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.storm.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.storm.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.storm.thrift.TApplicationException(org.apache.storm.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, sendSupervisorWorkerHeartbeat_args args, org.apache.storm.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.storm.thrift.TException {
        iface.sendSupervisorWorkerHeartbeat(args.heartbeat,resultHandler);
      }
    }

  }

  public static class sendSupervisorAssignments_args implements org.apache.storm.thrift.TBase<sendSupervisorAssignments_args, sendSupervisorAssignments_args._Fields>, java.io.Serializable, Cloneable, Comparable<sendSupervisorAssignments_args>   {
    private static final org.apache.storm.thrift.protocol.TStruct STRUCT_DESC = new org.apache.storm.thrift.protocol.TStruct("sendSupervisorAssignments_args");

    private static final org.apache.storm.thrift.protocol.TField ASSIGNMENTS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("assignments", org.apache.storm.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.storm.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new sendSupervisorAssignments_argsStandardSchemeFactory();
    private static final org.apache.storm.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new sendSupervisorAssignments_argsTupleSchemeFactory();

    private @org.apache.storm.thrift.annotation.Nullable SupervisorAssignments assignments; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.storm.thrift.TFieldIdEnum {
      ASSIGNMENTS((short)1, "assignments");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      @org.apache.storm.thrift.annotation.Nullable
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // ASSIGNMENTS
            return ASSIGNMENTS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      @org.apache.storm.thrift.annotation.Nullable
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.ASSIGNMENTS, new org.apache.storm.thrift.meta_data.FieldMetaData("assignments", org.apache.storm.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, SupervisorAssignments.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.storm.thrift.meta_data.FieldMetaData.addStructMetaDataMap(sendSupervisorAssignments_args.class, metaDataMap);
    }

    public sendSupervisorAssignments_args() {
    }

    public sendSupervisorAssignments_args(
      SupervisorAssignments assignments)
    {
      this();
      this.assignments = assignments;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public sendSupervisorAssignments_args(sendSupervisorAssignments_args other) {
      if (other.is_set_assignments()) {
        this.assignments = new SupervisorAssignments(other.assignments);
      }
    }

    public sendSupervisorAssignments_args deepCopy() {
      return new sendSupervisorAssignments_args(this);
    }

    @Override
    public void clear() {
      this.assignments = null;
    }

    @org.apache.storm.thrift.annotation.Nullable
    public SupervisorAssignments get_assignments() {
      return this.assignments;
    }

    public void set_assignments(@org.apache.storm.thrift.annotation.Nullable SupervisorAssignments assignments) {
      this.assignments = assignments;
    }

    public void unset_assignments() {
      this.assignments = null;
    }

    /** Returns true if field assignments is set (has been assigned a value) and false otherwise */
    public boolean is_set_assignments() {
      return this.assignments != null;
    }

    public void set_assignments_isSet(boolean value) {
      if (!value) {
        this.assignments = null;
      }
    }

    public void setFieldValue(_Fields field, @org.apache.storm.thrift.annotation.Nullable java.lang.Object value) {
      switch (field) {
      case ASSIGNMENTS:
        if (value == null) {
          unset_assignments();
        } else {
          set_assignments((SupervisorAssignments)value);
        }
        break;

      }
    }

    @org.apache.storm.thrift.annotation.Nullable
    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case ASSIGNMENTS:
        return get_assignments();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case ASSIGNMENTS:
        return is_set_assignments();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof sendSupervisorAssignments_args)
        return this.equals((sendSupervisorAssignments_args)that);
      return false;
    }

    public boolean equals(sendSupervisorAssignments_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_assignments = true && this.is_set_assignments();
      boolean that_present_assignments = true && that.is_set_assignments();
      if (this_present_assignments || that_present_assignments) {
        if (!(this_present_assignments && that_present_assignments))
          return false;
        if (!this.assignments.equals(that.assignments))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((is_set_assignments()) ? 131071 : 524287);
      if (is_set_assignments())
        hashCode = hashCode * 8191 + assignments.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(sendSupervisorAssignments_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(is_set_assignments()).compareTo(other.is_set_assignments());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (is_set_assignments()) {
        lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.assignments, other.assignments);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    @org.apache.storm.thrift.annotation.Nullable
    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.storm.thrift.protocol.TProtocol iprot) throws org.apache.storm.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.storm.thrift.protocol.TProtocol oprot) throws org.apache.storm.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("sendSupervisorAssignments_args(");
      boolean first = true;

      sb.append("assignments:");
      if (this.assignments == null) {
        sb.append("null");
      } else {
        sb.append(this.assignments);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.storm.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (assignments != null) {
        assignments.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.storm.thrift.protocol.TCompactProtocol(new org.apache.storm.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.storm.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.storm.thrift.protocol.TCompactProtocol(new org.apache.storm.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.storm.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class sendSupervisorAssignments_argsStandardSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
      public sendSupervisorAssignments_argsStandardScheme getScheme() {
        return new sendSupervisorAssignments_argsStandardScheme();
      }
    }

    private static class sendSupervisorAssignments_argsStandardScheme extends org.apache.storm.thrift.scheme.StandardScheme<sendSupervisorAssignments_args> {

      public void read(org.apache.storm.thrift.protocol.TProtocol iprot, sendSupervisorAssignments_args struct) throws org.apache.storm.thrift.TException {
        org.apache.storm.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.storm.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // ASSIGNMENTS
              if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRUCT) {
                struct.assignments = new SupervisorAssignments();
                struct.assignments.read(iprot);
                struct.set_assignments_isSet(true);
              } else { 
                org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();
        struct.validate();
      }

      public void write(org.apache.storm.thrift.protocol.TProtocol oprot, sendSupervisorAssignments_args struct) throws org.apache.storm.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.assignments != null) {
          oprot.writeFieldBegin(ASSIGNMENTS_FIELD_DESC);
          struct.assignments.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class sendSupervisorAssignments_argsTupleSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
      public sendSupervisorAssignments_argsTupleScheme getScheme() {
        return new sendSupervisorAssignments_argsTupleScheme();
      }
    }

    private static class sendSupervisorAssignments_argsTupleScheme extends org.apache.storm.thrift.scheme.TupleScheme<sendSupervisorAssignments_args> {

      @Override
      public void write(org.apache.storm.thrift.protocol.TProtocol prot, sendSupervisorAssignments_args struct) throws org.apache.storm.thrift.TException {
        org.apache.storm.thrift.protocol.TTupleProtocol oprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.is_set_assignments()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.is_set_assignments()) {
          struct.assignments.write(oprot);
        }
      }

      @Override
      public void read(org.apache.storm.thrift.protocol.TProtocol prot, sendSupervisorAssignments_args struct) throws org.apache.storm.thrift.TException {
        org.apache.storm.thrift.protocol.TTupleProtocol iprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.assignments = new SupervisorAssignments();
          struct.assignments.read(iprot);
          struct.set_assignments_isSet(true);
        }
      }
    }

    private static <S extends org.apache.storm.thrift.scheme.IScheme> S scheme(org.apache.storm.thrift.protocol.TProtocol proto) {
      return (org.apache.storm.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class sendSupervisorAssignments_result implements org.apache.storm.thrift.TBase<sendSupervisorAssignments_result, sendSupervisorAssignments_result._Fields>, java.io.Serializable, Cloneable, Comparable<sendSupervisorAssignments_result>   {
    private static final org.apache.storm.thrift.protocol.TStruct STRUCT_DESC = new org.apache.storm.thrift.protocol.TStruct("sendSupervisorAssignments_result");

    private static final org.apache.storm.thrift.protocol.TField AZE_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("aze", org.apache.storm.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.storm.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new sendSupervisorAssignments_resultStandardSchemeFactory();
    private static final org.apache.storm.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new sendSupervisorAssignments_resultTupleSchemeFactory();

    private @org.apache.storm.thrift.annotation.Nullable AuthorizationException aze; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.storm.thrift.TFieldIdEnum {
      AZE((short)1, "aze");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      @org.apache.storm.thrift.annotation.Nullable
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AZE
            return AZE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      @org.apache.storm.thrift.annotation.Nullable
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.AZE, new org.apache.storm.thrift.meta_data.FieldMetaData("aze", org.apache.storm.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, AuthorizationException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.storm.thrift.meta_data.FieldMetaData.addStructMetaDataMap(sendSupervisorAssignments_result.class, metaDataMap);
    }

    public sendSupervisorAssignments_result() {
    }

    public sendSupervisorAssignments_result(
      AuthorizationException aze)
    {
      this();
      this.aze = aze;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public sendSupervisorAssignments_result(sendSupervisorAssignments_result other) {
      if (other.is_set_aze()) {
        this.aze = new AuthorizationException(other.aze);
      }
    }

    public sendSupervisorAssignments_result deepCopy() {
      return new sendSupervisorAssignments_result(this);
    }

    @Override
    public void clear() {
      this.aze = null;
    }

    @org.apache.storm.thrift.annotation.Nullable
    public AuthorizationException get_aze() {
      return this.aze;
    }

    public void set_aze(@org.apache.storm.thrift.annotation.Nullable AuthorizationException aze) {
      this.aze = aze;
    }

    public void unset_aze() {
      this.aze = null;
    }

    /** Returns true if field aze is set (has been assigned a value) and false otherwise */
    public boolean is_set_aze() {
      return this.aze != null;
    }

    public void set_aze_isSet(boolean value) {
      if (!value) {
        this.aze = null;
      }
    }

    public void setFieldValue(_Fields field, @org.apache.storm.thrift.annotation.Nullable java.lang.Object value) {
      switch (field) {
      case AZE:
        if (value == null) {
          unset_aze();
        } else {
          set_aze((AuthorizationException)value);
        }
        break;

      }
    }

    @org.apache.storm.thrift.annotation.Nullable
    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case AZE:
        return get_aze();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case AZE:
        return is_set_aze();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof sendSupervisorAssignments_result)
        return this.equals((sendSupervisorAssignments_result)that);
      return false;
    }

    public boolean equals(sendSupervisorAssignments_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_aze = true && this.is_set_aze();
      boolean that_present_aze = true && that.is_set_aze();
      if (this_present_aze || that_present_aze) {
        if (!(this_present_aze && that_present_aze))
          return false;
        if (!this.aze.equals(that.aze))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((is_set_aze()) ? 131071 : 524287);
      if (is_set_aze())
        hashCode = hashCode * 8191 + aze.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(sendSupervisorAssignments_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(is_set_aze()).compareTo(other.is_set_aze());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (is_set_aze()) {
        lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.aze, other.aze);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    @org.apache.storm.thrift.annotation.Nullable
    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.storm.thrift.protocol.TProtocol iprot) throws org.apache.storm.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.storm.thrift.protocol.TProtocol oprot) throws org.apache.storm.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("sendSupervisorAssignments_result(");
      boolean first = true;

      sb.append("aze:");
      if (this.aze == null) {
        sb.append("null");
      } else {
        sb.append(this.aze);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.storm.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.storm.thrift.protocol.TCompactProtocol(new org.apache.storm.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.storm.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.storm.thrift.protocol.TCompactProtocol(new org.apache.storm.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.storm.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class sendSupervisorAssignments_resultStandardSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
      public sendSupervisorAssignments_resultStandardScheme getScheme() {
        return new sendSupervisorAssignments_resultStandardScheme();
      }
    }

    private static class sendSupervisorAssignments_resultStandardScheme extends org.apache.storm.thrift.scheme.StandardScheme<sendSupervisorAssignments_result> {

      public void read(org.apache.storm.thrift.protocol.TProtocol iprot, sendSupervisorAssignments_result struct) throws org.apache.storm.thrift.TException {
        org.apache.storm.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.storm.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // AZE
              if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRUCT) {
                struct.aze = new AuthorizationException();
                struct.aze.read(iprot);
                struct.set_aze_isSet(true);
              } else { 
                org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();
        struct.validate();
      }

      public void write(org.apache.storm.thrift.protocol.TProtocol oprot, sendSupervisorAssignments_result struct) throws org.apache.storm.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.aze != null) {
          oprot.writeFieldBegin(AZE_FIELD_DESC);
          struct.aze.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class sendSupervisorAssignments_resultTupleSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
      public sendSupervisorAssignments_resultTupleScheme getScheme() {
        return new sendSupervisorAssignments_resultTupleScheme();
      }
    }

    private static class sendSupervisorAssignments_resultTupleScheme extends org.apache.storm.thrift.scheme.TupleScheme<sendSupervisorAssignments_result> {

      @Override
      public void write(org.apache.storm.thrift.protocol.TProtocol prot, sendSupervisorAssignments_result struct) throws org.apache.storm.thrift.TException {
        org.apache.storm.thrift.protocol.TTupleProtocol oprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.is_set_aze()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.is_set_aze()) {
          struct.aze.write(oprot);
        }
      }

      @Override
      public void read(org.apache.storm.thrift.protocol.TProtocol prot, sendSupervisorAssignments_result struct) throws org.apache.storm.thrift.TException {
        org.apache.storm.thrift.protocol.TTupleProtocol iprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.aze = new AuthorizationException();
          struct.aze.read(iprot);
          struct.set_aze_isSet(true);
        }
      }
    }

    private static <S extends org.apache.storm.thrift.scheme.IScheme> S scheme(org.apache.storm.thrift.protocol.TProtocol proto) {
      return (org.apache.storm.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getLocalAssignmentForStorm_args implements org.apache.storm.thrift.TBase<getLocalAssignmentForStorm_args, getLocalAssignmentForStorm_args._Fields>, java.io.Serializable, Cloneable, Comparable<getLocalAssignmentForStorm_args>   {
    private static final org.apache.storm.thrift.protocol.TStruct STRUCT_DESC = new org.apache.storm.thrift.protocol.TStruct("getLocalAssignmentForStorm_args");

    private static final org.apache.storm.thrift.protocol.TField ID_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("id", org.apache.storm.thrift.protocol.TType.STRING, (short)1);

    private static final org.apache.storm.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getLocalAssignmentForStorm_argsStandardSchemeFactory();
    private static final org.apache.storm.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getLocalAssignmentForStorm_argsTupleSchemeFactory();

    private @org.apache.storm.thrift.annotation.Nullable java.lang.String id; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.storm.thrift.TFieldIdEnum {
      ID((short)1, "id");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      @org.apache.storm.thrift.annotation.Nullable
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // ID
            return ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      @org.apache.storm.thrift.annotation.Nullable
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.ID, new org.apache.storm.thrift.meta_data.FieldMetaData("id", org.apache.storm.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.storm.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getLocalAssignmentForStorm_args.class, metaDataMap);
    }

    public getLocalAssignmentForStorm_args() {
    }

    public getLocalAssignmentForStorm_args(
      java.lang.String id)
    {
      this();
      this.id = id;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getLocalAssignmentForStorm_args(getLocalAssignmentForStorm_args other) {
      if (other.is_set_id()) {
        this.id = other.id;
      }
    }

    public getLocalAssignmentForStorm_args deepCopy() {
      return new getLocalAssignmentForStorm_args(this);
    }

    @Override
    public void clear() {
      this.id = null;
    }

    @org.apache.storm.thrift.annotation.Nullable
    public java.lang.String get_id() {
      return this.id;
    }

    public void set_id(@org.apache.storm.thrift.annotation.Nullable java.lang.String id) {
      this.id = id;
    }

    public void unset_id() {
      this.id = null;
    }

    /** Returns true if field id is set (has been assigned a value) and false otherwise */
    public boolean is_set_id() {
      return this.id != null;
    }

    public void set_id_isSet(boolean value) {
      if (!value) {
        this.id = null;
      }
    }

    public void setFieldValue(_Fields field, @org.apache.storm.thrift.annotation.Nullable java.lang.Object value) {
      switch (field) {
      case ID:
        if (value == null) {
          unset_id();
        } else {
          set_id((java.lang.String)value);
        }
        break;

      }
    }

    @org.apache.storm.thrift.annotation.Nullable
    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case ID:
        return get_id();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case ID:
        return is_set_id();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getLocalAssignmentForStorm_args)
        return this.equals((getLocalAssignmentForStorm_args)that);
      return false;
    }

    public boolean equals(getLocalAssignmentForStorm_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_id = true && this.is_set_id();
      boolean that_present_id = true && that.is_set_id();
      if (this_present_id || that_present_id) {
        if (!(this_present_id && that_present_id))
          return false;
        if (!this.id.equals(that.id))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((is_set_id()) ? 131071 : 524287);
      if (is_set_id())
        hashCode = hashCode * 8191 + id.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getLocalAssignmentForStorm_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(is_set_id()).compareTo(other.is_set_id());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (is_set_id()) {
        lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.id, other.id);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    @org.apache.storm.thrift.annotation.Nullable
    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.storm.thrift.protocol.TProtocol iprot) throws org.apache.storm.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.storm.thrift.protocol.TProtocol oprot) throws org.apache.storm.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getLocalAssignmentForStorm_args(");
      boolean first = true;

      sb.append("id:");
      if (this.id == null) {
        sb.append("null");
      } else {
        sb.append(this.id);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.storm.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.storm.thrift.protocol.TCompactProtocol(new org.apache.storm.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.storm.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.storm.thrift.protocol.TCompactProtocol(new org.apache.storm.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.storm.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getLocalAssignmentForStorm_argsStandardSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
      public getLocalAssignmentForStorm_argsStandardScheme getScheme() {
        return new getLocalAssignmentForStorm_argsStandardScheme();
      }
    }

    private static class getLocalAssignmentForStorm_argsStandardScheme extends org.apache.storm.thrift.scheme.StandardScheme<getLocalAssignmentForStorm_args> {

      public void read(org.apache.storm.thrift.protocol.TProtocol iprot, getLocalAssignmentForStorm_args struct) throws org.apache.storm.thrift.TException {
        org.apache.storm.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.storm.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // ID
              if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
                struct.id = iprot.readString();
                struct.set_id_isSet(true);
              } else { 
                org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();
        struct.validate();
      }

      public void write(org.apache.storm.thrift.protocol.TProtocol oprot, getLocalAssignmentForStorm_args struct) throws org.apache.storm.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.id != null) {
          oprot.writeFieldBegin(ID_FIELD_DESC);
          oprot.writeString(struct.id);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getLocalAssignmentForStorm_argsTupleSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
      public getLocalAssignmentForStorm_argsTupleScheme getScheme() {
        return new getLocalAssignmentForStorm_argsTupleScheme();
      }
    }

    private static class getLocalAssignmentForStorm_argsTupleScheme extends org.apache.storm.thrift.scheme.TupleScheme<getLocalAssignmentForStorm_args> {

      @Override
      public void write(org.apache.storm.thrift.protocol.TProtocol prot, getLocalAssignmentForStorm_args struct) throws org.apache.storm.thrift.TException {
        org.apache.storm.thrift.protocol.TTupleProtocol oprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.is_set_id()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.is_set_id()) {
          oprot.writeString(struct.id);
        }
      }

      @Override
      public void read(org.apache.storm.thrift.protocol.TProtocol prot, getLocalAssignmentForStorm_args struct) throws org.apache.storm.thrift.TException {
        org.apache.storm.thrift.protocol.TTupleProtocol iprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.id = iprot.readString();
          struct.set_id_isSet(true);
        }
      }
    }

    private static <S extends org.apache.storm.thrift.scheme.IScheme> S scheme(org.apache.storm.thrift.protocol.TProtocol proto) {
      return (org.apache.storm.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getLocalAssignmentForStorm_result implements org.apache.storm.thrift.TBase<getLocalAssignmentForStorm_result, getLocalAssignmentForStorm_result._Fields>, java.io.Serializable, Cloneable, Comparable<getLocalAssignmentForStorm_result>   {
    private static final org.apache.storm.thrift.protocol.TStruct STRUCT_DESC = new org.apache.storm.thrift.protocol.TStruct("getLocalAssignmentForStorm_result");

    private static final org.apache.storm.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("success", org.apache.storm.thrift.protocol.TType.STRUCT, (short)0);
    private static final org.apache.storm.thrift.protocol.TField E_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("e", org.apache.storm.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.storm.thrift.protocol.TField AZE_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("aze", org.apache.storm.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.storm.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getLocalAssignmentForStorm_resultStandardSchemeFactory();
    private static final org.apache.storm.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getLocalAssignmentForStorm_resultTupleSchemeFactory();

    private @org.apache.storm.thrift.annotation.Nullable Assignment success; // required
    private @org.apache.storm.thrift.annotation.Nullable NotAliveException e; // required
    private @org.apache.storm.thrift.annotation.Nullable AuthorizationException aze; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.storm.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      E((short)1, "e"),
      AZE((short)2, "aze");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      @org.apache.storm.thrift.annotation.Nullable
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // E
            return E;
          case 2: // AZE
            return AZE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      @org.apache.storm.thrift.annotation.Nullable
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.storm.thrift.meta_data.FieldMetaData("success", org.apache.storm.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, Assignment.class)));
      tmpMap.put(_Fields.E, new org.apache.storm.thrift.meta_data.FieldMetaData("e", org.apache.storm.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, NotAliveException.class)));
      tmpMap.put(_Fields.AZE, new org.apache.storm.thrift.meta_data.FieldMetaData("aze", org.apache.storm.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, AuthorizationException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.storm.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getLocalAssignmentForStorm_result.class, metaDataMap);
    }

    public getLocalAssignmentForStorm_result() {
    }

    public getLocalAssignmentForStorm_result(
      Assignment success,
      NotAliveException e,
      AuthorizationException aze)
    {
      this();
      this.success = success;
      this.e = e;
      this.aze = aze;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getLocalAssignmentForStorm_result(getLocalAssignmentForStorm_result other) {
      if (other.is_set_success()) {
        this.success = new Assignment(other.success);
      }
      if (other.is_set_e()) {
        this.e = new NotAliveException(other.e);
      }
      if (other.is_set_aze()) {
        this.aze = new AuthorizationException(other.aze);
      }
    }

    public getLocalAssignmentForStorm_result deepCopy() {
      return new getLocalAssignmentForStorm_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.e = null;
      this.aze = null;
    }

    @org.apache.storm.thrift.annotation.Nullable
    public Assignment get_success() {
      return this.success;
    }

    public void set_success(@org.apache.storm.thrift.annotation.Nullable Assignment success) {
      this.success = success;
    }

    public void unset_success() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean is_set_success() {
      return this.success != null;
    }

    public void set_success_isSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    @org.apache.storm.thrift.annotation.Nullable
    public NotAliveException get_e() {
      return this.e;
    }

    public void set_e(@org.apache.storm.thrift.annotation.Nullable NotAliveException e) {
      this.e = e;
    }

    public void unset_e() {
      this.e = null;
    }

    /** Returns true if field e is set (has been assigned a value) and false otherwise */
    public boolean is_set_e() {
      return this.e != null;
    }

    public void set_e_isSet(boolean value) {
      if (!value) {
        this.e = null;
      }
    }

    @org.apache.storm.thrift.annotation.Nullable
    public AuthorizationException get_aze() {
      return this.aze;
    }

    public void set_aze(@org.apache.storm.thrift.annotation.Nullable AuthorizationException aze) {
      this.aze = aze;
    }

    public void unset_aze() {
      this.aze = null;
    }

    /** Returns true if field aze is set (has been assigned a value) and false otherwise */
    public boolean is_set_aze() {
      return this.aze != null;
    }

    public void set_aze_isSet(boolean value) {
      if (!value) {
        this.aze = null;
      }
    }

    public void setFieldValue(_Fields field, @org.apache.storm.thrift.annotation.Nullable java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unset_success();
        } else {
          set_success((Assignment)value);
        }
        break;

      case E:
        if (value == null) {
          unset_e();
        } else {
          set_e((NotAliveException)value);
        }
        break;

      case AZE:
        if (value == null) {
          unset_aze();
        } else {
          set_aze((AuthorizationException)value);
        }
        break;

      }
    }

    @org.apache.storm.thrift.annotation.Nullable
    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return get_success();

      case E:
        return get_e();

      case AZE:
        return get_aze();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return is_set_success();
      case E:
        return is_set_e();
      case AZE:
        return is_set_aze();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getLocalAssignmentForStorm_result)
        return this.equals((getLocalAssignmentForStorm_result)that);
      return false;
    }

    public boolean equals(getLocalAssignmentForStorm_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.is_set_success();
      boolean that_present_success = true && that.is_set_success();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_e = true && this.is_set_e();
      boolean that_present_e = true && that.is_set_e();
      if (this_present_e || that_present_e) {
        if (!(this_present_e && that_present_e))
          return false;
        if (!this.e.equals(that.e))
          return false;
      }

      boolean this_present_aze = true && this.is_set_aze();
      boolean that_present_aze = true && that.is_set_aze();
      if (this_present_aze || that_present_aze) {
        if (!(this_present_aze && that_present_aze))
          return false;
        if (!this.aze.equals(that.aze))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((is_set_success()) ? 131071 : 524287);
      if (is_set_success())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((is_set_e()) ? 131071 : 524287);
      if (is_set_e())
        hashCode = hashCode * 8191 + e.hashCode();

      hashCode = hashCode * 8191 + ((is_set_aze()) ? 131071 : 524287);
      if (is_set_aze())
        hashCode = hashCode * 8191 + aze.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getLocalAssignmentForStorm_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(is_set_success()).compareTo(other.is_set_success());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (is_set_success()) {
        lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(is_set_e()).compareTo(other.is_set_e());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (is_set_e()) {
        lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.e, other.e);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(is_set_aze()).compareTo(other.is_set_aze());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (is_set_aze()) {
        lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.aze, other.aze);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    @org.apache.storm.thrift.annotation.Nullable
    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.storm.thrift.protocol.TProtocol iprot) throws org.apache.storm.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.storm.thrift.protocol.TProtocol oprot) throws org.apache.storm.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getLocalAssignmentForStorm_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("e:");
      if (this.e == null) {
        sb.append("null");
      } else {
        sb.append(this.e);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("aze:");
      if (this.aze == null) {
        sb.append("null");
      } else {
        sb.append(this.aze);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.storm.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.storm.thrift.protocol.TCompactProtocol(new org.apache.storm.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.storm.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.storm.thrift.protocol.TCompactProtocol(new org.apache.storm.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.storm.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getLocalAssignmentForStorm_resultStandardSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
      public getLocalAssignmentForStorm_resultStandardScheme getScheme() {
        return new getLocalAssignmentForStorm_resultStandardScheme();
      }
    }

    private static class getLocalAssignmentForStorm_resultStandardScheme extends org.apache.storm.thrift.scheme.StandardScheme<getLocalAssignmentForStorm_result> {

      public void read(org.apache.storm.thrift.protocol.TProtocol iprot, getLocalAssignmentForStorm_result struct) throws org.apache.storm.thrift.TException {
        org.apache.storm.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.storm.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRUCT) {
                struct.success = new Assignment();
                struct.success.read(iprot);
                struct.set_success_isSet(true);
              } else { 
                org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // E
              if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRUCT) {
                struct.e = new NotAliveException();
                struct.e.read(iprot);
                struct.set_e_isSet(true);
              } else { 
                org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // AZE
              if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRUCT) {
                struct.aze = new AuthorizationException();
                struct.aze.read(iprot);
                struct.set_aze_isSet(true);
              } else { 
                org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();
        struct.validate();
      }

      public void write(org.apache.storm.thrift.protocol.TProtocol oprot, getLocalAssignmentForStorm_result struct) throws org.apache.storm.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          struct.success.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.e != null) {
          oprot.writeFieldBegin(E_FIELD_DESC);
          struct.e.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.aze != null) {
          oprot.writeFieldBegin(AZE_FIELD_DESC);
          struct.aze.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getLocalAssignmentForStorm_resultTupleSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
      public getLocalAssignmentForStorm_resultTupleScheme getScheme() {
        return new getLocalAssignmentForStorm_resultTupleScheme();
      }
    }

    private static class getLocalAssignmentForStorm_resultTupleScheme extends org.apache.storm.thrift.scheme.TupleScheme<getLocalAssignmentForStorm_result> {

      @Override
      public void write(org.apache.storm.thrift.protocol.TProtocol prot, getLocalAssignmentForStorm_result struct) throws org.apache.storm.thrift.TException {
        org.apache.storm.thrift.protocol.TTupleProtocol oprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.is_set_success()) {
          optionals.set(0);
        }
        if (struct.is_set_e()) {
          optionals.set(1);
        }
        if (struct.is_set_aze()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.is_set_success()) {
          struct.success.write(oprot);
        }
        if (struct.is_set_e()) {
          struct.e.write(oprot);
        }
        if (struct.is_set_aze()) {
          struct.aze.write(oprot);
        }
      }

      @Override
      public void read(org.apache.storm.thrift.protocol.TProtocol prot, getLocalAssignmentForStorm_result struct) throws org.apache.storm.thrift.TException {
        org.apache.storm.thrift.protocol.TTupleProtocol iprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.success = new Assignment();
          struct.success.read(iprot);
          struct.set_success_isSet(true);
        }
        if (incoming.get(1)) {
          struct.e = new NotAliveException();
          struct.e.read(iprot);
          struct.set_e_isSet(true);
        }
        if (incoming.get(2)) {
          struct.aze = new AuthorizationException();
          struct.aze.read(iprot);
          struct.set_aze_isSet(true);
        }
      }
    }

    private static <S extends org.apache.storm.thrift.scheme.IScheme> S scheme(org.apache.storm.thrift.protocol.TProtocol proto) {
      return (org.apache.storm.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class sendSupervisorWorkerHeartbeat_args implements org.apache.storm.thrift.TBase<sendSupervisorWorkerHeartbeat_args, sendSupervisorWorkerHeartbeat_args._Fields>, java.io.Serializable, Cloneable, Comparable<sendSupervisorWorkerHeartbeat_args>   {
    private static final org.apache.storm.thrift.protocol.TStruct STRUCT_DESC = new org.apache.storm.thrift.protocol.TStruct("sendSupervisorWorkerHeartbeat_args");

    private static final org.apache.storm.thrift.protocol.TField HEARTBEAT_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("heartbeat", org.apache.storm.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.storm.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new sendSupervisorWorkerHeartbeat_argsStandardSchemeFactory();
    private static final org.apache.storm.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new sendSupervisorWorkerHeartbeat_argsTupleSchemeFactory();

    private @org.apache.storm.thrift.annotation.Nullable SupervisorWorkerHeartbeat heartbeat; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.storm.thrift.TFieldIdEnum {
      HEARTBEAT((short)1, "heartbeat");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      @org.apache.storm.thrift.annotation.Nullable
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // HEARTBEAT
            return HEARTBEAT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      @org.apache.storm.thrift.annotation.Nullable
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.HEARTBEAT, new org.apache.storm.thrift.meta_data.FieldMetaData("heartbeat", org.apache.storm.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, SupervisorWorkerHeartbeat.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.storm.thrift.meta_data.FieldMetaData.addStructMetaDataMap(sendSupervisorWorkerHeartbeat_args.class, metaDataMap);
    }

    public sendSupervisorWorkerHeartbeat_args() {
    }

    public sendSupervisorWorkerHeartbeat_args(
      SupervisorWorkerHeartbeat heartbeat)
    {
      this();
      this.heartbeat = heartbeat;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public sendSupervisorWorkerHeartbeat_args(sendSupervisorWorkerHeartbeat_args other) {
      if (other.is_set_heartbeat()) {
        this.heartbeat = new SupervisorWorkerHeartbeat(other.heartbeat);
      }
    }

    public sendSupervisorWorkerHeartbeat_args deepCopy() {
      return new sendSupervisorWorkerHeartbeat_args(this);
    }

    @Override
    public void clear() {
      this.heartbeat = null;
    }

    @org.apache.storm.thrift.annotation.Nullable
    public SupervisorWorkerHeartbeat get_heartbeat() {
      return this.heartbeat;
    }

    public void set_heartbeat(@org.apache.storm.thrift.annotation.Nullable SupervisorWorkerHeartbeat heartbeat) {
      this.heartbeat = heartbeat;
    }

    public void unset_heartbeat() {
      this.heartbeat = null;
    }

    /** Returns true if field heartbeat is set (has been assigned a value) and false otherwise */
    public boolean is_set_heartbeat() {
      return this.heartbeat != null;
    }

    public void set_heartbeat_isSet(boolean value) {
      if (!value) {
        this.heartbeat = null;
      }
    }

    public void setFieldValue(_Fields field, @org.apache.storm.thrift.annotation.Nullable java.lang.Object value) {
      switch (field) {
      case HEARTBEAT:
        if (value == null) {
          unset_heartbeat();
        } else {
          set_heartbeat((SupervisorWorkerHeartbeat)value);
        }
        break;

      }
    }

    @org.apache.storm.thrift.annotation.Nullable
    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case HEARTBEAT:
        return get_heartbeat();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case HEARTBEAT:
        return is_set_heartbeat();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof sendSupervisorWorkerHeartbeat_args)
        return this.equals((sendSupervisorWorkerHeartbeat_args)that);
      return false;
    }

    public boolean equals(sendSupervisorWorkerHeartbeat_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_heartbeat = true && this.is_set_heartbeat();
      boolean that_present_heartbeat = true && that.is_set_heartbeat();
      if (this_present_heartbeat || that_present_heartbeat) {
        if (!(this_present_heartbeat && that_present_heartbeat))
          return false;
        if (!this.heartbeat.equals(that.heartbeat))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((is_set_heartbeat()) ? 131071 : 524287);
      if (is_set_heartbeat())
        hashCode = hashCode * 8191 + heartbeat.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(sendSupervisorWorkerHeartbeat_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(is_set_heartbeat()).compareTo(other.is_set_heartbeat());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (is_set_heartbeat()) {
        lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.heartbeat, other.heartbeat);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    @org.apache.storm.thrift.annotation.Nullable
    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.storm.thrift.protocol.TProtocol iprot) throws org.apache.storm.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.storm.thrift.protocol.TProtocol oprot) throws org.apache.storm.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("sendSupervisorWorkerHeartbeat_args(");
      boolean first = true;

      sb.append("heartbeat:");
      if (this.heartbeat == null) {
        sb.append("null");
      } else {
        sb.append(this.heartbeat);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.storm.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (heartbeat != null) {
        heartbeat.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.storm.thrift.protocol.TCompactProtocol(new org.apache.storm.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.storm.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.storm.thrift.protocol.TCompactProtocol(new org.apache.storm.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.storm.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class sendSupervisorWorkerHeartbeat_argsStandardSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
      public sendSupervisorWorkerHeartbeat_argsStandardScheme getScheme() {
        return new sendSupervisorWorkerHeartbeat_argsStandardScheme();
      }
    }

    private static class sendSupervisorWorkerHeartbeat_argsStandardScheme extends org.apache.storm.thrift.scheme.StandardScheme<sendSupervisorWorkerHeartbeat_args> {

      public void read(org.apache.storm.thrift.protocol.TProtocol iprot, sendSupervisorWorkerHeartbeat_args struct) throws org.apache.storm.thrift.TException {
        org.apache.storm.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.storm.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // HEARTBEAT
              if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRUCT) {
                struct.heartbeat = new SupervisorWorkerHeartbeat();
                struct.heartbeat.read(iprot);
                struct.set_heartbeat_isSet(true);
              } else { 
                org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();
        struct.validate();
      }

      public void write(org.apache.storm.thrift.protocol.TProtocol oprot, sendSupervisorWorkerHeartbeat_args struct) throws org.apache.storm.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.heartbeat != null) {
          oprot.writeFieldBegin(HEARTBEAT_FIELD_DESC);
          struct.heartbeat.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class sendSupervisorWorkerHeartbeat_argsTupleSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
      public sendSupervisorWorkerHeartbeat_argsTupleScheme getScheme() {
        return new sendSupervisorWorkerHeartbeat_argsTupleScheme();
      }
    }

    private static class sendSupervisorWorkerHeartbeat_argsTupleScheme extends org.apache.storm.thrift.scheme.TupleScheme<sendSupervisorWorkerHeartbeat_args> {

      @Override
      public void write(org.apache.storm.thrift.protocol.TProtocol prot, sendSupervisorWorkerHeartbeat_args struct) throws org.apache.storm.thrift.TException {
        org.apache.storm.thrift.protocol.TTupleProtocol oprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.is_set_heartbeat()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.is_set_heartbeat()) {
          struct.heartbeat.write(oprot);
        }
      }

      @Override
      public void read(org.apache.storm.thrift.protocol.TProtocol prot, sendSupervisorWorkerHeartbeat_args struct) throws org.apache.storm.thrift.TException {
        org.apache.storm.thrift.protocol.TTupleProtocol iprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.heartbeat = new SupervisorWorkerHeartbeat();
          struct.heartbeat.read(iprot);
          struct.set_heartbeat_isSet(true);
        }
      }
    }

    private static <S extends org.apache.storm.thrift.scheme.IScheme> S scheme(org.apache.storm.thrift.protocol.TProtocol proto) {
      return (org.apache.storm.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class sendSupervisorWorkerHeartbeat_result implements org.apache.storm.thrift.TBase<sendSupervisorWorkerHeartbeat_result, sendSupervisorWorkerHeartbeat_result._Fields>, java.io.Serializable, Cloneable, Comparable<sendSupervisorWorkerHeartbeat_result>   {
    private static final org.apache.storm.thrift.protocol.TStruct STRUCT_DESC = new org.apache.storm.thrift.protocol.TStruct("sendSupervisorWorkerHeartbeat_result");

    private static final org.apache.storm.thrift.protocol.TField AZE_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("aze", org.apache.storm.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.storm.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new sendSupervisorWorkerHeartbeat_resultStandardSchemeFactory();
    private static final org.apache.storm.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new sendSupervisorWorkerHeartbeat_resultTupleSchemeFactory();

    private @org.apache.storm.thrift.annotation.Nullable AuthorizationException aze; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.storm.thrift.TFieldIdEnum {
      AZE((short)1, "aze");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      @org.apache.storm.thrift.annotation.Nullable
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AZE
            return AZE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      @org.apache.storm.thrift.annotation.Nullable
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.AZE, new org.apache.storm.thrift.meta_data.FieldMetaData("aze", org.apache.storm.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, AuthorizationException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.storm.thrift.meta_data.FieldMetaData.addStructMetaDataMap(sendSupervisorWorkerHeartbeat_result.class, metaDataMap);
    }

    public sendSupervisorWorkerHeartbeat_result() {
    }

    public sendSupervisorWorkerHeartbeat_result(
      AuthorizationException aze)
    {
      this();
      this.aze = aze;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public sendSupervisorWorkerHeartbeat_result(sendSupervisorWorkerHeartbeat_result other) {
      if (other.is_set_aze()) {
        this.aze = new AuthorizationException(other.aze);
      }
    }

    public sendSupervisorWorkerHeartbeat_result deepCopy() {
      return new sendSupervisorWorkerHeartbeat_result(this);
    }

    @Override
    public void clear() {
      this.aze = null;
    }

    @org.apache.storm.thrift.annotation.Nullable
    public AuthorizationException get_aze() {
      return this.aze;
    }

    public void set_aze(@org.apache.storm.thrift.annotation.Nullable AuthorizationException aze) {
      this.aze = aze;
    }

    public void unset_aze() {
      this.aze = null;
    }

    /** Returns true if field aze is set (has been assigned a value) and false otherwise */
    public boolean is_set_aze() {
      return this.aze != null;
    }

    public void set_aze_isSet(boolean value) {
      if (!value) {
        this.aze = null;
      }
    }

    public void setFieldValue(_Fields field, @org.apache.storm.thrift.annotation.Nullable java.lang.Object value) {
      switch (field) {
      case AZE:
        if (value == null) {
          unset_aze();
        } else {
          set_aze((AuthorizationException)value);
        }
        break;

      }
    }

    @org.apache.storm.thrift.annotation.Nullable
    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case AZE:
        return get_aze();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case AZE:
        return is_set_aze();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof sendSupervisorWorkerHeartbeat_result)
        return this.equals((sendSupervisorWorkerHeartbeat_result)that);
      return false;
    }

    public boolean equals(sendSupervisorWorkerHeartbeat_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_aze = true && this.is_set_aze();
      boolean that_present_aze = true && that.is_set_aze();
      if (this_present_aze || that_present_aze) {
        if (!(this_present_aze && that_present_aze))
          return false;
        if (!this.aze.equals(that.aze))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((is_set_aze()) ? 131071 : 524287);
      if (is_set_aze())
        hashCode = hashCode * 8191 + aze.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(sendSupervisorWorkerHeartbeat_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(is_set_aze()).compareTo(other.is_set_aze());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (is_set_aze()) {
        lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.aze, other.aze);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    @org.apache.storm.thrift.annotation.Nullable
    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.storm.thrift.protocol.TProtocol iprot) throws org.apache.storm.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.storm.thrift.protocol.TProtocol oprot) throws org.apache.storm.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("sendSupervisorWorkerHeartbeat_result(");
      boolean first = true;

      sb.append("aze:");
      if (this.aze == null) {
        sb.append("null");
      } else {
        sb.append(this.aze);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.storm.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.storm.thrift.protocol.TCompactProtocol(new org.apache.storm.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.storm.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        read(new org.apache.storm.thrift.protocol.TCompactProtocol(new org.apache.storm.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.storm.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class sendSupervisorWorkerHeartbeat_resultStandardSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
      public sendSupervisorWorkerHeartbeat_resultStandardScheme getScheme() {
        return new sendSupervisorWorkerHeartbeat_resultStandardScheme();
      }
    }

    private static class sendSupervisorWorkerHeartbeat_resultStandardScheme extends org.apache.storm.thrift.scheme.StandardScheme<sendSupervisorWorkerHeartbeat_result> {

      public void read(org.apache.storm.thrift.protocol.TProtocol iprot, sendSupervisorWorkerHeartbeat_result struct) throws org.apache.storm.thrift.TException {
        org.apache.storm.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.storm.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // AZE
              if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRUCT) {
                struct.aze = new AuthorizationException();
                struct.aze.read(iprot);
                struct.set_aze_isSet(true);
              } else { 
                org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();
        struct.validate();
      }

      public void write(org.apache.storm.thrift.protocol.TProtocol oprot, sendSupervisorWorkerHeartbeat_result struct) throws org.apache.storm.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.aze != null) {
          oprot.writeFieldBegin(AZE_FIELD_DESC);
          struct.aze.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class sendSupervisorWorkerHeartbeat_resultTupleSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
      public sendSupervisorWorkerHeartbeat_resultTupleScheme getScheme() {
        return new sendSupervisorWorkerHeartbeat_resultTupleScheme();
      }
    }

    private static class sendSupervisorWorkerHeartbeat_resultTupleScheme extends org.apache.storm.thrift.scheme.TupleScheme<sendSupervisorWorkerHeartbeat_result> {

      @Override
      public void write(org.apache.storm.thrift.protocol.TProtocol prot, sendSupervisorWorkerHeartbeat_result struct) throws org.apache.storm.thrift.TException {
        org.apache.storm.thrift.protocol.TTupleProtocol oprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.is_set_aze()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.is_set_aze()) {
          struct.aze.write(oprot);
        }
      }

      @Override
      public void read(org.apache.storm.thrift.protocol.TProtocol prot, sendSupervisorWorkerHeartbeat_result struct) throws org.apache.storm.thrift.TException {
        org.apache.storm.thrift.protocol.TTupleProtocol iprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.aze = new AuthorizationException();
          struct.aze.read(iprot);
          struct.set_aze_isSet(true);
        }
      }
    }

    private static <S extends org.apache.storm.thrift.scheme.IScheme> S scheme(org.apache.storm.thrift.protocol.TProtocol proto) {
      return (org.apache.storm.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

}
