/**
 * Autogenerated by Thrift
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 */
package com.facebook.fb303;

import java.util.ArrayList;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.HashSet;
import com.facebook.thrift.*;

import com.facebook.thrift.protocol.*;
import com.facebook.thrift.transport.*;

public class FacebookService {

  public interface Iface {
    public String getName() throws TException;
    public String getVersion() throws TException;
    public int getStatus() throws TException;
    public String getStatusDetails() throws TException;
    public AbstractMap<String,Long> getCounters() throws TException;
    public long getCounter(String key) throws TException;
    public void setOption(String key, String value) throws TException;
    public String getOption(String key) throws TException;
    public AbstractMap<String,String> getOptions() throws TException;
    public long aliveSince() throws TException;
    public com.facebook.thrift.reflection.limited.Service getLimitedReflection() throws TException;
    public void reinitialize() throws TException;
    public void shutdown() throws TException;
  }

  public static class Client implements Iface {
    public Client(TProtocol prot)
    {
      this(prot, prot);
    }

    public Client(TProtocol iprot, TProtocol oprot)
    {
      iprot_ = iprot;
      oprot_ = oprot;
    }

    protected TProtocol iprot_;
    protected TProtocol oprot_;

    protected int seqid_;

    public String getName() throws TException
    {
      send_getName();
      return recv_getName();
    }

    public void send_getName() throws TException
    {
      oprot_.writeMessageBegin(new TMessage("getName", TMessageType.CALL, seqid_));
      getName_args args = new getName_args();
      args.write(oprot_);
      oprot_.writeMessageEnd();
      oprot_.getTransport().flush();
    }

    public String recv_getName() throws TException
    {
      TMessage msg = iprot_.readMessageBegin();
      if (msg.type == TMessageType.EXCEPTION) {
        TApplicationException x = TApplicationException.read(iprot_);
        iprot_.readMessageEnd();
        throw x;
      }
      getName_result result = new getName_result();
      result.read(iprot_);
      iprot_.readMessageEnd();
      if (result.__isset.success) {
        return result.success;
      }
      throw new TApplicationException(TApplicationException.MISSING_RESULT, "getName failed: unknown result");
    }

    public String getVersion() throws TException
    {
      send_getVersion();
      return recv_getVersion();
    }

    public void send_getVersion() throws TException
    {
      oprot_.writeMessageBegin(new TMessage("getVersion", TMessageType.CALL, seqid_));
      getVersion_args args = new getVersion_args();
      args.write(oprot_);
      oprot_.writeMessageEnd();
      oprot_.getTransport().flush();
    }

    public String recv_getVersion() throws TException
    {
      TMessage msg = iprot_.readMessageBegin();
      if (msg.type == TMessageType.EXCEPTION) {
        TApplicationException x = TApplicationException.read(iprot_);
        iprot_.readMessageEnd();
        throw x;
      }
      getVersion_result result = new getVersion_result();
      result.read(iprot_);
      iprot_.readMessageEnd();
      if (result.__isset.success) {
        return result.success;
      }
      throw new TApplicationException(TApplicationException.MISSING_RESULT, "getVersion failed: unknown result");
    }

    public int getStatus() throws TException
    {
      send_getStatus();
      return recv_getStatus();
    }

    public void send_getStatus() throws TException
    {
      oprot_.writeMessageBegin(new TMessage("getStatus", TMessageType.CALL, seqid_));
      getStatus_args args = new getStatus_args();
      args.write(oprot_);
      oprot_.writeMessageEnd();
      oprot_.getTransport().flush();
    }

    public int recv_getStatus() throws TException
    {
      TMessage msg = iprot_.readMessageBegin();
      if (msg.type == TMessageType.EXCEPTION) {
        TApplicationException x = TApplicationException.read(iprot_);
        iprot_.readMessageEnd();
        throw x;
      }
      getStatus_result result = new getStatus_result();
      result.read(iprot_);
      iprot_.readMessageEnd();
      if (result.__isset.success) {
        return result.success;
      }
      throw new TApplicationException(TApplicationException.MISSING_RESULT, "getStatus failed: unknown result");
    }

    public String getStatusDetails() throws TException
    {
      send_getStatusDetails();
      return recv_getStatusDetails();
    }

    public void send_getStatusDetails() throws TException
    {
      oprot_.writeMessageBegin(new TMessage("getStatusDetails", TMessageType.CALL, seqid_));
      getStatusDetails_args args = new getStatusDetails_args();
      args.write(oprot_);
      oprot_.writeMessageEnd();
      oprot_.getTransport().flush();
    }

    public String recv_getStatusDetails() throws TException
    {
      TMessage msg = iprot_.readMessageBegin();
      if (msg.type == TMessageType.EXCEPTION) {
        TApplicationException x = TApplicationException.read(iprot_);
        iprot_.readMessageEnd();
        throw x;
      }
      getStatusDetails_result result = new getStatusDetails_result();
      result.read(iprot_);
      iprot_.readMessageEnd();
      if (result.__isset.success) {
        return result.success;
      }
      throw new TApplicationException(TApplicationException.MISSING_RESULT, "getStatusDetails failed: unknown result");
    }

    public AbstractMap<String,Long> getCounters() throws TException
    {
      send_getCounters();
      return recv_getCounters();
    }

    public void send_getCounters() throws TException
    {
      oprot_.writeMessageBegin(new TMessage("getCounters", TMessageType.CALL, seqid_));
      getCounters_args args = new getCounters_args();
      args.write(oprot_);
      oprot_.writeMessageEnd();
      oprot_.getTransport().flush();
    }

    public AbstractMap<String,Long> recv_getCounters() throws TException
    {
      TMessage msg = iprot_.readMessageBegin();
      if (msg.type == TMessageType.EXCEPTION) {
        TApplicationException x = TApplicationException.read(iprot_);
        iprot_.readMessageEnd();
        throw x;
      }
      getCounters_result result = new getCounters_result();
      result.read(iprot_);
      iprot_.readMessageEnd();
      if (result.__isset.success) {
        return result.success;
      }
      throw new TApplicationException(TApplicationException.MISSING_RESULT, "getCounters failed: unknown result");
    }

    public long getCounter(String key) throws TException
    {
      send_getCounter(key);
      return recv_getCounter();
    }

    public void send_getCounter(String key) throws TException
    {
      oprot_.writeMessageBegin(new TMessage("getCounter", TMessageType.CALL, seqid_));
      getCounter_args args = new getCounter_args();
      args.key = key;
      args.write(oprot_);
      oprot_.writeMessageEnd();
      oprot_.getTransport().flush();
    }

    public long recv_getCounter() throws TException
    {
      TMessage msg = iprot_.readMessageBegin();
      if (msg.type == TMessageType.EXCEPTION) {
        TApplicationException x = TApplicationException.read(iprot_);
        iprot_.readMessageEnd();
        throw x;
      }
      getCounter_result result = new getCounter_result();
      result.read(iprot_);
      iprot_.readMessageEnd();
      if (result.__isset.success) {
        return result.success;
      }
      throw new TApplicationException(TApplicationException.MISSING_RESULT, "getCounter failed: unknown result");
    }

    public void setOption(String key, String value) throws TException
    {
      send_setOption(key, value);
      recv_setOption();
    }

    public void send_setOption(String key, String value) throws TException
    {
      oprot_.writeMessageBegin(new TMessage("setOption", TMessageType.CALL, seqid_));
      setOption_args args = new setOption_args();
      args.key = key;
      args.value = value;
      args.write(oprot_);
      oprot_.writeMessageEnd();
      oprot_.getTransport().flush();
    }

    public void recv_setOption() throws TException
    {
      TMessage msg = iprot_.readMessageBegin();
      if (msg.type == TMessageType.EXCEPTION) {
        TApplicationException x = TApplicationException.read(iprot_);
        iprot_.readMessageEnd();
        throw x;
      }
      setOption_result result = new setOption_result();
      result.read(iprot_);
      iprot_.readMessageEnd();
      return;
    }

    public String getOption(String key) throws TException
    {
      send_getOption(key);
      return recv_getOption();
    }

    public void send_getOption(String key) throws TException
    {
      oprot_.writeMessageBegin(new TMessage("getOption", TMessageType.CALL, seqid_));
      getOption_args args = new getOption_args();
      args.key = key;
      args.write(oprot_);
      oprot_.writeMessageEnd();
      oprot_.getTransport().flush();
    }

    public String recv_getOption() throws TException
    {
      TMessage msg = iprot_.readMessageBegin();
      if (msg.type == TMessageType.EXCEPTION) {
        TApplicationException x = TApplicationException.read(iprot_);
        iprot_.readMessageEnd();
        throw x;
      }
      getOption_result result = new getOption_result();
      result.read(iprot_);
      iprot_.readMessageEnd();
      if (result.__isset.success) {
        return result.success;
      }
      throw new TApplicationException(TApplicationException.MISSING_RESULT, "getOption failed: unknown result");
    }

    public AbstractMap<String,String> getOptions() throws TException
    {
      send_getOptions();
      return recv_getOptions();
    }

    public void send_getOptions() throws TException
    {
      oprot_.writeMessageBegin(new TMessage("getOptions", TMessageType.CALL, seqid_));
      getOptions_args args = new getOptions_args();
      args.write(oprot_);
      oprot_.writeMessageEnd();
      oprot_.getTransport().flush();
    }

    public AbstractMap<String,String> recv_getOptions() throws TException
    {
      TMessage msg = iprot_.readMessageBegin();
      if (msg.type == TMessageType.EXCEPTION) {
        TApplicationException x = TApplicationException.read(iprot_);
        iprot_.readMessageEnd();
        throw x;
      }
      getOptions_result result = new getOptions_result();
      result.read(iprot_);
      iprot_.readMessageEnd();
      if (result.__isset.success) {
        return result.success;
      }
      throw new TApplicationException(TApplicationException.MISSING_RESULT, "getOptions failed: unknown result");
    }

    public long aliveSince() throws TException
    {
      send_aliveSince();
      return recv_aliveSince();
    }

    public void send_aliveSince() throws TException
    {
      oprot_.writeMessageBegin(new TMessage("aliveSince", TMessageType.CALL, seqid_));
      aliveSince_args args = new aliveSince_args();
      args.write(oprot_);
      oprot_.writeMessageEnd();
      oprot_.getTransport().flush();
    }

    public long recv_aliveSince() throws TException
    {
      TMessage msg = iprot_.readMessageBegin();
      if (msg.type == TMessageType.EXCEPTION) {
        TApplicationException x = TApplicationException.read(iprot_);
        iprot_.readMessageEnd();
        throw x;
      }
      aliveSince_result result = new aliveSince_result();
      result.read(iprot_);
      iprot_.readMessageEnd();
      if (result.__isset.success) {
        return result.success;
      }
      throw new TApplicationException(TApplicationException.MISSING_RESULT, "aliveSince failed: unknown result");
    }

    public com.facebook.thrift.reflection.limited.Service getLimitedReflection() throws TException
    {
      send_getLimitedReflection();
      return recv_getLimitedReflection();
    }

    public void send_getLimitedReflection() throws TException
    {
      oprot_.writeMessageBegin(new TMessage("getLimitedReflection", TMessageType.CALL, seqid_));
      getLimitedReflection_args args = new getLimitedReflection_args();
      args.write(oprot_);
      oprot_.writeMessageEnd();
      oprot_.getTransport().flush();
    }

    public com.facebook.thrift.reflection.limited.Service recv_getLimitedReflection() throws TException
    {
      TMessage msg = iprot_.readMessageBegin();
      if (msg.type == TMessageType.EXCEPTION) {
        TApplicationException x = TApplicationException.read(iprot_);
        iprot_.readMessageEnd();
        throw x;
      }
      getLimitedReflection_result result = new getLimitedReflection_result();
      result.read(iprot_);
      iprot_.readMessageEnd();
      if (result.__isset.success) {
        return result.success;
      }
      throw new TApplicationException(TApplicationException.MISSING_RESULT, "getLimitedReflection failed: unknown result");
    }

    public void reinitialize() throws TException
    {
      send_reinitialize();
    }

    public void send_reinitialize() throws TException
    {
      oprot_.writeMessageBegin(new TMessage("reinitialize", TMessageType.CALL, seqid_));
      reinitialize_args args = new reinitialize_args();
      args.write(oprot_);
      oprot_.writeMessageEnd();
      oprot_.getTransport().flush();
    }

    public void shutdown() throws TException
    {
      send_shutdown();
    }

    public void send_shutdown() throws TException
    {
      oprot_.writeMessageBegin(new TMessage("shutdown", TMessageType.CALL, seqid_));
      shutdown_args args = new shutdown_args();
      args.write(oprot_);
      oprot_.writeMessageEnd();
      oprot_.getTransport().flush();
    }

  }
  public static class Processor implements TProcessor {
    public Processor(Iface iface)
    {
      iface_ = iface;
      processMap_.put("getName", new getName());
      processMap_.put("getVersion", new getVersion());
      processMap_.put("getStatus", new getStatus());
      processMap_.put("getStatusDetails", new getStatusDetails());
      processMap_.put("getCounters", new getCounters());
      processMap_.put("getCounter", new getCounter());
      processMap_.put("setOption", new setOption());
      processMap_.put("getOption", new getOption());
      processMap_.put("getOptions", new getOptions());
      processMap_.put("aliveSince", new aliveSince());
      processMap_.put("getLimitedReflection", new getLimitedReflection());
      processMap_.put("reinitialize", new reinitialize());
      processMap_.put("shutdown", new shutdown());
    }

    protected static interface ProcessFunction {
      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException;
    }

    private Iface iface_;
    protected final HashMap<String,ProcessFunction> processMap_ = new HashMap<String,ProcessFunction>();

    public boolean process(TProtocol iprot, TProtocol oprot) throws TException
    {
      TMessage msg = iprot.readMessageBegin();
      ProcessFunction fn = processMap_.get(msg.name);
      if (fn == null) {
        TProtocolUtil.skip(iprot, TType.STRUCT);
        iprot.readMessageEnd();
        TApplicationException x = new TApplicationException(TApplicationException.UNKNOWN_METHOD, "Invalid method name: '"+msg.name+"'");
        oprot.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));
        x.write(oprot);
        oprot.writeMessageEnd();
        oprot.getTransport().flush();
        return true;
      }
      fn.process(msg.seqid, iprot, oprot);
      return true;
    }

    private class getName implements ProcessFunction {
      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
      {
        getName_args args = new getName_args();
        args.read(iprot);
        iprot.readMessageEnd();
        getName_result result = new getName_result();
        result.success = iface_.getName();
        result.__isset.success = true;
        oprot.writeMessageBegin(new TMessage("getName", TMessageType.REPLY, seqid));
        result.write(oprot);
        oprot.writeMessageEnd();
        oprot.getTransport().flush();
      }

    }

    private class getVersion implements ProcessFunction {
      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
      {
        getVersion_args args = new getVersion_args();
        args.read(iprot);
        iprot.readMessageEnd();
        getVersion_result result = new getVersion_result();
        result.success = iface_.getVersion();
        result.__isset.success = true;
        oprot.writeMessageBegin(new TMessage("getVersion", TMessageType.REPLY, seqid));
        result.write(oprot);
        oprot.writeMessageEnd();
        oprot.getTransport().flush();
      }

    }

    private class getStatus implements ProcessFunction {
      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
      {
        getStatus_args args = new getStatus_args();
        args.read(iprot);
        iprot.readMessageEnd();
        getStatus_result result = new getStatus_result();
        result.success = iface_.getStatus();
        result.__isset.success = true;
        oprot.writeMessageBegin(new TMessage("getStatus", TMessageType.REPLY, seqid));
        result.write(oprot);
        oprot.writeMessageEnd();
        oprot.getTransport().flush();
      }

    }

    private class getStatusDetails implements ProcessFunction {
      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
      {
        getStatusDetails_args args = new getStatusDetails_args();
        args.read(iprot);
        iprot.readMessageEnd();
        getStatusDetails_result result = new getStatusDetails_result();
        result.success = iface_.getStatusDetails();
        result.__isset.success = true;
        oprot.writeMessageBegin(new TMessage("getStatusDetails", TMessageType.REPLY, seqid));
        result.write(oprot);
        oprot.writeMessageEnd();
        oprot.getTransport().flush();
      }

    }

    private class getCounters implements ProcessFunction {
      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
      {
        getCounters_args args = new getCounters_args();
        args.read(iprot);
        iprot.readMessageEnd();
        getCounters_result result = new getCounters_result();
        result.success = iface_.getCounters();
        result.__isset.success = true;
        oprot.writeMessageBegin(new TMessage("getCounters", TMessageType.REPLY, seqid));
        result.write(oprot);
        oprot.writeMessageEnd();
        oprot.getTransport().flush();
      }

    }

    private class getCounter implements ProcessFunction {
      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
      {
        getCounter_args args = new getCounter_args();
        args.read(iprot);
        iprot.readMessageEnd();
        getCounter_result result = new getCounter_result();
        result.success = iface_.getCounter(args.key);
        result.__isset.success = true;
        oprot.writeMessageBegin(new TMessage("getCounter", TMessageType.REPLY, seqid));
        result.write(oprot);
        oprot.writeMessageEnd();
        oprot.getTransport().flush();
      }

    }

    private class setOption implements ProcessFunction {
      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
      {
        setOption_args args = new setOption_args();
        args.read(iprot);
        iprot.readMessageEnd();
        setOption_result result = new setOption_result();
        iface_.setOption(args.key, args.value);
        oprot.writeMessageBegin(new TMessage("setOption", TMessageType.REPLY, seqid));
        result.write(oprot);
        oprot.writeMessageEnd();
        oprot.getTransport().flush();
      }

    }

    private class getOption implements ProcessFunction {
      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
      {
        getOption_args args = new getOption_args();
        args.read(iprot);
        iprot.readMessageEnd();
        getOption_result result = new getOption_result();
        result.success = iface_.getOption(args.key);
        result.__isset.success = true;
        oprot.writeMessageBegin(new TMessage("getOption", TMessageType.REPLY, seqid));
        result.write(oprot);
        oprot.writeMessageEnd();
        oprot.getTransport().flush();
      }

    }

    private class getOptions implements ProcessFunction {
      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
      {
        getOptions_args args = new getOptions_args();
        args.read(iprot);
        iprot.readMessageEnd();
        getOptions_result result = new getOptions_result();
        result.success = iface_.getOptions();
        result.__isset.success = true;
        oprot.writeMessageBegin(new TMessage("getOptions", TMessageType.REPLY, seqid));
        result.write(oprot);
        oprot.writeMessageEnd();
        oprot.getTransport().flush();
      }

    }

    private class aliveSince implements ProcessFunction {
      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
      {
        aliveSince_args args = new aliveSince_args();
        args.read(iprot);
        iprot.readMessageEnd();
        aliveSince_result result = new aliveSince_result();
        result.success = iface_.aliveSince();
        result.__isset.success = true;
        oprot.writeMessageBegin(new TMessage("aliveSince", TMessageType.REPLY, seqid));
        result.write(oprot);
        oprot.writeMessageEnd();
        oprot.getTransport().flush();
      }

    }

    private class getLimitedReflection implements ProcessFunction {
      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
      {
        getLimitedReflection_args args = new getLimitedReflection_args();
        args.read(iprot);
        iprot.readMessageEnd();
        getLimitedReflection_result result = new getLimitedReflection_result();
        result.success = iface_.getLimitedReflection();
        result.__isset.success = true;
        oprot.writeMessageBegin(new TMessage("getLimitedReflection", TMessageType.REPLY, seqid));
        result.write(oprot);
        oprot.writeMessageEnd();
        oprot.getTransport().flush();
      }

    }

    private class reinitialize implements ProcessFunction {
      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
      {
        reinitialize_args args = new reinitialize_args();
        args.read(iprot);
        iprot.readMessageEnd();
        iface_.reinitialize();
        return;
      }
    }

    private class shutdown implements ProcessFunction {
      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
      {
        shutdown_args args = new shutdown_args();
        args.read(iprot);
        iprot.readMessageEnd();
        iface_.shutdown();
        return;
      }
    }

  }

  public static class getName_args   {
    public getName_args() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("getName_args");
      TField field = new TField();
      oprot.writeStructBegin(struct);
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("getName_args(");
      sb.append(")");
      return sb.toString();
    }

  }

  public static class getName_result   {
    public String success;

    public final Isset __isset = new Isset();
    public final class Isset {
      public boolean success = false;
    }

    public getName_result() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          case 0:
            if (field.type == TType.STRING) {
              this.success = iprot.readString();
              this.__isset.success = true;
            } else { 
              TProtocolUtil.skip(iprot, field.type);
            }
            break;
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("getName_result");
      TField field = new TField();
      oprot.writeStructBegin(struct);

      if (this.__isset.success) {
        if (this.success != null) {
          field.name = "success";
          field.type = TType.STRING;
          field.id = 0;
          oprot.writeFieldBegin(field);
          oprot.writeString(this.success);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("getName_result(");
      sb.append("success:");
      sb.append(this.success);
      sb.append(")");
      return sb.toString();
    }

  }

  public static class getVersion_args   {
    public getVersion_args() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("getVersion_args");
      TField field = new TField();
      oprot.writeStructBegin(struct);
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("getVersion_args(");
      sb.append(")");
      return sb.toString();
    }

  }

  public static class getVersion_result   {
    public String success;

    public final Isset __isset = new Isset();
    public final class Isset {
      public boolean success = false;
    }

    public getVersion_result() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          case 0:
            if (field.type == TType.STRING) {
              this.success = iprot.readString();
              this.__isset.success = true;
            } else { 
              TProtocolUtil.skip(iprot, field.type);
            }
            break;
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("getVersion_result");
      TField field = new TField();
      oprot.writeStructBegin(struct);

      if (this.__isset.success) {
        if (this.success != null) {
          field.name = "success";
          field.type = TType.STRING;
          field.id = 0;
          oprot.writeFieldBegin(field);
          oprot.writeString(this.success);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("getVersion_result(");
      sb.append("success:");
      sb.append(this.success);
      sb.append(")");
      return sb.toString();
    }

  }

  public static class getStatus_args   {
    public getStatus_args() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("getStatus_args");
      TField field = new TField();
      oprot.writeStructBegin(struct);
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("getStatus_args(");
      sb.append(")");
      return sb.toString();
    }

  }

  public static class getStatus_result   {
    public int success;

    public final Isset __isset = new Isset();
    public final class Isset {
      public boolean success = false;
    }

    public getStatus_result() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          case 0:
            if (field.type == TType.I32) {
              this.success = iprot.readI32();
              this.__isset.success = true;
            } else { 
              TProtocolUtil.skip(iprot, field.type);
            }
            break;
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("getStatus_result");
      TField field = new TField();
      oprot.writeStructBegin(struct);

      if (this.__isset.success) {
        field.name = "success";
        field.type = TType.I32;
        field.id = 0;
        oprot.writeFieldBegin(field);
        oprot.writeI32(this.success);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("getStatus_result(");
      sb.append("success:");
      sb.append(this.success);
      sb.append(")");
      return sb.toString();
    }

  }

  public static class getStatusDetails_args   {
    public getStatusDetails_args() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("getStatusDetails_args");
      TField field = new TField();
      oprot.writeStructBegin(struct);
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("getStatusDetails_args(");
      sb.append(")");
      return sb.toString();
    }

  }

  public static class getStatusDetails_result   {
    public String success;

    public final Isset __isset = new Isset();
    public final class Isset {
      public boolean success = false;
    }

    public getStatusDetails_result() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          case 0:
            if (field.type == TType.STRING) {
              this.success = iprot.readString();
              this.__isset.success = true;
            } else { 
              TProtocolUtil.skip(iprot, field.type);
            }
            break;
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("getStatusDetails_result");
      TField field = new TField();
      oprot.writeStructBegin(struct);

      if (this.__isset.success) {
        if (this.success != null) {
          field.name = "success";
          field.type = TType.STRING;
          field.id = 0;
          oprot.writeFieldBegin(field);
          oprot.writeString(this.success);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("getStatusDetails_result(");
      sb.append("success:");
      sb.append(this.success);
      sb.append(")");
      return sb.toString();
    }

  }

  public static class getCounters_args   {
    public getCounters_args() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("getCounters_args");
      TField field = new TField();
      oprot.writeStructBegin(struct);
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("getCounters_args(");
      sb.append(")");
      return sb.toString();
    }

  }

  public static class getCounters_result   {
    public AbstractMap<String,Long> success;

    public final Isset __isset = new Isset();
    public final class Isset {
      public boolean success = false;
    }

    public getCounters_result() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          case 0:
            if (field.type == TType.MAP) {
              {
                TMap _map0 = iprot.readMapBegin();
                this.success = new HashMap<String,Long>(2*_map0.size);
                for (int _i1 = 0; _i1 < _map0.size; ++_i1)
                {
                  String _key2;
                  long _val3;
                  _key2 = iprot.readString();
                  _val3 = iprot.readI64();
                  this.success.put(_key2, _val3);
                }
                iprot.readMapEnd();
              }
              this.__isset.success = true;
            } else { 
              TProtocolUtil.skip(iprot, field.type);
            }
            break;
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("getCounters_result");
      TField field = new TField();
      oprot.writeStructBegin(struct);

      if (this.__isset.success) {
        if (this.success != null) {
          field.name = "success";
          field.type = TType.MAP;
          field.id = 0;
          oprot.writeFieldBegin(field);
          {
            oprot.writeMapBegin(new TMap(TType.STRING, TType.I64, this.success.size()));
            for (String _iter4 : this.success.keySet())            {
              oprot.writeString(_iter4);
              oprot.writeI64(this.success.get(_iter4));
              oprot.writeMapEnd();
            }
          }
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("getCounters_result(");
      sb.append("success:");
      sb.append(this.success);
      sb.append(")");
      return sb.toString();
    }

  }

  public static class getCounter_args   {
    public String key;

    public final Isset __isset = new Isset();
    public final class Isset {
      public boolean key = false;
    }

    public getCounter_args() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          case 1:
            if (field.type == TType.STRING) {
              this.key = iprot.readString();
              this.__isset.key = true;
            } else { 
              TProtocolUtil.skip(iprot, field.type);
            }
            break;
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("getCounter_args");
      TField field = new TField();
      oprot.writeStructBegin(struct);
      if (this.key != null) {
        field.name = "key";
        field.type = TType.STRING;
        field.id = 1;
        oprot.writeFieldBegin(field);
        oprot.writeString(this.key);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("getCounter_args(");
      sb.append("key:");
      sb.append(this.key);
      sb.append(")");
      return sb.toString();
    }

  }

  public static class getCounter_result   {
    public long success;

    public final Isset __isset = new Isset();
    public final class Isset {
      public boolean success = false;
    }

    public getCounter_result() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          case 0:
            if (field.type == TType.I64) {
              this.success = iprot.readI64();
              this.__isset.success = true;
            } else { 
              TProtocolUtil.skip(iprot, field.type);
            }
            break;
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("getCounter_result");
      TField field = new TField();
      oprot.writeStructBegin(struct);

      if (this.__isset.success) {
        field.name = "success";
        field.type = TType.I64;
        field.id = 0;
        oprot.writeFieldBegin(field);
        oprot.writeI64(this.success);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("getCounter_result(");
      sb.append("success:");
      sb.append(this.success);
      sb.append(")");
      return sb.toString();
    }

  }

  public static class setOption_args   {
    public String key;
    public String value;

    public final Isset __isset = new Isset();
    public final class Isset {
      public boolean key = false;
      public boolean value = false;
    }

    public setOption_args() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          case 1:
            if (field.type == TType.STRING) {
              this.key = iprot.readString();
              this.__isset.key = true;
            } else { 
              TProtocolUtil.skip(iprot, field.type);
            }
            break;
          case 2:
            if (field.type == TType.STRING) {
              this.value = iprot.readString();
              this.__isset.value = true;
            } else { 
              TProtocolUtil.skip(iprot, field.type);
            }
            break;
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("setOption_args");
      TField field = new TField();
      oprot.writeStructBegin(struct);
      if (this.key != null) {
        field.name = "key";
        field.type = TType.STRING;
        field.id = 1;
        oprot.writeFieldBegin(field);
        oprot.writeString(this.key);
        oprot.writeFieldEnd();
      }
      if (this.value != null) {
        field.name = "value";
        field.type = TType.STRING;
        field.id = 2;
        oprot.writeFieldBegin(field);
        oprot.writeString(this.value);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("setOption_args(");
      sb.append("key:");
      sb.append(this.key);
      sb.append(",value:");
      sb.append(this.value);
      sb.append(")");
      return sb.toString();
    }

  }

  public static class setOption_result   {
    public setOption_result() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("setOption_result");
      TField field = new TField();
      oprot.writeStructBegin(struct);

      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("setOption_result(");
      sb.append(")");
      return sb.toString();
    }

  }

  public static class getOption_args   {
    public String key;

    public final Isset __isset = new Isset();
    public final class Isset {
      public boolean key = false;
    }

    public getOption_args() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          case 1:
            if (field.type == TType.STRING) {
              this.key = iprot.readString();
              this.__isset.key = true;
            } else { 
              TProtocolUtil.skip(iprot, field.type);
            }
            break;
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("getOption_args");
      TField field = new TField();
      oprot.writeStructBegin(struct);
      if (this.key != null) {
        field.name = "key";
        field.type = TType.STRING;
        field.id = 1;
        oprot.writeFieldBegin(field);
        oprot.writeString(this.key);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("getOption_args(");
      sb.append("key:");
      sb.append(this.key);
      sb.append(")");
      return sb.toString();
    }

  }

  public static class getOption_result   {
    public String success;

    public final Isset __isset = new Isset();
    public final class Isset {
      public boolean success = false;
    }

    public getOption_result() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          case 0:
            if (field.type == TType.STRING) {
              this.success = iprot.readString();
              this.__isset.success = true;
            } else { 
              TProtocolUtil.skip(iprot, field.type);
            }
            break;
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("getOption_result");
      TField field = new TField();
      oprot.writeStructBegin(struct);

      if (this.__isset.success) {
        if (this.success != null) {
          field.name = "success";
          field.type = TType.STRING;
          field.id = 0;
          oprot.writeFieldBegin(field);
          oprot.writeString(this.success);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("getOption_result(");
      sb.append("success:");
      sb.append(this.success);
      sb.append(")");
      return sb.toString();
    }

  }

  public static class getOptions_args   {
    public getOptions_args() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("getOptions_args");
      TField field = new TField();
      oprot.writeStructBegin(struct);
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("getOptions_args(");
      sb.append(")");
      return sb.toString();
    }

  }

  public static class getOptions_result   {
    public AbstractMap<String,String> success;

    public final Isset __isset = new Isset();
    public final class Isset {
      public boolean success = false;
    }

    public getOptions_result() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          case 0:
            if (field.type == TType.MAP) {
              {
                TMap _map5 = iprot.readMapBegin();
                this.success = new HashMap<String,String>(2*_map5.size);
                for (int _i6 = 0; _i6 < _map5.size; ++_i6)
                {
                  String _key7;
                  String _val8;
                  _key7 = iprot.readString();
                  _val8 = iprot.readString();
                  this.success.put(_key7, _val8);
                }
                iprot.readMapEnd();
              }
              this.__isset.success = true;
            } else { 
              TProtocolUtil.skip(iprot, field.type);
            }
            break;
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("getOptions_result");
      TField field = new TField();
      oprot.writeStructBegin(struct);

      if (this.__isset.success) {
        if (this.success != null) {
          field.name = "success";
          field.type = TType.MAP;
          field.id = 0;
          oprot.writeFieldBegin(field);
          {
            oprot.writeMapBegin(new TMap(TType.STRING, TType.STRING, this.success.size()));
            for (String _iter9 : this.success.keySet())            {
              oprot.writeString(_iter9);
              oprot.writeString(this.success.get(_iter9));
              oprot.writeMapEnd();
            }
          }
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("getOptions_result(");
      sb.append("success:");
      sb.append(this.success);
      sb.append(")");
      return sb.toString();
    }

  }

  public static class aliveSince_args   {
    public aliveSince_args() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("aliveSince_args");
      TField field = new TField();
      oprot.writeStructBegin(struct);
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("aliveSince_args(");
      sb.append(")");
      return sb.toString();
    }

  }

  public static class aliveSince_result   {
    public long success;

    public final Isset __isset = new Isset();
    public final class Isset {
      public boolean success = false;
    }

    public aliveSince_result() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          case 0:
            if (field.type == TType.I64) {
              this.success = iprot.readI64();
              this.__isset.success = true;
            } else { 
              TProtocolUtil.skip(iprot, field.type);
            }
            break;
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("aliveSince_result");
      TField field = new TField();
      oprot.writeStructBegin(struct);

      if (this.__isset.success) {
        field.name = "success";
        field.type = TType.I64;
        field.id = 0;
        oprot.writeFieldBegin(field);
        oprot.writeI64(this.success);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("aliveSince_result(");
      sb.append("success:");
      sb.append(this.success);
      sb.append(")");
      return sb.toString();
    }

  }

  public static class getLimitedReflection_args   {
    public getLimitedReflection_args() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("getLimitedReflection_args");
      TField field = new TField();
      oprot.writeStructBegin(struct);
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("getLimitedReflection_args(");
      sb.append(")");
      return sb.toString();
    }

  }

  public static class getLimitedReflection_result   {
    public com.facebook.thrift.reflection.limited.Service success;

    public final Isset __isset = new Isset();
    public final class Isset {
      public boolean success = false;
    }

    public getLimitedReflection_result() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          case 0:
            if (field.type == TType.STRUCT) {
              this.success = new com.facebook.thrift.reflection.limited.Service();
              this.success.read(iprot);
              this.__isset.success = true;
            } else { 
              TProtocolUtil.skip(iprot, field.type);
            }
            break;
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("getLimitedReflection_result");
      TField field = new TField();
      oprot.writeStructBegin(struct);

      if (this.__isset.success) {
        if (this.success != null) {
          field.name = "success";
          field.type = TType.STRUCT;
          field.id = 0;
          oprot.writeFieldBegin(field);
          this.success.write(oprot);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("getLimitedReflection_result(");
      sb.append("success:");
      sb.append(this.success.toString());
      sb.append(")");
      return sb.toString();
    }

  }

  public static class reinitialize_args   {
    public reinitialize_args() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("reinitialize_args");
      TField field = new TField();
      oprot.writeStructBegin(struct);
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("reinitialize_args(");
      sb.append(")");
      return sb.toString();
    }

  }

  public static class shutdown_args   {
    public shutdown_args() {
    }

    public void read(TProtocol iprot) throws TException {
      TField field;
      TStruct struct = iprot.readStructBegin();
      while (true)
      {
        field = iprot.readFieldBegin();
        if (field.type == TType.STOP) { 
          break;
        }
        switch (field.id)
        {
          default:
            TProtocolUtil.skip(iprot, field.type);
            break;
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
    }

    public void write(TProtocol oprot) throws TException {
      TStruct struct = new TStruct("shutdown_args");
      TField field = new TField();
      oprot.writeStructBegin(struct);
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

    public String toString() {
      StringBuilder sb = new StringBuilder("shutdown_args(");
      sb.append(")");
      return sb.toString();
    }

  }

}
