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

  private static final org.apache.thrift.protocol.TField COMPONENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("component_id", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField COMPONENT_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("component_type", org.apache.thrift.protocol.TType.I32, (short)2);
  private static final org.apache.thrift.protocol.TField TOPOLOGY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("topology_id", org.apache.thrift.protocol.TType.STRING, (short)3);
  private static final org.apache.thrift.protocol.TField TOPOLOGY_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("topology_name", org.apache.thrift.protocol.TType.STRING, (short)4);
  private static final org.apache.thrift.protocol.TField NUM_EXECUTORS_FIELD_DESC = new org.apache.thrift.protocol.TField("num_executors", org.apache.thrift.protocol.TType.I32, (short)5);
  private static final org.apache.thrift.protocol.TField NUM_TASKS_FIELD_DESC = new org.apache.thrift.protocol.TField("num_tasks", org.apache.thrift.protocol.TType.I32, (short)6);
  private static final org.apache.thrift.protocol.TField WINDOW_TO_STATS_FIELD_DESC = new org.apache.thrift.protocol.TField("window_to_stats", org.apache.thrift.protocol.TType.MAP, (short)7);
  private static final org.apache.thrift.protocol.TField GSID_TO_INPUT_STATS_FIELD_DESC = new org.apache.thrift.protocol.TField("gsid_to_input_stats", org.apache.thrift.protocol.TType.MAP, (short)8);
  private static final org.apache.thrift.protocol.TField SID_TO_OUTPUT_STATS_FIELD_DESC = new org.apache.thrift.protocol.TField("sid_to_output_stats", org.apache.thrift.protocol.TType.MAP, (short)9);
  private static final org.apache.thrift.protocol.TField EXEC_STATS_FIELD_DESC = new org.apache.thrift.protocol.TField("exec_stats", org.apache.thrift.protocol.TType.LIST, (short)10);
  private static final org.apache.thrift.protocol.TField ERRORS_FIELD_DESC = new org.apache.thrift.protocol.TField("errors", org.apache.thrift.protocol.TType.LIST, (short)11);
  private static final org.apache.thrift.protocol.TField EVENTLOG_HOST_FIELD_DESC = new org.apache.thrift.protocol.TField("eventlog_host", org.apache.thrift.protocol.TType.STRING, (short)12);
  private static final org.apache.thrift.protocol.TField EVENTLOG_PORT_FIELD_DESC = new org.apache.thrift.protocol.TField("eventlog_port", org.apache.thrift.protocol.TType.I32, (short)13);
  private static final org.apache.thrift.protocol.TField DEBUG_OPTIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("debug_options", org.apache.thrift.protocol.TType.STRUCT, (short)14);
  private static final org.apache.thrift.protocol.TField TOPOLOGY_STATUS_FIELD_DESC = new org.apache.thrift.protocol.TField("topology_status", org.apache.thrift.protocol.TType.STRING, (short)15);

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

  private String component_id; // required
  private ComponentType component_type; // required
  private String topology_id; // optional
  private String topology_name; // optional
  private int num_executors; // optional
  private int num_tasks; // optional
  private Map<String,ComponentAggregateStats> window_to_stats; // optional
  private Map<GlobalStreamId,ComponentAggregateStats> gsid_to_input_stats; // optional
  private Map<String,ComponentAggregateStats> sid_to_output_stats; // optional
  private List<ExecutorAggregateStats> exec_stats; // optional
  private List<ErrorInfo> errors; // optional
  private String eventlog_host; // optional
  private int eventlog_port; // optional
  private DebugOptions debug_options; // optional
  private String topology_status; // 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 {
    COMPONENT_ID((short)1, "component_id"),
    /**
     * 
     * @see ComponentType
     */
    COMPONENT_TYPE((short)2, "component_type"),
    TOPOLOGY_ID((short)3, "topology_id"),
    TOPOLOGY_NAME((short)4, "topology_name"),
    NUM_EXECUTORS((short)5, "num_executors"),
    NUM_TASKS((short)6, "num_tasks"),
    WINDOW_TO_STATS((short)7, "window_to_stats"),
    GSID_TO_INPUT_STATS((short)8, "gsid_to_input_stats"),
    SID_TO_OUTPUT_STATS((short)9, "sid_to_output_stats"),
    EXEC_STATS((short)10, "exec_stats"),
    ERRORS((short)11, "errors"),
    EVENTLOG_HOST((short)12, "eventlog_host"),
    EVENTLOG_PORT((short)13, "eventlog_port"),
    DEBUG_OPTIONS((short)14, "debug_options"),
    TOPOLOGY_STATUS((short)15, "topology_status");

    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: // COMPONENT_ID
          return COMPONENT_ID;
        case 2: // COMPONENT_TYPE
          return COMPONENT_TYPE;
        case 3: // TOPOLOGY_ID
          return TOPOLOGY_ID;
        case 4: // TOPOLOGY_NAME
          return TOPOLOGY_NAME;
        case 5: // NUM_EXECUTORS
          return NUM_EXECUTORS;
        case 6: // NUM_TASKS
          return NUM_TASKS;
        case 7: // WINDOW_TO_STATS
          return WINDOW_TO_STATS;
        case 8: // GSID_TO_INPUT_STATS
          return GSID_TO_INPUT_STATS;
        case 9: // SID_TO_OUTPUT_STATS
          return SID_TO_OUTPUT_STATS;
        case 10: // EXEC_STATS
          return EXEC_STATS;
        case 11: // ERRORS
          return ERRORS;
        case 12: // EVENTLOG_HOST
          return EVENTLOG_HOST;
        case 13: // EVENTLOG_PORT
          return EVENTLOG_PORT;
        case 14: // DEBUG_OPTIONS
          return DEBUG_OPTIONS;
        case 15: // TOPOLOGY_STATUS
          return TOPOLOGY_STATUS;
        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_EXECUTORS_ISSET_ID = 0;
  private static final int __NUM_TASKS_ISSET_ID = 1;
  private static final int __EVENTLOG_PORT_ISSET_ID = 2;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.TOPOLOGY_ID,_Fields.TOPOLOGY_NAME,_Fields.NUM_EXECUTORS,_Fields.NUM_TASKS,_Fields.WINDOW_TO_STATS,_Fields.GSID_TO_INPUT_STATS,_Fields.SID_TO_OUTPUT_STATS,_Fields.EXEC_STATS,_Fields.ERRORS,_Fields.EVENTLOG_HOST,_Fields.EVENTLOG_PORT,_Fields.DEBUG_OPTIONS,_Fields.TOPOLOGY_STATUS};
  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.COMPONENT_ID, new org.apache.thrift.meta_data.FieldMetaData("component_id", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.COMPONENT_TYPE, new org.apache.thrift.meta_data.FieldMetaData("component_type", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ComponentType.class)));
    tmpMap.put(_Fields.TOPOLOGY_ID, new org.apache.thrift.meta_data.FieldMetaData("topology_id", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.TOPOLOGY_NAME, new org.apache.thrift.meta_data.FieldMetaData("topology_name", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.NUM_EXECUTORS, new org.apache.thrift.meta_data.FieldMetaData("num_executors", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.NUM_TASKS, new org.apache.thrift.meta_data.FieldMetaData("num_tasks", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.WINDOW_TO_STATS, new org.apache.thrift.meta_data.FieldMetaData("window_to_stats", 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, ComponentAggregateStats.class))));
    tmpMap.put(_Fields.GSID_TO_INPUT_STATS, new org.apache.thrift.meta_data.FieldMetaData("gsid_to_input_stats", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, GlobalStreamId.class), 
            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ComponentAggregateStats.class))));
    tmpMap.put(_Fields.SID_TO_OUTPUT_STATS, new org.apache.thrift.meta_data.FieldMetaData("sid_to_output_stats", 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, ComponentAggregateStats.class))));
    tmpMap.put(_Fields.EXEC_STATS, new org.apache.thrift.meta_data.FieldMetaData("exec_stats", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        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, ExecutorAggregateStats.class))));
    tmpMap.put(_Fields.ERRORS, new org.apache.thrift.meta_data.FieldMetaData("errors", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        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.EVENTLOG_HOST, new org.apache.thrift.meta_data.FieldMetaData("eventlog_host", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.EVENTLOG_PORT, new org.apache.thrift.meta_data.FieldMetaData("eventlog_port", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.DEBUG_OPTIONS, new org.apache.thrift.meta_data.FieldMetaData("debug_options", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, DebugOptions.class)));
    tmpMap.put(_Fields.TOPOLOGY_STATUS, new org.apache.thrift.meta_data.FieldMetaData("topology_status", 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(ComponentPageInfo.class, metaDataMap);
  }

  public ComponentPageInfo() {
  }

  public ComponentPageInfo(
    String component_id,
    ComponentType component_type)
  {
    this();
    this.component_id = component_id;
    this.component_type = component_type;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public ComponentPageInfo(ComponentPageInfo other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.is_set_component_id()) {
      this.component_id = other.component_id;
    }
    if (other.is_set_component_type()) {
      this.component_type = other.component_type;
    }
    if (other.is_set_topology_id()) {
      this.topology_id = other.topology_id;
    }
    if (other.is_set_topology_name()) {
      this.topology_name = other.topology_name;
    }
    this.num_executors = other.num_executors;
    this.num_tasks = other.num_tasks;
    if (other.is_set_window_to_stats()) {
      Map<String,ComponentAggregateStats> __this__window_to_stats = new HashMap<String,ComponentAggregateStats>(other.window_to_stats.size());
      for (Map.Entry<String, ComponentAggregateStats> other_element : other.window_to_stats.entrySet()) {

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

        String __this__window_to_stats_copy_key = other_element_key;

        ComponentAggregateStats __this__window_to_stats_copy_value = new ComponentAggregateStats(other_element_value);

        __this__window_to_stats.put(__this__window_to_stats_copy_key, __this__window_to_stats_copy_value);
      }
      this.window_to_stats = __this__window_to_stats;
    }
    if (other.is_set_gsid_to_input_stats()) {
      Map<GlobalStreamId,ComponentAggregateStats> __this__gsid_to_input_stats = new HashMap<GlobalStreamId,ComponentAggregateStats>(other.gsid_to_input_stats.size());
      for (Map.Entry<GlobalStreamId, ComponentAggregateStats> other_element : other.gsid_to_input_stats.entrySet()) {

        GlobalStreamId other_element_key = other_element.getKey();
        ComponentAggregateStats other_element_value = other_element.getValue();

        GlobalStreamId __this__gsid_to_input_stats_copy_key = new GlobalStreamId(other_element_key);

        ComponentAggregateStats __this__gsid_to_input_stats_copy_value = new ComponentAggregateStats(other_element_value);

        __this__gsid_to_input_stats.put(__this__gsid_to_input_stats_copy_key, __this__gsid_to_input_stats_copy_value);
      }
      this.gsid_to_input_stats = __this__gsid_to_input_stats;
    }
    if (other.is_set_sid_to_output_stats()) {
      Map<String,ComponentAggregateStats> __this__sid_to_output_stats = new HashMap<String,ComponentAggregateStats>(other.sid_to_output_stats.size());
      for (Map.Entry<String, ComponentAggregateStats> other_element : other.sid_to_output_stats.entrySet()) {

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

        String __this__sid_to_output_stats_copy_key = other_element_key;

        ComponentAggregateStats __this__sid_to_output_stats_copy_value = new ComponentAggregateStats(other_element_value);

        __this__sid_to_output_stats.put(__this__sid_to_output_stats_copy_key, __this__sid_to_output_stats_copy_value);
      }
      this.sid_to_output_stats = __this__sid_to_output_stats;
    }
    if (other.is_set_exec_stats()) {
      List<ExecutorAggregateStats> __this__exec_stats = new ArrayList<ExecutorAggregateStats>(other.exec_stats.size());
      for (ExecutorAggregateStats other_element : other.exec_stats) {
        __this__exec_stats.add(new ExecutorAggregateStats(other_element));
      }
      this.exec_stats = __this__exec_stats;
    }
    if (other.is_set_errors()) {
      List<ErrorInfo> __this__errors = new ArrayList<ErrorInfo>(other.errors.size());
      for (ErrorInfo other_element : other.errors) {
        __this__errors.add(new ErrorInfo(other_element));
      }
      this.errors = __this__errors;
    }
    if (other.is_set_eventlog_host()) {
      this.eventlog_host = other.eventlog_host;
    }
    this.eventlog_port = other.eventlog_port;
    if (other.is_set_debug_options()) {
      this.debug_options = new DebugOptions(other.debug_options);
    }
    if (other.is_set_topology_status()) {
      this.topology_status = other.topology_status;
    }
  }

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

  @Override
  public void clear() {
    this.component_id = null;
    this.component_type = null;
    this.topology_id = null;
    this.topology_name = null;
    set_num_executors_isSet(false);
    this.num_executors = 0;
    set_num_tasks_isSet(false);
    this.num_tasks = 0;
    this.window_to_stats = null;
    this.gsid_to_input_stats = null;
    this.sid_to_output_stats = null;
    this.exec_stats = null;
    this.errors = null;
    this.eventlog_host = null;
    set_eventlog_port_isSet(false);
    this.eventlog_port = 0;
    this.debug_options = null;
    this.topology_status = null;
  }

  public String get_component_id() {
    return this.component_id;
  }

  public void set_component_id(String component_id) {
    this.component_id = component_id;
  }

  public void unset_component_id() {
    this.component_id = null;
  }

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

  public void set_component_id_isSet(boolean value) {
    if (!value) {
      this.component_id = null;
    }
  }

  /**
   * 
   * @see ComponentType
   */
  public ComponentType get_component_type() {
    return this.component_type;
  }

  /**
   * 
   * @see ComponentType
   */
  public void set_component_type(ComponentType component_type) {
    this.component_type = component_type;
  }

  public void unset_component_type() {
    this.component_type = null;
  }

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

  public void set_component_type_isSet(boolean value) {
    if (!value) {
      this.component_type = null;
    }
  }

  public String get_topology_id() {
    return this.topology_id;
  }

  public void set_topology_id(String topology_id) {
    this.topology_id = topology_id;
  }

  public void unset_topology_id() {
    this.topology_id = null;
  }

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

  public void set_topology_id_isSet(boolean value) {
    if (!value) {
      this.topology_id = null;
    }
  }

  public String get_topology_name() {
    return this.topology_name;
  }

  public void set_topology_name(String topology_name) {
    this.topology_name = topology_name;
  }

  public void unset_topology_name() {
    this.topology_name = null;
  }

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

  public void set_topology_name_isSet(boolean value) {
    if (!value) {
      this.topology_name = null;
    }
  }

  public int get_num_executors() {
    return this.num_executors;
  }

  public void set_num_executors(int num_executors) {
    this.num_executors = num_executors;
    set_num_executors_isSet(true);
  }

  public void unset_num_executors() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __NUM_EXECUTORS_ISSET_ID);
  }

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

  public void set_num_executors_isSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __NUM_EXECUTORS_ISSET_ID, value);
  }

  public int get_num_tasks() {
    return this.num_tasks;
  }

  public void set_num_tasks(int num_tasks) {
    this.num_tasks = num_tasks;
    set_num_tasks_isSet(true);
  }

  public void unset_num_tasks() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __NUM_TASKS_ISSET_ID);
  }

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

  public void set_num_tasks_isSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __NUM_TASKS_ISSET_ID, value);
  }

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

  public void put_to_window_to_stats(String key, ComponentAggregateStats val) {
    if (this.window_to_stats == null) {
      this.window_to_stats = new HashMap<String,ComponentAggregateStats>();
    }
    this.window_to_stats.put(key, val);
  }

  public Map<String,ComponentAggregateStats> get_window_to_stats() {
    return this.window_to_stats;
  }

  public void set_window_to_stats(Map<String,ComponentAggregateStats> window_to_stats) {
    this.window_to_stats = window_to_stats;
  }

  public void unset_window_to_stats() {
    this.window_to_stats = null;
  }

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

  public void set_window_to_stats_isSet(boolean value) {
    if (!value) {
      this.window_to_stats = null;
    }
  }

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

  public void put_to_gsid_to_input_stats(GlobalStreamId key, ComponentAggregateStats val) {
    if (this.gsid_to_input_stats == null) {
      this.gsid_to_input_stats = new HashMap<GlobalStreamId,ComponentAggregateStats>();
    }
    this.gsid_to_input_stats.put(key, val);
  }

  public Map<GlobalStreamId,ComponentAggregateStats> get_gsid_to_input_stats() {
    return this.gsid_to_input_stats;
  }

  public void set_gsid_to_input_stats(Map<GlobalStreamId,ComponentAggregateStats> gsid_to_input_stats) {
    this.gsid_to_input_stats = gsid_to_input_stats;
  }

  public void unset_gsid_to_input_stats() {
    this.gsid_to_input_stats = null;
  }

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

  public void set_gsid_to_input_stats_isSet(boolean value) {
    if (!value) {
      this.gsid_to_input_stats = null;
    }
  }

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

  public void put_to_sid_to_output_stats(String key, ComponentAggregateStats val) {
    if (this.sid_to_output_stats == null) {
      this.sid_to_output_stats = new HashMap<String,ComponentAggregateStats>();
    }
    this.sid_to_output_stats.put(key, val);
  }

  public Map<String,ComponentAggregateStats> get_sid_to_output_stats() {
    return this.sid_to_output_stats;
  }

  public void set_sid_to_output_stats(Map<String,ComponentAggregateStats> sid_to_output_stats) {
    this.sid_to_output_stats = sid_to_output_stats;
  }

  public void unset_sid_to_output_stats() {
    this.sid_to_output_stats = null;
  }

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

  public void set_sid_to_output_stats_isSet(boolean value) {
    if (!value) {
      this.sid_to_output_stats = null;
    }
  }

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

  public java.util.Iterator<ExecutorAggregateStats> get_exec_stats_iterator() {
    return (this.exec_stats == null) ? null : this.exec_stats.iterator();
  }

  public void add_to_exec_stats(ExecutorAggregateStats elem) {
    if (this.exec_stats == null) {
      this.exec_stats = new ArrayList<ExecutorAggregateStats>();
    }
    this.exec_stats.add(elem);
  }

  public List<ExecutorAggregateStats> get_exec_stats() {
    return this.exec_stats;
  }

  public void set_exec_stats(List<ExecutorAggregateStats> exec_stats) {
    this.exec_stats = exec_stats;
  }

  public void unset_exec_stats() {
    this.exec_stats = null;
  }

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

  public void set_exec_stats_isSet(boolean value) {
    if (!value) {
      this.exec_stats = null;
    }
  }

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

  public java.util.Iterator<ErrorInfo> get_errors_iterator() {
    return (this.errors == null) ? null : this.errors.iterator();
  }

  public void add_to_errors(ErrorInfo elem) {
    if (this.errors == null) {
      this.errors = new ArrayList<ErrorInfo>();
    }
    this.errors.add(elem);
  }

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

  public void set_errors(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 String get_eventlog_host() {
    return this.eventlog_host;
  }

  public void set_eventlog_host(String eventlog_host) {
    this.eventlog_host = eventlog_host;
  }

  public void unset_eventlog_host() {
    this.eventlog_host = null;
  }

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

  public void set_eventlog_host_isSet(boolean value) {
    if (!value) {
      this.eventlog_host = null;
    }
  }

  public int get_eventlog_port() {
    return this.eventlog_port;
  }

  public void set_eventlog_port(int eventlog_port) {
    this.eventlog_port = eventlog_port;
    set_eventlog_port_isSet(true);
  }

  public void unset_eventlog_port() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __EVENTLOG_PORT_ISSET_ID);
  }

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

  public void set_eventlog_port_isSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __EVENTLOG_PORT_ISSET_ID, value);
  }

  public DebugOptions get_debug_options() {
    return this.debug_options;
  }

  public void set_debug_options(DebugOptions debug_options) {
    this.debug_options = debug_options;
  }

  public void unset_debug_options() {
    this.debug_options = null;
  }

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

  public void set_debug_options_isSet(boolean value) {
    if (!value) {
      this.debug_options = null;
    }
  }

  public String get_topology_status() {
    return this.topology_status;
  }

  public void set_topology_status(String topology_status) {
    this.topology_status = topology_status;
  }

  public void unset_topology_status() {
    this.topology_status = null;
  }

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

  public void set_topology_status_isSet(boolean value) {
    if (!value) {
      this.topology_status = null;
    }
  }

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case COMPONENT_ID:
      if (value == null) {
        unset_component_id();
      } else {
        set_component_id((String)value);
      }
      break;

    case COMPONENT_TYPE:
      if (value == null) {
        unset_component_type();
      } else {
        set_component_type((ComponentType)value);
      }
      break;

    case TOPOLOGY_ID:
      if (value == null) {
        unset_topology_id();
      } else {
        set_topology_id((String)value);
      }
      break;

    case TOPOLOGY_NAME:
      if (value == null) {
        unset_topology_name();
      } else {
        set_topology_name((String)value);
      }
      break;

    case NUM_EXECUTORS:
      if (value == null) {
        unset_num_executors();
      } else {
        set_num_executors((Integer)value);
      }
      break;

    case NUM_TASKS:
      if (value == null) {
        unset_num_tasks();
      } else {
        set_num_tasks((Integer)value);
      }
      break;

    case WINDOW_TO_STATS:
      if (value == null) {
        unset_window_to_stats();
      } else {
        set_window_to_stats((Map<String,ComponentAggregateStats>)value);
      }
      break;

    case GSID_TO_INPUT_STATS:
      if (value == null) {
        unset_gsid_to_input_stats();
      } else {
        set_gsid_to_input_stats((Map<GlobalStreamId,ComponentAggregateStats>)value);
      }
      break;

    case SID_TO_OUTPUT_STATS:
      if (value == null) {
        unset_sid_to_output_stats();
      } else {
        set_sid_to_output_stats((Map<String,ComponentAggregateStats>)value);
      }
      break;

    case EXEC_STATS:
      if (value == null) {
        unset_exec_stats();
      } else {
        set_exec_stats((List<ExecutorAggregateStats>)value);
      }
      break;

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

    case EVENTLOG_HOST:
      if (value == null) {
        unset_eventlog_host();
      } else {
        set_eventlog_host((String)value);
      }
      break;

    case EVENTLOG_PORT:
      if (value == null) {
        unset_eventlog_port();
      } else {
        set_eventlog_port((Integer)value);
      }
      break;

    case DEBUG_OPTIONS:
      if (value == null) {
        unset_debug_options();
      } else {
        set_debug_options((DebugOptions)value);
      }
      break;

    case TOPOLOGY_STATUS:
      if (value == null) {
        unset_topology_status();
      } else {
        set_topology_status((String)value);
      }
      break;

    }
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case COMPONENT_ID:
      return get_component_id();

    case COMPONENT_TYPE:
      return get_component_type();

    case TOPOLOGY_ID:
      return get_topology_id();

    case TOPOLOGY_NAME:
      return get_topology_name();

    case NUM_EXECUTORS:
      return get_num_executors();

    case NUM_TASKS:
      return get_num_tasks();

    case WINDOW_TO_STATS:
      return get_window_to_stats();

    case GSID_TO_INPUT_STATS:
      return get_gsid_to_input_stats();

    case SID_TO_OUTPUT_STATS:
      return get_sid_to_output_stats();

    case EXEC_STATS:
      return get_exec_stats();

    case ERRORS:
      return get_errors();

    case EVENTLOG_HOST:
      return get_eventlog_host();

    case EVENTLOG_PORT:
      return get_eventlog_port();

    case DEBUG_OPTIONS:
      return get_debug_options();

    case TOPOLOGY_STATUS:
      return get_topology_status();

    }
    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 COMPONENT_ID:
      return is_set_component_id();
    case COMPONENT_TYPE:
      return is_set_component_type();
    case TOPOLOGY_ID:
      return is_set_topology_id();
    case TOPOLOGY_NAME:
      return is_set_topology_name();
    case NUM_EXECUTORS:
      return is_set_num_executors();
    case NUM_TASKS:
      return is_set_num_tasks();
    case WINDOW_TO_STATS:
      return is_set_window_to_stats();
    case GSID_TO_INPUT_STATS:
      return is_set_gsid_to_input_stats();
    case SID_TO_OUTPUT_STATS:
      return is_set_sid_to_output_stats();
    case EXEC_STATS:
      return is_set_exec_stats();
    case ERRORS:
      return is_set_errors();
    case EVENTLOG_HOST:
      return is_set_eventlog_host();
    case EVENTLOG_PORT:
      return is_set_eventlog_port();
    case DEBUG_OPTIONS:
      return is_set_debug_options();
    case TOPOLOGY_STATUS:
      return is_set_topology_status();
    }
    throw new IllegalStateException();
  }

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

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

    boolean this_present_component_id = true && this.is_set_component_id();
    boolean that_present_component_id = true && that.is_set_component_id();
    if (this_present_component_id || that_present_component_id) {
      if (!(this_present_component_id && that_present_component_id))
        return false;
      if (!this.component_id.equals(that.component_id))
        return false;
    }

    boolean this_present_component_type = true && this.is_set_component_type();
    boolean that_present_component_type = true && that.is_set_component_type();
    if (this_present_component_type || that_present_component_type) {
      if (!(this_present_component_type && that_present_component_type))
        return false;
      if (!this.component_type.equals(that.component_type))
        return false;
    }

    boolean this_present_topology_id = true && this.is_set_topology_id();
    boolean that_present_topology_id = true && that.is_set_topology_id();
    if (this_present_topology_id || that_present_topology_id) {
      if (!(this_present_topology_id && that_present_topology_id))
        return false;
      if (!this.topology_id.equals(that.topology_id))
        return false;
    }

    boolean this_present_topology_name = true && this.is_set_topology_name();
    boolean that_present_topology_name = true && that.is_set_topology_name();
    if (this_present_topology_name || that_present_topology_name) {
      if (!(this_present_topology_name && that_present_topology_name))
        return false;
      if (!this.topology_name.equals(that.topology_name))
        return false;
    }

    boolean this_present_num_executors = true && this.is_set_num_executors();
    boolean that_present_num_executors = true && that.is_set_num_executors();
    if (this_present_num_executors || that_present_num_executors) {
      if (!(this_present_num_executors && that_present_num_executors))
        return false;
      if (this.num_executors != that.num_executors)
        return false;
    }

    boolean this_present_num_tasks = true && this.is_set_num_tasks();
    boolean that_present_num_tasks = true && that.is_set_num_tasks();
    if (this_present_num_tasks || that_present_num_tasks) {
      if (!(this_present_num_tasks && that_present_num_tasks))
        return false;
      if (this.num_tasks != that.num_tasks)
        return false;
    }

    boolean this_present_window_to_stats = true && this.is_set_window_to_stats();
    boolean that_present_window_to_stats = true && that.is_set_window_to_stats();
    if (this_present_window_to_stats || that_present_window_to_stats) {
      if (!(this_present_window_to_stats && that_present_window_to_stats))
        return false;
      if (!this.window_to_stats.equals(that.window_to_stats))
        return false;
    }

    boolean this_present_gsid_to_input_stats = true && this.is_set_gsid_to_input_stats();
    boolean that_present_gsid_to_input_stats = true && that.is_set_gsid_to_input_stats();
    if (this_present_gsid_to_input_stats || that_present_gsid_to_input_stats) {
      if (!(this_present_gsid_to_input_stats && that_present_gsid_to_input_stats))
        return false;
      if (!this.gsid_to_input_stats.equals(that.gsid_to_input_stats))
        return false;
    }

    boolean this_present_sid_to_output_stats = true && this.is_set_sid_to_output_stats();
    boolean that_present_sid_to_output_stats = true && that.is_set_sid_to_output_stats();
    if (this_present_sid_to_output_stats || that_present_sid_to_output_stats) {
      if (!(this_present_sid_to_output_stats && that_present_sid_to_output_stats))
        return false;
      if (!this.sid_to_output_stats.equals(that.sid_to_output_stats))
        return false;
    }

    boolean this_present_exec_stats = true && this.is_set_exec_stats();
    boolean that_present_exec_stats = true && that.is_set_exec_stats();
    if (this_present_exec_stats || that_present_exec_stats) {
      if (!(this_present_exec_stats && that_present_exec_stats))
        return false;
      if (!this.exec_stats.equals(that.exec_stats))
        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_eventlog_host = true && this.is_set_eventlog_host();
    boolean that_present_eventlog_host = true && that.is_set_eventlog_host();
    if (this_present_eventlog_host || that_present_eventlog_host) {
      if (!(this_present_eventlog_host && that_present_eventlog_host))
        return false;
      if (!this.eventlog_host.equals(that.eventlog_host))
        return false;
    }

    boolean this_present_eventlog_port = true && this.is_set_eventlog_port();
    boolean that_present_eventlog_port = true && that.is_set_eventlog_port();
    if (this_present_eventlog_port || that_present_eventlog_port) {
      if (!(this_present_eventlog_port && that_present_eventlog_port))
        return false;
      if (this.eventlog_port != that.eventlog_port)
        return false;
    }

    boolean this_present_debug_options = true && this.is_set_debug_options();
    boolean that_present_debug_options = true && that.is_set_debug_options();
    if (this_present_debug_options || that_present_debug_options) {
      if (!(this_present_debug_options && that_present_debug_options))
        return false;
      if (!this.debug_options.equals(that.debug_options))
        return false;
    }

    boolean this_present_topology_status = true && this.is_set_topology_status();
    boolean that_present_topology_status = true && that.is_set_topology_status();
    if (this_present_topology_status || that_present_topology_status) {
      if (!(this_present_topology_status && that_present_topology_status))
        return false;
      if (!this.topology_status.equals(that.topology_status))
        return false;
    }

    return true;
  }

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

    boolean present_component_id = true && (is_set_component_id());
    list.add(present_component_id);
    if (present_component_id)
      list.add(component_id);

    boolean present_component_type = true && (is_set_component_type());
    list.add(present_component_type);
    if (present_component_type)
      list.add(component_type.getValue());

    boolean present_topology_id = true && (is_set_topology_id());
    list.add(present_topology_id);
    if (present_topology_id)
      list.add(topology_id);

    boolean present_topology_name = true && (is_set_topology_name());
    list.add(present_topology_name);
    if (present_topology_name)
      list.add(topology_name);

    boolean present_num_executors = true && (is_set_num_executors());
    list.add(present_num_executors);
    if (present_num_executors)
      list.add(num_executors);

    boolean present_num_tasks = true && (is_set_num_tasks());
    list.add(present_num_tasks);
    if (present_num_tasks)
      list.add(num_tasks);

    boolean present_window_to_stats = true && (is_set_window_to_stats());
    list.add(present_window_to_stats);
    if (present_window_to_stats)
      list.add(window_to_stats);

    boolean present_gsid_to_input_stats = true && (is_set_gsid_to_input_stats());
    list.add(present_gsid_to_input_stats);
    if (present_gsid_to_input_stats)
      list.add(gsid_to_input_stats);

    boolean present_sid_to_output_stats = true && (is_set_sid_to_output_stats());
    list.add(present_sid_to_output_stats);
    if (present_sid_to_output_stats)
      list.add(sid_to_output_stats);

    boolean present_exec_stats = true && (is_set_exec_stats());
    list.add(present_exec_stats);
    if (present_exec_stats)
      list.add(exec_stats);

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

    boolean present_eventlog_host = true && (is_set_eventlog_host());
    list.add(present_eventlog_host);
    if (present_eventlog_host)
      list.add(eventlog_host);

    boolean present_eventlog_port = true && (is_set_eventlog_port());
    list.add(present_eventlog_port);
    if (present_eventlog_port)
      list.add(eventlog_port);

    boolean present_debug_options = true && (is_set_debug_options());
    list.add(present_debug_options);
    if (present_debug_options)
      list.add(debug_options);

    boolean present_topology_status = true && (is_set_topology_status());
    list.add(present_topology_status);
    if (present_topology_status)
      list.add(topology_status);

    return list.hashCode();
  }

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

    int lastComparison = 0;

    lastComparison = Boolean.valueOf(is_set_component_id()).compareTo(other.is_set_component_id());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_component_id()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.component_id, other.component_id);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_component_type()).compareTo(other.is_set_component_type());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_component_type()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.component_type, other.component_type);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_topology_id()).compareTo(other.is_set_topology_id());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_topology_id()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.topology_id, other.topology_id);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_topology_name()).compareTo(other.is_set_topology_name());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_topology_name()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.topology_name, other.topology_name);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_num_executors()).compareTo(other.is_set_num_executors());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_num_executors()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.num_executors, other.num_executors);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_num_tasks()).compareTo(other.is_set_num_tasks());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_num_tasks()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.num_tasks, other.num_tasks);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_window_to_stats()).compareTo(other.is_set_window_to_stats());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_window_to_stats()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.window_to_stats, other.window_to_stats);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_gsid_to_input_stats()).compareTo(other.is_set_gsid_to_input_stats());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_gsid_to_input_stats()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.gsid_to_input_stats, other.gsid_to_input_stats);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_sid_to_output_stats()).compareTo(other.is_set_sid_to_output_stats());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_sid_to_output_stats()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sid_to_output_stats, other.sid_to_output_stats);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_exec_stats()).compareTo(other.is_set_exec_stats());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_exec_stats()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.exec_stats, other.exec_stats);
      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_eventlog_host()).compareTo(other.is_set_eventlog_host());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_eventlog_host()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.eventlog_host, other.eventlog_host);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_eventlog_port()).compareTo(other.is_set_eventlog_port());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_eventlog_port()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.eventlog_port, other.eventlog_port);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_debug_options()).compareTo(other.is_set_debug_options());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_debug_options()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.debug_options, other.debug_options);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_topology_status()).compareTo(other.is_set_topology_status());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_topology_status()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.topology_status, other.topology_status);
      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("ComponentPageInfo(");
    boolean first = true;

    sb.append("component_id:");
    if (this.component_id == null) {
      sb.append("null");
    } else {
      sb.append(this.component_id);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("component_type:");
    if (this.component_type == null) {
      sb.append("null");
    } else {
      sb.append(this.component_type);
    }
    first = false;
    if (is_set_topology_id()) {
      if (!first) sb.append(", ");
      sb.append("topology_id:");
      if (this.topology_id == null) {
        sb.append("null");
      } else {
        sb.append(this.topology_id);
      }
      first = false;
    }
    if (is_set_topology_name()) {
      if (!first) sb.append(", ");
      sb.append("topology_name:");
      if (this.topology_name == null) {
        sb.append("null");
      } else {
        sb.append(this.topology_name);
      }
      first = false;
    }
    if (is_set_num_executors()) {
      if (!first) sb.append(", ");
      sb.append("num_executors:");
      sb.append(this.num_executors);
      first = false;
    }
    if (is_set_num_tasks()) {
      if (!first) sb.append(", ");
      sb.append("num_tasks:");
      sb.append(this.num_tasks);
      first = false;
    }
    if (is_set_window_to_stats()) {
      if (!first) sb.append(", ");
      sb.append("window_to_stats:");
      if (this.window_to_stats == null) {
        sb.append("null");
      } else {
        sb.append(this.window_to_stats);
      }
      first = false;
    }
    if (is_set_gsid_to_input_stats()) {
      if (!first) sb.append(", ");
      sb.append("gsid_to_input_stats:");
      if (this.gsid_to_input_stats == null) {
        sb.append("null");
      } else {
        sb.append(this.gsid_to_input_stats);
      }
      first = false;
    }
    if (is_set_sid_to_output_stats()) {
      if (!first) sb.append(", ");
      sb.append("sid_to_output_stats:");
      if (this.sid_to_output_stats == null) {
        sb.append("null");
      } else {
        sb.append(this.sid_to_output_stats);
      }
      first = false;
    }
    if (is_set_exec_stats()) {
      if (!first) sb.append(", ");
      sb.append("exec_stats:");
      if (this.exec_stats == null) {
        sb.append("null");
      } else {
        sb.append(this.exec_stats);
      }
      first = false;
    }
    if (is_set_errors()) {
      if (!first) sb.append(", ");
      sb.append("errors:");
      if (this.errors == null) {
        sb.append("null");
      } else {
        sb.append(this.errors);
      }
      first = false;
    }
    if (is_set_eventlog_host()) {
      if (!first) sb.append(", ");
      sb.append("eventlog_host:");
      if (this.eventlog_host == null) {
        sb.append("null");
      } else {
        sb.append(this.eventlog_host);
      }
      first = false;
    }
    if (is_set_eventlog_port()) {
      if (!first) sb.append(", ");
      sb.append("eventlog_port:");
      sb.append(this.eventlog_port);
      first = false;
    }
    if (is_set_debug_options()) {
      if (!first) sb.append(", ");
      sb.append("debug_options:");
      if (this.debug_options == null) {
        sb.append("null");
      } else {
        sb.append(this.debug_options);
      }
      first = false;
    }
    if (is_set_topology_status()) {
      if (!first) sb.append(", ");
      sb.append("topology_status:");
      if (this.topology_status == null) {
        sb.append("null");
      } else {
        sb.append(this.topology_status);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

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

    // check for sub-struct validity
    if (debug_options != null) {
      debug_options.validate();
    }
  }

  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 ComponentPageInfoStandardSchemeFactory implements SchemeFactory {
    public ComponentPageInfoStandardScheme getScheme() {
      return new ComponentPageInfoStandardScheme();
    }
  }

  private static class ComponentPageInfoStandardScheme extends StandardScheme<ComponentPageInfo> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, ComponentPageInfo 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: // COMPONENT_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.component_id = iprot.readString();
              struct.set_component_id_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // COMPONENT_TYPE
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.component_type = org.apache.storm.generated.ComponentType.findByValue(iprot.readI32());
              struct.set_component_type_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // TOPOLOGY_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.topology_id = iprot.readString();
              struct.set_topology_id_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // TOPOLOGY_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.topology_name = iprot.readString();
              struct.set_topology_name_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // NUM_EXECUTORS
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.num_executors = iprot.readI32();
              struct.set_num_executors_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // NUM_TASKS
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.num_tasks = iprot.readI32();
              struct.set_num_tasks_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // WINDOW_TO_STATS
            if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
              {
                org.apache.thrift.protocol.TMap _map422 = iprot.readMapBegin();
                struct.window_to_stats = new HashMap<String,ComponentAggregateStats>(2*_map422.size);
                String _key423;
                ComponentAggregateStats _val424;
                for (int _i425 = 0; _i425 < _map422.size; ++_i425)
                {
                  _key423 = iprot.readString();
                  _val424 = new ComponentAggregateStats();
                  _val424.read(iprot);
                  struct.window_to_stats.put(_key423, _val424);
                }
                iprot.readMapEnd();
              }
              struct.set_window_to_stats_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // GSID_TO_INPUT_STATS
            if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
              {
                org.apache.thrift.protocol.TMap _map426 = iprot.readMapBegin();
                struct.gsid_to_input_stats = new HashMap<GlobalStreamId,ComponentAggregateStats>(2*_map426.size);
                GlobalStreamId _key427;
                ComponentAggregateStats _val428;
                for (int _i429 = 0; _i429 < _map426.size; ++_i429)
                {
                  _key427 = new GlobalStreamId();
                  _key427.read(iprot);
                  _val428 = new ComponentAggregateStats();
                  _val428.read(iprot);
                  struct.gsid_to_input_stats.put(_key427, _val428);
                }
                iprot.readMapEnd();
              }
              struct.set_gsid_to_input_stats_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // SID_TO_OUTPUT_STATS
            if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
              {
                org.apache.thrift.protocol.TMap _map430 = iprot.readMapBegin();
                struct.sid_to_output_stats = new HashMap<String,ComponentAggregateStats>(2*_map430.size);
                String _key431;
                ComponentAggregateStats _val432;
                for (int _i433 = 0; _i433 < _map430.size; ++_i433)
                {
                  _key431 = iprot.readString();
                  _val432 = new ComponentAggregateStats();
                  _val432.read(iprot);
                  struct.sid_to_output_stats.put(_key431, _val432);
                }
                iprot.readMapEnd();
              }
              struct.set_sid_to_output_stats_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // EXEC_STATS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list434 = iprot.readListBegin();
                struct.exec_stats = new ArrayList<ExecutorAggregateStats>(_list434.size);
                ExecutorAggregateStats _elem435;
                for (int _i436 = 0; _i436 < _list434.size; ++_i436)
                {
                  _elem435 = new ExecutorAggregateStats();
                  _elem435.read(iprot);
                  struct.exec_stats.add(_elem435);
                }
                iprot.readListEnd();
              }
              struct.set_exec_stats_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 11: // ERRORS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list437 = iprot.readListBegin();
                struct.errors = new ArrayList<ErrorInfo>(_list437.size);
                ErrorInfo _elem438;
                for (int _i439 = 0; _i439 < _list437.size; ++_i439)
                {
                  _elem438 = new ErrorInfo();
                  _elem438.read(iprot);
                  struct.errors.add(_elem438);
                }
                iprot.readListEnd();
              }
              struct.set_errors_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 12: // EVENTLOG_HOST
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.eventlog_host = iprot.readString();
              struct.set_eventlog_host_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 13: // EVENTLOG_PORT
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.eventlog_port = iprot.readI32();
              struct.set_eventlog_port_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 14: // DEBUG_OPTIONS
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.debug_options = new DebugOptions();
              struct.debug_options.read(iprot);
              struct.set_debug_options_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 15: // TOPOLOGY_STATUS
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.topology_status = iprot.readString();
              struct.set_topology_status_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, ComponentPageInfo struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.component_id != null) {
        oprot.writeFieldBegin(COMPONENT_ID_FIELD_DESC);
        oprot.writeString(struct.component_id);
        oprot.writeFieldEnd();
      }
      if (struct.component_type != null) {
        oprot.writeFieldBegin(COMPONENT_TYPE_FIELD_DESC);
        oprot.writeI32(struct.component_type.getValue());
        oprot.writeFieldEnd();
      }
      if (struct.topology_id != null) {
        if (struct.is_set_topology_id()) {
          oprot.writeFieldBegin(TOPOLOGY_ID_FIELD_DESC);
          oprot.writeString(struct.topology_id);
          oprot.writeFieldEnd();
        }
      }
      if (struct.topology_name != null) {
        if (struct.is_set_topology_name()) {
          oprot.writeFieldBegin(TOPOLOGY_NAME_FIELD_DESC);
          oprot.writeString(struct.topology_name);
          oprot.writeFieldEnd();
        }
      }
      if (struct.is_set_num_executors()) {
        oprot.writeFieldBegin(NUM_EXECUTORS_FIELD_DESC);
        oprot.writeI32(struct.num_executors);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_num_tasks()) {
        oprot.writeFieldBegin(NUM_TASKS_FIELD_DESC);
        oprot.writeI32(struct.num_tasks);
        oprot.writeFieldEnd();
      }
      if (struct.window_to_stats != null) {
        if (struct.is_set_window_to_stats()) {
          oprot.writeFieldBegin(WINDOW_TO_STATS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRUCT, struct.window_to_stats.size()));
            for (Map.Entry<String, ComponentAggregateStats> _iter440 : struct.window_to_stats.entrySet())
            {
              oprot.writeString(_iter440.getKey());
              _iter440.getValue().write(oprot);
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.gsid_to_input_stats != null) {
        if (struct.is_set_gsid_to_input_stats()) {
          oprot.writeFieldBegin(GSID_TO_INPUT_STATS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRUCT, org.apache.thrift.protocol.TType.STRUCT, struct.gsid_to_input_stats.size()));
            for (Map.Entry<GlobalStreamId, ComponentAggregateStats> _iter441 : struct.gsid_to_input_stats.entrySet())
            {
              _iter441.getKey().write(oprot);
              _iter441.getValue().write(oprot);
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.sid_to_output_stats != null) {
        if (struct.is_set_sid_to_output_stats()) {
          oprot.writeFieldBegin(SID_TO_OUTPUT_STATS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRUCT, struct.sid_to_output_stats.size()));
            for (Map.Entry<String, ComponentAggregateStats> _iter442 : struct.sid_to_output_stats.entrySet())
            {
              oprot.writeString(_iter442.getKey());
              _iter442.getValue().write(oprot);
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.exec_stats != null) {
        if (struct.is_set_exec_stats()) {
          oprot.writeFieldBegin(EXEC_STATS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.exec_stats.size()));
            for (ExecutorAggregateStats _iter443 : struct.exec_stats)
            {
              _iter443.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.errors != null) {
        if (struct.is_set_errors()) {
          oprot.writeFieldBegin(ERRORS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.errors.size()));
            for (ErrorInfo _iter444 : struct.errors)
            {
              _iter444.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.eventlog_host != null) {
        if (struct.is_set_eventlog_host()) {
          oprot.writeFieldBegin(EVENTLOG_HOST_FIELD_DESC);
          oprot.writeString(struct.eventlog_host);
          oprot.writeFieldEnd();
        }
      }
      if (struct.is_set_eventlog_port()) {
        oprot.writeFieldBegin(EVENTLOG_PORT_FIELD_DESC);
        oprot.writeI32(struct.eventlog_port);
        oprot.writeFieldEnd();
      }
      if (struct.debug_options != null) {
        if (struct.is_set_debug_options()) {
          oprot.writeFieldBegin(DEBUG_OPTIONS_FIELD_DESC);
          struct.debug_options.write(oprot);
          oprot.writeFieldEnd();
        }
      }
      if (struct.topology_status != null) {
        if (struct.is_set_topology_status()) {
          oprot.writeFieldBegin(TOPOLOGY_STATUS_FIELD_DESC);
          oprot.writeString(struct.topology_status);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class ComponentPageInfoTupleSchemeFactory implements SchemeFactory {
    public ComponentPageInfoTupleScheme getScheme() {
      return new ComponentPageInfoTupleScheme();
    }
  }

  private static class ComponentPageInfoTupleScheme extends TupleScheme<ComponentPageInfo> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, ComponentPageInfo struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      oprot.writeString(struct.component_id);
      oprot.writeI32(struct.component_type.getValue());
      BitSet optionals = new BitSet();
      if (struct.is_set_topology_id()) {
        optionals.set(0);
      }
      if (struct.is_set_topology_name()) {
        optionals.set(1);
      }
      if (struct.is_set_num_executors()) {
        optionals.set(2);
      }
      if (struct.is_set_num_tasks()) {
        optionals.set(3);
      }
      if (struct.is_set_window_to_stats()) {
        optionals.set(4);
      }
      if (struct.is_set_gsid_to_input_stats()) {
        optionals.set(5);
      }
      if (struct.is_set_sid_to_output_stats()) {
        optionals.set(6);
      }
      if (struct.is_set_exec_stats()) {
        optionals.set(7);
      }
      if (struct.is_set_errors()) {
        optionals.set(8);
      }
      if (struct.is_set_eventlog_host()) {
        optionals.set(9);
      }
      if (struct.is_set_eventlog_port()) {
        optionals.set(10);
      }
      if (struct.is_set_debug_options()) {
        optionals.set(11);
      }
      if (struct.is_set_topology_status()) {
        optionals.set(12);
      }
      oprot.writeBitSet(optionals, 13);
      if (struct.is_set_topology_id()) {
        oprot.writeString(struct.topology_id);
      }
      if (struct.is_set_topology_name()) {
        oprot.writeString(struct.topology_name);
      }
      if (struct.is_set_num_executors()) {
        oprot.writeI32(struct.num_executors);
      }
      if (struct.is_set_num_tasks()) {
        oprot.writeI32(struct.num_tasks);
      }
      if (struct.is_set_window_to_stats()) {
        {
          oprot.writeI32(struct.window_to_stats.size());
          for (Map.Entry<String, ComponentAggregateStats> _iter445 : struct.window_to_stats.entrySet())
          {
            oprot.writeString(_iter445.getKey());
            _iter445.getValue().write(oprot);
          }
        }
      }
      if (struct.is_set_gsid_to_input_stats()) {
        {
          oprot.writeI32(struct.gsid_to_input_stats.size());
          for (Map.Entry<GlobalStreamId, ComponentAggregateStats> _iter446 : struct.gsid_to_input_stats.entrySet())
          {
            _iter446.getKey().write(oprot);
            _iter446.getValue().write(oprot);
          }
        }
      }
      if (struct.is_set_sid_to_output_stats()) {
        {
          oprot.writeI32(struct.sid_to_output_stats.size());
          for (Map.Entry<String, ComponentAggregateStats> _iter447 : struct.sid_to_output_stats.entrySet())
          {
            oprot.writeString(_iter447.getKey());
            _iter447.getValue().write(oprot);
          }
        }
      }
      if (struct.is_set_exec_stats()) {
        {
          oprot.writeI32(struct.exec_stats.size());
          for (ExecutorAggregateStats _iter448 : struct.exec_stats)
          {
            _iter448.write(oprot);
          }
        }
      }
      if (struct.is_set_errors()) {
        {
          oprot.writeI32(struct.errors.size());
          for (ErrorInfo _iter449 : struct.errors)
          {
            _iter449.write(oprot);
          }
        }
      }
      if (struct.is_set_eventlog_host()) {
        oprot.writeString(struct.eventlog_host);
      }
      if (struct.is_set_eventlog_port()) {
        oprot.writeI32(struct.eventlog_port);
      }
      if (struct.is_set_debug_options()) {
        struct.debug_options.write(oprot);
      }
      if (struct.is_set_topology_status()) {
        oprot.writeString(struct.topology_status);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, ComponentPageInfo struct) throws org.apache.thrift.TException {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      struct.component_id = iprot.readString();
      struct.set_component_id_isSet(true);
      struct.component_type = org.apache.storm.generated.ComponentType.findByValue(iprot.readI32());
      struct.set_component_type_isSet(true);
      BitSet incoming = iprot.readBitSet(13);
      if (incoming.get(0)) {
        struct.topology_id = iprot.readString();
        struct.set_topology_id_isSet(true);
      }
      if (incoming.get(1)) {
        struct.topology_name = iprot.readString();
        struct.set_topology_name_isSet(true);
      }
      if (incoming.get(2)) {
        struct.num_executors = iprot.readI32();
        struct.set_num_executors_isSet(true);
      }
      if (incoming.get(3)) {
        struct.num_tasks = iprot.readI32();
        struct.set_num_tasks_isSet(true);
      }
      if (incoming.get(4)) {
        {
          org.apache.thrift.protocol.TMap _map450 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.window_to_stats = new HashMap<String,ComponentAggregateStats>(2*_map450.size);
          String _key451;
          ComponentAggregateStats _val452;
          for (int _i453 = 0; _i453 < _map450.size; ++_i453)
          {
            _key451 = iprot.readString();
            _val452 = new ComponentAggregateStats();
            _val452.read(iprot);
            struct.window_to_stats.put(_key451, _val452);
          }
        }
        struct.set_window_to_stats_isSet(true);
      }
      if (incoming.get(5)) {
        {
          org.apache.thrift.protocol.TMap _map454 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRUCT, org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.gsid_to_input_stats = new HashMap<GlobalStreamId,ComponentAggregateStats>(2*_map454.size);
          GlobalStreamId _key455;
          ComponentAggregateStats _val456;
          for (int _i457 = 0; _i457 < _map454.size; ++_i457)
          {
            _key455 = new GlobalStreamId();
            _key455.read(iprot);
            _val456 = new ComponentAggregateStats();
            _val456.read(iprot);
            struct.gsid_to_input_stats.put(_key455, _val456);
          }
        }
        struct.set_gsid_to_input_stats_isSet(true);
      }
      if (incoming.get(6)) {
        {
          org.apache.thrift.protocol.TMap _map458 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.sid_to_output_stats = new HashMap<String,ComponentAggregateStats>(2*_map458.size);
          String _key459;
          ComponentAggregateStats _val460;
          for (int _i461 = 0; _i461 < _map458.size; ++_i461)
          {
            _key459 = iprot.readString();
            _val460 = new ComponentAggregateStats();
            _val460.read(iprot);
            struct.sid_to_output_stats.put(_key459, _val460);
          }
        }
        struct.set_sid_to_output_stats_isSet(true);
      }
      if (incoming.get(7)) {
        {
          org.apache.thrift.protocol.TList _list462 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.exec_stats = new ArrayList<ExecutorAggregateStats>(_list462.size);
          ExecutorAggregateStats _elem463;
          for (int _i464 = 0; _i464 < _list462.size; ++_i464)
          {
            _elem463 = new ExecutorAggregateStats();
            _elem463.read(iprot);
            struct.exec_stats.add(_elem463);
          }
        }
        struct.set_exec_stats_isSet(true);
      }
      if (incoming.get(8)) {
        {
          org.apache.thrift.protocol.TList _list465 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.errors = new ArrayList<ErrorInfo>(_list465.size);
          ErrorInfo _elem466;
          for (int _i467 = 0; _i467 < _list465.size; ++_i467)
          {
            _elem466 = new ErrorInfo();
            _elem466.read(iprot);
            struct.errors.add(_elem466);
          }
        }
        struct.set_errors_isSet(true);
      }
      if (incoming.get(9)) {
        struct.eventlog_host = iprot.readString();
        struct.set_eventlog_host_isSet(true);
      }
      if (incoming.get(10)) {
        struct.eventlog_port = iprot.readI32();
        struct.set_eventlog_port_isSet(true);
      }
      if (incoming.get(11)) {
        struct.debug_options = new DebugOptions();
        struct.debug_options.read(iprot);
        struct.set_debug_options_isSet(true);
      }
      if (incoming.get(12)) {
        struct.topology_status = iprot.readString();
        struct.set_topology_status_isSet(true);
      }
    }
  }

}

