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

  private static final org.apache.storm.thrift.protocol.TField SPOUTS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("spouts", org.apache.storm.thrift.protocol.TType.MAP, (short)1);
  private static final org.apache.storm.thrift.protocol.TField BOLTS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("bolts", org.apache.storm.thrift.protocol.TType.MAP, (short)2);
  private static final org.apache.storm.thrift.protocol.TField STATE_SPOUTS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("state_spouts", org.apache.storm.thrift.protocol.TType.MAP, (short)3);
  private static final org.apache.storm.thrift.protocol.TField WORKER_HOOKS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("worker_hooks", org.apache.storm.thrift.protocol.TType.LIST, (short)4);
  private static final org.apache.storm.thrift.protocol.TField DEPENDENCY_JARS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("dependency_jars", org.apache.storm.thrift.protocol.TType.LIST, (short)5);
  private static final org.apache.storm.thrift.protocol.TField DEPENDENCY_ARTIFACTS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("dependency_artifacts", org.apache.storm.thrift.protocol.TType.LIST, (short)6);
  private static final org.apache.storm.thrift.protocol.TField STORM_VERSION_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("storm_version", org.apache.storm.thrift.protocol.TType.STRING, (short)7);
  private static final org.apache.storm.thrift.protocol.TField JDK_VERSION_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("jdk_version", org.apache.storm.thrift.protocol.TType.STRING, (short)8);
  private static final org.apache.storm.thrift.protocol.TField COMPONENT_TO_SHARED_MEMORY_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("component_to_shared_memory", org.apache.storm.thrift.protocol.TType.MAP, (short)9);
  private static final org.apache.storm.thrift.protocol.TField SHARED_MEMORY_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("shared_memory", org.apache.storm.thrift.protocol.TType.MAP, (short)10);

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

  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,SpoutSpec> spouts; // required
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,Bolt> bolts; // required
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,StateSpoutSpec> state_spouts; // required
  private @org.apache.storm.thrift.annotation.Nullable java.util.List<java.nio.ByteBuffer> worker_hooks; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.List<java.lang.String> dependency_jars; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.List<java.lang.String> dependency_artifacts; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String storm_version; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String jdk_version; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.util.Set<java.lang.String>> component_to_shared_memory; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,SharedMemory> shared_memory; // 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 {
    SPOUTS((short)1, "spouts"),
    BOLTS((short)2, "bolts"),
    STATE_SPOUTS((short)3, "state_spouts"),
    WORKER_HOOKS((short)4, "worker_hooks"),
    DEPENDENCY_JARS((short)5, "dependency_jars"),
    DEPENDENCY_ARTIFACTS((short)6, "dependency_artifacts"),
    STORM_VERSION((short)7, "storm_version"),
    JDK_VERSION((short)8, "jdk_version"),
    COMPONENT_TO_SHARED_MEMORY((short)9, "component_to_shared_memory"),
    SHARED_MEMORY((short)10, "shared_memory");

    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: // SPOUTS
          return SPOUTS;
        case 2: // BOLTS
          return BOLTS;
        case 3: // STATE_SPOUTS
          return STATE_SPOUTS;
        case 4: // WORKER_HOOKS
          return WORKER_HOOKS;
        case 5: // DEPENDENCY_JARS
          return DEPENDENCY_JARS;
        case 6: // DEPENDENCY_ARTIFACTS
          return DEPENDENCY_ARTIFACTS;
        case 7: // STORM_VERSION
          return STORM_VERSION;
        case 8: // JDK_VERSION
          return JDK_VERSION;
        case 9: // COMPONENT_TO_SHARED_MEMORY
          return COMPONENT_TO_SHARED_MEMORY;
        case 10: // SHARED_MEMORY
          return SHARED_MEMORY;
        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 _Fields optionals[] = {_Fields.WORKER_HOOKS,_Fields.DEPENDENCY_JARS,_Fields.DEPENDENCY_ARTIFACTS,_Fields.STORM_VERSION,_Fields.JDK_VERSION,_Fields.COMPONENT_TO_SHARED_MEMORY,_Fields.SHARED_MEMORY};
  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.SPOUTS, new org.apache.storm.thrift.meta_data.FieldMetaData("spouts", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        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, SpoutSpec.class))));
    tmpMap.put(_Fields.BOLTS, new org.apache.storm.thrift.meta_data.FieldMetaData("bolts", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        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, Bolt.class))));
    tmpMap.put(_Fields.STATE_SPOUTS, new org.apache.storm.thrift.meta_data.FieldMetaData("state_spouts", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        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, StateSpoutSpec.class))));
    tmpMap.put(_Fields.WORKER_HOOKS, new org.apache.storm.thrift.meta_data.FieldMetaData("worker_hooks", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.ListMetaData(org.apache.storm.thrift.protocol.TType.LIST, 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING            , true))));
    tmpMap.put(_Fields.DEPENDENCY_JARS, new org.apache.storm.thrift.meta_data.FieldMetaData("dependency_jars", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.ListMetaData(org.apache.storm.thrift.protocol.TType.LIST, 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING))));
    tmpMap.put(_Fields.DEPENDENCY_ARTIFACTS, new org.apache.storm.thrift.meta_data.FieldMetaData("dependency_artifacts", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.ListMetaData(org.apache.storm.thrift.protocol.TType.LIST, 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING))));
    tmpMap.put(_Fields.STORM_VERSION, new org.apache.storm.thrift.meta_data.FieldMetaData("storm_version", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.JDK_VERSION, new org.apache.storm.thrift.meta_data.FieldMetaData("jdk_version", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.COMPONENT_TO_SHARED_MEMORY, new org.apache.storm.thrift.meta_data.FieldMetaData("component_to_shared_memory", 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.SetMetaData(org.apache.storm.thrift.protocol.TType.SET, 
                new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)))));
    tmpMap.put(_Fields.SHARED_MEMORY, new org.apache.storm.thrift.meta_data.FieldMetaData("shared_memory", 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, SharedMemory.class))));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.storm.thrift.meta_data.FieldMetaData.addStructMetaDataMap(StormTopology.class, metaDataMap);
  }

  public StormTopology() {
  }

  public StormTopology(
    java.util.Map<java.lang.String,SpoutSpec> spouts,
    java.util.Map<java.lang.String,Bolt> bolts,
    java.util.Map<java.lang.String,StateSpoutSpec> state_spouts)
  {
    this();
    this.spouts = spouts;
    this.bolts = bolts;
    this.state_spouts = state_spouts;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public StormTopology(StormTopology other) {
    if (other.is_set_spouts()) {
      java.util.Map<java.lang.String,SpoutSpec> __this__spouts = new java.util.HashMap<java.lang.String,SpoutSpec>(other.spouts.size());
      for (java.util.Map.Entry<java.lang.String, SpoutSpec> other_element : other.spouts.entrySet()) {

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

        java.lang.String __this__spouts_copy_key = other_element_key;

        SpoutSpec __this__spouts_copy_value = new SpoutSpec(other_element_value);

        __this__spouts.put(__this__spouts_copy_key, __this__spouts_copy_value);
      }
      this.spouts = __this__spouts;
    }
    if (other.is_set_bolts()) {
      java.util.Map<java.lang.String,Bolt> __this__bolts = new java.util.HashMap<java.lang.String,Bolt>(other.bolts.size());
      for (java.util.Map.Entry<java.lang.String, Bolt> other_element : other.bolts.entrySet()) {

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

        java.lang.String __this__bolts_copy_key = other_element_key;

        Bolt __this__bolts_copy_value = new Bolt(other_element_value);

        __this__bolts.put(__this__bolts_copy_key, __this__bolts_copy_value);
      }
      this.bolts = __this__bolts;
    }
    if (other.is_set_state_spouts()) {
      java.util.Map<java.lang.String,StateSpoutSpec> __this__state_spouts = new java.util.HashMap<java.lang.String,StateSpoutSpec>(other.state_spouts.size());
      for (java.util.Map.Entry<java.lang.String, StateSpoutSpec> other_element : other.state_spouts.entrySet()) {

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

        java.lang.String __this__state_spouts_copy_key = other_element_key;

        StateSpoutSpec __this__state_spouts_copy_value = new StateSpoutSpec(other_element_value);

        __this__state_spouts.put(__this__state_spouts_copy_key, __this__state_spouts_copy_value);
      }
      this.state_spouts = __this__state_spouts;
    }
    if (other.is_set_worker_hooks()) {
      java.util.List<java.nio.ByteBuffer> __this__worker_hooks = new java.util.ArrayList<java.nio.ByteBuffer>(other.worker_hooks);
      this.worker_hooks = __this__worker_hooks;
    }
    if (other.is_set_dependency_jars()) {
      java.util.List<java.lang.String> __this__dependency_jars = new java.util.ArrayList<java.lang.String>(other.dependency_jars);
      this.dependency_jars = __this__dependency_jars;
    }
    if (other.is_set_dependency_artifacts()) {
      java.util.List<java.lang.String> __this__dependency_artifacts = new java.util.ArrayList<java.lang.String>(other.dependency_artifacts);
      this.dependency_artifacts = __this__dependency_artifacts;
    }
    if (other.is_set_storm_version()) {
      this.storm_version = other.storm_version;
    }
    if (other.is_set_jdk_version()) {
      this.jdk_version = other.jdk_version;
    }
    if (other.is_set_component_to_shared_memory()) {
      java.util.Map<java.lang.String,java.util.Set<java.lang.String>> __this__component_to_shared_memory = new java.util.HashMap<java.lang.String,java.util.Set<java.lang.String>>(other.component_to_shared_memory.size());
      for (java.util.Map.Entry<java.lang.String, java.util.Set<java.lang.String>> other_element : other.component_to_shared_memory.entrySet()) {

        java.lang.String other_element_key = other_element.getKey();
        java.util.Set<java.lang.String> other_element_value = other_element.getValue();

        java.lang.String __this__component_to_shared_memory_copy_key = other_element_key;

        java.util.Set<java.lang.String> __this__component_to_shared_memory_copy_value = new java.util.HashSet<java.lang.String>(other_element_value);

        __this__component_to_shared_memory.put(__this__component_to_shared_memory_copy_key, __this__component_to_shared_memory_copy_value);
      }
      this.component_to_shared_memory = __this__component_to_shared_memory;
    }
    if (other.is_set_shared_memory()) {
      java.util.Map<java.lang.String,SharedMemory> __this__shared_memory = new java.util.HashMap<java.lang.String,SharedMemory>(other.shared_memory.size());
      for (java.util.Map.Entry<java.lang.String, SharedMemory> other_element : other.shared_memory.entrySet()) {

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

        java.lang.String __this__shared_memory_copy_key = other_element_key;

        SharedMemory __this__shared_memory_copy_value = new SharedMemory(other_element_value);

        __this__shared_memory.put(__this__shared_memory_copy_key, __this__shared_memory_copy_value);
      }
      this.shared_memory = __this__shared_memory;
    }
  }

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

  @Override
  public void clear() {
    this.spouts = null;
    this.bolts = null;
    this.state_spouts = null;
    this.worker_hooks = null;
    this.dependency_jars = null;
    this.dependency_artifacts = null;
    this.storm_version = null;
    this.jdk_version = null;
    this.component_to_shared_memory = null;
    this.shared_memory = null;
  }

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

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

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

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

  public void unset_spouts() {
    this.spouts = null;
  }

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

  public void set_spouts_isSet(boolean value) {
    if (!value) {
      this.spouts = null;
    }
  }

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

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

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

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

  public void unset_bolts() {
    this.bolts = null;
  }

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

  public void set_bolts_isSet(boolean value) {
    if (!value) {
      this.bolts = null;
    }
  }

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

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

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

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

  public void unset_state_spouts() {
    this.state_spouts = null;
  }

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

  public void set_state_spouts_isSet(boolean value) {
    if (!value) {
      this.state_spouts = null;
    }
  }

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

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.Iterator<java.nio.ByteBuffer> get_worker_hooks_iterator() {
    return (this.worker_hooks == null) ? null : this.worker_hooks.iterator();
  }

  public void add_to_worker_hooks(java.nio.ByteBuffer elem) {
    if (this.worker_hooks == null) {
      this.worker_hooks = new java.util.ArrayList<java.nio.ByteBuffer>();
    }
    this.worker_hooks.add(elem);
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.List<java.nio.ByteBuffer> get_worker_hooks() {
    return this.worker_hooks;
  }

  public void set_worker_hooks(@org.apache.storm.thrift.annotation.Nullable java.util.List<java.nio.ByteBuffer> worker_hooks) {
    this.worker_hooks = worker_hooks;
  }

  public void unset_worker_hooks() {
    this.worker_hooks = null;
  }

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

  public void set_worker_hooks_isSet(boolean value) {
    if (!value) {
      this.worker_hooks = null;
    }
  }

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

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

  public void add_to_dependency_jars(java.lang.String elem) {
    if (this.dependency_jars == null) {
      this.dependency_jars = new java.util.ArrayList<java.lang.String>();
    }
    this.dependency_jars.add(elem);
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.List<java.lang.String> get_dependency_jars() {
    return this.dependency_jars;
  }

  public void set_dependency_jars(@org.apache.storm.thrift.annotation.Nullable java.util.List<java.lang.String> dependency_jars) {
    this.dependency_jars = dependency_jars;
  }

  public void unset_dependency_jars() {
    this.dependency_jars = null;
  }

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

  public void set_dependency_jars_isSet(boolean value) {
    if (!value) {
      this.dependency_jars = null;
    }
  }

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

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

  public void add_to_dependency_artifacts(java.lang.String elem) {
    if (this.dependency_artifacts == null) {
      this.dependency_artifacts = new java.util.ArrayList<java.lang.String>();
    }
    this.dependency_artifacts.add(elem);
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.List<java.lang.String> get_dependency_artifacts() {
    return this.dependency_artifacts;
  }

  public void set_dependency_artifacts(@org.apache.storm.thrift.annotation.Nullable java.util.List<java.lang.String> dependency_artifacts) {
    this.dependency_artifacts = dependency_artifacts;
  }

  public void unset_dependency_artifacts() {
    this.dependency_artifacts = null;
  }

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

  public void set_dependency_artifacts_isSet(boolean value) {
    if (!value) {
      this.dependency_artifacts = null;
    }
  }

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

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

  public void unset_storm_version() {
    this.storm_version = null;
  }

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

  public void set_storm_version_isSet(boolean value) {
    if (!value) {
      this.storm_version = null;
    }
  }

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

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

  public void unset_jdk_version() {
    this.jdk_version = null;
  }

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

  public void set_jdk_version_isSet(boolean value) {
    if (!value) {
      this.jdk_version = null;
    }
  }

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

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

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

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

  public void unset_component_to_shared_memory() {
    this.component_to_shared_memory = null;
  }

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

  public void set_component_to_shared_memory_isSet(boolean value) {
    if (!value) {
      this.component_to_shared_memory = null;
    }
  }

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

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

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

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

  public void unset_shared_memory() {
    this.shared_memory = null;
  }

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

  public void set_shared_memory_isSet(boolean value) {
    if (!value) {
      this.shared_memory = null;
    }
  }

  public void setFieldValue(_Fields field, @org.apache.storm.thrift.annotation.Nullable java.lang.Object value) {
    switch (field) {
    case SPOUTS:
      if (value == null) {
        unset_spouts();
      } else {
        set_spouts((java.util.Map<java.lang.String,SpoutSpec>)value);
      }
      break;

    case BOLTS:
      if (value == null) {
        unset_bolts();
      } else {
        set_bolts((java.util.Map<java.lang.String,Bolt>)value);
      }
      break;

    case STATE_SPOUTS:
      if (value == null) {
        unset_state_spouts();
      } else {
        set_state_spouts((java.util.Map<java.lang.String,StateSpoutSpec>)value);
      }
      break;

    case WORKER_HOOKS:
      if (value == null) {
        unset_worker_hooks();
      } else {
        set_worker_hooks((java.util.List<java.nio.ByteBuffer>)value);
      }
      break;

    case DEPENDENCY_JARS:
      if (value == null) {
        unset_dependency_jars();
      } else {
        set_dependency_jars((java.util.List<java.lang.String>)value);
      }
      break;

    case DEPENDENCY_ARTIFACTS:
      if (value == null) {
        unset_dependency_artifacts();
      } else {
        set_dependency_artifacts((java.util.List<java.lang.String>)value);
      }
      break;

    case STORM_VERSION:
      if (value == null) {
        unset_storm_version();
      } else {
        set_storm_version((java.lang.String)value);
      }
      break;

    case JDK_VERSION:
      if (value == null) {
        unset_jdk_version();
      } else {
        set_jdk_version((java.lang.String)value);
      }
      break;

    case COMPONENT_TO_SHARED_MEMORY:
      if (value == null) {
        unset_component_to_shared_memory();
      } else {
        set_component_to_shared_memory((java.util.Map<java.lang.String,java.util.Set<java.lang.String>>)value);
      }
      break;

    case SHARED_MEMORY:
      if (value == null) {
        unset_shared_memory();
      } else {
        set_shared_memory((java.util.Map<java.lang.String,SharedMemory>)value);
      }
      break;

    }
  }

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

    case BOLTS:
      return get_bolts();

    case STATE_SPOUTS:
      return get_state_spouts();

    case WORKER_HOOKS:
      return get_worker_hooks();

    case DEPENDENCY_JARS:
      return get_dependency_jars();

    case DEPENDENCY_ARTIFACTS:
      return get_dependency_artifacts();

    case STORM_VERSION:
      return get_storm_version();

    case JDK_VERSION:
      return get_jdk_version();

    case COMPONENT_TO_SHARED_MEMORY:
      return get_component_to_shared_memory();

    case SHARED_MEMORY:
      return get_shared_memory();

    }
    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 SPOUTS:
      return is_set_spouts();
    case BOLTS:
      return is_set_bolts();
    case STATE_SPOUTS:
      return is_set_state_spouts();
    case WORKER_HOOKS:
      return is_set_worker_hooks();
    case DEPENDENCY_JARS:
      return is_set_dependency_jars();
    case DEPENDENCY_ARTIFACTS:
      return is_set_dependency_artifacts();
    case STORM_VERSION:
      return is_set_storm_version();
    case JDK_VERSION:
      return is_set_jdk_version();
    case COMPONENT_TO_SHARED_MEMORY:
      return is_set_component_to_shared_memory();
    case SHARED_MEMORY:
      return is_set_shared_memory();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_spouts = true && this.is_set_spouts();
    boolean that_present_spouts = true && that.is_set_spouts();
    if (this_present_spouts || that_present_spouts) {
      if (!(this_present_spouts && that_present_spouts))
        return false;
      if (!this.spouts.equals(that.spouts))
        return false;
    }

    boolean this_present_bolts = true && this.is_set_bolts();
    boolean that_present_bolts = true && that.is_set_bolts();
    if (this_present_bolts || that_present_bolts) {
      if (!(this_present_bolts && that_present_bolts))
        return false;
      if (!this.bolts.equals(that.bolts))
        return false;
    }

    boolean this_present_state_spouts = true && this.is_set_state_spouts();
    boolean that_present_state_spouts = true && that.is_set_state_spouts();
    if (this_present_state_spouts || that_present_state_spouts) {
      if (!(this_present_state_spouts && that_present_state_spouts))
        return false;
      if (!this.state_spouts.equals(that.state_spouts))
        return false;
    }

    boolean this_present_worker_hooks = true && this.is_set_worker_hooks();
    boolean that_present_worker_hooks = true && that.is_set_worker_hooks();
    if (this_present_worker_hooks || that_present_worker_hooks) {
      if (!(this_present_worker_hooks && that_present_worker_hooks))
        return false;
      if (!this.worker_hooks.equals(that.worker_hooks))
        return false;
    }

    boolean this_present_dependency_jars = true && this.is_set_dependency_jars();
    boolean that_present_dependency_jars = true && that.is_set_dependency_jars();
    if (this_present_dependency_jars || that_present_dependency_jars) {
      if (!(this_present_dependency_jars && that_present_dependency_jars))
        return false;
      if (!this.dependency_jars.equals(that.dependency_jars))
        return false;
    }

    boolean this_present_dependency_artifacts = true && this.is_set_dependency_artifacts();
    boolean that_present_dependency_artifacts = true && that.is_set_dependency_artifacts();
    if (this_present_dependency_artifacts || that_present_dependency_artifacts) {
      if (!(this_present_dependency_artifacts && that_present_dependency_artifacts))
        return false;
      if (!this.dependency_artifacts.equals(that.dependency_artifacts))
        return false;
    }

    boolean this_present_storm_version = true && this.is_set_storm_version();
    boolean that_present_storm_version = true && that.is_set_storm_version();
    if (this_present_storm_version || that_present_storm_version) {
      if (!(this_present_storm_version && that_present_storm_version))
        return false;
      if (!this.storm_version.equals(that.storm_version))
        return false;
    }

    boolean this_present_jdk_version = true && this.is_set_jdk_version();
    boolean that_present_jdk_version = true && that.is_set_jdk_version();
    if (this_present_jdk_version || that_present_jdk_version) {
      if (!(this_present_jdk_version && that_present_jdk_version))
        return false;
      if (!this.jdk_version.equals(that.jdk_version))
        return false;
    }

    boolean this_present_component_to_shared_memory = true && this.is_set_component_to_shared_memory();
    boolean that_present_component_to_shared_memory = true && that.is_set_component_to_shared_memory();
    if (this_present_component_to_shared_memory || that_present_component_to_shared_memory) {
      if (!(this_present_component_to_shared_memory && that_present_component_to_shared_memory))
        return false;
      if (!this.component_to_shared_memory.equals(that.component_to_shared_memory))
        return false;
    }

    boolean this_present_shared_memory = true && this.is_set_shared_memory();
    boolean that_present_shared_memory = true && that.is_set_shared_memory();
    if (this_present_shared_memory || that_present_shared_memory) {
      if (!(this_present_shared_memory && that_present_shared_memory))
        return false;
      if (!this.shared_memory.equals(that.shared_memory))
        return false;
    }

    return true;
  }

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

    hashCode = hashCode * 8191 + ((is_set_spouts()) ? 131071 : 524287);
    if (is_set_spouts())
      hashCode = hashCode * 8191 + spouts.hashCode();

    hashCode = hashCode * 8191 + ((is_set_bolts()) ? 131071 : 524287);
    if (is_set_bolts())
      hashCode = hashCode * 8191 + bolts.hashCode();

    hashCode = hashCode * 8191 + ((is_set_state_spouts()) ? 131071 : 524287);
    if (is_set_state_spouts())
      hashCode = hashCode * 8191 + state_spouts.hashCode();

    hashCode = hashCode * 8191 + ((is_set_worker_hooks()) ? 131071 : 524287);
    if (is_set_worker_hooks())
      hashCode = hashCode * 8191 + worker_hooks.hashCode();

    hashCode = hashCode * 8191 + ((is_set_dependency_jars()) ? 131071 : 524287);
    if (is_set_dependency_jars())
      hashCode = hashCode * 8191 + dependency_jars.hashCode();

    hashCode = hashCode * 8191 + ((is_set_dependency_artifacts()) ? 131071 : 524287);
    if (is_set_dependency_artifacts())
      hashCode = hashCode * 8191 + dependency_artifacts.hashCode();

    hashCode = hashCode * 8191 + ((is_set_storm_version()) ? 131071 : 524287);
    if (is_set_storm_version())
      hashCode = hashCode * 8191 + storm_version.hashCode();

    hashCode = hashCode * 8191 + ((is_set_jdk_version()) ? 131071 : 524287);
    if (is_set_jdk_version())
      hashCode = hashCode * 8191 + jdk_version.hashCode();

    hashCode = hashCode * 8191 + ((is_set_component_to_shared_memory()) ? 131071 : 524287);
    if (is_set_component_to_shared_memory())
      hashCode = hashCode * 8191 + component_to_shared_memory.hashCode();

    hashCode = hashCode * 8191 + ((is_set_shared_memory()) ? 131071 : 524287);
    if (is_set_shared_memory())
      hashCode = hashCode * 8191 + shared_memory.hashCode();

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(is_set_spouts()).compareTo(other.is_set_spouts());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_spouts()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.spouts, other.spouts);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_bolts()).compareTo(other.is_set_bolts());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_bolts()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.bolts, other.bolts);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_state_spouts()).compareTo(other.is_set_state_spouts());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_state_spouts()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.state_spouts, other.state_spouts);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_worker_hooks()).compareTo(other.is_set_worker_hooks());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_worker_hooks()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.worker_hooks, other.worker_hooks);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_dependency_jars()).compareTo(other.is_set_dependency_jars());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_dependency_jars()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.dependency_jars, other.dependency_jars);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_dependency_artifacts()).compareTo(other.is_set_dependency_artifacts());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_dependency_artifacts()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.dependency_artifacts, other.dependency_artifacts);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_storm_version()).compareTo(other.is_set_storm_version());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_storm_version()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.storm_version, other.storm_version);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_jdk_version()).compareTo(other.is_set_jdk_version());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_jdk_version()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.jdk_version, other.jdk_version);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_component_to_shared_memory()).compareTo(other.is_set_component_to_shared_memory());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_component_to_shared_memory()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.component_to_shared_memory, other.component_to_shared_memory);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_shared_memory()).compareTo(other.is_set_shared_memory());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_shared_memory()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.shared_memory, other.shared_memory);
      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("StormTopology(");
    boolean first = true;

    sb.append("spouts:");
    if (this.spouts == null) {
      sb.append("null");
    } else {
      sb.append(this.spouts);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("bolts:");
    if (this.bolts == null) {
      sb.append("null");
    } else {
      sb.append(this.bolts);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("state_spouts:");
    if (this.state_spouts == null) {
      sb.append("null");
    } else {
      sb.append(this.state_spouts);
    }
    first = false;
    if (is_set_worker_hooks()) {
      if (!first) sb.append(", ");
      sb.append("worker_hooks:");
      if (this.worker_hooks == null) {
        sb.append("null");
      } else {
        org.apache.storm.thrift.TBaseHelper.toString(this.worker_hooks, sb);
      }
      first = false;
    }
    if (is_set_dependency_jars()) {
      if (!first) sb.append(", ");
      sb.append("dependency_jars:");
      if (this.dependency_jars == null) {
        sb.append("null");
      } else {
        sb.append(this.dependency_jars);
      }
      first = false;
    }
    if (is_set_dependency_artifacts()) {
      if (!first) sb.append(", ");
      sb.append("dependency_artifacts:");
      if (this.dependency_artifacts == null) {
        sb.append("null");
      } else {
        sb.append(this.dependency_artifacts);
      }
      first = false;
    }
    if (is_set_storm_version()) {
      if (!first) sb.append(", ");
      sb.append("storm_version:");
      if (this.storm_version == null) {
        sb.append("null");
      } else {
        sb.append(this.storm_version);
      }
      first = false;
    }
    if (is_set_jdk_version()) {
      if (!first) sb.append(", ");
      sb.append("jdk_version:");
      if (this.jdk_version == null) {
        sb.append("null");
      } else {
        sb.append(this.jdk_version);
      }
      first = false;
    }
    if (is_set_component_to_shared_memory()) {
      if (!first) sb.append(", ");
      sb.append("component_to_shared_memory:");
      if (this.component_to_shared_memory == null) {
        sb.append("null");
      } else {
        sb.append(this.component_to_shared_memory);
      }
      first = false;
    }
    if (is_set_shared_memory()) {
      if (!first) sb.append(", ");
      sb.append("shared_memory:");
      if (this.shared_memory == null) {
        sb.append("null");
      } else {
        sb.append(this.shared_memory);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

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

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

    // check for sub-struct validity
  }

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

  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
    try {
      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 StormTopologyStandardSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
    public StormTopologyStandardScheme getScheme() {
      return new StormTopologyStandardScheme();
    }
  }

  private static class StormTopologyStandardScheme extends org.apache.storm.thrift.scheme.StandardScheme<StormTopology> {

    public void read(org.apache.storm.thrift.protocol.TProtocol iprot, StormTopology 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: // SPOUTS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map44 = iprot.readMapBegin();
                struct.spouts = new java.util.HashMap<java.lang.String,SpoutSpec>(2*_map44.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key45;
                @org.apache.storm.thrift.annotation.Nullable SpoutSpec _val46;
                for (int _i47 = 0; _i47 < _map44.size; ++_i47)
                {
                  _key45 = iprot.readString();
                  _val46 = new SpoutSpec();
                  _val46.read(iprot);
                  struct.spouts.put(_key45, _val46);
                }
                iprot.readMapEnd();
              }
              struct.set_spouts_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // BOLTS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map48 = iprot.readMapBegin();
                struct.bolts = new java.util.HashMap<java.lang.String,Bolt>(2*_map48.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key49;
                @org.apache.storm.thrift.annotation.Nullable Bolt _val50;
                for (int _i51 = 0; _i51 < _map48.size; ++_i51)
                {
                  _key49 = iprot.readString();
                  _val50 = new Bolt();
                  _val50.read(iprot);
                  struct.bolts.put(_key49, _val50);
                }
                iprot.readMapEnd();
              }
              struct.set_bolts_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // STATE_SPOUTS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map52 = iprot.readMapBegin();
                struct.state_spouts = new java.util.HashMap<java.lang.String,StateSpoutSpec>(2*_map52.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key53;
                @org.apache.storm.thrift.annotation.Nullable StateSpoutSpec _val54;
                for (int _i55 = 0; _i55 < _map52.size; ++_i55)
                {
                  _key53 = iprot.readString();
                  _val54 = new StateSpoutSpec();
                  _val54.read(iprot);
                  struct.state_spouts.put(_key53, _val54);
                }
                iprot.readMapEnd();
              }
              struct.set_state_spouts_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // WORKER_HOOKS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.LIST) {
              {
                org.apache.storm.thrift.protocol.TList _list56 = iprot.readListBegin();
                struct.worker_hooks = new java.util.ArrayList<java.nio.ByteBuffer>(_list56.size);
                @org.apache.storm.thrift.annotation.Nullable java.nio.ByteBuffer _elem57;
                for (int _i58 = 0; _i58 < _list56.size; ++_i58)
                {
                  _elem57 = iprot.readBinary();
                  struct.worker_hooks.add(_elem57);
                }
                iprot.readListEnd();
              }
              struct.set_worker_hooks_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // DEPENDENCY_JARS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.LIST) {
              {
                org.apache.storm.thrift.protocol.TList _list59 = iprot.readListBegin();
                struct.dependency_jars = new java.util.ArrayList<java.lang.String>(_list59.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _elem60;
                for (int _i61 = 0; _i61 < _list59.size; ++_i61)
                {
                  _elem60 = iprot.readString();
                  struct.dependency_jars.add(_elem60);
                }
                iprot.readListEnd();
              }
              struct.set_dependency_jars_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // DEPENDENCY_ARTIFACTS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.LIST) {
              {
                org.apache.storm.thrift.protocol.TList _list62 = iprot.readListBegin();
                struct.dependency_artifacts = new java.util.ArrayList<java.lang.String>(_list62.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _elem63;
                for (int _i64 = 0; _i64 < _list62.size; ++_i64)
                {
                  _elem63 = iprot.readString();
                  struct.dependency_artifacts.add(_elem63);
                }
                iprot.readListEnd();
              }
              struct.set_dependency_artifacts_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // STORM_VERSION
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.storm_version = iprot.readString();
              struct.set_storm_version_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // JDK_VERSION
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.jdk_version = iprot.readString();
              struct.set_jdk_version_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // COMPONENT_TO_SHARED_MEMORY
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map65 = iprot.readMapBegin();
                struct.component_to_shared_memory = new java.util.HashMap<java.lang.String,java.util.Set<java.lang.String>>(2*_map65.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key66;
                @org.apache.storm.thrift.annotation.Nullable java.util.Set<java.lang.String> _val67;
                for (int _i68 = 0; _i68 < _map65.size; ++_i68)
                {
                  _key66 = iprot.readString();
                  {
                    org.apache.storm.thrift.protocol.TSet _set69 = iprot.readSetBegin();
                    _val67 = new java.util.HashSet<java.lang.String>(2*_set69.size);
                    @org.apache.storm.thrift.annotation.Nullable java.lang.String _elem70;
                    for (int _i71 = 0; _i71 < _set69.size; ++_i71)
                    {
                      _elem70 = iprot.readString();
                      _val67.add(_elem70);
                    }
                    iprot.readSetEnd();
                  }
                  struct.component_to_shared_memory.put(_key66, _val67);
                }
                iprot.readMapEnd();
              }
              struct.set_component_to_shared_memory_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // SHARED_MEMORY
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map72 = iprot.readMapBegin();
                struct.shared_memory = new java.util.HashMap<java.lang.String,SharedMemory>(2*_map72.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key73;
                @org.apache.storm.thrift.annotation.Nullable SharedMemory _val74;
                for (int _i75 = 0; _i75 < _map72.size; ++_i75)
                {
                  _key73 = iprot.readString();
                  _val74 = new SharedMemory();
                  _val74.read(iprot);
                  struct.shared_memory.put(_key73, _val74);
                }
                iprot.readMapEnd();
              }
              struct.set_shared_memory_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, StormTopology struct) throws org.apache.storm.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.spouts != null) {
        oprot.writeFieldBegin(SPOUTS_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.spouts.size()));
          for (java.util.Map.Entry<java.lang.String, SpoutSpec> _iter76 : struct.spouts.entrySet())
          {
            oprot.writeString(_iter76.getKey());
            _iter76.getValue().write(oprot);
          }
          oprot.writeMapEnd();
        }
        oprot.writeFieldEnd();
      }
      if (struct.bolts != null) {
        oprot.writeFieldBegin(BOLTS_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.bolts.size()));
          for (java.util.Map.Entry<java.lang.String, Bolt> _iter77 : struct.bolts.entrySet())
          {
            oprot.writeString(_iter77.getKey());
            _iter77.getValue().write(oprot);
          }
          oprot.writeMapEnd();
        }
        oprot.writeFieldEnd();
      }
      if (struct.state_spouts != null) {
        oprot.writeFieldBegin(STATE_SPOUTS_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.state_spouts.size()));
          for (java.util.Map.Entry<java.lang.String, StateSpoutSpec> _iter78 : struct.state_spouts.entrySet())
          {
            oprot.writeString(_iter78.getKey());
            _iter78.getValue().write(oprot);
          }
          oprot.writeMapEnd();
        }
        oprot.writeFieldEnd();
      }
      if (struct.worker_hooks != null) {
        if (struct.is_set_worker_hooks()) {
          oprot.writeFieldBegin(WORKER_HOOKS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.STRING, struct.worker_hooks.size()));
            for (java.nio.ByteBuffer _iter79 : struct.worker_hooks)
            {
              oprot.writeBinary(_iter79);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.dependency_jars != null) {
        if (struct.is_set_dependency_jars()) {
          oprot.writeFieldBegin(DEPENDENCY_JARS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.STRING, struct.dependency_jars.size()));
            for (java.lang.String _iter80 : struct.dependency_jars)
            {
              oprot.writeString(_iter80);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.dependency_artifacts != null) {
        if (struct.is_set_dependency_artifacts()) {
          oprot.writeFieldBegin(DEPENDENCY_ARTIFACTS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.STRING, struct.dependency_artifacts.size()));
            for (java.lang.String _iter81 : struct.dependency_artifacts)
            {
              oprot.writeString(_iter81);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.storm_version != null) {
        if (struct.is_set_storm_version()) {
          oprot.writeFieldBegin(STORM_VERSION_FIELD_DESC);
          oprot.writeString(struct.storm_version);
          oprot.writeFieldEnd();
        }
      }
      if (struct.jdk_version != null) {
        if (struct.is_set_jdk_version()) {
          oprot.writeFieldBegin(JDK_VERSION_FIELD_DESC);
          oprot.writeString(struct.jdk_version);
          oprot.writeFieldEnd();
        }
      }
      if (struct.component_to_shared_memory != null) {
        if (struct.is_set_component_to_shared_memory()) {
          oprot.writeFieldBegin(COMPONENT_TO_SHARED_MEMORY_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.SET, struct.component_to_shared_memory.size()));
            for (java.util.Map.Entry<java.lang.String, java.util.Set<java.lang.String>> _iter82 : struct.component_to_shared_memory.entrySet())
            {
              oprot.writeString(_iter82.getKey());
              {
                oprot.writeSetBegin(new org.apache.storm.thrift.protocol.TSet(org.apache.storm.thrift.protocol.TType.STRING, _iter82.getValue().size()));
                for (java.lang.String _iter83 : _iter82.getValue())
                {
                  oprot.writeString(_iter83);
                }
                oprot.writeSetEnd();
              }
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.shared_memory != null) {
        if (struct.is_set_shared_memory()) {
          oprot.writeFieldBegin(SHARED_MEMORY_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.shared_memory.size()));
            for (java.util.Map.Entry<java.lang.String, SharedMemory> _iter84 : struct.shared_memory.entrySet())
            {
              oprot.writeString(_iter84.getKey());
              _iter84.getValue().write(oprot);
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

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

  private static class StormTopologyTupleScheme extends org.apache.storm.thrift.scheme.TupleScheme<StormTopology> {

    @Override
    public void write(org.apache.storm.thrift.protocol.TProtocol prot, StormTopology struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol oprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      {
        oprot.writeI32(struct.spouts.size());
        for (java.util.Map.Entry<java.lang.String, SpoutSpec> _iter85 : struct.spouts.entrySet())
        {
          oprot.writeString(_iter85.getKey());
          _iter85.getValue().write(oprot);
        }
      }
      {
        oprot.writeI32(struct.bolts.size());
        for (java.util.Map.Entry<java.lang.String, Bolt> _iter86 : struct.bolts.entrySet())
        {
          oprot.writeString(_iter86.getKey());
          _iter86.getValue().write(oprot);
        }
      }
      {
        oprot.writeI32(struct.state_spouts.size());
        for (java.util.Map.Entry<java.lang.String, StateSpoutSpec> _iter87 : struct.state_spouts.entrySet())
        {
          oprot.writeString(_iter87.getKey());
          _iter87.getValue().write(oprot);
        }
      }
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.is_set_worker_hooks()) {
        optionals.set(0);
      }
      if (struct.is_set_dependency_jars()) {
        optionals.set(1);
      }
      if (struct.is_set_dependency_artifacts()) {
        optionals.set(2);
      }
      if (struct.is_set_storm_version()) {
        optionals.set(3);
      }
      if (struct.is_set_jdk_version()) {
        optionals.set(4);
      }
      if (struct.is_set_component_to_shared_memory()) {
        optionals.set(5);
      }
      if (struct.is_set_shared_memory()) {
        optionals.set(6);
      }
      oprot.writeBitSet(optionals, 7);
      if (struct.is_set_worker_hooks()) {
        {
          oprot.writeI32(struct.worker_hooks.size());
          for (java.nio.ByteBuffer _iter88 : struct.worker_hooks)
          {
            oprot.writeBinary(_iter88);
          }
        }
      }
      if (struct.is_set_dependency_jars()) {
        {
          oprot.writeI32(struct.dependency_jars.size());
          for (java.lang.String _iter89 : struct.dependency_jars)
          {
            oprot.writeString(_iter89);
          }
        }
      }
      if (struct.is_set_dependency_artifacts()) {
        {
          oprot.writeI32(struct.dependency_artifacts.size());
          for (java.lang.String _iter90 : struct.dependency_artifacts)
          {
            oprot.writeString(_iter90);
          }
        }
      }
      if (struct.is_set_storm_version()) {
        oprot.writeString(struct.storm_version);
      }
      if (struct.is_set_jdk_version()) {
        oprot.writeString(struct.jdk_version);
      }
      if (struct.is_set_component_to_shared_memory()) {
        {
          oprot.writeI32(struct.component_to_shared_memory.size());
          for (java.util.Map.Entry<java.lang.String, java.util.Set<java.lang.String>> _iter91 : struct.component_to_shared_memory.entrySet())
          {
            oprot.writeString(_iter91.getKey());
            {
              oprot.writeI32(_iter91.getValue().size());
              for (java.lang.String _iter92 : _iter91.getValue())
              {
                oprot.writeString(_iter92);
              }
            }
          }
        }
      }
      if (struct.is_set_shared_memory()) {
        {
          oprot.writeI32(struct.shared_memory.size());
          for (java.util.Map.Entry<java.lang.String, SharedMemory> _iter93 : struct.shared_memory.entrySet())
          {
            oprot.writeString(_iter93.getKey());
            _iter93.getValue().write(oprot);
          }
        }
      }
    }

    @Override
    public void read(org.apache.storm.thrift.protocol.TProtocol prot, StormTopology struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol iprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      {
        org.apache.storm.thrift.protocol.TMap _map94 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.STRUCT, iprot.readI32());
        struct.spouts = new java.util.HashMap<java.lang.String,SpoutSpec>(2*_map94.size);
        @org.apache.storm.thrift.annotation.Nullable java.lang.String _key95;
        @org.apache.storm.thrift.annotation.Nullable SpoutSpec _val96;
        for (int _i97 = 0; _i97 < _map94.size; ++_i97)
        {
          _key95 = iprot.readString();
          _val96 = new SpoutSpec();
          _val96.read(iprot);
          struct.spouts.put(_key95, _val96);
        }
      }
      struct.set_spouts_isSet(true);
      {
        org.apache.storm.thrift.protocol.TMap _map98 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.STRUCT, iprot.readI32());
        struct.bolts = new java.util.HashMap<java.lang.String,Bolt>(2*_map98.size);
        @org.apache.storm.thrift.annotation.Nullable java.lang.String _key99;
        @org.apache.storm.thrift.annotation.Nullable Bolt _val100;
        for (int _i101 = 0; _i101 < _map98.size; ++_i101)
        {
          _key99 = iprot.readString();
          _val100 = new Bolt();
          _val100.read(iprot);
          struct.bolts.put(_key99, _val100);
        }
      }
      struct.set_bolts_isSet(true);
      {
        org.apache.storm.thrift.protocol.TMap _map102 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.STRUCT, iprot.readI32());
        struct.state_spouts = new java.util.HashMap<java.lang.String,StateSpoutSpec>(2*_map102.size);
        @org.apache.storm.thrift.annotation.Nullable java.lang.String _key103;
        @org.apache.storm.thrift.annotation.Nullable StateSpoutSpec _val104;
        for (int _i105 = 0; _i105 < _map102.size; ++_i105)
        {
          _key103 = iprot.readString();
          _val104 = new StateSpoutSpec();
          _val104.read(iprot);
          struct.state_spouts.put(_key103, _val104);
        }
      }
      struct.set_state_spouts_isSet(true);
      java.util.BitSet incoming = iprot.readBitSet(7);
      if (incoming.get(0)) {
        {
          org.apache.storm.thrift.protocol.TList _list106 = new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.STRING, iprot.readI32());
          struct.worker_hooks = new java.util.ArrayList<java.nio.ByteBuffer>(_list106.size);
          @org.apache.storm.thrift.annotation.Nullable java.nio.ByteBuffer _elem107;
          for (int _i108 = 0; _i108 < _list106.size; ++_i108)
          {
            _elem107 = iprot.readBinary();
            struct.worker_hooks.add(_elem107);
          }
        }
        struct.set_worker_hooks_isSet(true);
      }
      if (incoming.get(1)) {
        {
          org.apache.storm.thrift.protocol.TList _list109 = new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.STRING, iprot.readI32());
          struct.dependency_jars = new java.util.ArrayList<java.lang.String>(_list109.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _elem110;
          for (int _i111 = 0; _i111 < _list109.size; ++_i111)
          {
            _elem110 = iprot.readString();
            struct.dependency_jars.add(_elem110);
          }
        }
        struct.set_dependency_jars_isSet(true);
      }
      if (incoming.get(2)) {
        {
          org.apache.storm.thrift.protocol.TList _list112 = new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.STRING, iprot.readI32());
          struct.dependency_artifacts = new java.util.ArrayList<java.lang.String>(_list112.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _elem113;
          for (int _i114 = 0; _i114 < _list112.size; ++_i114)
          {
            _elem113 = iprot.readString();
            struct.dependency_artifacts.add(_elem113);
          }
        }
        struct.set_dependency_artifacts_isSet(true);
      }
      if (incoming.get(3)) {
        struct.storm_version = iprot.readString();
        struct.set_storm_version_isSet(true);
      }
      if (incoming.get(4)) {
        struct.jdk_version = iprot.readString();
        struct.set_jdk_version_isSet(true);
      }
      if (incoming.get(5)) {
        {
          org.apache.storm.thrift.protocol.TMap _map115 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.SET, iprot.readI32());
          struct.component_to_shared_memory = new java.util.HashMap<java.lang.String,java.util.Set<java.lang.String>>(2*_map115.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key116;
          @org.apache.storm.thrift.annotation.Nullable java.util.Set<java.lang.String> _val117;
          for (int _i118 = 0; _i118 < _map115.size; ++_i118)
          {
            _key116 = iprot.readString();
            {
              org.apache.storm.thrift.protocol.TSet _set119 = new org.apache.storm.thrift.protocol.TSet(org.apache.storm.thrift.protocol.TType.STRING, iprot.readI32());
              _val117 = new java.util.HashSet<java.lang.String>(2*_set119.size);
              @org.apache.storm.thrift.annotation.Nullable java.lang.String _elem120;
              for (int _i121 = 0; _i121 < _set119.size; ++_i121)
              {
                _elem120 = iprot.readString();
                _val117.add(_elem120);
              }
            }
            struct.component_to_shared_memory.put(_key116, _val117);
          }
        }
        struct.set_component_to_shared_memory_isSet(true);
      }
      if (incoming.get(6)) {
        {
          org.apache.storm.thrift.protocol.TMap _map122 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.shared_memory = new java.util.HashMap<java.lang.String,SharedMemory>(2*_map122.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key123;
          @org.apache.storm.thrift.annotation.Nullable SharedMemory _val124;
          for (int _i125 = 0; _i125 < _map122.size; ++_i125)
          {
            _key123 = iprot.readString();
            _val124 = new SharedMemory();
            _val124.read(iprot);
            struct.shared_memory.put(_key123, _val124);
          }
        }
        struct.set_shared_memory_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();
  }
}

