/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * Autogenerated by Thrift Compiler (0.9.3)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.storm.generated;

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

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

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

  private static final org.apache.thrift.protocol.TField NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("name", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField STATUS_FIELD_DESC = new org.apache.thrift.protocol.TField("status", org.apache.thrift.protocol.TType.I32, (short)2);
  private static final org.apache.thrift.protocol.TField NUM_WORKERS_FIELD_DESC = new org.apache.thrift.protocol.TField("num_workers", org.apache.thrift.protocol.TType.I32, (short)3);
  private static final org.apache.thrift.protocol.TField COMPONENT_EXECUTORS_FIELD_DESC = new org.apache.thrift.protocol.TField("component_executors", org.apache.thrift.protocol.TType.MAP, (short)4);
  private static final org.apache.thrift.protocol.TField LAUNCH_TIME_SECS_FIELD_DESC = new org.apache.thrift.protocol.TField("launch_time_secs", org.apache.thrift.protocol.TType.I32, (short)5);
  private static final org.apache.thrift.protocol.TField OWNER_FIELD_DESC = new org.apache.thrift.protocol.TField("owner", org.apache.thrift.protocol.TType.STRING, (short)6);
  private static final org.apache.thrift.protocol.TField TOPOLOGY_ACTION_OPTIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("topology_action_options", org.apache.thrift.protocol.TType.STRUCT, (short)7);
  private static final org.apache.thrift.protocol.TField PREV_STATUS_FIELD_DESC = new org.apache.thrift.protocol.TField("prev_status", org.apache.thrift.protocol.TType.I32, (short)8);
  private static final org.apache.thrift.protocol.TField COMPONENT_DEBUG_FIELD_DESC = new org.apache.thrift.protocol.TField("component_debug", org.apache.thrift.protocol.TType.MAP, (short)9);
  private static final org.apache.thrift.protocol.TField PRINCIPAL_FIELD_DESC = new org.apache.thrift.protocol.TField("principal", org.apache.thrift.protocol.TType.STRING, (short)10);

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

  private String name; // required
  private TopologyStatus status; // required
  private int num_workers; // required
  private Map<String,Integer> component_executors; // optional
  private int launch_time_secs; // optional
  private String owner; // optional
  private TopologyActionOptions topology_action_options; // optional
  private TopologyStatus prev_status; // optional
  private Map<String,DebugOptions> component_debug; // optional
  private String principal; // optional

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
    NAME((short)1, "name"),
    /**
     * 
     * @see TopologyStatus
     */
    STATUS((short)2, "status"),
    NUM_WORKERS((short)3, "num_workers"),
    COMPONENT_EXECUTORS((short)4, "component_executors"),
    LAUNCH_TIME_SECS((short)5, "launch_time_secs"),
    OWNER((short)6, "owner"),
    TOPOLOGY_ACTION_OPTIONS((short)7, "topology_action_options"),
    /**
     * 
     * @see TopologyStatus
     */
    PREV_STATUS((short)8, "prev_status"),
    COMPONENT_DEBUG((short)9, "component_debug"),
    PRINCIPAL((short)10, "principal");

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

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

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // NAME
          return NAME;
        case 2: // STATUS
          return STATUS;
        case 3: // NUM_WORKERS
          return NUM_WORKERS;
        case 4: // COMPONENT_EXECUTORS
          return COMPONENT_EXECUTORS;
        case 5: // LAUNCH_TIME_SECS
          return LAUNCH_TIME_SECS;
        case 6: // OWNER
          return OWNER;
        case 7: // TOPOLOGY_ACTION_OPTIONS
          return TOPOLOGY_ACTION_OPTIONS;
        case 8: // PREV_STATUS
          return PREV_STATUS;
        case 9: // COMPONENT_DEBUG
          return COMPONENT_DEBUG;
        case 10: // PRINCIPAL
          return PRINCIPAL;
        default:
          return null;
      }
    }

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

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

    private final short _thriftId;
    private final String _fieldName;

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

    public short getThriftFieldId() {
      return _thriftId;
    }

    public String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final int __NUM_WORKERS_ISSET_ID = 0;
  private static final int __LAUNCH_TIME_SECS_ISSET_ID = 1;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.COMPONENT_EXECUTORS,_Fields.LAUNCH_TIME_SECS,_Fields.OWNER,_Fields.TOPOLOGY_ACTION_OPTIONS,_Fields.PREV_STATUS,_Fields.COMPONENT_DEBUG,_Fields.PRINCIPAL};
  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.NAME, new org.apache.thrift.meta_data.FieldMetaData("name", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.STATUS, new org.apache.thrift.meta_data.FieldMetaData("status", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, TopologyStatus.class)));
    tmpMap.put(_Fields.NUM_WORKERS, new org.apache.thrift.meta_data.FieldMetaData("num_workers", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.COMPONENT_EXECUTORS, new org.apache.thrift.meta_data.FieldMetaData("component_executors", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))));
    tmpMap.put(_Fields.LAUNCH_TIME_SECS, new org.apache.thrift.meta_data.FieldMetaData("launch_time_secs", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.OWNER, new org.apache.thrift.meta_data.FieldMetaData("owner", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.TOPOLOGY_ACTION_OPTIONS, new org.apache.thrift.meta_data.FieldMetaData("topology_action_options", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TopologyActionOptions.class)));
    tmpMap.put(_Fields.PREV_STATUS, new org.apache.thrift.meta_data.FieldMetaData("prev_status", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, TopologyStatus.class)));
    tmpMap.put(_Fields.COMPONENT_DEBUG, new org.apache.thrift.meta_data.FieldMetaData("component_debug", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, DebugOptions.class))));
    tmpMap.put(_Fields.PRINCIPAL, new org.apache.thrift.meta_data.FieldMetaData("principal", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(StormBase.class, metaDataMap);
  }

  public StormBase() {
  }

  public StormBase(
    String name,
    TopologyStatus status,
    int num_workers)
  {
    this();
    this.name = name;
    this.status = status;
    this.num_workers = num_workers;
    set_num_workers_isSet(true);
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public StormBase(StormBase other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.is_set_name()) {
      this.name = other.name;
    }
    if (other.is_set_status()) {
      this.status = other.status;
    }
    this.num_workers = other.num_workers;
    if (other.is_set_component_executors()) {
      Map<String,Integer> __this__component_executors = new HashMap<String,Integer>(other.component_executors);
      this.component_executors = __this__component_executors;
    }
    this.launch_time_secs = other.launch_time_secs;
    if (other.is_set_owner()) {
      this.owner = other.owner;
    }
    if (other.is_set_topology_action_options()) {
      this.topology_action_options = new TopologyActionOptions(other.topology_action_options);
    }
    if (other.is_set_prev_status()) {
      this.prev_status = other.prev_status;
    }
    if (other.is_set_component_debug()) {
      Map<String,DebugOptions> __this__component_debug = new HashMap<String,DebugOptions>(other.component_debug.size());
      for (Map.Entry<String, DebugOptions> other_element : other.component_debug.entrySet()) {

        String other_element_key = other_element.getKey();
        DebugOptions other_element_value = other_element.getValue();

        String __this__component_debug_copy_key = other_element_key;

        DebugOptions __this__component_debug_copy_value = new DebugOptions(other_element_value);

        __this__component_debug.put(__this__component_debug_copy_key, __this__component_debug_copy_value);
      }
      this.component_debug = __this__component_debug;
    }
    if (other.is_set_principal()) {
      this.principal = other.principal;
    }
  }

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

  @Override
  public void clear() {
    this.name = null;
    this.status = null;
    set_num_workers_isSet(false);
    this.num_workers = 0;
    this.component_executors = null;
    set_launch_time_secs_isSet(false);
    this.launch_time_secs = 0;
    this.owner = null;
    this.topology_action_options = null;
    this.prev_status = null;
    this.component_debug = null;
    this.principal = null;
  }

  public String get_name() {
    return this.name;
  }

  public void set_name(String name) {
    this.name = name;
  }

  public void unset_name() {
    this.name = null;
  }

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

  public void set_name_isSet(boolean value) {
    if (!value) {
      this.name = null;
    }
  }

  /**
   * 
   * @see TopologyStatus
   */
  public TopologyStatus get_status() {
    return this.status;
  }

  /**
   * 
   * @see TopologyStatus
   */
  public void set_status(TopologyStatus status) {
    this.status = status;
  }

  public void unset_status() {
    this.status = null;
  }

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

  public void set_status_isSet(boolean value) {
    if (!value) {
      this.status = null;
    }
  }

  public int get_num_workers() {
    return this.num_workers;
  }

  public void set_num_workers(int num_workers) {
    this.num_workers = num_workers;
    set_num_workers_isSet(true);
  }

  public void unset_num_workers() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __NUM_WORKERS_ISSET_ID);
  }

  /** Returns true if field num_workers is set (has been assigned a value) and false otherwise */
  public boolean is_set_num_workers() {
    return EncodingUtils.testBit(__isset_bitfield, __NUM_WORKERS_ISSET_ID);
  }

  public void set_num_workers_isSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __NUM_WORKERS_ISSET_ID, value);
  }

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

  public void put_to_component_executors(String key, int val) {
    if (this.component_executors == null) {
      this.component_executors = new HashMap<String,Integer>();
    }
    this.component_executors.put(key, val);
  }

  public Map<String,Integer> get_component_executors() {
    return this.component_executors;
  }

  public void set_component_executors(Map<String,Integer> component_executors) {
    this.component_executors = component_executors;
  }

  public void unset_component_executors() {
    this.component_executors = null;
  }

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

  public void set_component_executors_isSet(boolean value) {
    if (!value) {
      this.component_executors = null;
    }
  }

  public int get_launch_time_secs() {
    return this.launch_time_secs;
  }

  public void set_launch_time_secs(int launch_time_secs) {
    this.launch_time_secs = launch_time_secs;
    set_launch_time_secs_isSet(true);
  }

  public void unset_launch_time_secs() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __LAUNCH_TIME_SECS_ISSET_ID);
  }

  /** Returns true if field launch_time_secs is set (has been assigned a value) and false otherwise */
  public boolean is_set_launch_time_secs() {
    return EncodingUtils.testBit(__isset_bitfield, __LAUNCH_TIME_SECS_ISSET_ID);
  }

  public void set_launch_time_secs_isSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __LAUNCH_TIME_SECS_ISSET_ID, value);
  }

  public String get_owner() {
    return this.owner;
  }

  public void set_owner(String owner) {
    this.owner = owner;
  }

  public void unset_owner() {
    this.owner = null;
  }

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

  public void set_owner_isSet(boolean value) {
    if (!value) {
      this.owner = null;
    }
  }

  public TopologyActionOptions get_topology_action_options() {
    return this.topology_action_options;
  }

  public void set_topology_action_options(TopologyActionOptions topology_action_options) {
    this.topology_action_options = topology_action_options;
  }

  public void unset_topology_action_options() {
    this.topology_action_options = null;
  }

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

  public void set_topology_action_options_isSet(boolean value) {
    if (!value) {
      this.topology_action_options = null;
    }
  }

  /**
   * 
   * @see TopologyStatus
   */
  public TopologyStatus get_prev_status() {
    return this.prev_status;
  }

  /**
   * 
   * @see TopologyStatus
   */
  public void set_prev_status(TopologyStatus prev_status) {
    this.prev_status = prev_status;
  }

  public void unset_prev_status() {
    this.prev_status = null;
  }

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

  public void set_prev_status_isSet(boolean value) {
    if (!value) {
      this.prev_status = null;
    }
  }

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

  public void put_to_component_debug(String key, DebugOptions val) {
    if (this.component_debug == null) {
      this.component_debug = new HashMap<String,DebugOptions>();
    }
    this.component_debug.put(key, val);
  }

  public Map<String,DebugOptions> get_component_debug() {
    return this.component_debug;
  }

  public void set_component_debug(Map<String,DebugOptions> component_debug) {
    this.component_debug = component_debug;
  }

  public void unset_component_debug() {
    this.component_debug = null;
  }

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

  public void set_component_debug_isSet(boolean value) {
    if (!value) {
      this.component_debug = null;
    }
  }

  public String get_principal() {
    return this.principal;
  }

  public void set_principal(String principal) {
    this.principal = principal;
  }

  public void unset_principal() {
    this.principal = null;
  }

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

  public void set_principal_isSet(boolean value) {
    if (!value) {
      this.principal = null;
    }
  }

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case NAME:
      if (value == null) {
        unset_name();
      } else {
        set_name((String)value);
      }
      break;

    case STATUS:
      if (value == null) {
        unset_status();
      } else {
        set_status((TopologyStatus)value);
      }
      break;

    case NUM_WORKERS:
      if (value == null) {
        unset_num_workers();
      } else {
        set_num_workers((Integer)value);
      }
      break;

    case COMPONENT_EXECUTORS:
      if (value == null) {
        unset_component_executors();
      } else {
        set_component_executors((Map<String,Integer>)value);
      }
      break;

    case LAUNCH_TIME_SECS:
      if (value == null) {
        unset_launch_time_secs();
      } else {
        set_launch_time_secs((Integer)value);
      }
      break;

    case OWNER:
      if (value == null) {
        unset_owner();
      } else {
        set_owner((String)value);
      }
      break;

    case TOPOLOGY_ACTION_OPTIONS:
      if (value == null) {
        unset_topology_action_options();
      } else {
        set_topology_action_options((TopologyActionOptions)value);
      }
      break;

    case PREV_STATUS:
      if (value == null) {
        unset_prev_status();
      } else {
        set_prev_status((TopologyStatus)value);
      }
      break;

    case COMPONENT_DEBUG:
      if (value == null) {
        unset_component_debug();
      } else {
        set_component_debug((Map<String,DebugOptions>)value);
      }
      break;

    case PRINCIPAL:
      if (value == null) {
        unset_principal();
      } else {
        set_principal((String)value);
      }
      break;

    }
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case NAME:
      return get_name();

    case STATUS:
      return get_status();

    case NUM_WORKERS:
      return get_num_workers();

    case COMPONENT_EXECUTORS:
      return get_component_executors();

    case LAUNCH_TIME_SECS:
      return get_launch_time_secs();

    case OWNER:
      return get_owner();

    case TOPOLOGY_ACTION_OPTIONS:
      return get_topology_action_options();

    case PREV_STATUS:
      return get_prev_status();

    case COMPONENT_DEBUG:
      return get_component_debug();

    case PRINCIPAL:
      return get_principal();

    }
    throw new IllegalStateException();
  }

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

    switch (field) {
    case NAME:
      return is_set_name();
    case STATUS:
      return is_set_status();
    case NUM_WORKERS:
      return is_set_num_workers();
    case COMPONENT_EXECUTORS:
      return is_set_component_executors();
    case LAUNCH_TIME_SECS:
      return is_set_launch_time_secs();
    case OWNER:
      return is_set_owner();
    case TOPOLOGY_ACTION_OPTIONS:
      return is_set_topology_action_options();
    case PREV_STATUS:
      return is_set_prev_status();
    case COMPONENT_DEBUG:
      return is_set_component_debug();
    case PRINCIPAL:
      return is_set_principal();
    }
    throw new IllegalStateException();
  }

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

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

    boolean this_present_name = true && this.is_set_name();
    boolean that_present_name = true && that.is_set_name();
    if (this_present_name || that_present_name) {
      if (!(this_present_name && that_present_name))
        return false;
      if (!this.name.equals(that.name))
        return false;
    }

    boolean this_present_status = true && this.is_set_status();
    boolean that_present_status = true && that.is_set_status();
    if (this_present_status || that_present_status) {
      if (!(this_present_status && that_present_status))
        return false;
      if (!this.status.equals(that.status))
        return false;
    }

    boolean this_present_num_workers = true;
    boolean that_present_num_workers = true;
    if (this_present_num_workers || that_present_num_workers) {
      if (!(this_present_num_workers && that_present_num_workers))
        return false;
      if (this.num_workers != that.num_workers)
        return false;
    }

    boolean this_present_component_executors = true && this.is_set_component_executors();
    boolean that_present_component_executors = true && that.is_set_component_executors();
    if (this_present_component_executors || that_present_component_executors) {
      if (!(this_present_component_executors && that_present_component_executors))
        return false;
      if (!this.component_executors.equals(that.component_executors))
        return false;
    }

    boolean this_present_launch_time_secs = true && this.is_set_launch_time_secs();
    boolean that_present_launch_time_secs = true && that.is_set_launch_time_secs();
    if (this_present_launch_time_secs || that_present_launch_time_secs) {
      if (!(this_present_launch_time_secs && that_present_launch_time_secs))
        return false;
      if (this.launch_time_secs != that.launch_time_secs)
        return false;
    }

    boolean this_present_owner = true && this.is_set_owner();
    boolean that_present_owner = true && that.is_set_owner();
    if (this_present_owner || that_present_owner) {
      if (!(this_present_owner && that_present_owner))
        return false;
      if (!this.owner.equals(that.owner))
        return false;
    }

    boolean this_present_topology_action_options = true && this.is_set_topology_action_options();
    boolean that_present_topology_action_options = true && that.is_set_topology_action_options();
    if (this_present_topology_action_options || that_present_topology_action_options) {
      if (!(this_present_topology_action_options && that_present_topology_action_options))
        return false;
      if (!this.topology_action_options.equals(that.topology_action_options))
        return false;
    }

    boolean this_present_prev_status = true && this.is_set_prev_status();
    boolean that_present_prev_status = true && that.is_set_prev_status();
    if (this_present_prev_status || that_present_prev_status) {
      if (!(this_present_prev_status && that_present_prev_status))
        return false;
      if (!this.prev_status.equals(that.prev_status))
        return false;
    }

    boolean this_present_component_debug = true && this.is_set_component_debug();
    boolean that_present_component_debug = true && that.is_set_component_debug();
    if (this_present_component_debug || that_present_component_debug) {
      if (!(this_present_component_debug && that_present_component_debug))
        return false;
      if (!this.component_debug.equals(that.component_debug))
        return false;
    }

    boolean this_present_principal = true && this.is_set_principal();
    boolean that_present_principal = true && that.is_set_principal();
    if (this_present_principal || that_present_principal) {
      if (!(this_present_principal && that_present_principal))
        return false;
      if (!this.principal.equals(that.principal))
        return false;
    }

    return true;
  }

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

    boolean present_name = true && (is_set_name());
    list.add(present_name);
    if (present_name)
      list.add(name);

    boolean present_status = true && (is_set_status());
    list.add(present_status);
    if (present_status)
      list.add(status.getValue());

    boolean present_num_workers = true;
    list.add(present_num_workers);
    if (present_num_workers)
      list.add(num_workers);

    boolean present_component_executors = true && (is_set_component_executors());
    list.add(present_component_executors);
    if (present_component_executors)
      list.add(component_executors);

    boolean present_launch_time_secs = true && (is_set_launch_time_secs());
    list.add(present_launch_time_secs);
    if (present_launch_time_secs)
      list.add(launch_time_secs);

    boolean present_owner = true && (is_set_owner());
    list.add(present_owner);
    if (present_owner)
      list.add(owner);

    boolean present_topology_action_options = true && (is_set_topology_action_options());
    list.add(present_topology_action_options);
    if (present_topology_action_options)
      list.add(topology_action_options);

    boolean present_prev_status = true && (is_set_prev_status());
    list.add(present_prev_status);
    if (present_prev_status)
      list.add(prev_status.getValue());

    boolean present_component_debug = true && (is_set_component_debug());
    list.add(present_component_debug);
    if (present_component_debug)
      list.add(component_debug);

    boolean present_principal = true && (is_set_principal());
    list.add(present_principal);
    if (present_principal)
      list.add(principal);

    return list.hashCode();
  }

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

    int lastComparison = 0;

    lastComparison = Boolean.valueOf(is_set_name()).compareTo(other.is_set_name());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_name()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.name, other.name);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_status()).compareTo(other.is_set_status());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_status()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.status, other.status);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_num_workers()).compareTo(other.is_set_num_workers());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_num_workers()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.num_workers, other.num_workers);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_component_executors()).compareTo(other.is_set_component_executors());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_component_executors()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.component_executors, other.component_executors);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_launch_time_secs()).compareTo(other.is_set_launch_time_secs());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_launch_time_secs()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.launch_time_secs, other.launch_time_secs);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_owner()).compareTo(other.is_set_owner());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_owner()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.owner, other.owner);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_topology_action_options()).compareTo(other.is_set_topology_action_options());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_topology_action_options()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.topology_action_options, other.topology_action_options);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_prev_status()).compareTo(other.is_set_prev_status());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_prev_status()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.prev_status, other.prev_status);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_component_debug()).compareTo(other.is_set_component_debug());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_component_debug()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.component_debug, other.component_debug);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_principal()).compareTo(other.is_set_principal());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_principal()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.principal, other.principal);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

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

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

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

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

    sb.append("name:");
    if (this.name == null) {
      sb.append("null");
    } else {
      sb.append(this.name);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("status:");
    if (this.status == null) {
      sb.append("null");
    } else {
      sb.append(this.status);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("num_workers:");
    sb.append(this.num_workers);
    first = false;
    if (is_set_component_executors()) {
      if (!first) sb.append(", ");
      sb.append("component_executors:");
      if (this.component_executors == null) {
        sb.append("null");
      } else {
        sb.append(this.component_executors);
      }
      first = false;
    }
    if (is_set_launch_time_secs()) {
      if (!first) sb.append(", ");
      sb.append("launch_time_secs:");
      sb.append(this.launch_time_secs);
      first = false;
    }
    if (is_set_owner()) {
      if (!first) sb.append(", ");
      sb.append("owner:");
      if (this.owner == null) {
        sb.append("null");
      } else {
        sb.append(this.owner);
      }
      first = false;
    }
    if (is_set_topology_action_options()) {
      if (!first) sb.append(", ");
      sb.append("topology_action_options:");
      if (this.topology_action_options == null) {
        sb.append("null");
      } else {
        sb.append(this.topology_action_options);
      }
      first = false;
    }
    if (is_set_prev_status()) {
      if (!first) sb.append(", ");
      sb.append("prev_status:");
      if (this.prev_status == null) {
        sb.append("null");
      } else {
        sb.append(this.prev_status);
      }
      first = false;
    }
    if (is_set_component_debug()) {
      if (!first) sb.append(", ");
      sb.append("component_debug:");
      if (this.component_debug == null) {
        sb.append("null");
      } else {
        sb.append(this.component_debug);
      }
      first = false;
    }
    if (is_set_principal()) {
      if (!first) sb.append(", ");
      sb.append("principal:");
      if (this.principal == null) {
        sb.append("null");
      } else {
        sb.append(this.principal);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

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

    if (!is_set_num_workers()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'num_workers' 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.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
    try {
      // 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.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private static class StormBaseStandardSchemeFactory implements SchemeFactory {
    public StormBaseStandardScheme getScheme() {
      return new StormBaseStandardScheme();
    }
  }

  private static class StormBaseStandardScheme extends StandardScheme<StormBase> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, StormBase struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TField schemeField;
      iprot.readStructBegin();
      while (true)
      {
        schemeField = iprot.readFieldBegin();
        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
          break;
        }
        switch (schemeField.id) {
          case 1: // NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.name = iprot.readString();
              struct.set_name_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // STATUS
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.status = org.apache.storm.generated.TopologyStatus.findByValue(iprot.readI32());
              struct.set_status_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // NUM_WORKERS
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.num_workers = iprot.readI32();
              struct.set_num_workers_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // COMPONENT_EXECUTORS
            if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
              {
                org.apache.thrift.protocol.TMap _map604 = iprot.readMapBegin();
                struct.component_executors = new HashMap<String,Integer>(2*_map604.size);
                String _key605;
                int _val606;
                for (int _i607 = 0; _i607 < _map604.size; ++_i607)
                {
                  _key605 = iprot.readString();
                  _val606 = iprot.readI32();
                  struct.component_executors.put(_key605, _val606);
                }
                iprot.readMapEnd();
              }
              struct.set_component_executors_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // LAUNCH_TIME_SECS
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.launch_time_secs = iprot.readI32();
              struct.set_launch_time_secs_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // OWNER
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.owner = iprot.readString();
              struct.set_owner_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // TOPOLOGY_ACTION_OPTIONS
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.topology_action_options = new TopologyActionOptions();
              struct.topology_action_options.read(iprot);
              struct.set_topology_action_options_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // PREV_STATUS
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.prev_status = org.apache.storm.generated.TopologyStatus.findByValue(iprot.readI32());
              struct.set_prev_status_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // COMPONENT_DEBUG
            if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
              {
                org.apache.thrift.protocol.TMap _map608 = iprot.readMapBegin();
                struct.component_debug = new HashMap<String,DebugOptions>(2*_map608.size);
                String _key609;
                DebugOptions _val610;
                for (int _i611 = 0; _i611 < _map608.size; ++_i611)
                {
                  _key609 = iprot.readString();
                  _val610 = new DebugOptions();
                  _val610.read(iprot);
                  struct.component_debug.put(_key609, _val610);
                }
                iprot.readMapEnd();
              }
              struct.set_component_debug_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // PRINCIPAL
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.principal = iprot.readString();
              struct.set_principal_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          default:
            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
      struct.validate();
    }

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

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.name != null) {
        oprot.writeFieldBegin(NAME_FIELD_DESC);
        oprot.writeString(struct.name);
        oprot.writeFieldEnd();
      }
      if (struct.status != null) {
        oprot.writeFieldBegin(STATUS_FIELD_DESC);
        oprot.writeI32(struct.status.getValue());
        oprot.writeFieldEnd();
      }
      oprot.writeFieldBegin(NUM_WORKERS_FIELD_DESC);
      oprot.writeI32(struct.num_workers);
      oprot.writeFieldEnd();
      if (struct.component_executors != null) {
        if (struct.is_set_component_executors()) {
          oprot.writeFieldBegin(COMPONENT_EXECUTORS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.I32, struct.component_executors.size()));
            for (Map.Entry<String, Integer> _iter612 : struct.component_executors.entrySet())
            {
              oprot.writeString(_iter612.getKey());
              oprot.writeI32(_iter612.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.is_set_launch_time_secs()) {
        oprot.writeFieldBegin(LAUNCH_TIME_SECS_FIELD_DESC);
        oprot.writeI32(struct.launch_time_secs);
        oprot.writeFieldEnd();
      }
      if (struct.owner != null) {
        if (struct.is_set_owner()) {
          oprot.writeFieldBegin(OWNER_FIELD_DESC);
          oprot.writeString(struct.owner);
          oprot.writeFieldEnd();
        }
      }
      if (struct.topology_action_options != null) {
        if (struct.is_set_topology_action_options()) {
          oprot.writeFieldBegin(TOPOLOGY_ACTION_OPTIONS_FIELD_DESC);
          struct.topology_action_options.write(oprot);
          oprot.writeFieldEnd();
        }
      }
      if (struct.prev_status != null) {
        if (struct.is_set_prev_status()) {
          oprot.writeFieldBegin(PREV_STATUS_FIELD_DESC);
          oprot.writeI32(struct.prev_status.getValue());
          oprot.writeFieldEnd();
        }
      }
      if (struct.component_debug != null) {
        if (struct.is_set_component_debug()) {
          oprot.writeFieldBegin(COMPONENT_DEBUG_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRUCT, struct.component_debug.size()));
            for (Map.Entry<String, DebugOptions> _iter613 : struct.component_debug.entrySet())
            {
              oprot.writeString(_iter613.getKey());
              _iter613.getValue().write(oprot);
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.principal != null) {
        if (struct.is_set_principal()) {
          oprot.writeFieldBegin(PRINCIPAL_FIELD_DESC);
          oprot.writeString(struct.principal);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class StormBaseTupleSchemeFactory implements SchemeFactory {
    public StormBaseTupleScheme getScheme() {
      return new StormBaseTupleScheme();
    }
  }

  private static class StormBaseTupleScheme extends TupleScheme<StormBase> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, StormBase struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      oprot.writeString(struct.name);
      oprot.writeI32(struct.status.getValue());
      oprot.writeI32(struct.num_workers);
      BitSet optionals = new BitSet();
      if (struct.is_set_component_executors()) {
        optionals.set(0);
      }
      if (struct.is_set_launch_time_secs()) {
        optionals.set(1);
      }
      if (struct.is_set_owner()) {
        optionals.set(2);
      }
      if (struct.is_set_topology_action_options()) {
        optionals.set(3);
      }
      if (struct.is_set_prev_status()) {
        optionals.set(4);
      }
      if (struct.is_set_component_debug()) {
        optionals.set(5);
      }
      if (struct.is_set_principal()) {
        optionals.set(6);
      }
      oprot.writeBitSet(optionals, 7);
      if (struct.is_set_component_executors()) {
        {
          oprot.writeI32(struct.component_executors.size());
          for (Map.Entry<String, Integer> _iter614 : struct.component_executors.entrySet())
          {
            oprot.writeString(_iter614.getKey());
            oprot.writeI32(_iter614.getValue());
          }
        }
      }
      if (struct.is_set_launch_time_secs()) {
        oprot.writeI32(struct.launch_time_secs);
      }
      if (struct.is_set_owner()) {
        oprot.writeString(struct.owner);
      }
      if (struct.is_set_topology_action_options()) {
        struct.topology_action_options.write(oprot);
      }
      if (struct.is_set_prev_status()) {
        oprot.writeI32(struct.prev_status.getValue());
      }
      if (struct.is_set_component_debug()) {
        {
          oprot.writeI32(struct.component_debug.size());
          for (Map.Entry<String, DebugOptions> _iter615 : struct.component_debug.entrySet())
          {
            oprot.writeString(_iter615.getKey());
            _iter615.getValue().write(oprot);
          }
        }
      }
      if (struct.is_set_principal()) {
        oprot.writeString(struct.principal);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, StormBase struct) throws org.apache.thrift.TException {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      struct.name = iprot.readString();
      struct.set_name_isSet(true);
      struct.status = org.apache.storm.generated.TopologyStatus.findByValue(iprot.readI32());
      struct.set_status_isSet(true);
      struct.num_workers = iprot.readI32();
      struct.set_num_workers_isSet(true);
      BitSet incoming = iprot.readBitSet(7);
      if (incoming.get(0)) {
        {
          org.apache.thrift.protocol.TMap _map616 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.I32, iprot.readI32());
          struct.component_executors = new HashMap<String,Integer>(2*_map616.size);
          String _key617;
          int _val618;
          for (int _i619 = 0; _i619 < _map616.size; ++_i619)
          {
            _key617 = iprot.readString();
            _val618 = iprot.readI32();
            struct.component_executors.put(_key617, _val618);
          }
        }
        struct.set_component_executors_isSet(true);
      }
      if (incoming.get(1)) {
        struct.launch_time_secs = iprot.readI32();
        struct.set_launch_time_secs_isSet(true);
      }
      if (incoming.get(2)) {
        struct.owner = iprot.readString();
        struct.set_owner_isSet(true);
      }
      if (incoming.get(3)) {
        struct.topology_action_options = new TopologyActionOptions();
        struct.topology_action_options.read(iprot);
        struct.set_topology_action_options_isSet(true);
      }
      if (incoming.get(4)) {
        struct.prev_status = org.apache.storm.generated.TopologyStatus.findByValue(iprot.readI32());
        struct.set_prev_status_isSet(true);
      }
      if (incoming.get(5)) {
        {
          org.apache.thrift.protocol.TMap _map620 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.component_debug = new HashMap<String,DebugOptions>(2*_map620.size);
          String _key621;
          DebugOptions _val622;
          for (int _i623 = 0; _i623 < _map620.size; ++_i623)
          {
            _key621 = iprot.readString();
            _val622 = new DebugOptions();
            _val622.read(iprot);
            struct.component_debug.put(_key621, _val622);
          }
        }
        struct.set_component_debug_isSet(true);
      }
      if (incoming.get(6)) {
        struct.principal = iprot.readString();
        struct.set_principal_isSet(true);
      }
    }
  }

}

