/**
 * 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 TopologyInfo implements org.apache.thrift.TBase<TopologyInfo, TopologyInfo._Fields>, java.io.Serializable, Cloneable, Comparable<TopologyInfo> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TopologyInfo");

  private static final org.apache.thrift.protocol.TField ID_FIELD_DESC = new org.apache.thrift.protocol.TField("id", org.apache.thrift.protocol.TType.STRING, (short)1);
  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)2);
  private static final org.apache.thrift.protocol.TField UPTIME_SECS_FIELD_DESC = new org.apache.thrift.protocol.TField("uptime_secs", org.apache.thrift.protocol.TType.I32, (short)3);
  private static final org.apache.thrift.protocol.TField EXECUTORS_FIELD_DESC = new org.apache.thrift.protocol.TField("executors", org.apache.thrift.protocol.TType.LIST, (short)4);
  private static final org.apache.thrift.protocol.TField STATUS_FIELD_DESC = new org.apache.thrift.protocol.TField("status", org.apache.thrift.protocol.TType.STRING, (short)5);
  private static final org.apache.thrift.protocol.TField ERRORS_FIELD_DESC = new org.apache.thrift.protocol.TField("errors", org.apache.thrift.protocol.TType.MAP, (short)6);
  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)7);
  private static final org.apache.thrift.protocol.TField SCHED_STATUS_FIELD_DESC = new org.apache.thrift.protocol.TField("sched_status", org.apache.thrift.protocol.TType.STRING, (short)513);
  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)514);
  private static final org.apache.thrift.protocol.TField REPLICATION_COUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("replication_count", org.apache.thrift.protocol.TType.I32, (short)515);
  private static final org.apache.thrift.protocol.TField REQUESTED_MEMONHEAP_FIELD_DESC = new org.apache.thrift.protocol.TField("requested_memonheap", org.apache.thrift.protocol.TType.DOUBLE, (short)521);
  private static final org.apache.thrift.protocol.TField REQUESTED_MEMOFFHEAP_FIELD_DESC = new org.apache.thrift.protocol.TField("requested_memoffheap", org.apache.thrift.protocol.TType.DOUBLE, (short)522);
  private static final org.apache.thrift.protocol.TField REQUESTED_CPU_FIELD_DESC = new org.apache.thrift.protocol.TField("requested_cpu", org.apache.thrift.protocol.TType.DOUBLE, (short)523);
  private static final org.apache.thrift.protocol.TField ASSIGNED_MEMONHEAP_FIELD_DESC = new org.apache.thrift.protocol.TField("assigned_memonheap", org.apache.thrift.protocol.TType.DOUBLE, (short)524);
  private static final org.apache.thrift.protocol.TField ASSIGNED_MEMOFFHEAP_FIELD_DESC = new org.apache.thrift.protocol.TField("assigned_memoffheap", org.apache.thrift.protocol.TType.DOUBLE, (short)525);
  private static final org.apache.thrift.protocol.TField ASSIGNED_CPU_FIELD_DESC = new org.apache.thrift.protocol.TField("assigned_cpu", org.apache.thrift.protocol.TType.DOUBLE, (short)526);

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

  private String id; // required
  private String name; // required
  private int uptime_secs; // required
  private List<ExecutorSummary> executors; // required
  private String status; // required
  private Map<String,List<ErrorInfo>> errors; // required
  private Map<String,DebugOptions> component_debug; // optional
  private String sched_status; // optional
  private String owner; // optional
  private int replication_count; // optional
  private double requested_memonheap; // optional
  private double requested_memoffheap; // optional
  private double requested_cpu; // optional
  private double assigned_memonheap; // optional
  private double assigned_memoffheap; // optional
  private double assigned_cpu; // 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 {
    ID((short)1, "id"),
    NAME((short)2, "name"),
    UPTIME_SECS((short)3, "uptime_secs"),
    EXECUTORS((short)4, "executors"),
    STATUS((short)5, "status"),
    ERRORS((short)6, "errors"),
    COMPONENT_DEBUG((short)7, "component_debug"),
    SCHED_STATUS((short)513, "sched_status"),
    OWNER((short)514, "owner"),
    REPLICATION_COUNT((short)515, "replication_count"),
    REQUESTED_MEMONHEAP((short)521, "requested_memonheap"),
    REQUESTED_MEMOFFHEAP((short)522, "requested_memoffheap"),
    REQUESTED_CPU((short)523, "requested_cpu"),
    ASSIGNED_MEMONHEAP((short)524, "assigned_memonheap"),
    ASSIGNED_MEMOFFHEAP((short)525, "assigned_memoffheap"),
    ASSIGNED_CPU((short)526, "assigned_cpu");

    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: // ID
          return ID;
        case 2: // NAME
          return NAME;
        case 3: // UPTIME_SECS
          return UPTIME_SECS;
        case 4: // EXECUTORS
          return EXECUTORS;
        case 5: // STATUS
          return STATUS;
        case 6: // ERRORS
          return ERRORS;
        case 7: // COMPONENT_DEBUG
          return COMPONENT_DEBUG;
        case 513: // SCHED_STATUS
          return SCHED_STATUS;
        case 514: // OWNER
          return OWNER;
        case 515: // REPLICATION_COUNT
          return REPLICATION_COUNT;
        case 521: // REQUESTED_MEMONHEAP
          return REQUESTED_MEMONHEAP;
        case 522: // REQUESTED_MEMOFFHEAP
          return REQUESTED_MEMOFFHEAP;
        case 523: // REQUESTED_CPU
          return REQUESTED_CPU;
        case 524: // ASSIGNED_MEMONHEAP
          return ASSIGNED_MEMONHEAP;
        case 525: // ASSIGNED_MEMOFFHEAP
          return ASSIGNED_MEMOFFHEAP;
        case 526: // ASSIGNED_CPU
          return ASSIGNED_CPU;
        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 __UPTIME_SECS_ISSET_ID = 0;
  private static final int __REPLICATION_COUNT_ISSET_ID = 1;
  private static final int __REQUESTED_MEMONHEAP_ISSET_ID = 2;
  private static final int __REQUESTED_MEMOFFHEAP_ISSET_ID = 3;
  private static final int __REQUESTED_CPU_ISSET_ID = 4;
  private static final int __ASSIGNED_MEMONHEAP_ISSET_ID = 5;
  private static final int __ASSIGNED_MEMOFFHEAP_ISSET_ID = 6;
  private static final int __ASSIGNED_CPU_ISSET_ID = 7;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.COMPONENT_DEBUG,_Fields.SCHED_STATUS,_Fields.OWNER,_Fields.REPLICATION_COUNT,_Fields.REQUESTED_MEMONHEAP,_Fields.REQUESTED_MEMOFFHEAP,_Fields.REQUESTED_CPU,_Fields.ASSIGNED_MEMONHEAP,_Fields.ASSIGNED_MEMOFFHEAP,_Fields.ASSIGNED_CPU};
  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.ID, new org.apache.thrift.meta_data.FieldMetaData("id", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    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.UPTIME_SECS, new org.apache.thrift.meta_data.FieldMetaData("uptime_secs", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.EXECUTORS, new org.apache.thrift.meta_data.FieldMetaData("executors", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ExecutorSummary.class))));
    tmpMap.put(_Fields.STATUS, new org.apache.thrift.meta_data.FieldMetaData("status", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.ERRORS, new org.apache.thrift.meta_data.FieldMetaData("errors", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        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.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
                new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ErrorInfo.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.SCHED_STATUS, new org.apache.thrift.meta_data.FieldMetaData("sched_status", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    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.REPLICATION_COUNT, new org.apache.thrift.meta_data.FieldMetaData("replication_count", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.REQUESTED_MEMONHEAP, new org.apache.thrift.meta_data.FieldMetaData("requested_memonheap", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.REQUESTED_MEMOFFHEAP, new org.apache.thrift.meta_data.FieldMetaData("requested_memoffheap", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.REQUESTED_CPU, new org.apache.thrift.meta_data.FieldMetaData("requested_cpu", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.ASSIGNED_MEMONHEAP, new org.apache.thrift.meta_data.FieldMetaData("assigned_memonheap", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.ASSIGNED_MEMOFFHEAP, new org.apache.thrift.meta_data.FieldMetaData("assigned_memoffheap", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.ASSIGNED_CPU, new org.apache.thrift.meta_data.FieldMetaData("assigned_cpu", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.DOUBLE)));
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TopologyInfo.class, metaDataMap);
  }

  public TopologyInfo() {
  }

  public TopologyInfo(
    String id,
    String name,
    int uptime_secs,
    List<ExecutorSummary> executors,
    String status,
    Map<String,List<ErrorInfo>> errors)
  {
    this();
    this.id = id;
    this.name = name;
    this.uptime_secs = uptime_secs;
    set_uptime_secs_isSet(true);
    this.executors = executors;
    this.status = status;
    this.errors = errors;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public TopologyInfo(TopologyInfo other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.is_set_id()) {
      this.id = other.id;
    }
    if (other.is_set_name()) {
      this.name = other.name;
    }
    this.uptime_secs = other.uptime_secs;
    if (other.is_set_executors()) {
      List<ExecutorSummary> __this__executors = new ArrayList<ExecutorSummary>(other.executors.size());
      for (ExecutorSummary other_element : other.executors) {
        __this__executors.add(new ExecutorSummary(other_element));
      }
      this.executors = __this__executors;
    }
    if (other.is_set_status()) {
      this.status = other.status;
    }
    if (other.is_set_errors()) {
      Map<String,List<ErrorInfo>> __this__errors = new HashMap<String,List<ErrorInfo>>(other.errors.size());
      for (Map.Entry<String, List<ErrorInfo>> other_element : other.errors.entrySet()) {

        String other_element_key = other_element.getKey();
        List<ErrorInfo> other_element_value = other_element.getValue();

        String __this__errors_copy_key = other_element_key;

        List<ErrorInfo> __this__errors_copy_value = new ArrayList<ErrorInfo>(other_element_value.size());
        for (ErrorInfo other_element_value_element : other_element_value) {
          __this__errors_copy_value.add(new ErrorInfo(other_element_value_element));
        }

        __this__errors.put(__this__errors_copy_key, __this__errors_copy_value);
      }
      this.errors = __this__errors;
    }
    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_sched_status()) {
      this.sched_status = other.sched_status;
    }
    if (other.is_set_owner()) {
      this.owner = other.owner;
    }
    this.replication_count = other.replication_count;
    this.requested_memonheap = other.requested_memonheap;
    this.requested_memoffheap = other.requested_memoffheap;
    this.requested_cpu = other.requested_cpu;
    this.assigned_memonheap = other.assigned_memonheap;
    this.assigned_memoffheap = other.assigned_memoffheap;
    this.assigned_cpu = other.assigned_cpu;
  }

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

  @Override
  public void clear() {
    this.id = null;
    this.name = null;
    set_uptime_secs_isSet(false);
    this.uptime_secs = 0;
    this.executors = null;
    this.status = null;
    this.errors = null;
    this.component_debug = null;
    this.sched_status = null;
    this.owner = null;
    set_replication_count_isSet(false);
    this.replication_count = 0;
    set_requested_memonheap_isSet(false);
    this.requested_memonheap = 0.0;
    set_requested_memoffheap_isSet(false);
    this.requested_memoffheap = 0.0;
    set_requested_cpu_isSet(false);
    this.requested_cpu = 0.0;
    set_assigned_memonheap_isSet(false);
    this.assigned_memonheap = 0.0;
    set_assigned_memoffheap_isSet(false);
    this.assigned_memoffheap = 0.0;
    set_assigned_cpu_isSet(false);
    this.assigned_cpu = 0.0;
  }

  public String get_id() {
    return this.id;
  }

  public void set_id(String id) {
    this.id = id;
  }

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

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

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

  public 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;
    }
  }

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

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

  public void unset_uptime_secs() {
    __isset_bitfield = 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 EncodingUtils.testBit(__isset_bitfield, __UPTIME_SECS_ISSET_ID);
  }

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

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

  public java.util.Iterator<ExecutorSummary> get_executors_iterator() {
    return (this.executors == null) ? null : this.executors.iterator();
  }

  public void add_to_executors(ExecutorSummary elem) {
    if (this.executors == null) {
      this.executors = new ArrayList<ExecutorSummary>();
    }
    this.executors.add(elem);
  }

  public List<ExecutorSummary> get_executors() {
    return this.executors;
  }

  public void set_executors(List<ExecutorSummary> executors) {
    this.executors = executors;
  }

  public void unset_executors() {
    this.executors = null;
  }

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

  public void set_executors_isSet(boolean value) {
    if (!value) {
      this.executors = null;
    }
  }

  public String get_status() {
    return this.status;
  }

  public void set_status(String 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_errors_size() {
    return (this.errors == null) ? 0 : this.errors.size();
  }

  public void put_to_errors(String key, List<ErrorInfo> val) {
    if (this.errors == null) {
      this.errors = new HashMap<String,List<ErrorInfo>>();
    }
    this.errors.put(key, val);
  }

  public Map<String,List<ErrorInfo>> get_errors() {
    return this.errors;
  }

  public void set_errors(Map<String,List<ErrorInfo>> errors) {
    this.errors = errors;
  }

  public void unset_errors() {
    this.errors = null;
  }

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

  public void set_errors_isSet(boolean value) {
    if (!value) {
      this.errors = 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_sched_status() {
    return this.sched_status;
  }

  public void set_sched_status(String sched_status) {
    this.sched_status = sched_status;
  }

  public void unset_sched_status() {
    this.sched_status = null;
  }

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

  public void set_sched_status_isSet(boolean value) {
    if (!value) {
      this.sched_status = null;
    }
  }

  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 int get_replication_count() {
    return this.replication_count;
  }

  public void set_replication_count(int replication_count) {
    this.replication_count = replication_count;
    set_replication_count_isSet(true);
  }

  public void unset_replication_count() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __REPLICATION_COUNT_ISSET_ID);
  }

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

  public void set_replication_count_isSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __REPLICATION_COUNT_ISSET_ID, value);
  }

  public double get_requested_memonheap() {
    return this.requested_memonheap;
  }

  public void set_requested_memonheap(double requested_memonheap) {
    this.requested_memonheap = requested_memonheap;
    set_requested_memonheap_isSet(true);
  }

  public void unset_requested_memonheap() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __REQUESTED_MEMONHEAP_ISSET_ID);
  }

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

  public void set_requested_memonheap_isSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __REQUESTED_MEMONHEAP_ISSET_ID, value);
  }

  public double get_requested_memoffheap() {
    return this.requested_memoffheap;
  }

  public void set_requested_memoffheap(double requested_memoffheap) {
    this.requested_memoffheap = requested_memoffheap;
    set_requested_memoffheap_isSet(true);
  }

  public void unset_requested_memoffheap() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __REQUESTED_MEMOFFHEAP_ISSET_ID);
  }

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

  public void set_requested_memoffheap_isSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __REQUESTED_MEMOFFHEAP_ISSET_ID, value);
  }

  public double get_requested_cpu() {
    return this.requested_cpu;
  }

  public void set_requested_cpu(double requested_cpu) {
    this.requested_cpu = requested_cpu;
    set_requested_cpu_isSet(true);
  }

  public void unset_requested_cpu() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __REQUESTED_CPU_ISSET_ID);
  }

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

  public void set_requested_cpu_isSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __REQUESTED_CPU_ISSET_ID, value);
  }

  public double get_assigned_memonheap() {
    return this.assigned_memonheap;
  }

  public void set_assigned_memonheap(double assigned_memonheap) {
    this.assigned_memonheap = assigned_memonheap;
    set_assigned_memonheap_isSet(true);
  }

  public void unset_assigned_memonheap() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ASSIGNED_MEMONHEAP_ISSET_ID);
  }

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

  public void set_assigned_memonheap_isSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ASSIGNED_MEMONHEAP_ISSET_ID, value);
  }

  public double get_assigned_memoffheap() {
    return this.assigned_memoffheap;
  }

  public void set_assigned_memoffheap(double assigned_memoffheap) {
    this.assigned_memoffheap = assigned_memoffheap;
    set_assigned_memoffheap_isSet(true);
  }

  public void unset_assigned_memoffheap() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ASSIGNED_MEMOFFHEAP_ISSET_ID);
  }

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

  public void set_assigned_memoffheap_isSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ASSIGNED_MEMOFFHEAP_ISSET_ID, value);
  }

  public double get_assigned_cpu() {
    return this.assigned_cpu;
  }

  public void set_assigned_cpu(double assigned_cpu) {
    this.assigned_cpu = assigned_cpu;
    set_assigned_cpu_isSet(true);
  }

  public void unset_assigned_cpu() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ASSIGNED_CPU_ISSET_ID);
  }

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

  public void set_assigned_cpu_isSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ASSIGNED_CPU_ISSET_ID, value);
  }

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case ID:
      if (value == null) {
        unset_id();
      } else {
        set_id((String)value);
      }
      break;

    case NAME:
      if (value == null) {
        unset_name();
      } else {
        set_name((String)value);
      }
      break;

    case UPTIME_SECS:
      if (value == null) {
        unset_uptime_secs();
      } else {
        set_uptime_secs((Integer)value);
      }
      break;

    case EXECUTORS:
      if (value == null) {
        unset_executors();
      } else {
        set_executors((List<ExecutorSummary>)value);
      }
      break;

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

    case ERRORS:
      if (value == null) {
        unset_errors();
      } else {
        set_errors((Map<String,List<ErrorInfo>>)value);
      }
      break;

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

    case SCHED_STATUS:
      if (value == null) {
        unset_sched_status();
      } else {
        set_sched_status((String)value);
      }
      break;

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

    case REPLICATION_COUNT:
      if (value == null) {
        unset_replication_count();
      } else {
        set_replication_count((Integer)value);
      }
      break;

    case REQUESTED_MEMONHEAP:
      if (value == null) {
        unset_requested_memonheap();
      } else {
        set_requested_memonheap((Double)value);
      }
      break;

    case REQUESTED_MEMOFFHEAP:
      if (value == null) {
        unset_requested_memoffheap();
      } else {
        set_requested_memoffheap((Double)value);
      }
      break;

    case REQUESTED_CPU:
      if (value == null) {
        unset_requested_cpu();
      } else {
        set_requested_cpu((Double)value);
      }
      break;

    case ASSIGNED_MEMONHEAP:
      if (value == null) {
        unset_assigned_memonheap();
      } else {
        set_assigned_memonheap((Double)value);
      }
      break;

    case ASSIGNED_MEMOFFHEAP:
      if (value == null) {
        unset_assigned_memoffheap();
      } else {
        set_assigned_memoffheap((Double)value);
      }
      break;

    case ASSIGNED_CPU:
      if (value == null) {
        unset_assigned_cpu();
      } else {
        set_assigned_cpu((Double)value);
      }
      break;

    }
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case ID:
      return get_id();

    case NAME:
      return get_name();

    case UPTIME_SECS:
      return get_uptime_secs();

    case EXECUTORS:
      return get_executors();

    case STATUS:
      return get_status();

    case ERRORS:
      return get_errors();

    case COMPONENT_DEBUG:
      return get_component_debug();

    case SCHED_STATUS:
      return get_sched_status();

    case OWNER:
      return get_owner();

    case REPLICATION_COUNT:
      return get_replication_count();

    case REQUESTED_MEMONHEAP:
      return get_requested_memonheap();

    case REQUESTED_MEMOFFHEAP:
      return get_requested_memoffheap();

    case REQUESTED_CPU:
      return get_requested_cpu();

    case ASSIGNED_MEMONHEAP:
      return get_assigned_memonheap();

    case ASSIGNED_MEMOFFHEAP:
      return get_assigned_memoffheap();

    case ASSIGNED_CPU:
      return get_assigned_cpu();

    }
    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 ID:
      return is_set_id();
    case NAME:
      return is_set_name();
    case UPTIME_SECS:
      return is_set_uptime_secs();
    case EXECUTORS:
      return is_set_executors();
    case STATUS:
      return is_set_status();
    case ERRORS:
      return is_set_errors();
    case COMPONENT_DEBUG:
      return is_set_component_debug();
    case SCHED_STATUS:
      return is_set_sched_status();
    case OWNER:
      return is_set_owner();
    case REPLICATION_COUNT:
      return is_set_replication_count();
    case REQUESTED_MEMONHEAP:
      return is_set_requested_memonheap();
    case REQUESTED_MEMOFFHEAP:
      return is_set_requested_memoffheap();
    case REQUESTED_CPU:
      return is_set_requested_cpu();
    case ASSIGNED_MEMONHEAP:
      return is_set_assigned_memonheap();
    case ASSIGNED_MEMOFFHEAP:
      return is_set_assigned_memoffheap();
    case ASSIGNED_CPU:
      return is_set_assigned_cpu();
    }
    throw new IllegalStateException();
  }

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

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

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

    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_uptime_secs = true;
    boolean that_present_uptime_secs = true;
    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_executors = true && this.is_set_executors();
    boolean that_present_executors = true && that.is_set_executors();
    if (this_present_executors || that_present_executors) {
      if (!(this_present_executors && that_present_executors))
        return false;
      if (!this.executors.equals(that.executors))
        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_errors = true && this.is_set_errors();
    boolean that_present_errors = true && that.is_set_errors();
    if (this_present_errors || that_present_errors) {
      if (!(this_present_errors && that_present_errors))
        return false;
      if (!this.errors.equals(that.errors))
        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_sched_status = true && this.is_set_sched_status();
    boolean that_present_sched_status = true && that.is_set_sched_status();
    if (this_present_sched_status || that_present_sched_status) {
      if (!(this_present_sched_status && that_present_sched_status))
        return false;
      if (!this.sched_status.equals(that.sched_status))
        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_replication_count = true && this.is_set_replication_count();
    boolean that_present_replication_count = true && that.is_set_replication_count();
    if (this_present_replication_count || that_present_replication_count) {
      if (!(this_present_replication_count && that_present_replication_count))
        return false;
      if (this.replication_count != that.replication_count)
        return false;
    }

    boolean this_present_requested_memonheap = true && this.is_set_requested_memonheap();
    boolean that_present_requested_memonheap = true && that.is_set_requested_memonheap();
    if (this_present_requested_memonheap || that_present_requested_memonheap) {
      if (!(this_present_requested_memonheap && that_present_requested_memonheap))
        return false;
      if (this.requested_memonheap != that.requested_memonheap)
        return false;
    }

    boolean this_present_requested_memoffheap = true && this.is_set_requested_memoffheap();
    boolean that_present_requested_memoffheap = true && that.is_set_requested_memoffheap();
    if (this_present_requested_memoffheap || that_present_requested_memoffheap) {
      if (!(this_present_requested_memoffheap && that_present_requested_memoffheap))
        return false;
      if (this.requested_memoffheap != that.requested_memoffheap)
        return false;
    }

    boolean this_present_requested_cpu = true && this.is_set_requested_cpu();
    boolean that_present_requested_cpu = true && that.is_set_requested_cpu();
    if (this_present_requested_cpu || that_present_requested_cpu) {
      if (!(this_present_requested_cpu && that_present_requested_cpu))
        return false;
      if (this.requested_cpu != that.requested_cpu)
        return false;
    }

    boolean this_present_assigned_memonheap = true && this.is_set_assigned_memonheap();
    boolean that_present_assigned_memonheap = true && that.is_set_assigned_memonheap();
    if (this_present_assigned_memonheap || that_present_assigned_memonheap) {
      if (!(this_present_assigned_memonheap && that_present_assigned_memonheap))
        return false;
      if (this.assigned_memonheap != that.assigned_memonheap)
        return false;
    }

    boolean this_present_assigned_memoffheap = true && this.is_set_assigned_memoffheap();
    boolean that_present_assigned_memoffheap = true && that.is_set_assigned_memoffheap();
    if (this_present_assigned_memoffheap || that_present_assigned_memoffheap) {
      if (!(this_present_assigned_memoffheap && that_present_assigned_memoffheap))
        return false;
      if (this.assigned_memoffheap != that.assigned_memoffheap)
        return false;
    }

    boolean this_present_assigned_cpu = true && this.is_set_assigned_cpu();
    boolean that_present_assigned_cpu = true && that.is_set_assigned_cpu();
    if (this_present_assigned_cpu || that_present_assigned_cpu) {
      if (!(this_present_assigned_cpu && that_present_assigned_cpu))
        return false;
      if (this.assigned_cpu != that.assigned_cpu)
        return false;
    }

    return true;
  }

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

    boolean present_id = true && (is_set_id());
    list.add(present_id);
    if (present_id)
      list.add(id);

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

    boolean present_uptime_secs = true;
    list.add(present_uptime_secs);
    if (present_uptime_secs)
      list.add(uptime_secs);

    boolean present_executors = true && (is_set_executors());
    list.add(present_executors);
    if (present_executors)
      list.add(executors);

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

    boolean present_errors = true && (is_set_errors());
    list.add(present_errors);
    if (present_errors)
      list.add(errors);

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

    boolean present_sched_status = true && (is_set_sched_status());
    list.add(present_sched_status);
    if (present_sched_status)
      list.add(sched_status);

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

    boolean present_replication_count = true && (is_set_replication_count());
    list.add(present_replication_count);
    if (present_replication_count)
      list.add(replication_count);

    boolean present_requested_memonheap = true && (is_set_requested_memonheap());
    list.add(present_requested_memonheap);
    if (present_requested_memonheap)
      list.add(requested_memonheap);

    boolean present_requested_memoffheap = true && (is_set_requested_memoffheap());
    list.add(present_requested_memoffheap);
    if (present_requested_memoffheap)
      list.add(requested_memoffheap);

    boolean present_requested_cpu = true && (is_set_requested_cpu());
    list.add(present_requested_cpu);
    if (present_requested_cpu)
      list.add(requested_cpu);

    boolean present_assigned_memonheap = true && (is_set_assigned_memonheap());
    list.add(present_assigned_memonheap);
    if (present_assigned_memonheap)
      list.add(assigned_memonheap);

    boolean present_assigned_memoffheap = true && (is_set_assigned_memoffheap());
    list.add(present_assigned_memoffheap);
    if (present_assigned_memoffheap)
      list.add(assigned_memoffheap);

    boolean present_assigned_cpu = true && (is_set_assigned_cpu());
    list.add(present_assigned_cpu);
    if (present_assigned_cpu)
      list.add(assigned_cpu);

    return list.hashCode();
  }

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

    int lastComparison = 0;

    lastComparison = Boolean.valueOf(is_set_id()).compareTo(other.is_set_id());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_id()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.id, other.id);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    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_uptime_secs()).compareTo(other.is_set_uptime_secs());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_uptime_secs()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.uptime_secs, other.uptime_secs);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_executors()).compareTo(other.is_set_executors());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_executors()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.executors, other.executors);
      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_errors()).compareTo(other.is_set_errors());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_errors()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.errors, other.errors);
      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_sched_status()).compareTo(other.is_set_sched_status());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_sched_status()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sched_status, other.sched_status);
      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_replication_count()).compareTo(other.is_set_replication_count());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_replication_count()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.replication_count, other.replication_count);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_requested_memonheap()).compareTo(other.is_set_requested_memonheap());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_requested_memonheap()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.requested_memonheap, other.requested_memonheap);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_requested_memoffheap()).compareTo(other.is_set_requested_memoffheap());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_requested_memoffheap()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.requested_memoffheap, other.requested_memoffheap);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_requested_cpu()).compareTo(other.is_set_requested_cpu());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_requested_cpu()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.requested_cpu, other.requested_cpu);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_assigned_memonheap()).compareTo(other.is_set_assigned_memonheap());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_assigned_memonheap()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.assigned_memonheap, other.assigned_memonheap);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_assigned_memoffheap()).compareTo(other.is_set_assigned_memoffheap());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_assigned_memoffheap()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.assigned_memoffheap, other.assigned_memoffheap);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_assigned_cpu()).compareTo(other.is_set_assigned_cpu());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_assigned_cpu()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.assigned_cpu, other.assigned_cpu);
      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("TopologyInfo(");
    boolean first = true;

    sb.append("id:");
    if (this.id == null) {
      sb.append("null");
    } else {
      sb.append(this.id);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("name:");
    if (this.name == null) {
      sb.append("null");
    } else {
      sb.append(this.name);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("uptime_secs:");
    sb.append(this.uptime_secs);
    first = false;
    if (!first) sb.append(", ");
    sb.append("executors:");
    if (this.executors == null) {
      sb.append("null");
    } else {
      sb.append(this.executors);
    }
    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("errors:");
    if (this.errors == null) {
      sb.append("null");
    } else {
      sb.append(this.errors);
    }
    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_sched_status()) {
      if (!first) sb.append(", ");
      sb.append("sched_status:");
      if (this.sched_status == null) {
        sb.append("null");
      } else {
        sb.append(this.sched_status);
      }
      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_replication_count()) {
      if (!first) sb.append(", ");
      sb.append("replication_count:");
      sb.append(this.replication_count);
      first = false;
    }
    if (is_set_requested_memonheap()) {
      if (!first) sb.append(", ");
      sb.append("requested_memonheap:");
      sb.append(this.requested_memonheap);
      first = false;
    }
    if (is_set_requested_memoffheap()) {
      if (!first) sb.append(", ");
      sb.append("requested_memoffheap:");
      sb.append(this.requested_memoffheap);
      first = false;
    }
    if (is_set_requested_cpu()) {
      if (!first) sb.append(", ");
      sb.append("requested_cpu:");
      sb.append(this.requested_cpu);
      first = false;
    }
    if (is_set_assigned_memonheap()) {
      if (!first) sb.append(", ");
      sb.append("assigned_memonheap:");
      sb.append(this.assigned_memonheap);
      first = false;
    }
    if (is_set_assigned_memoffheap()) {
      if (!first) sb.append(", ");
      sb.append("assigned_memoffheap:");
      sb.append(this.assigned_memoffheap);
      first = false;
    }
    if (is_set_assigned_cpu()) {
      if (!first) sb.append(", ");
      sb.append("assigned_cpu:");
      sb.append(this.assigned_cpu);
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

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

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

    if (!is_set_executors()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'executors' 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_errors()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'errors' 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 TopologyInfoStandardSchemeFactory implements SchemeFactory {
    public TopologyInfoStandardScheme getScheme() {
      return new TopologyInfoStandardScheme();
    }
  }

  private static class TopologyInfoStandardScheme extends StandardScheme<TopologyInfo> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, TopologyInfo 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: // ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.id = iprot.readString();
              struct.set_id_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // 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 3: // UPTIME_SECS
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.uptime_secs = iprot.readI32();
              struct.set_uptime_secs_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // EXECUTORS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list316 = iprot.readListBegin();
                struct.executors = new ArrayList<ExecutorSummary>(_list316.size);
                ExecutorSummary _elem317;
                for (int _i318 = 0; _i318 < _list316.size; ++_i318)
                {
                  _elem317 = new ExecutorSummary();
                  _elem317.read(iprot);
                  struct.executors.add(_elem317);
                }
                iprot.readListEnd();
              }
              struct.set_executors_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // STATUS
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.status = iprot.readString();
              struct.set_status_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // ERRORS
            if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
              {
                org.apache.thrift.protocol.TMap _map319 = iprot.readMapBegin();
                struct.errors = new HashMap<String,List<ErrorInfo>>(2*_map319.size);
                String _key320;
                List<ErrorInfo> _val321;
                for (int _i322 = 0; _i322 < _map319.size; ++_i322)
                {
                  _key320 = iprot.readString();
                  {
                    org.apache.thrift.protocol.TList _list323 = iprot.readListBegin();
                    _val321 = new ArrayList<ErrorInfo>(_list323.size);
                    ErrorInfo _elem324;
                    for (int _i325 = 0; _i325 < _list323.size; ++_i325)
                    {
                      _elem324 = new ErrorInfo();
                      _elem324.read(iprot);
                      _val321.add(_elem324);
                    }
                    iprot.readListEnd();
                  }
                  struct.errors.put(_key320, _val321);
                }
                iprot.readMapEnd();
              }
              struct.set_errors_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // COMPONENT_DEBUG
            if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
              {
                org.apache.thrift.protocol.TMap _map326 = iprot.readMapBegin();
                struct.component_debug = new HashMap<String,DebugOptions>(2*_map326.size);
                String _key327;
                DebugOptions _val328;
                for (int _i329 = 0; _i329 < _map326.size; ++_i329)
                {
                  _key327 = iprot.readString();
                  _val328 = new DebugOptions();
                  _val328.read(iprot);
                  struct.component_debug.put(_key327, _val328);
                }
                iprot.readMapEnd();
              }
              struct.set_component_debug_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 513: // SCHED_STATUS
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.sched_status = iprot.readString();
              struct.set_sched_status_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 514: // 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 515: // REPLICATION_COUNT
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.replication_count = iprot.readI32();
              struct.set_replication_count_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 521: // REQUESTED_MEMONHEAP
            if (schemeField.type == org.apache.thrift.protocol.TType.DOUBLE) {
              struct.requested_memonheap = iprot.readDouble();
              struct.set_requested_memonheap_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 522: // REQUESTED_MEMOFFHEAP
            if (schemeField.type == org.apache.thrift.protocol.TType.DOUBLE) {
              struct.requested_memoffheap = iprot.readDouble();
              struct.set_requested_memoffheap_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 523: // REQUESTED_CPU
            if (schemeField.type == org.apache.thrift.protocol.TType.DOUBLE) {
              struct.requested_cpu = iprot.readDouble();
              struct.set_requested_cpu_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 524: // ASSIGNED_MEMONHEAP
            if (schemeField.type == org.apache.thrift.protocol.TType.DOUBLE) {
              struct.assigned_memonheap = iprot.readDouble();
              struct.set_assigned_memonheap_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 525: // ASSIGNED_MEMOFFHEAP
            if (schemeField.type == org.apache.thrift.protocol.TType.DOUBLE) {
              struct.assigned_memoffheap = iprot.readDouble();
              struct.set_assigned_memoffheap_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 526: // ASSIGNED_CPU
            if (schemeField.type == org.apache.thrift.protocol.TType.DOUBLE) {
              struct.assigned_cpu = iprot.readDouble();
              struct.set_assigned_cpu_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, TopologyInfo struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.id != null) {
        oprot.writeFieldBegin(ID_FIELD_DESC);
        oprot.writeString(struct.id);
        oprot.writeFieldEnd();
      }
      if (struct.name != null) {
        oprot.writeFieldBegin(NAME_FIELD_DESC);
        oprot.writeString(struct.name);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldBegin(UPTIME_SECS_FIELD_DESC);
      oprot.writeI32(struct.uptime_secs);
      oprot.writeFieldEnd();
      if (struct.executors != null) {
        oprot.writeFieldBegin(EXECUTORS_FIELD_DESC);
        {
          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.executors.size()));
          for (ExecutorSummary _iter330 : struct.executors)
          {
            _iter330.write(oprot);
          }
          oprot.writeListEnd();
        }
        oprot.writeFieldEnd();
      }
      if (struct.status != null) {
        oprot.writeFieldBegin(STATUS_FIELD_DESC);
        oprot.writeString(struct.status);
        oprot.writeFieldEnd();
      }
      if (struct.errors != null) {
        oprot.writeFieldBegin(ERRORS_FIELD_DESC);
        {
          oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.LIST, struct.errors.size()));
          for (Map.Entry<String, List<ErrorInfo>> _iter331 : struct.errors.entrySet())
          {
            oprot.writeString(_iter331.getKey());
            {
              oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, _iter331.getValue().size()));
              for (ErrorInfo _iter332 : _iter331.getValue())
              {
                _iter332.write(oprot);
              }
              oprot.writeListEnd();
            }
          }
          oprot.writeMapEnd();
        }
        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> _iter333 : struct.component_debug.entrySet())
            {
              oprot.writeString(_iter333.getKey());
              _iter333.getValue().write(oprot);
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.sched_status != null) {
        if (struct.is_set_sched_status()) {
          oprot.writeFieldBegin(SCHED_STATUS_FIELD_DESC);
          oprot.writeString(struct.sched_status);
          oprot.writeFieldEnd();
        }
      }
      if (struct.owner != null) {
        if (struct.is_set_owner()) {
          oprot.writeFieldBegin(OWNER_FIELD_DESC);
          oprot.writeString(struct.owner);
          oprot.writeFieldEnd();
        }
      }
      if (struct.is_set_replication_count()) {
        oprot.writeFieldBegin(REPLICATION_COUNT_FIELD_DESC);
        oprot.writeI32(struct.replication_count);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_requested_memonheap()) {
        oprot.writeFieldBegin(REQUESTED_MEMONHEAP_FIELD_DESC);
        oprot.writeDouble(struct.requested_memonheap);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_requested_memoffheap()) {
        oprot.writeFieldBegin(REQUESTED_MEMOFFHEAP_FIELD_DESC);
        oprot.writeDouble(struct.requested_memoffheap);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_requested_cpu()) {
        oprot.writeFieldBegin(REQUESTED_CPU_FIELD_DESC);
        oprot.writeDouble(struct.requested_cpu);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_assigned_memonheap()) {
        oprot.writeFieldBegin(ASSIGNED_MEMONHEAP_FIELD_DESC);
        oprot.writeDouble(struct.assigned_memonheap);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_assigned_memoffheap()) {
        oprot.writeFieldBegin(ASSIGNED_MEMOFFHEAP_FIELD_DESC);
        oprot.writeDouble(struct.assigned_memoffheap);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_assigned_cpu()) {
        oprot.writeFieldBegin(ASSIGNED_CPU_FIELD_DESC);
        oprot.writeDouble(struct.assigned_cpu);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class TopologyInfoTupleSchemeFactory implements SchemeFactory {
    public TopologyInfoTupleScheme getScheme() {
      return new TopologyInfoTupleScheme();
    }
  }

  private static class TopologyInfoTupleScheme extends TupleScheme<TopologyInfo> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, TopologyInfo struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      oprot.writeString(struct.id);
      oprot.writeString(struct.name);
      oprot.writeI32(struct.uptime_secs);
      {
        oprot.writeI32(struct.executors.size());
        for (ExecutorSummary _iter334 : struct.executors)
        {
          _iter334.write(oprot);
        }
      }
      oprot.writeString(struct.status);
      {
        oprot.writeI32(struct.errors.size());
        for (Map.Entry<String, List<ErrorInfo>> _iter335 : struct.errors.entrySet())
        {
          oprot.writeString(_iter335.getKey());
          {
            oprot.writeI32(_iter335.getValue().size());
            for (ErrorInfo _iter336 : _iter335.getValue())
            {
              _iter336.write(oprot);
            }
          }
        }
      }
      BitSet optionals = new BitSet();
      if (struct.is_set_component_debug()) {
        optionals.set(0);
      }
      if (struct.is_set_sched_status()) {
        optionals.set(1);
      }
      if (struct.is_set_owner()) {
        optionals.set(2);
      }
      if (struct.is_set_replication_count()) {
        optionals.set(3);
      }
      if (struct.is_set_requested_memonheap()) {
        optionals.set(4);
      }
      if (struct.is_set_requested_memoffheap()) {
        optionals.set(5);
      }
      if (struct.is_set_requested_cpu()) {
        optionals.set(6);
      }
      if (struct.is_set_assigned_memonheap()) {
        optionals.set(7);
      }
      if (struct.is_set_assigned_memoffheap()) {
        optionals.set(8);
      }
      if (struct.is_set_assigned_cpu()) {
        optionals.set(9);
      }
      oprot.writeBitSet(optionals, 10);
      if (struct.is_set_component_debug()) {
        {
          oprot.writeI32(struct.component_debug.size());
          for (Map.Entry<String, DebugOptions> _iter337 : struct.component_debug.entrySet())
          {
            oprot.writeString(_iter337.getKey());
            _iter337.getValue().write(oprot);
          }
        }
      }
      if (struct.is_set_sched_status()) {
        oprot.writeString(struct.sched_status);
      }
      if (struct.is_set_owner()) {
        oprot.writeString(struct.owner);
      }
      if (struct.is_set_replication_count()) {
        oprot.writeI32(struct.replication_count);
      }
      if (struct.is_set_requested_memonheap()) {
        oprot.writeDouble(struct.requested_memonheap);
      }
      if (struct.is_set_requested_memoffheap()) {
        oprot.writeDouble(struct.requested_memoffheap);
      }
      if (struct.is_set_requested_cpu()) {
        oprot.writeDouble(struct.requested_cpu);
      }
      if (struct.is_set_assigned_memonheap()) {
        oprot.writeDouble(struct.assigned_memonheap);
      }
      if (struct.is_set_assigned_memoffheap()) {
        oprot.writeDouble(struct.assigned_memoffheap);
      }
      if (struct.is_set_assigned_cpu()) {
        oprot.writeDouble(struct.assigned_cpu);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, TopologyInfo struct) throws org.apache.thrift.TException {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      struct.id = iprot.readString();
      struct.set_id_isSet(true);
      struct.name = iprot.readString();
      struct.set_name_isSet(true);
      struct.uptime_secs = iprot.readI32();
      struct.set_uptime_secs_isSet(true);
      {
        org.apache.thrift.protocol.TList _list338 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
        struct.executors = new ArrayList<ExecutorSummary>(_list338.size);
        ExecutorSummary _elem339;
        for (int _i340 = 0; _i340 < _list338.size; ++_i340)
        {
          _elem339 = new ExecutorSummary();
          _elem339.read(iprot);
          struct.executors.add(_elem339);
        }
      }
      struct.set_executors_isSet(true);
      struct.status = iprot.readString();
      struct.set_status_isSet(true);
      {
        org.apache.thrift.protocol.TMap _map341 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.LIST, iprot.readI32());
        struct.errors = new HashMap<String,List<ErrorInfo>>(2*_map341.size);
        String _key342;
        List<ErrorInfo> _val343;
        for (int _i344 = 0; _i344 < _map341.size; ++_i344)
        {
          _key342 = iprot.readString();
          {
            org.apache.thrift.protocol.TList _list345 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            _val343 = new ArrayList<ErrorInfo>(_list345.size);
            ErrorInfo _elem346;
            for (int _i347 = 0; _i347 < _list345.size; ++_i347)
            {
              _elem346 = new ErrorInfo();
              _elem346.read(iprot);
              _val343.add(_elem346);
            }
          }
          struct.errors.put(_key342, _val343);
        }
      }
      struct.set_errors_isSet(true);
      BitSet incoming = iprot.readBitSet(10);
      if (incoming.get(0)) {
        {
          org.apache.thrift.protocol.TMap _map348 = 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*_map348.size);
          String _key349;
          DebugOptions _val350;
          for (int _i351 = 0; _i351 < _map348.size; ++_i351)
          {
            _key349 = iprot.readString();
            _val350 = new DebugOptions();
            _val350.read(iprot);
            struct.component_debug.put(_key349, _val350);
          }
        }
        struct.set_component_debug_isSet(true);
      }
      if (incoming.get(1)) {
        struct.sched_status = iprot.readString();
        struct.set_sched_status_isSet(true);
      }
      if (incoming.get(2)) {
        struct.owner = iprot.readString();
        struct.set_owner_isSet(true);
      }
      if (incoming.get(3)) {
        struct.replication_count = iprot.readI32();
        struct.set_replication_count_isSet(true);
      }
      if (incoming.get(4)) {
        struct.requested_memonheap = iprot.readDouble();
        struct.set_requested_memonheap_isSet(true);
      }
      if (incoming.get(5)) {
        struct.requested_memoffheap = iprot.readDouble();
        struct.set_requested_memoffheap_isSet(true);
      }
      if (incoming.get(6)) {
        struct.requested_cpu = iprot.readDouble();
        struct.set_requested_cpu_isSet(true);
      }
      if (incoming.get(7)) {
        struct.assigned_memonheap = iprot.readDouble();
        struct.set_assigned_memonheap_isSet(true);
      }
      if (incoming.get(8)) {
        struct.assigned_memoffheap = iprot.readDouble();
        struct.set_assigned_memoffheap_isSet(true);
      }
      if (incoming.get(9)) {
        struct.assigned_cpu = iprot.readDouble();
        struct.set_assigned_cpu_isSet(true);
      }
    }
  }

}

