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

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.18.1)")
public class SupervisorInfo implements org.apache.storm.thrift.TBase<SupervisorInfo, SupervisorInfo._Fields>, java.io.Serializable, Cloneable, Comparable<SupervisorInfo> {
  private static final org.apache.storm.thrift.protocol.TStruct STRUCT_DESC = new org.apache.storm.thrift.protocol.TStruct("SupervisorInfo");

  private static final org.apache.storm.thrift.protocol.TField TIME_SECS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("time_secs", org.apache.storm.thrift.protocol.TType.I64, (short)1);
  private static final org.apache.storm.thrift.protocol.TField HOSTNAME_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("hostname", org.apache.storm.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.storm.thrift.protocol.TField ASSIGNMENT_ID_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("assignment_id", org.apache.storm.thrift.protocol.TType.STRING, (short)3);
  private static final org.apache.storm.thrift.protocol.TField USED_PORTS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("used_ports", org.apache.storm.thrift.protocol.TType.LIST, (short)4);
  private static final org.apache.storm.thrift.protocol.TField META_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("meta", org.apache.storm.thrift.protocol.TType.LIST, (short)5);
  private static final org.apache.storm.thrift.protocol.TField SCHEDULER_META_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("scheduler_meta", org.apache.storm.thrift.protocol.TType.MAP, (short)6);
  private static final org.apache.storm.thrift.protocol.TField UPTIME_SECS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("uptime_secs", org.apache.storm.thrift.protocol.TType.I64, (short)7);
  private static final org.apache.storm.thrift.protocol.TField VERSION_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("version", org.apache.storm.thrift.protocol.TType.STRING, (short)8);
  private static final org.apache.storm.thrift.protocol.TField RESOURCES_MAP_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("resources_map", org.apache.storm.thrift.protocol.TType.MAP, (short)9);
  private static final org.apache.storm.thrift.protocol.TField SERVER_PORT_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("server_port", org.apache.storm.thrift.protocol.TType.I32, (short)10);

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

  private long time_secs; // required
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String hostname; // required
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String assignment_id; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.List<java.lang.Long> used_ports; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.List<java.lang.Long> meta; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.String> scheduler_meta; // optional
  private long uptime_secs; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String version; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.Double> resources_map; // optional
  private int server_port; // optional

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.storm.thrift.TFieldIdEnum {
    TIME_SECS((short)1, "time_secs"),
    HOSTNAME((short)2, "hostname"),
    ASSIGNMENT_ID((short)3, "assignment_id"),
    USED_PORTS((short)4, "used_ports"),
    META((short)5, "meta"),
    SCHEDULER_META((short)6, "scheduler_meta"),
    UPTIME_SECS((short)7, "uptime_secs"),
    VERSION((short)8, "version"),
    RESOURCES_MAP((short)9, "resources_map"),
    SERVER_PORT((short)10, "server_port");

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

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

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    @org.apache.storm.thrift.annotation.Nullable
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // TIME_SECS
          return TIME_SECS;
        case 2: // HOSTNAME
          return HOSTNAME;
        case 3: // ASSIGNMENT_ID
          return ASSIGNMENT_ID;
        case 4: // USED_PORTS
          return USED_PORTS;
        case 5: // META
          return META;
        case 6: // SCHEDULER_META
          return SCHEDULER_META;
        case 7: // UPTIME_SECS
          return UPTIME_SECS;
        case 8: // VERSION
          return VERSION;
        case 9: // RESOURCES_MAP
          return RESOURCES_MAP;
        case 10: // SERVER_PORT
          return SERVER_PORT;
        default:
          return null;
      }
    }

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

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

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

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

    @Override
    public short getThriftFieldId() {
      return _thriftId;
    }

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

  // isset id assignments
  private static final int __TIME_SECS_ISSET_ID = 0;
  private static final int __UPTIME_SECS_ISSET_ID = 1;
  private static final int __SERVER_PORT_ISSET_ID = 2;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.ASSIGNMENT_ID,_Fields.USED_PORTS,_Fields.META,_Fields.SCHEDULER_META,_Fields.UPTIME_SECS,_Fields.VERSION,_Fields.RESOURCES_MAP,_Fields.SERVER_PORT};
  public static final java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.TIME_SECS, new org.apache.storm.thrift.meta_data.FieldMetaData("time_secs", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.HOSTNAME, new org.apache.storm.thrift.meta_data.FieldMetaData("hostname", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.ASSIGNMENT_ID, new org.apache.storm.thrift.meta_data.FieldMetaData("assignment_id", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.USED_PORTS, new org.apache.storm.thrift.meta_data.FieldMetaData("used_ports", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.ListMetaData(org.apache.storm.thrift.protocol.TType.LIST, 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I64))));
    tmpMap.put(_Fields.META, new org.apache.storm.thrift.meta_data.FieldMetaData("meta", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.ListMetaData(org.apache.storm.thrift.protocol.TType.LIST, 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I64))));
    tmpMap.put(_Fields.SCHEDULER_META, new org.apache.storm.thrift.meta_data.FieldMetaData("scheduler_meta", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.MapMetaData(org.apache.storm.thrift.protocol.TType.MAP, 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING), 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING))));
    tmpMap.put(_Fields.UPTIME_SECS, new org.apache.storm.thrift.meta_data.FieldMetaData("uptime_secs", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.VERSION, new org.apache.storm.thrift.meta_data.FieldMetaData("version", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.RESOURCES_MAP, new org.apache.storm.thrift.meta_data.FieldMetaData("resources_map", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.MapMetaData(org.apache.storm.thrift.protocol.TType.MAP, 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING), 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE))));
    tmpMap.put(_Fields.SERVER_PORT, new org.apache.storm.thrift.meta_data.FieldMetaData("server_port", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I32)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.storm.thrift.meta_data.FieldMetaData.addStructMetaDataMap(SupervisorInfo.class, metaDataMap);
  }

  public SupervisorInfo() {
  }

  public SupervisorInfo(
    long time_secs,
    java.lang.String hostname)
  {
    this();
    this.time_secs = time_secs;
    set_time_secs_isSet(true);
    this.hostname = hostname;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public SupervisorInfo(SupervisorInfo other) {
    __isset_bitfield = other.__isset_bitfield;
    this.time_secs = other.time_secs;
    if (other.is_set_hostname()) {
      this.hostname = other.hostname;
    }
    if (other.is_set_assignment_id()) {
      this.assignment_id = other.assignment_id;
    }
    if (other.is_set_used_ports()) {
      java.util.List<java.lang.Long> __this__used_ports = new java.util.ArrayList<java.lang.Long>(other.used_ports);
      this.used_ports = __this__used_ports;
    }
    if (other.is_set_meta()) {
      java.util.List<java.lang.Long> __this__meta = new java.util.ArrayList<java.lang.Long>(other.meta);
      this.meta = __this__meta;
    }
    if (other.is_set_scheduler_meta()) {
      java.util.Map<java.lang.String,java.lang.String> __this__scheduler_meta = new java.util.HashMap<java.lang.String,java.lang.String>(other.scheduler_meta);
      this.scheduler_meta = __this__scheduler_meta;
    }
    this.uptime_secs = other.uptime_secs;
    if (other.is_set_version()) {
      this.version = other.version;
    }
    if (other.is_set_resources_map()) {
      java.util.Map<java.lang.String,java.lang.Double> __this__resources_map = new java.util.HashMap<java.lang.String,java.lang.Double>(other.resources_map);
      this.resources_map = __this__resources_map;
    }
    this.server_port = other.server_port;
  }

  @Override
  public SupervisorInfo deepCopy() {
    return new SupervisorInfo(this);
  }

  @Override
  public void clear() {
    set_time_secs_isSet(false);
    this.time_secs = 0;
    this.hostname = null;
    this.assignment_id = null;
    this.used_ports = null;
    this.meta = null;
    this.scheduler_meta = null;
    set_uptime_secs_isSet(false);
    this.uptime_secs = 0;
    this.version = null;
    this.resources_map = null;
    set_server_port_isSet(false);
    this.server_port = 0;
  }

  public long get_time_secs() {
    return this.time_secs;
  }

  public void set_time_secs(long time_secs) {
    this.time_secs = time_secs;
    set_time_secs_isSet(true);
  }

  public void unset_time_secs() {
    __isset_bitfield = org.apache.storm.thrift.EncodingUtils.clearBit(__isset_bitfield, __TIME_SECS_ISSET_ID);
  }

  /** Returns true if field time_secs is set (has been assigned a value) and false otherwise */
  public boolean is_set_time_secs() {
    return org.apache.storm.thrift.EncodingUtils.testBit(__isset_bitfield, __TIME_SECS_ISSET_ID);
  }

  public void set_time_secs_isSet(boolean value) {
    __isset_bitfield = org.apache.storm.thrift.EncodingUtils.setBit(__isset_bitfield, __TIME_SECS_ISSET_ID, value);
  }

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

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

  public void unset_hostname() {
    this.hostname = null;
  }

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

  public void set_hostname_isSet(boolean value) {
    if (!value) {
      this.hostname = null;
    }
  }

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

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

  public void unset_assignment_id() {
    this.assignment_id = null;
  }

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

  public void set_assignment_id_isSet(boolean value) {
    if (!value) {
      this.assignment_id = null;
    }
  }

  public int get_used_ports_size() {
    return (this.used_ports == null) ? 0 : this.used_ports.size();
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.Iterator<java.lang.Long> get_used_ports_iterator() {
    return (this.used_ports == null) ? null : this.used_ports.iterator();
  }

  public void add_to_used_ports(long elem) {
    if (this.used_ports == null) {
      this.used_ports = new java.util.ArrayList<java.lang.Long>();
    }
    this.used_ports.add(elem);
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.List<java.lang.Long> get_used_ports() {
    return this.used_ports;
  }

  public void set_used_ports(@org.apache.storm.thrift.annotation.Nullable java.util.List<java.lang.Long> used_ports) {
    this.used_ports = used_ports;
  }

  public void unset_used_ports() {
    this.used_ports = null;
  }

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

  public void set_used_ports_isSet(boolean value) {
    if (!value) {
      this.used_ports = null;
    }
  }

  public int get_meta_size() {
    return (this.meta == null) ? 0 : this.meta.size();
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.Iterator<java.lang.Long> get_meta_iterator() {
    return (this.meta == null) ? null : this.meta.iterator();
  }

  public void add_to_meta(long elem) {
    if (this.meta == null) {
      this.meta = new java.util.ArrayList<java.lang.Long>();
    }
    this.meta.add(elem);
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.List<java.lang.Long> get_meta() {
    return this.meta;
  }

  public void set_meta(@org.apache.storm.thrift.annotation.Nullable java.util.List<java.lang.Long> meta) {
    this.meta = meta;
  }

  public void unset_meta() {
    this.meta = null;
  }

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

  public void set_meta_isSet(boolean value) {
    if (!value) {
      this.meta = null;
    }
  }

  public int get_scheduler_meta_size() {
    return (this.scheduler_meta == null) ? 0 : this.scheduler_meta.size();
  }

  public void put_to_scheduler_meta(java.lang.String key, java.lang.String val) {
    if (this.scheduler_meta == null) {
      this.scheduler_meta = new java.util.HashMap<java.lang.String,java.lang.String>();
    }
    this.scheduler_meta.put(key, val);
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.Map<java.lang.String,java.lang.String> get_scheduler_meta() {
    return this.scheduler_meta;
  }

  public void set_scheduler_meta(@org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.String> scheduler_meta) {
    this.scheduler_meta = scheduler_meta;
  }

  public void unset_scheduler_meta() {
    this.scheduler_meta = null;
  }

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

  public void set_scheduler_meta_isSet(boolean value) {
    if (!value) {
      this.scheduler_meta = null;
    }
  }

  public long get_uptime_secs() {
    return this.uptime_secs;
  }

  public void set_uptime_secs(long uptime_secs) {
    this.uptime_secs = uptime_secs;
    set_uptime_secs_isSet(true);
  }

  public void unset_uptime_secs() {
    __isset_bitfield = org.apache.storm.thrift.EncodingUtils.clearBit(__isset_bitfield, __UPTIME_SECS_ISSET_ID);
  }

  /** Returns true if field uptime_secs is set (has been assigned a value) and false otherwise */
  public boolean is_set_uptime_secs() {
    return org.apache.storm.thrift.EncodingUtils.testBit(__isset_bitfield, __UPTIME_SECS_ISSET_ID);
  }

  public void set_uptime_secs_isSet(boolean value) {
    __isset_bitfield = org.apache.storm.thrift.EncodingUtils.setBit(__isset_bitfield, __UPTIME_SECS_ISSET_ID, value);
  }

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

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

  public void unset_version() {
    this.version = null;
  }

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

  public void set_version_isSet(boolean value) {
    if (!value) {
      this.version = null;
    }
  }

  public int get_resources_map_size() {
    return (this.resources_map == null) ? 0 : this.resources_map.size();
  }

  public void put_to_resources_map(java.lang.String key, double val) {
    if (this.resources_map == null) {
      this.resources_map = new java.util.HashMap<java.lang.String,java.lang.Double>();
    }
    this.resources_map.put(key, val);
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.Map<java.lang.String,java.lang.Double> get_resources_map() {
    return this.resources_map;
  }

  public void set_resources_map(@org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.Double> resources_map) {
    this.resources_map = resources_map;
  }

  public void unset_resources_map() {
    this.resources_map = null;
  }

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

  public void set_resources_map_isSet(boolean value) {
    if (!value) {
      this.resources_map = null;
    }
  }

  public int get_server_port() {
    return this.server_port;
  }

  public void set_server_port(int server_port) {
    this.server_port = server_port;
    set_server_port_isSet(true);
  }

  public void unset_server_port() {
    __isset_bitfield = org.apache.storm.thrift.EncodingUtils.clearBit(__isset_bitfield, __SERVER_PORT_ISSET_ID);
  }

  /** Returns true if field server_port is set (has been assigned a value) and false otherwise */
  public boolean is_set_server_port() {
    return org.apache.storm.thrift.EncodingUtils.testBit(__isset_bitfield, __SERVER_PORT_ISSET_ID);
  }

  public void set_server_port_isSet(boolean value) {
    __isset_bitfield = org.apache.storm.thrift.EncodingUtils.setBit(__isset_bitfield, __SERVER_PORT_ISSET_ID, value);
  }

  @Override
  public void setFieldValue(_Fields field, @org.apache.storm.thrift.annotation.Nullable java.lang.Object value) {
    switch (field) {
    case TIME_SECS:
      if (value == null) {
        unset_time_secs();
      } else {
        set_time_secs((java.lang.Long)value);
      }
      break;

    case HOSTNAME:
      if (value == null) {
        unset_hostname();
      } else {
        set_hostname((java.lang.String)value);
      }
      break;

    case ASSIGNMENT_ID:
      if (value == null) {
        unset_assignment_id();
      } else {
        set_assignment_id((java.lang.String)value);
      }
      break;

    case USED_PORTS:
      if (value == null) {
        unset_used_ports();
      } else {
        set_used_ports((java.util.List<java.lang.Long>)value);
      }
      break;

    case META:
      if (value == null) {
        unset_meta();
      } else {
        set_meta((java.util.List<java.lang.Long>)value);
      }
      break;

    case SCHEDULER_META:
      if (value == null) {
        unset_scheduler_meta();
      } else {
        set_scheduler_meta((java.util.Map<java.lang.String,java.lang.String>)value);
      }
      break;

    case UPTIME_SECS:
      if (value == null) {
        unset_uptime_secs();
      } else {
        set_uptime_secs((java.lang.Long)value);
      }
      break;

    case VERSION:
      if (value == null) {
        unset_version();
      } else {
        set_version((java.lang.String)value);
      }
      break;

    case RESOURCES_MAP:
      if (value == null) {
        unset_resources_map();
      } else {
        set_resources_map((java.util.Map<java.lang.String,java.lang.Double>)value);
      }
      break;

    case SERVER_PORT:
      if (value == null) {
        unset_server_port();
      } else {
        set_server_port((java.lang.Integer)value);
      }
      break;

    }
  }

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

    case HOSTNAME:
      return get_hostname();

    case ASSIGNMENT_ID:
      return get_assignment_id();

    case USED_PORTS:
      return get_used_ports();

    case META:
      return get_meta();

    case SCHEDULER_META:
      return get_scheduler_meta();

    case UPTIME_SECS:
      return get_uptime_secs();

    case VERSION:
      return get_version();

    case RESOURCES_MAP:
      return get_resources_map();

    case SERVER_PORT:
      return get_server_port();

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

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

    switch (field) {
    case TIME_SECS:
      return is_set_time_secs();
    case HOSTNAME:
      return is_set_hostname();
    case ASSIGNMENT_ID:
      return is_set_assignment_id();
    case USED_PORTS:
      return is_set_used_ports();
    case META:
      return is_set_meta();
    case SCHEDULER_META:
      return is_set_scheduler_meta();
    case UPTIME_SECS:
      return is_set_uptime_secs();
    case VERSION:
      return is_set_version();
    case RESOURCES_MAP:
      return is_set_resources_map();
    case SERVER_PORT:
      return is_set_server_port();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_time_secs = true;
    boolean that_present_time_secs = true;
    if (this_present_time_secs || that_present_time_secs) {
      if (!(this_present_time_secs && that_present_time_secs))
        return false;
      if (this.time_secs != that.time_secs)
        return false;
    }

    boolean this_present_hostname = true && this.is_set_hostname();
    boolean that_present_hostname = true && that.is_set_hostname();
    if (this_present_hostname || that_present_hostname) {
      if (!(this_present_hostname && that_present_hostname))
        return false;
      if (!this.hostname.equals(that.hostname))
        return false;
    }

    boolean this_present_assignment_id = true && this.is_set_assignment_id();
    boolean that_present_assignment_id = true && that.is_set_assignment_id();
    if (this_present_assignment_id || that_present_assignment_id) {
      if (!(this_present_assignment_id && that_present_assignment_id))
        return false;
      if (!this.assignment_id.equals(that.assignment_id))
        return false;
    }

    boolean this_present_used_ports = true && this.is_set_used_ports();
    boolean that_present_used_ports = true && that.is_set_used_ports();
    if (this_present_used_ports || that_present_used_ports) {
      if (!(this_present_used_ports && that_present_used_ports))
        return false;
      if (!this.used_ports.equals(that.used_ports))
        return false;
    }

    boolean this_present_meta = true && this.is_set_meta();
    boolean that_present_meta = true && that.is_set_meta();
    if (this_present_meta || that_present_meta) {
      if (!(this_present_meta && that_present_meta))
        return false;
      if (!this.meta.equals(that.meta))
        return false;
    }

    boolean this_present_scheduler_meta = true && this.is_set_scheduler_meta();
    boolean that_present_scheduler_meta = true && that.is_set_scheduler_meta();
    if (this_present_scheduler_meta || that_present_scheduler_meta) {
      if (!(this_present_scheduler_meta && that_present_scheduler_meta))
        return false;
      if (!this.scheduler_meta.equals(that.scheduler_meta))
        return false;
    }

    boolean this_present_uptime_secs = true && this.is_set_uptime_secs();
    boolean that_present_uptime_secs = true && that.is_set_uptime_secs();
    if (this_present_uptime_secs || that_present_uptime_secs) {
      if (!(this_present_uptime_secs && that_present_uptime_secs))
        return false;
      if (this.uptime_secs != that.uptime_secs)
        return false;
    }

    boolean this_present_version = true && this.is_set_version();
    boolean that_present_version = true && that.is_set_version();
    if (this_present_version || that_present_version) {
      if (!(this_present_version && that_present_version))
        return false;
      if (!this.version.equals(that.version))
        return false;
    }

    boolean this_present_resources_map = true && this.is_set_resources_map();
    boolean that_present_resources_map = true && that.is_set_resources_map();
    if (this_present_resources_map || that_present_resources_map) {
      if (!(this_present_resources_map && that_present_resources_map))
        return false;
      if (!this.resources_map.equals(that.resources_map))
        return false;
    }

    boolean this_present_server_port = true && this.is_set_server_port();
    boolean that_present_server_port = true && that.is_set_server_port();
    if (this_present_server_port || that_present_server_port) {
      if (!(this_present_server_port && that_present_server_port))
        return false;
      if (this.server_port != that.server_port)
        return false;
    }

    return true;
  }

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

    hashCode = hashCode * 8191 + org.apache.storm.thrift.TBaseHelper.hashCode(time_secs);

    hashCode = hashCode * 8191 + ((is_set_hostname()) ? 131071 : 524287);
    if (is_set_hostname())
      hashCode = hashCode * 8191 + hostname.hashCode();

    hashCode = hashCode * 8191 + ((is_set_assignment_id()) ? 131071 : 524287);
    if (is_set_assignment_id())
      hashCode = hashCode * 8191 + assignment_id.hashCode();

    hashCode = hashCode * 8191 + ((is_set_used_ports()) ? 131071 : 524287);
    if (is_set_used_ports())
      hashCode = hashCode * 8191 + used_ports.hashCode();

    hashCode = hashCode * 8191 + ((is_set_meta()) ? 131071 : 524287);
    if (is_set_meta())
      hashCode = hashCode * 8191 + meta.hashCode();

    hashCode = hashCode * 8191 + ((is_set_scheduler_meta()) ? 131071 : 524287);
    if (is_set_scheduler_meta())
      hashCode = hashCode * 8191 + scheduler_meta.hashCode();

    hashCode = hashCode * 8191 + ((is_set_uptime_secs()) ? 131071 : 524287);
    if (is_set_uptime_secs())
      hashCode = hashCode * 8191 + org.apache.storm.thrift.TBaseHelper.hashCode(uptime_secs);

    hashCode = hashCode * 8191 + ((is_set_version()) ? 131071 : 524287);
    if (is_set_version())
      hashCode = hashCode * 8191 + version.hashCode();

    hashCode = hashCode * 8191 + ((is_set_resources_map()) ? 131071 : 524287);
    if (is_set_resources_map())
      hashCode = hashCode * 8191 + resources_map.hashCode();

    hashCode = hashCode * 8191 + ((is_set_server_port()) ? 131071 : 524287);
    if (is_set_server_port())
      hashCode = hashCode * 8191 + server_port;

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.compare(is_set_time_secs(), other.is_set_time_secs());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_time_secs()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.time_secs, other.time_secs);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(is_set_hostname(), other.is_set_hostname());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_hostname()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.hostname, other.hostname);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(is_set_assignment_id(), other.is_set_assignment_id());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_assignment_id()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.assignment_id, other.assignment_id);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(is_set_used_ports(), other.is_set_used_ports());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_used_ports()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.used_ports, other.used_ports);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(is_set_meta(), other.is_set_meta());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_meta()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.meta, other.meta);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(is_set_scheduler_meta(), other.is_set_scheduler_meta());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_scheduler_meta()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.scheduler_meta, other.scheduler_meta);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(is_set_uptime_secs(), other.is_set_uptime_secs());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_uptime_secs()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.uptime_secs, other.uptime_secs);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(is_set_version(), other.is_set_version());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_version()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.version, other.version);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(is_set_resources_map(), other.is_set_resources_map());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_resources_map()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.resources_map, other.resources_map);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(is_set_server_port(), other.is_set_server_port());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_server_port()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.server_port, other.server_port);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

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

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

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

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

    sb.append("time_secs:");
    sb.append(this.time_secs);
    first = false;
    if (!first) sb.append(", ");
    sb.append("hostname:");
    if (this.hostname == null) {
      sb.append("null");
    } else {
      sb.append(this.hostname);
    }
    first = false;
    if (is_set_assignment_id()) {
      if (!first) sb.append(", ");
      sb.append("assignment_id:");
      if (this.assignment_id == null) {
        sb.append("null");
      } else {
        sb.append(this.assignment_id);
      }
      first = false;
    }
    if (is_set_used_ports()) {
      if (!first) sb.append(", ");
      sb.append("used_ports:");
      if (this.used_ports == null) {
        sb.append("null");
      } else {
        sb.append(this.used_ports);
      }
      first = false;
    }
    if (is_set_meta()) {
      if (!first) sb.append(", ");
      sb.append("meta:");
      if (this.meta == null) {
        sb.append("null");
      } else {
        sb.append(this.meta);
      }
      first = false;
    }
    if (is_set_scheduler_meta()) {
      if (!first) sb.append(", ");
      sb.append("scheduler_meta:");
      if (this.scheduler_meta == null) {
        sb.append("null");
      } else {
        sb.append(this.scheduler_meta);
      }
      first = false;
    }
    if (is_set_uptime_secs()) {
      if (!first) sb.append(", ");
      sb.append("uptime_secs:");
      sb.append(this.uptime_secs);
      first = false;
    }
    if (is_set_version()) {
      if (!first) sb.append(", ");
      sb.append("version:");
      if (this.version == null) {
        sb.append("null");
      } else {
        sb.append(this.version);
      }
      first = false;
    }
    if (is_set_resources_map()) {
      if (!first) sb.append(", ");
      sb.append("resources_map:");
      if (this.resources_map == null) {
        sb.append("null");
      } else {
        sb.append(this.resources_map);
      }
      first = false;
    }
    if (is_set_server_port()) {
      if (!first) sb.append(", ");
      sb.append("server_port:");
      sb.append(this.server_port);
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.storm.thrift.TException {
    // check for required fields
    if (!is_set_time_secs()) {
      throw new org.apache.storm.thrift.protocol.TProtocolException("Required field 'time_secs' is unset! Struct:" + toString());
    }

    if (!is_set_hostname()) {
      throw new org.apache.storm.thrift.protocol.TProtocolException("Required field 'hostname' is unset! Struct:" + toString());
    }

    // check for sub-struct validity
  }

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

  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
    try {
      // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
      __isset_bitfield = 0;
      read(new org.apache.storm.thrift.protocol.TCompactProtocol(new org.apache.storm.thrift.transport.TIOStreamTransport(in)));
    } catch (org.apache.storm.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private static class SupervisorInfoStandardSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
    @Override
    public SupervisorInfoStandardScheme getScheme() {
      return new SupervisorInfoStandardScheme();
    }
  }

  private static class SupervisorInfoStandardScheme extends org.apache.storm.thrift.scheme.StandardScheme<SupervisorInfo> {

    @Override
    public void read(org.apache.storm.thrift.protocol.TProtocol iprot, SupervisorInfo struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TField schemeField;
      iprot.readStructBegin();
      while (true)
      {
        schemeField = iprot.readFieldBegin();
        if (schemeField.type == org.apache.storm.thrift.protocol.TType.STOP) { 
          break;
        }
        switch (schemeField.id) {
          case 1: // TIME_SECS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I64) {
              struct.time_secs = iprot.readI64();
              struct.set_time_secs_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // HOSTNAME
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.hostname = iprot.readString();
              struct.set_hostname_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // ASSIGNMENT_ID
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.assignment_id = iprot.readString();
              struct.set_assignment_id_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // USED_PORTS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.LIST) {
              {
                org.apache.storm.thrift.protocol.TList _list672 = iprot.readListBegin();
                struct.used_ports = new java.util.ArrayList<java.lang.Long>(_list672.size);
                long _elem673;
                for (int _i674 = 0; _i674 < _list672.size; ++_i674)
                {
                  _elem673 = iprot.readI64();
                  struct.used_ports.add(_elem673);
                }
                iprot.readListEnd();
              }
              struct.set_used_ports_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // META
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.LIST) {
              {
                org.apache.storm.thrift.protocol.TList _list675 = iprot.readListBegin();
                struct.meta = new java.util.ArrayList<java.lang.Long>(_list675.size);
                long _elem676;
                for (int _i677 = 0; _i677 < _list675.size; ++_i677)
                {
                  _elem676 = iprot.readI64();
                  struct.meta.add(_elem676);
                }
                iprot.readListEnd();
              }
              struct.set_meta_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // SCHEDULER_META
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map678 = iprot.readMapBegin();
                struct.scheduler_meta = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map678.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key679;
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _val680;
                for (int _i681 = 0; _i681 < _map678.size; ++_i681)
                {
                  _key679 = iprot.readString();
                  _val680 = iprot.readString();
                  struct.scheduler_meta.put(_key679, _val680);
                }
                iprot.readMapEnd();
              }
              struct.set_scheduler_meta_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // UPTIME_SECS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I64) {
              struct.uptime_secs = iprot.readI64();
              struct.set_uptime_secs_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // VERSION
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.version = iprot.readString();
              struct.set_version_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // RESOURCES_MAP
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map682 = iprot.readMapBegin();
                struct.resources_map = new java.util.HashMap<java.lang.String,java.lang.Double>(2*_map682.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key683;
                double _val684;
                for (int _i685 = 0; _i685 < _map682.size; ++_i685)
                {
                  _key683 = iprot.readString();
                  _val684 = iprot.readDouble();
                  struct.resources_map.put(_key683, _val684);
                }
                iprot.readMapEnd();
              }
              struct.set_resources_map_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // SERVER_PORT
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.server_port = iprot.readI32();
              struct.set_server_port_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          default:
            org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
      struct.validate();
    }

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

      oprot.writeStructBegin(STRUCT_DESC);
      oprot.writeFieldBegin(TIME_SECS_FIELD_DESC);
      oprot.writeI64(struct.time_secs);
      oprot.writeFieldEnd();
      if (struct.hostname != null) {
        oprot.writeFieldBegin(HOSTNAME_FIELD_DESC);
        oprot.writeString(struct.hostname);
        oprot.writeFieldEnd();
      }
      if (struct.assignment_id != null) {
        if (struct.is_set_assignment_id()) {
          oprot.writeFieldBegin(ASSIGNMENT_ID_FIELD_DESC);
          oprot.writeString(struct.assignment_id);
          oprot.writeFieldEnd();
        }
      }
      if (struct.used_ports != null) {
        if (struct.is_set_used_ports()) {
          oprot.writeFieldBegin(USED_PORTS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.I64, struct.used_ports.size()));
            for (long _iter686 : struct.used_ports)
            {
              oprot.writeI64(_iter686);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.meta != null) {
        if (struct.is_set_meta()) {
          oprot.writeFieldBegin(META_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.I64, struct.meta.size()));
            for (long _iter687 : struct.meta)
            {
              oprot.writeI64(_iter687);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.scheduler_meta != null) {
        if (struct.is_set_scheduler_meta()) {
          oprot.writeFieldBegin(SCHEDULER_META_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.STRING, struct.scheduler_meta.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter688 : struct.scheduler_meta.entrySet())
            {
              oprot.writeString(_iter688.getKey());
              oprot.writeString(_iter688.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.is_set_uptime_secs()) {
        oprot.writeFieldBegin(UPTIME_SECS_FIELD_DESC);
        oprot.writeI64(struct.uptime_secs);
        oprot.writeFieldEnd();
      }
      if (struct.version != null) {
        if (struct.is_set_version()) {
          oprot.writeFieldBegin(VERSION_FIELD_DESC);
          oprot.writeString(struct.version);
          oprot.writeFieldEnd();
        }
      }
      if (struct.resources_map != null) {
        if (struct.is_set_resources_map()) {
          oprot.writeFieldBegin(RESOURCES_MAP_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.DOUBLE, struct.resources_map.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.Double> _iter689 : struct.resources_map.entrySet())
            {
              oprot.writeString(_iter689.getKey());
              oprot.writeDouble(_iter689.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.is_set_server_port()) {
        oprot.writeFieldBegin(SERVER_PORT_FIELD_DESC);
        oprot.writeI32(struct.server_port);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class SupervisorInfoTupleSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
    @Override
    public SupervisorInfoTupleScheme getScheme() {
      return new SupervisorInfoTupleScheme();
    }
  }

  private static class SupervisorInfoTupleScheme extends org.apache.storm.thrift.scheme.TupleScheme<SupervisorInfo> {

    @Override
    public void write(org.apache.storm.thrift.protocol.TProtocol prot, SupervisorInfo struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol oprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      oprot.writeI64(struct.time_secs);
      oprot.writeString(struct.hostname);
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.is_set_assignment_id()) {
        optionals.set(0);
      }
      if (struct.is_set_used_ports()) {
        optionals.set(1);
      }
      if (struct.is_set_meta()) {
        optionals.set(2);
      }
      if (struct.is_set_scheduler_meta()) {
        optionals.set(3);
      }
      if (struct.is_set_uptime_secs()) {
        optionals.set(4);
      }
      if (struct.is_set_version()) {
        optionals.set(5);
      }
      if (struct.is_set_resources_map()) {
        optionals.set(6);
      }
      if (struct.is_set_server_port()) {
        optionals.set(7);
      }
      oprot.writeBitSet(optionals, 8);
      if (struct.is_set_assignment_id()) {
        oprot.writeString(struct.assignment_id);
      }
      if (struct.is_set_used_ports()) {
        {
          oprot.writeI32(struct.used_ports.size());
          for (long _iter690 : struct.used_ports)
          {
            oprot.writeI64(_iter690);
          }
        }
      }
      if (struct.is_set_meta()) {
        {
          oprot.writeI32(struct.meta.size());
          for (long _iter691 : struct.meta)
          {
            oprot.writeI64(_iter691);
          }
        }
      }
      if (struct.is_set_scheduler_meta()) {
        {
          oprot.writeI32(struct.scheduler_meta.size());
          for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter692 : struct.scheduler_meta.entrySet())
          {
            oprot.writeString(_iter692.getKey());
            oprot.writeString(_iter692.getValue());
          }
        }
      }
      if (struct.is_set_uptime_secs()) {
        oprot.writeI64(struct.uptime_secs);
      }
      if (struct.is_set_version()) {
        oprot.writeString(struct.version);
      }
      if (struct.is_set_resources_map()) {
        {
          oprot.writeI32(struct.resources_map.size());
          for (java.util.Map.Entry<java.lang.String, java.lang.Double> _iter693 : struct.resources_map.entrySet())
          {
            oprot.writeString(_iter693.getKey());
            oprot.writeDouble(_iter693.getValue());
          }
        }
      }
      if (struct.is_set_server_port()) {
        oprot.writeI32(struct.server_port);
      }
    }

    @Override
    public void read(org.apache.storm.thrift.protocol.TProtocol prot, SupervisorInfo struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol iprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      struct.time_secs = iprot.readI64();
      struct.set_time_secs_isSet(true);
      struct.hostname = iprot.readString();
      struct.set_hostname_isSet(true);
      java.util.BitSet incoming = iprot.readBitSet(8);
      if (incoming.get(0)) {
        struct.assignment_id = iprot.readString();
        struct.set_assignment_id_isSet(true);
      }
      if (incoming.get(1)) {
        {
          org.apache.storm.thrift.protocol.TList _list694 = iprot.readListBegin(org.apache.storm.thrift.protocol.TType.I64);
          struct.used_ports = new java.util.ArrayList<java.lang.Long>(_list694.size);
          long _elem695;
          for (int _i696 = 0; _i696 < _list694.size; ++_i696)
          {
            _elem695 = iprot.readI64();
            struct.used_ports.add(_elem695);
          }
        }
        struct.set_used_ports_isSet(true);
      }
      if (incoming.get(2)) {
        {
          org.apache.storm.thrift.protocol.TList _list697 = iprot.readListBegin(org.apache.storm.thrift.protocol.TType.I64);
          struct.meta = new java.util.ArrayList<java.lang.Long>(_list697.size);
          long _elem698;
          for (int _i699 = 0; _i699 < _list697.size; ++_i699)
          {
            _elem698 = iprot.readI64();
            struct.meta.add(_elem698);
          }
        }
        struct.set_meta_isSet(true);
      }
      if (incoming.get(3)) {
        {
          org.apache.storm.thrift.protocol.TMap _map700 = iprot.readMapBegin(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.STRING); 
          struct.scheduler_meta = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map700.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key701;
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _val702;
          for (int _i703 = 0; _i703 < _map700.size; ++_i703)
          {
            _key701 = iprot.readString();
            _val702 = iprot.readString();
            struct.scheduler_meta.put(_key701, _val702);
          }
        }
        struct.set_scheduler_meta_isSet(true);
      }
      if (incoming.get(4)) {
        struct.uptime_secs = iprot.readI64();
        struct.set_uptime_secs_isSet(true);
      }
      if (incoming.get(5)) {
        struct.version = iprot.readString();
        struct.set_version_isSet(true);
      }
      if (incoming.get(6)) {
        {
          org.apache.storm.thrift.protocol.TMap _map704 = iprot.readMapBegin(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.DOUBLE); 
          struct.resources_map = new java.util.HashMap<java.lang.String,java.lang.Double>(2*_map704.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key705;
          double _val706;
          for (int _i707 = 0; _i707 < _map704.size; ++_i707)
          {
            _key705 = iprot.readString();
            _val706 = iprot.readDouble();
            struct.resources_map.put(_key705, _val706);
          }
        }
        struct.set_resources_map_isSet(true);
      }
      if (incoming.get(7)) {
        struct.server_port = iprot.readI32();
        struct.set_server_port_isSet(true);
      }
    }
  }

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

