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

import org.apache.thrift.scheme.IScheme;
import org.apache.thrift.scheme.SchemeFactory;
import org.apache.thrift.scheme.StandardScheme;

import org.apache.thrift.scheme.TupleScheme;
import org.apache.thrift.protocol.TTupleProtocol;
import org.apache.thrift.protocol.TProtocolException;
import org.apache.thrift.EncodingUtils;
import org.apache.thrift.TException;
import org.apache.thrift.async.AsyncMethodCallback;
import org.apache.thrift.server.AbstractNonblockingServer.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.Set;
import java.util.HashSet;
import java.util.EnumSet;
import java.util.Collections;
import java.util.BitSet;
import java.nio.ByteBuffer;
import java.util.Arrays;
import javax.annotation.Generated;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
public class DistributedRPC {

  public interface Iface {

    public String execute(String functionName, String funcArgs) throws DRPCExecutionException, AuthorizationException, org.apache.thrift.TException;

  }

  public interface AsyncIface {

    public void execute(String functionName, String funcArgs, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

  }

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

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

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

    public String execute(String functionName, String funcArgs) throws DRPCExecutionException, AuthorizationException, org.apache.thrift.TException
    {
      send_execute(functionName, funcArgs);
      return recv_execute();
    }

    public void send_execute(String functionName, String funcArgs) throws org.apache.thrift.TException
    {
      execute_args args = new execute_args();
      args.set_functionName(functionName);
      args.set_funcArgs(funcArgs);
      sendBase("execute", args);
    }

    public String recv_execute() throws DRPCExecutionException, AuthorizationException, org.apache.thrift.TException
    {
      execute_result result = new execute_result();
      receiveBase(result, "execute");
      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.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "execute failed: unknown result");
    }

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

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

    public void execute(String functionName, String funcArgs, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      execute_call method_call = new execute_call(functionName, funcArgs, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class execute_call extends org.apache.thrift.async.TAsyncMethodCall {
      private String functionName;
      private String funcArgs;
      public execute_call(String functionName, String funcArgs, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.functionName = functionName;
        this.funcArgs = funcArgs;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("execute", org.apache.thrift.protocol.TMessageType.CALL, 0));
        execute_args args = new execute_args();
        args.set_functionName(functionName);
        args.set_funcArgs(funcArgs);
        args.write(prot);
        prot.writeMessageEnd();
      }

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

  }

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

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

    private static <I extends Iface> Map<String,  org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> getProcessMap(Map<String,  org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> processMap) {
      processMap.put("execute", new execute());
      return processMap;
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public execute_result getResult(I iface, execute_args args) throws org.apache.thrift.TException {
        execute_result result = new execute_result();
        try {
          result.success = iface.execute(args.functionName, args.funcArgs);
        } catch (DRPCExecutionException e) {
          result.e = e;
        } catch (AuthorizationException aze) {
          result.aze = aze;
        }
        return result;
      }
    }

  }

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

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

    private static <I extends AsyncIface> Map<String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase,?>> getProcessMap(Map<String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
      processMap.put("execute", new execute());
      return processMap;
    }

    public static class execute<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, execute_args, String> {
      public execute() {
        super("execute");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            execute_result result = new execute_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            execute_result result = new execute_result();
            if (e instanceof DRPCExecutionException) {
                        result.e = (DRPCExecutionException) 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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, execute_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.execute(args.functionName, args.funcArgs,resultHandler);
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField FUNCTION_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("functionName", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField FUNC_ARGS_FIELD_DESC = new org.apache.thrift.protocol.TField("funcArgs", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new execute_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new execute_argsTupleSchemeFactory());
    }

    private String functionName; // required
    private String funcArgs; // required

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

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // FUNCTION_NAME
            return FUNCTION_NAME;
          case 2: // FUNC_ARGS
            return FUNC_ARGS;
          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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

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

    public execute_args() {
    }

    public execute_args(
      String functionName,
      String funcArgs)
    {
      this();
      this.functionName = functionName;
      this.funcArgs = funcArgs;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public execute_args(execute_args other) {
      if (other.is_set_functionName()) {
        this.functionName = other.functionName;
      }
      if (other.is_set_funcArgs()) {
        this.funcArgs = other.funcArgs;
      }
    }

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

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

    public String get_functionName() {
      return this.functionName;
    }

    public void set_functionName(String functionName) {
      this.functionName = functionName;
    }

    public void unset_functionName() {
      this.functionName = null;
    }

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

    public void set_functionName_isSet(boolean value) {
      if (!value) {
        this.functionName = null;
      }
    }

    public String get_funcArgs() {
      return this.funcArgs;
    }

    public void set_funcArgs(String funcArgs) {
      this.funcArgs = funcArgs;
    }

    public void unset_funcArgs() {
      this.funcArgs = null;
    }

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

    public void set_funcArgs_isSet(boolean value) {
      if (!value) {
        this.funcArgs = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case FUNCTION_NAME:
        if (value == null) {
          unset_functionName();
        } else {
          set_functionName((String)value);
        }
        break;

      case FUNC_ARGS:
        if (value == null) {
          unset_funcArgs();
        } else {
          set_funcArgs((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case FUNCTION_NAME:
        return get_functionName();

      case FUNC_ARGS:
        return get_funcArgs();

      }
      throw new 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 IllegalArgumentException();
      }

      switch (field) {
      case FUNCTION_NAME:
        return is_set_functionName();
      case FUNC_ARGS:
        return is_set_funcArgs();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(execute_args that) {
      if (that == null)
        return false;

      boolean this_present_functionName = true && this.is_set_functionName();
      boolean that_present_functionName = true && that.is_set_functionName();
      if (this_present_functionName || that_present_functionName) {
        if (!(this_present_functionName && that_present_functionName))
          return false;
        if (!this.functionName.equals(that.functionName))
          return false;
      }

      boolean this_present_funcArgs = true && this.is_set_funcArgs();
      boolean that_present_funcArgs = true && that.is_set_funcArgs();
      if (this_present_funcArgs || that_present_funcArgs) {
        if (!(this_present_funcArgs && that_present_funcArgs))
          return false;
        if (!this.funcArgs.equals(that.funcArgs))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_functionName = true && (is_set_functionName());
      list.add(present_functionName);
      if (present_functionName)
        list.add(functionName);

      boolean present_funcArgs = true && (is_set_funcArgs());
      list.add(present_funcArgs);
      if (present_funcArgs)
        list.add(funcArgs);

      return list.hashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(is_set_functionName()).compareTo(other.is_set_functionName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (is_set_functionName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.functionName, other.functionName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(is_set_funcArgs()).compareTo(other.is_set_funcArgs());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (is_set_funcArgs()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.funcArgs, other.funcArgs);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("execute_args(");
      boolean first = true;

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

    public void validate() throws org.apache.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.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

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

    private static class execute_argsStandardSchemeFactory implements SchemeFactory {
      public execute_argsStandardScheme getScheme() {
        return new execute_argsStandardScheme();
      }
    }

    private static class execute_argsStandardScheme extends StandardScheme<execute_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, execute_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // FUNCTION_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.functionName = iprot.readString();
                struct.set_functionName_isSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // FUNC_ARGS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.funcArgs = iprot.readString();
                struct.set_funcArgs_isSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.functionName != null) {
          oprot.writeFieldBegin(FUNCTION_NAME_FIELD_DESC);
          oprot.writeString(struct.functionName);
          oprot.writeFieldEnd();
        }
        if (struct.funcArgs != null) {
          oprot.writeFieldBegin(FUNC_ARGS_FIELD_DESC);
          oprot.writeString(struct.funcArgs);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class execute_argsTupleSchemeFactory implements SchemeFactory {
      public execute_argsTupleScheme getScheme() {
        return new execute_argsTupleScheme();
      }
    }

    private static class execute_argsTupleScheme extends TupleScheme<execute_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, execute_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.is_set_functionName()) {
          optionals.set(0);
        }
        if (struct.is_set_funcArgs()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.is_set_functionName()) {
          oprot.writeString(struct.functionName);
        }
        if (struct.is_set_funcArgs()) {
          oprot.writeString(struct.funcArgs);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, execute_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.functionName = iprot.readString();
          struct.set_functionName_isSet(true);
        }
        if (incoming.get(1)) {
          struct.funcArgs = iprot.readString();
          struct.set_funcArgs_isSet(true);
        }
      }
    }

  }

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

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

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new execute_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new execute_resultTupleSchemeFactory());
    }

    private String success; // required
    private DRPCExecutionException e; // required
    private 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.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      E((short)1, "e"),
      AZE((short)2, "aze");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

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

    public execute_result() {
    }

    public execute_result(
      String success,
      DRPCExecutionException e,
      AuthorizationException aze)
    {
      this();
      this.success = success;
      this.e = e;
      this.aze = aze;
    }

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

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

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

    public String get_success() {
      return this.success;
    }

    public void set_success(String 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;
      }
    }

    public DRPCExecutionException get_e() {
      return this.e;
    }

    public void set_e(DRPCExecutionException 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;
      }
    }

    public AuthorizationException get_aze() {
      return this.aze;
    }

    public void set_aze(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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unset_success();
        } else {
          set_success((String)value);
        }
        break;

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

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

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return get_success();

      case E:
        return get_e();

      case AZE:
        return get_aze();

      }
      throw new 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 IllegalArgumentException();
      }

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

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

    public boolean equals(execute_result that) {
      if (that == null)
        return false;

      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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (is_set_success());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_e = true && (is_set_e());
      list.add(present_e);
      if (present_e)
        list.add(e);

      boolean present_aze = true && (is_set_aze());
      list.add(present_aze);
      if (present_aze)
        list.add(aze);

      return list.hashCode();
    }

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

      int lastComparison = 0;

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

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("execute_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.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.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

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

    private static class execute_resultStandardSchemeFactory implements SchemeFactory {
      public execute_resultStandardScheme getScheme() {
        return new execute_resultStandardScheme();
      }
    }

    private static class execute_resultStandardScheme extends StandardScheme<execute_result> {

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

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          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 execute_resultTupleSchemeFactory implements SchemeFactory {
      public execute_resultTupleScheme getScheme() {
        return new execute_resultTupleScheme();
      }
    }

    private static class execute_resultTupleScheme extends TupleScheme<execute_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, execute_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new 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()) {
          oprot.writeString(struct.success);
        }
        if (struct.is_set_e()) {
          struct.e.write(oprot);
        }
        if (struct.is_set_aze()) {
          struct.aze.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, execute_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.set_success_isSet(true);
        }
        if (incoming.get(1)) {
          struct.e = new DRPCExecutionException();
          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);
        }
      }
    }

  }

}
