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

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

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

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

  private @org.apache.storm.thrift.annotation.Nullable java.lang.String component_id; // required
  private @org.apache.storm.thrift.annotation.Nullable ComponentType component_type; // required
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String topology_id; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String topology_name; // optional
  private int num_executors; // optional
  private int num_tasks; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,ComponentAggregateStats> window_to_stats; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<GlobalStreamId,ComponentAggregateStats> gsid_to_input_stats; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,ComponentAggregateStats> sid_to_output_stats; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.List<ExecutorAggregateStats> exec_stats; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.List<ErrorInfo> errors; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String eventlog_host; // optional
  private int eventlog_port; // optional
  private @org.apache.storm.thrift.annotation.Nullable DebugOptions debug_options; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String topology_status; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.Double> resources_map; // optional

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.storm.thrift.TFieldIdEnum {
    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"),
    RESOURCES_MAP((short)16, "resources_map");

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

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

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    @org.apache.storm.thrift.annotation.Nullable
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // 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;
        case 16: // RESOURCES_MAP
          return RESOURCES_MAP;
        default:
          return null;
      }
    }

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

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

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

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

    public short getThriftFieldId() {
      return _thriftId;
    }

    public java.lang.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,_Fields.RESOURCES_MAP};
  public static final java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.COMPONENT_ID, new org.apache.storm.thrift.meta_data.FieldMetaData("component_id", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.COMPONENT_TYPE, new org.apache.storm.thrift.meta_data.FieldMetaData("component_type", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.EnumMetaData(org.apache.storm.thrift.protocol.TType.ENUM, ComponentType.class)));
    tmpMap.put(_Fields.TOPOLOGY_ID, new org.apache.storm.thrift.meta_data.FieldMetaData("topology_id", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.TOPOLOGY_NAME, new org.apache.storm.thrift.meta_data.FieldMetaData("topology_name", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.NUM_EXECUTORS, new org.apache.storm.thrift.meta_data.FieldMetaData("num_executors", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.NUM_TASKS, new org.apache.storm.thrift.meta_data.FieldMetaData("num_tasks", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.WINDOW_TO_STATS, new org.apache.storm.thrift.meta_data.FieldMetaData("window_to_stats", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.MapMetaData(org.apache.storm.thrift.protocol.TType.MAP, 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING), 
            new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, ComponentAggregateStats.class))));
    tmpMap.put(_Fields.GSID_TO_INPUT_STATS, new org.apache.storm.thrift.meta_data.FieldMetaData("gsid_to_input_stats", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.MapMetaData(org.apache.storm.thrift.protocol.TType.MAP, 
            new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, GlobalStreamId.class), 
            new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, ComponentAggregateStats.class))));
    tmpMap.put(_Fields.SID_TO_OUTPUT_STATS, new org.apache.storm.thrift.meta_data.FieldMetaData("sid_to_output_stats", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.MapMetaData(org.apache.storm.thrift.protocol.TType.MAP, 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING), 
            new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, ComponentAggregateStats.class))));
    tmpMap.put(_Fields.EXEC_STATS, new org.apache.storm.thrift.meta_data.FieldMetaData("exec_stats", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.ListMetaData(org.apache.storm.thrift.protocol.TType.LIST, 
            new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, ExecutorAggregateStats.class))));
    tmpMap.put(_Fields.ERRORS, new org.apache.storm.thrift.meta_data.FieldMetaData("errors", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.ListMetaData(org.apache.storm.thrift.protocol.TType.LIST, 
            new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, ErrorInfo.class))));
    tmpMap.put(_Fields.EVENTLOG_HOST, new org.apache.storm.thrift.meta_data.FieldMetaData("eventlog_host", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.EVENTLOG_PORT, new org.apache.storm.thrift.meta_data.FieldMetaData("eventlog_port", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.DEBUG_OPTIONS, new org.apache.storm.thrift.meta_data.FieldMetaData("debug_options", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, DebugOptions.class)));
    tmpMap.put(_Fields.TOPOLOGY_STATUS, new org.apache.storm.thrift.meta_data.FieldMetaData("topology_status", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.RESOURCES_MAP, new org.apache.storm.thrift.meta_data.FieldMetaData("resources_map", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.MapMetaData(org.apache.storm.thrift.protocol.TType.MAP, 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING), 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE))));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.storm.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ComponentPageInfo.class, metaDataMap);
  }

  public ComponentPageInfo() {
  }

  public ComponentPageInfo(
    java.lang.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()) {
      java.util.Map<java.lang.String,ComponentAggregateStats> __this__window_to_stats = new java.util.HashMap<java.lang.String,ComponentAggregateStats>(other.window_to_stats.size());
      for (java.util.Map.Entry<java.lang.String, ComponentAggregateStats> other_element : other.window_to_stats.entrySet()) {

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

        java.lang.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()) {
      java.util.Map<GlobalStreamId,ComponentAggregateStats> __this__gsid_to_input_stats = new java.util.HashMap<GlobalStreamId,ComponentAggregateStats>(other.gsid_to_input_stats.size());
      for (java.util.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()) {
      java.util.Map<java.lang.String,ComponentAggregateStats> __this__sid_to_output_stats = new java.util.HashMap<java.lang.String,ComponentAggregateStats>(other.sid_to_output_stats.size());
      for (java.util.Map.Entry<java.lang.String, ComponentAggregateStats> other_element : other.sid_to_output_stats.entrySet()) {

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

        java.lang.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()) {
      java.util.List<ExecutorAggregateStats> __this__exec_stats = new java.util.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()) {
      java.util.List<ErrorInfo> __this__errors = new java.util.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;
    }
    if (other.is_set_resources_map()) {
      java.util.Map<java.lang.String,java.lang.Double> __this__resources_map = new java.util.HashMap<java.lang.String,java.lang.Double>(other.resources_map);
      this.resources_map = __this__resources_map;
    }
  }

  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;
    this.resources_map = null;
  }

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

  public void set_component_id(@org.apache.storm.thrift.annotation.Nullable java.lang.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
   */
  @org.apache.storm.thrift.annotation.Nullable
  public ComponentType get_component_type() {
    return this.component_type;
  }

  /**
   * 
   * @see ComponentType
   */
  public void set_component_type(@org.apache.storm.thrift.annotation.Nullable 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;
    }
  }

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

  public void set_topology_id(@org.apache.storm.thrift.annotation.Nullable java.lang.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;
    }
  }

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

  public void set_topology_name(@org.apache.storm.thrift.annotation.Nullable java.lang.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 = org.apache.storm.thrift.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 org.apache.storm.thrift.EncodingUtils.testBit(__isset_bitfield, __NUM_EXECUTORS_ISSET_ID);
  }

  public void set_num_executors_isSet(boolean value) {
    __isset_bitfield = org.apache.storm.thrift.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 = org.apache.storm.thrift.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 org.apache.storm.thrift.EncodingUtils.testBit(__isset_bitfield, __NUM_TASKS_ISSET_ID);
  }

  public void set_num_tasks_isSet(boolean value) {
    __isset_bitfield = org.apache.storm.thrift.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(java.lang.String key, ComponentAggregateStats val) {
    if (this.window_to_stats == null) {
      this.window_to_stats = new java.util.HashMap<java.lang.String,ComponentAggregateStats>();
    }
    this.window_to_stats.put(key, val);
  }

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

  public void set_window_to_stats(@org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.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 java.util.HashMap<GlobalStreamId,ComponentAggregateStats>();
    }
    this.gsid_to_input_stats.put(key, val);
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.Map<GlobalStreamId,ComponentAggregateStats> get_gsid_to_input_stats() {
    return this.gsid_to_input_stats;
  }

  public void set_gsid_to_input_stats(@org.apache.storm.thrift.annotation.Nullable java.util.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(java.lang.String key, ComponentAggregateStats val) {
    if (this.sid_to_output_stats == null) {
      this.sid_to_output_stats = new java.util.HashMap<java.lang.String,ComponentAggregateStats>();
    }
    this.sid_to_output_stats.put(key, val);
  }

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

  public void set_sid_to_output_stats(@org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.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();
  }

  @org.apache.storm.thrift.annotation.Nullable
  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 java.util.ArrayList<ExecutorAggregateStats>();
    }
    this.exec_stats.add(elem);
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.List<ExecutorAggregateStats> get_exec_stats() {
    return this.exec_stats;
  }

  public void set_exec_stats(@org.apache.storm.thrift.annotation.Nullable java.util.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();
  }

  @org.apache.storm.thrift.annotation.Nullable
  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 java.util.ArrayList<ErrorInfo>();
    }
    this.errors.add(elem);
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.List<ErrorInfo> get_errors() {
    return this.errors;
  }

  public void set_errors(@org.apache.storm.thrift.annotation.Nullable java.util.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;
    }
  }

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

  public void set_eventlog_host(@org.apache.storm.thrift.annotation.Nullable java.lang.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 = org.apache.storm.thrift.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 org.apache.storm.thrift.EncodingUtils.testBit(__isset_bitfield, __EVENTLOG_PORT_ISSET_ID);
  }

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

  @org.apache.storm.thrift.annotation.Nullable
  public DebugOptions get_debug_options() {
    return this.debug_options;
  }

  public void set_debug_options(@org.apache.storm.thrift.annotation.Nullable 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;
    }
  }

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

  public void set_topology_status(@org.apache.storm.thrift.annotation.Nullable java.lang.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 int get_resources_map_size() {
    return (this.resources_map == null) ? 0 : this.resources_map.size();
  }

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

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

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

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

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

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

  public void setFieldValue(_Fields field, @org.apache.storm.thrift.annotation.Nullable java.lang.Object value) {
    switch (field) {
    case COMPONENT_ID:
      if (value == null) {
        unset_component_id();
      } else {
        set_component_id((java.lang.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((java.lang.String)value);
      }
      break;

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

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

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

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

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

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

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

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

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

    case EVENTLOG_PORT:
      if (value == null) {
        unset_eventlog_port();
      } else {
        set_eventlog_port((java.lang.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((java.lang.String)value);
      }
      break;

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

    }
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.lang.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();

    case RESOURCES_MAP:
      return get_resources_map();

    }
    throw new java.lang.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 java.lang.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();
    case RESOURCES_MAP:
      return is_set_resources_map();
    }
    throw new java.lang.IllegalStateException();
  }

  @Override
  public boolean equals(java.lang.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;
    if (this == that)
      return true;

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

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

    return true;
  }

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

    hashCode = hashCode * 8191 + ((is_set_component_id()) ? 131071 : 524287);
    if (is_set_component_id())
      hashCode = hashCode * 8191 + component_id.hashCode();

    hashCode = hashCode * 8191 + ((is_set_component_type()) ? 131071 : 524287);
    if (is_set_component_type())
      hashCode = hashCode * 8191 + component_type.getValue();

    hashCode = hashCode * 8191 + ((is_set_topology_id()) ? 131071 : 524287);
    if (is_set_topology_id())
      hashCode = hashCode * 8191 + topology_id.hashCode();

    hashCode = hashCode * 8191 + ((is_set_topology_name()) ? 131071 : 524287);
    if (is_set_topology_name())
      hashCode = hashCode * 8191 + topology_name.hashCode();

    hashCode = hashCode * 8191 + ((is_set_num_executors()) ? 131071 : 524287);
    if (is_set_num_executors())
      hashCode = hashCode * 8191 + num_executors;

    hashCode = hashCode * 8191 + ((is_set_num_tasks()) ? 131071 : 524287);
    if (is_set_num_tasks())
      hashCode = hashCode * 8191 + num_tasks;

    hashCode = hashCode * 8191 + ((is_set_window_to_stats()) ? 131071 : 524287);
    if (is_set_window_to_stats())
      hashCode = hashCode * 8191 + window_to_stats.hashCode();

    hashCode = hashCode * 8191 + ((is_set_gsid_to_input_stats()) ? 131071 : 524287);
    if (is_set_gsid_to_input_stats())
      hashCode = hashCode * 8191 + gsid_to_input_stats.hashCode();

    hashCode = hashCode * 8191 + ((is_set_sid_to_output_stats()) ? 131071 : 524287);
    if (is_set_sid_to_output_stats())
      hashCode = hashCode * 8191 + sid_to_output_stats.hashCode();

    hashCode = hashCode * 8191 + ((is_set_exec_stats()) ? 131071 : 524287);
    if (is_set_exec_stats())
      hashCode = hashCode * 8191 + exec_stats.hashCode();

    hashCode = hashCode * 8191 + ((is_set_errors()) ? 131071 : 524287);
    if (is_set_errors())
      hashCode = hashCode * 8191 + errors.hashCode();

    hashCode = hashCode * 8191 + ((is_set_eventlog_host()) ? 131071 : 524287);
    if (is_set_eventlog_host())
      hashCode = hashCode * 8191 + eventlog_host.hashCode();

    hashCode = hashCode * 8191 + ((is_set_eventlog_port()) ? 131071 : 524287);
    if (is_set_eventlog_port())
      hashCode = hashCode * 8191 + eventlog_port;

    hashCode = hashCode * 8191 + ((is_set_debug_options()) ? 131071 : 524287);
    if (is_set_debug_options())
      hashCode = hashCode * 8191 + debug_options.hashCode();

    hashCode = hashCode * 8191 + ((is_set_topology_status()) ? 131071 : 524287);
    if (is_set_topology_status())
      hashCode = hashCode * 8191 + topology_status.hashCode();

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

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.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.storm.thrift.TBaseHelper.compareTo(this.component_id, other.component_id);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.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.storm.thrift.TBaseHelper.compareTo(this.component_type, other.component_type);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.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.storm.thrift.TBaseHelper.compareTo(this.topology_id, other.topology_id);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.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.storm.thrift.TBaseHelper.compareTo(this.topology_name, other.topology_name);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.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.storm.thrift.TBaseHelper.compareTo(this.num_executors, other.num_executors);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.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.storm.thrift.TBaseHelper.compareTo(this.num_tasks, other.num_tasks);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.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.storm.thrift.TBaseHelper.compareTo(this.window_to_stats, other.window_to_stats);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.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.storm.thrift.TBaseHelper.compareTo(this.gsid_to_input_stats, other.gsid_to_input_stats);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.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.storm.thrift.TBaseHelper.compareTo(this.sid_to_output_stats, other.sid_to_output_stats);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.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.storm.thrift.TBaseHelper.compareTo(this.exec_stats, other.exec_stats);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_errors()).compareTo(other.is_set_errors());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_errors()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.errors, other.errors);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.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.storm.thrift.TBaseHelper.compareTo(this.eventlog_host, other.eventlog_host);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.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.storm.thrift.TBaseHelper.compareTo(this.eventlog_port, other.eventlog_port);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.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.storm.thrift.TBaseHelper.compareTo(this.debug_options, other.debug_options);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.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.storm.thrift.TBaseHelper.compareTo(this.topology_status, other.topology_status);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_resources_map()).compareTo(other.is_set_resources_map());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_resources_map()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.resources_map, other.resources_map);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

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

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

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

  @Override
  public java.lang.String toString() {
    java.lang.StringBuilder sb = new java.lang.StringBuilder("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;
    }
    if (is_set_resources_map()) {
      if (!first) sb.append(", ");
      sb.append("resources_map:");
      if (this.resources_map == null) {
        sb.append("null");
      } else {
        sb.append(this.resources_map);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

    if (!is_set_component_type()) {
      throw new org.apache.storm.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.storm.thrift.protocol.TCompactProtocol(new org.apache.storm.thrift.transport.TIOStreamTransport(out)));
    } catch (org.apache.storm.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

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

  private static class ComponentPageInfoStandardSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
    public ComponentPageInfoStandardScheme getScheme() {
      return new ComponentPageInfoStandardScheme();
    }
  }

  private static class ComponentPageInfoStandardScheme extends org.apache.storm.thrift.scheme.StandardScheme<ComponentPageInfo> {

    public void read(org.apache.storm.thrift.protocol.TProtocol iprot, ComponentPageInfo struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TField schemeField;
      iprot.readStructBegin();
      while (true)
      {
        schemeField = iprot.readFieldBegin();
        if (schemeField.type == org.apache.storm.thrift.protocol.TType.STOP) { 
          break;
        }
        switch (schemeField.id) {
          case 1: // COMPONENT_ID
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.component_id = iprot.readString();
              struct.set_component_id_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // COMPONENT_TYPE
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.component_type = org.apache.storm.generated.ComponentType.findByValue(iprot.readI32());
              struct.set_component_type_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // TOPOLOGY_ID
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.topology_id = iprot.readString();
              struct.set_topology_id_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // TOPOLOGY_NAME
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.topology_name = iprot.readString();
              struct.set_topology_name_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // NUM_EXECUTORS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.num_executors = iprot.readI32();
              struct.set_num_executors_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // NUM_TASKS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.num_tasks = iprot.readI32();
              struct.set_num_tasks_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // WINDOW_TO_STATS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map510 = iprot.readMapBegin();
                struct.window_to_stats = new java.util.HashMap<java.lang.String,ComponentAggregateStats>(2*_map510.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key511;
                @org.apache.storm.thrift.annotation.Nullable ComponentAggregateStats _val512;
                for (int _i513 = 0; _i513 < _map510.size; ++_i513)
                {
                  _key511 = iprot.readString();
                  _val512 = new ComponentAggregateStats();
                  _val512.read(iprot);
                  struct.window_to_stats.put(_key511, _val512);
                }
                iprot.readMapEnd();
              }
              struct.set_window_to_stats_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // GSID_TO_INPUT_STATS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map514 = iprot.readMapBegin();
                struct.gsid_to_input_stats = new java.util.HashMap<GlobalStreamId,ComponentAggregateStats>(2*_map514.size);
                @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key515;
                @org.apache.storm.thrift.annotation.Nullable ComponentAggregateStats _val516;
                for (int _i517 = 0; _i517 < _map514.size; ++_i517)
                {
                  _key515 = new GlobalStreamId();
                  _key515.read(iprot);
                  _val516 = new ComponentAggregateStats();
                  _val516.read(iprot);
                  struct.gsid_to_input_stats.put(_key515, _val516);
                }
                iprot.readMapEnd();
              }
              struct.set_gsid_to_input_stats_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // SID_TO_OUTPUT_STATS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map518 = iprot.readMapBegin();
                struct.sid_to_output_stats = new java.util.HashMap<java.lang.String,ComponentAggregateStats>(2*_map518.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key519;
                @org.apache.storm.thrift.annotation.Nullable ComponentAggregateStats _val520;
                for (int _i521 = 0; _i521 < _map518.size; ++_i521)
                {
                  _key519 = iprot.readString();
                  _val520 = new ComponentAggregateStats();
                  _val520.read(iprot);
                  struct.sid_to_output_stats.put(_key519, _val520);
                }
                iprot.readMapEnd();
              }
              struct.set_sid_to_output_stats_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // EXEC_STATS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.LIST) {
              {
                org.apache.storm.thrift.protocol.TList _list522 = iprot.readListBegin();
                struct.exec_stats = new java.util.ArrayList<ExecutorAggregateStats>(_list522.size);
                @org.apache.storm.thrift.annotation.Nullable ExecutorAggregateStats _elem523;
                for (int _i524 = 0; _i524 < _list522.size; ++_i524)
                {
                  _elem523 = new ExecutorAggregateStats();
                  _elem523.read(iprot);
                  struct.exec_stats.add(_elem523);
                }
                iprot.readListEnd();
              }
              struct.set_exec_stats_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 11: // ERRORS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.LIST) {
              {
                org.apache.storm.thrift.protocol.TList _list525 = iprot.readListBegin();
                struct.errors = new java.util.ArrayList<ErrorInfo>(_list525.size);
                @org.apache.storm.thrift.annotation.Nullable ErrorInfo _elem526;
                for (int _i527 = 0; _i527 < _list525.size; ++_i527)
                {
                  _elem526 = new ErrorInfo();
                  _elem526.read(iprot);
                  struct.errors.add(_elem526);
                }
                iprot.readListEnd();
              }
              struct.set_errors_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 12: // EVENTLOG_HOST
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.eventlog_host = iprot.readString();
              struct.set_eventlog_host_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 13: // EVENTLOG_PORT
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.eventlog_port = iprot.readI32();
              struct.set_eventlog_port_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 14: // DEBUG_OPTIONS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRUCT) {
              struct.debug_options = new DebugOptions();
              struct.debug_options.read(iprot);
              struct.set_debug_options_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 15: // TOPOLOGY_STATUS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.topology_status = iprot.readString();
              struct.set_topology_status_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 16: // RESOURCES_MAP
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map528 = iprot.readMapBegin();
                struct.resources_map = new java.util.HashMap<java.lang.String,java.lang.Double>(2*_map528.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key529;
                double _val530;
                for (int _i531 = 0; _i531 < _map528.size; ++_i531)
                {
                  _key529 = iprot.readString();
                  _val530 = iprot.readDouble();
                  struct.resources_map.put(_key529, _val530);
                }
                iprot.readMapEnd();
              }
              struct.set_resources_map_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          default:
            org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
      struct.validate();
    }

    public void write(org.apache.storm.thrift.protocol.TProtocol oprot, ComponentPageInfo struct) throws org.apache.storm.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.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.STRUCT, struct.window_to_stats.size()));
            for (java.util.Map.Entry<java.lang.String, ComponentAggregateStats> _iter532 : struct.window_to_stats.entrySet())
            {
              oprot.writeString(_iter532.getKey());
              _iter532.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.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.STRUCT, struct.gsid_to_input_stats.size()));
            for (java.util.Map.Entry<GlobalStreamId, ComponentAggregateStats> _iter533 : struct.gsid_to_input_stats.entrySet())
            {
              _iter533.getKey().write(oprot);
              _iter533.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.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.STRUCT, struct.sid_to_output_stats.size()));
            for (java.util.Map.Entry<java.lang.String, ComponentAggregateStats> _iter534 : struct.sid_to_output_stats.entrySet())
            {
              oprot.writeString(_iter534.getKey());
              _iter534.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.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.STRUCT, struct.exec_stats.size()));
            for (ExecutorAggregateStats _iter535 : struct.exec_stats)
            {
              _iter535.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.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.STRUCT, struct.errors.size()));
            for (ErrorInfo _iter536 : struct.errors)
            {
              _iter536.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();
        }
      }
      if (struct.resources_map != null) {
        if (struct.is_set_resources_map()) {
          oprot.writeFieldBegin(RESOURCES_MAP_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.DOUBLE, struct.resources_map.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.Double> _iter537 : struct.resources_map.entrySet())
            {
              oprot.writeString(_iter537.getKey());
              oprot.writeDouble(_iter537.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class ComponentPageInfoTupleSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
    public ComponentPageInfoTupleScheme getScheme() {
      return new ComponentPageInfoTupleScheme();
    }
  }

  private static class ComponentPageInfoTupleScheme extends org.apache.storm.thrift.scheme.TupleScheme<ComponentPageInfo> {

    @Override
    public void write(org.apache.storm.thrift.protocol.TProtocol prot, ComponentPageInfo struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol oprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      oprot.writeString(struct.component_id);
      oprot.writeI32(struct.component_type.getValue());
      java.util.BitSet optionals = new java.util.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);
      }
      if (struct.is_set_resources_map()) {
        optionals.set(13);
      }
      oprot.writeBitSet(optionals, 14);
      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 (java.util.Map.Entry<java.lang.String, ComponentAggregateStats> _iter538 : struct.window_to_stats.entrySet())
          {
            oprot.writeString(_iter538.getKey());
            _iter538.getValue().write(oprot);
          }
        }
      }
      if (struct.is_set_gsid_to_input_stats()) {
        {
          oprot.writeI32(struct.gsid_to_input_stats.size());
          for (java.util.Map.Entry<GlobalStreamId, ComponentAggregateStats> _iter539 : struct.gsid_to_input_stats.entrySet())
          {
            _iter539.getKey().write(oprot);
            _iter539.getValue().write(oprot);
          }
        }
      }
      if (struct.is_set_sid_to_output_stats()) {
        {
          oprot.writeI32(struct.sid_to_output_stats.size());
          for (java.util.Map.Entry<java.lang.String, ComponentAggregateStats> _iter540 : struct.sid_to_output_stats.entrySet())
          {
            oprot.writeString(_iter540.getKey());
            _iter540.getValue().write(oprot);
          }
        }
      }
      if (struct.is_set_exec_stats()) {
        {
          oprot.writeI32(struct.exec_stats.size());
          for (ExecutorAggregateStats _iter541 : struct.exec_stats)
          {
            _iter541.write(oprot);
          }
        }
      }
      if (struct.is_set_errors()) {
        {
          oprot.writeI32(struct.errors.size());
          for (ErrorInfo _iter542 : struct.errors)
          {
            _iter542.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);
      }
      if (struct.is_set_resources_map()) {
        {
          oprot.writeI32(struct.resources_map.size());
          for (java.util.Map.Entry<java.lang.String, java.lang.Double> _iter543 : struct.resources_map.entrySet())
          {
            oprot.writeString(_iter543.getKey());
            oprot.writeDouble(_iter543.getValue());
          }
        }
      }
    }

    @Override
    public void read(org.apache.storm.thrift.protocol.TProtocol prot, ComponentPageInfo struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol iprot = (org.apache.storm.thrift.protocol.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);
      java.util.BitSet incoming = iprot.readBitSet(14);
      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.storm.thrift.protocol.TMap _map544 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.window_to_stats = new java.util.HashMap<java.lang.String,ComponentAggregateStats>(2*_map544.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key545;
          @org.apache.storm.thrift.annotation.Nullable ComponentAggregateStats _val546;
          for (int _i547 = 0; _i547 < _map544.size; ++_i547)
          {
            _key545 = iprot.readString();
            _val546 = new ComponentAggregateStats();
            _val546.read(iprot);
            struct.window_to_stats.put(_key545, _val546);
          }
        }
        struct.set_window_to_stats_isSet(true);
      }
      if (incoming.get(5)) {
        {
          org.apache.storm.thrift.protocol.TMap _map548 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.gsid_to_input_stats = new java.util.HashMap<GlobalStreamId,ComponentAggregateStats>(2*_map548.size);
          @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key549;
          @org.apache.storm.thrift.annotation.Nullable ComponentAggregateStats _val550;
          for (int _i551 = 0; _i551 < _map548.size; ++_i551)
          {
            _key549 = new GlobalStreamId();
            _key549.read(iprot);
            _val550 = new ComponentAggregateStats();
            _val550.read(iprot);
            struct.gsid_to_input_stats.put(_key549, _val550);
          }
        }
        struct.set_gsid_to_input_stats_isSet(true);
      }
      if (incoming.get(6)) {
        {
          org.apache.storm.thrift.protocol.TMap _map552 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.sid_to_output_stats = new java.util.HashMap<java.lang.String,ComponentAggregateStats>(2*_map552.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key553;
          @org.apache.storm.thrift.annotation.Nullable ComponentAggregateStats _val554;
          for (int _i555 = 0; _i555 < _map552.size; ++_i555)
          {
            _key553 = iprot.readString();
            _val554 = new ComponentAggregateStats();
            _val554.read(iprot);
            struct.sid_to_output_stats.put(_key553, _val554);
          }
        }
        struct.set_sid_to_output_stats_isSet(true);
      }
      if (incoming.get(7)) {
        {
          org.apache.storm.thrift.protocol.TList _list556 = new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.exec_stats = new java.util.ArrayList<ExecutorAggregateStats>(_list556.size);
          @org.apache.storm.thrift.annotation.Nullable ExecutorAggregateStats _elem557;
          for (int _i558 = 0; _i558 < _list556.size; ++_i558)
          {
            _elem557 = new ExecutorAggregateStats();
            _elem557.read(iprot);
            struct.exec_stats.add(_elem557);
          }
        }
        struct.set_exec_stats_isSet(true);
      }
      if (incoming.get(8)) {
        {
          org.apache.storm.thrift.protocol.TList _list559 = new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.errors = new java.util.ArrayList<ErrorInfo>(_list559.size);
          @org.apache.storm.thrift.annotation.Nullable ErrorInfo _elem560;
          for (int _i561 = 0; _i561 < _list559.size; ++_i561)
          {
            _elem560 = new ErrorInfo();
            _elem560.read(iprot);
            struct.errors.add(_elem560);
          }
        }
        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);
      }
      if (incoming.get(13)) {
        {
          org.apache.storm.thrift.protocol.TMap _map562 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.DOUBLE, iprot.readI32());
          struct.resources_map = new java.util.HashMap<java.lang.String,java.lang.Double>(2*_map562.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key563;
          double _val564;
          for (int _i565 = 0; _i565 < _map562.size; ++_i565)
          {
            _key563 = iprot.readString();
            _val564 = iprot.readDouble();
            struct.resources_map.put(_key563, _val564);
          }
        }
        struct.set_resources_map_isSet(true);
      }
    }
  }

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

