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

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
/**
 * Computational Resource Description
 * 
 * computeResourceId: Airavata Internal Unique Identifier to distinguish Compute Resource.
 * 
 * hostName:
 *   Fully Qualified Host Name.
 * 
 * hostAliases:
 *   Aliases if any.
 * 
 * ipAddress:
 *   IP Addresses of the Resource.
 * 
 * resourceDescription:
 *  A user friendly description of the resource.
 * 
 * JobSubmissionProtocols:
 *  A computational resources may have one or more ways of submitting Jobs. This structure
 *    will hold all available mechanisms to interact with the resource.
 *  The key is the priority
 * 
 * DataMovementProtocol:
 *  Option to specify a prefered data movement mechanism of the available options.
 * 
 * fileSystems:
 *  Map of file systems type and the path.
 * 
 */
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
public class ComputeResourceDescription implements org.apache.thrift.TBase<ComputeResourceDescription, ComputeResourceDescription._Fields>, java.io.Serializable, Cloneable, Comparable<ComputeResourceDescription> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ComputeResourceDescription");

  private static final org.apache.thrift.protocol.TField COMPUTE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceId", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField HOST_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("hostName", org.apache.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.thrift.protocol.TField HOST_ALIASES_FIELD_DESC = new org.apache.thrift.protocol.TField("hostAliases", org.apache.thrift.protocol.TType.LIST, (short)3);
  private static final org.apache.thrift.protocol.TField IP_ADDRESSES_FIELD_DESC = new org.apache.thrift.protocol.TField("ipAddresses", org.apache.thrift.protocol.TType.LIST, (short)4);
  private static final org.apache.thrift.protocol.TField RESOURCE_DESCRIPTION_FIELD_DESC = new org.apache.thrift.protocol.TField("resourceDescription", org.apache.thrift.protocol.TType.STRING, (short)5);
  private static final org.apache.thrift.protocol.TField ENABLED_FIELD_DESC = new org.apache.thrift.protocol.TField("enabled", org.apache.thrift.protocol.TType.BOOL, (short)6);
  private static final org.apache.thrift.protocol.TField BATCH_QUEUES_FIELD_DESC = new org.apache.thrift.protocol.TField("batchQueues", org.apache.thrift.protocol.TType.LIST, (short)7);
  private static final org.apache.thrift.protocol.TField FILE_SYSTEMS_FIELD_DESC = new org.apache.thrift.protocol.TField("fileSystems", org.apache.thrift.protocol.TType.MAP, (short)8);
  private static final org.apache.thrift.protocol.TField JOB_SUBMISSION_INTERFACES_FIELD_DESC = new org.apache.thrift.protocol.TField("jobSubmissionInterfaces", org.apache.thrift.protocol.TType.LIST, (short)9);
  private static final org.apache.thrift.protocol.TField DATA_MOVEMENT_INTERFACES_FIELD_DESC = new org.apache.thrift.protocol.TField("dataMovementInterfaces", org.apache.thrift.protocol.TType.LIST, (short)10);
  private static final org.apache.thrift.protocol.TField MAX_MEMORY_PER_NODE_FIELD_DESC = new org.apache.thrift.protocol.TField("maxMemoryPerNode", org.apache.thrift.protocol.TType.I32, (short)11);
  private static final org.apache.thrift.protocol.TField GATEWAY_USAGE_REPORTING_FIELD_DESC = new org.apache.thrift.protocol.TField("gatewayUsageReporting", org.apache.thrift.protocol.TType.BOOL, (short)12);
  private static final org.apache.thrift.protocol.TField GATEWAY_USAGE_MODULE_LOAD_COMMAND_FIELD_DESC = new org.apache.thrift.protocol.TField("gatewayUsageModuleLoadCommand", org.apache.thrift.protocol.TType.STRING, (short)13);
  private static final org.apache.thrift.protocol.TField GATEWAY_USAGE_EXECUTABLE_FIELD_DESC = new org.apache.thrift.protocol.TField("gatewayUsageExecutable", org.apache.thrift.protocol.TType.STRING, (short)14);
  private static final org.apache.thrift.protocol.TField CPUS_PER_NODE_FIELD_DESC = new org.apache.thrift.protocol.TField("cpusPerNode", org.apache.thrift.protocol.TType.I32, (short)15);
  private static final org.apache.thrift.protocol.TField DEFAULT_NODE_COUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("defaultNodeCount", org.apache.thrift.protocol.TType.I32, (short)16);
  private static final org.apache.thrift.protocol.TField DEFAULT_CPUCOUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("defaultCPUCount", org.apache.thrift.protocol.TType.I32, (short)17);
  private static final org.apache.thrift.protocol.TField DEFAULT_WALLTIME_FIELD_DESC = new org.apache.thrift.protocol.TField("defaultWalltime", org.apache.thrift.protocol.TType.I32, (short)18);

  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new ComputeResourceDescriptionStandardSchemeFactory();
  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new ComputeResourceDescriptionTupleSchemeFactory();

  private java.lang.String computeResourceId; // required
  private java.lang.String hostName; // required
  private java.util.List<java.lang.String> hostAliases; // optional
  private java.util.List<java.lang.String> ipAddresses; // optional
  private java.lang.String resourceDescription; // optional
  private boolean enabled; // optional
  private java.util.List<BatchQueue> batchQueues; // optional
  private java.util.Map<FileSystems,java.lang.String> fileSystems; // optional
  private java.util.List<JobSubmissionInterface> jobSubmissionInterfaces; // optional
  private java.util.List<org.apache.airavata.model.data.movement.DataMovementInterface> dataMovementInterfaces; // optional
  private int maxMemoryPerNode; // optional
  private boolean gatewayUsageReporting; // optional
  private java.lang.String gatewayUsageModuleLoadCommand; // optional
  private java.lang.String gatewayUsageExecutable; // optional
  private int cpusPerNode; // optional
  private int defaultNodeCount; // optional
  private int defaultCPUCount; // optional
  private int defaultWalltime; // optional

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
    COMPUTE_RESOURCE_ID((short)1, "computeResourceId"),
    HOST_NAME((short)2, "hostName"),
    HOST_ALIASES((short)3, "hostAliases"),
    IP_ADDRESSES((short)4, "ipAddresses"),
    RESOURCE_DESCRIPTION((short)5, "resourceDescription"),
    ENABLED((short)6, "enabled"),
    BATCH_QUEUES((short)7, "batchQueues"),
    FILE_SYSTEMS((short)8, "fileSystems"),
    JOB_SUBMISSION_INTERFACES((short)9, "jobSubmissionInterfaces"),
    DATA_MOVEMENT_INTERFACES((short)10, "dataMovementInterfaces"),
    MAX_MEMORY_PER_NODE((short)11, "maxMemoryPerNode"),
    GATEWAY_USAGE_REPORTING((short)12, "gatewayUsageReporting"),
    GATEWAY_USAGE_MODULE_LOAD_COMMAND((short)13, "gatewayUsageModuleLoadCommand"),
    GATEWAY_USAGE_EXECUTABLE((short)14, "gatewayUsageExecutable"),
    CPUS_PER_NODE((short)15, "cpusPerNode"),
    DEFAULT_NODE_COUNT((short)16, "defaultNodeCount"),
    DEFAULT_CPUCOUNT((short)17, "defaultCPUCount"),
    DEFAULT_WALLTIME((short)18, "defaultWalltime");

    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.
     */
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // COMPUTE_RESOURCE_ID
          return COMPUTE_RESOURCE_ID;
        case 2: // HOST_NAME
          return HOST_NAME;
        case 3: // HOST_ALIASES
          return HOST_ALIASES;
        case 4: // IP_ADDRESSES
          return IP_ADDRESSES;
        case 5: // RESOURCE_DESCRIPTION
          return RESOURCE_DESCRIPTION;
        case 6: // ENABLED
          return ENABLED;
        case 7: // BATCH_QUEUES
          return BATCH_QUEUES;
        case 8: // FILE_SYSTEMS
          return FILE_SYSTEMS;
        case 9: // JOB_SUBMISSION_INTERFACES
          return JOB_SUBMISSION_INTERFACES;
        case 10: // DATA_MOVEMENT_INTERFACES
          return DATA_MOVEMENT_INTERFACES;
        case 11: // MAX_MEMORY_PER_NODE
          return MAX_MEMORY_PER_NODE;
        case 12: // GATEWAY_USAGE_REPORTING
          return GATEWAY_USAGE_REPORTING;
        case 13: // GATEWAY_USAGE_MODULE_LOAD_COMMAND
          return GATEWAY_USAGE_MODULE_LOAD_COMMAND;
        case 14: // GATEWAY_USAGE_EXECUTABLE
          return GATEWAY_USAGE_EXECUTABLE;
        case 15: // CPUS_PER_NODE
          return CPUS_PER_NODE;
        case 16: // DEFAULT_NODE_COUNT
          return DEFAULT_NODE_COUNT;
        case 17: // DEFAULT_CPUCOUNT
          return DEFAULT_CPUCOUNT;
        case 18: // DEFAULT_WALLTIME
          return DEFAULT_WALLTIME;
        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.
     */
    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 __ENABLED_ISSET_ID = 0;
  private static final int __MAXMEMORYPERNODE_ISSET_ID = 1;
  private static final int __GATEWAYUSAGEREPORTING_ISSET_ID = 2;
  private static final int __CPUSPERNODE_ISSET_ID = 3;
  private static final int __DEFAULTNODECOUNT_ISSET_ID = 4;
  private static final int __DEFAULTCPUCOUNT_ISSET_ID = 5;
  private static final int __DEFAULTWALLTIME_ISSET_ID = 6;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.HOST_ALIASES,_Fields.IP_ADDRESSES,_Fields.RESOURCE_DESCRIPTION,_Fields.ENABLED,_Fields.BATCH_QUEUES,_Fields.FILE_SYSTEMS,_Fields.JOB_SUBMISSION_INTERFACES,_Fields.DATA_MOVEMENT_INTERFACES,_Fields.MAX_MEMORY_PER_NODE,_Fields.GATEWAY_USAGE_REPORTING,_Fields.GATEWAY_USAGE_MODULE_LOAD_COMMAND,_Fields.GATEWAY_USAGE_EXECUTABLE,_Fields.CPUS_PER_NODE,_Fields.DEFAULT_NODE_COUNT,_Fields.DEFAULT_CPUCOUNT,_Fields.DEFAULT_WALLTIME};
  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.HOST_NAME, new org.apache.thrift.meta_data.FieldMetaData("hostName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.HOST_ALIASES, new org.apache.thrift.meta_data.FieldMetaData("hostAliases", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
    tmpMap.put(_Fields.IP_ADDRESSES, new org.apache.thrift.meta_data.FieldMetaData("ipAddresses", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
    tmpMap.put(_Fields.RESOURCE_DESCRIPTION, new org.apache.thrift.meta_data.FieldMetaData("resourceDescription", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.ENABLED, new org.apache.thrift.meta_data.FieldMetaData("enabled", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.BATCH_QUEUES, new org.apache.thrift.meta_data.FieldMetaData("batchQueues", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, BatchQueue.class))));
    tmpMap.put(_Fields.FILE_SYSTEMS, new org.apache.thrift.meta_data.FieldMetaData("fileSystems", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
            new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, FileSystems.class), 
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
    tmpMap.put(_Fields.JOB_SUBMISSION_INTERFACES, new org.apache.thrift.meta_data.FieldMetaData("jobSubmissionInterfaces", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, JobSubmissionInterface.class))));
    tmpMap.put(_Fields.DATA_MOVEMENT_INTERFACES, new org.apache.thrift.meta_data.FieldMetaData("dataMovementInterfaces", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.data.movement.DataMovementInterface.class))));
    tmpMap.put(_Fields.MAX_MEMORY_PER_NODE, new org.apache.thrift.meta_data.FieldMetaData("maxMemoryPerNode", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.GATEWAY_USAGE_REPORTING, new org.apache.thrift.meta_data.FieldMetaData("gatewayUsageReporting", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.GATEWAY_USAGE_MODULE_LOAD_COMMAND, new org.apache.thrift.meta_data.FieldMetaData("gatewayUsageModuleLoadCommand", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.GATEWAY_USAGE_EXECUTABLE, new org.apache.thrift.meta_data.FieldMetaData("gatewayUsageExecutable", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.CPUS_PER_NODE, new org.apache.thrift.meta_data.FieldMetaData("cpusPerNode", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.DEFAULT_NODE_COUNT, new org.apache.thrift.meta_data.FieldMetaData("defaultNodeCount", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.DEFAULT_CPUCOUNT, new org.apache.thrift.meta_data.FieldMetaData("defaultCPUCount", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.DEFAULT_WALLTIME, new org.apache.thrift.meta_data.FieldMetaData("defaultWalltime", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ComputeResourceDescription.class, metaDataMap);
  }

  public ComputeResourceDescription() {
    this.computeResourceId = "DO_NOT_SET_AT_CLIENTS";

  }

  public ComputeResourceDescription(
    java.lang.String computeResourceId,
    java.lang.String hostName)
  {
    this();
    this.computeResourceId = computeResourceId;
    this.hostName = hostName;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public ComputeResourceDescription(ComputeResourceDescription other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetComputeResourceId()) {
      this.computeResourceId = other.computeResourceId;
    }
    if (other.isSetHostName()) {
      this.hostName = other.hostName;
    }
    if (other.isSetHostAliases()) {
      java.util.List<java.lang.String> __this__hostAliases = new java.util.ArrayList<java.lang.String>(other.hostAliases);
      this.hostAliases = __this__hostAliases;
    }
    if (other.isSetIpAddresses()) {
      java.util.List<java.lang.String> __this__ipAddresses = new java.util.ArrayList<java.lang.String>(other.ipAddresses);
      this.ipAddresses = __this__ipAddresses;
    }
    if (other.isSetResourceDescription()) {
      this.resourceDescription = other.resourceDescription;
    }
    this.enabled = other.enabled;
    if (other.isSetBatchQueues()) {
      java.util.List<BatchQueue> __this__batchQueues = new java.util.ArrayList<BatchQueue>(other.batchQueues.size());
      for (BatchQueue other_element : other.batchQueues) {
        __this__batchQueues.add(new BatchQueue(other_element));
      }
      this.batchQueues = __this__batchQueues;
    }
    if (other.isSetFileSystems()) {
      java.util.Map<FileSystems,java.lang.String> __this__fileSystems = new java.util.HashMap<FileSystems,java.lang.String>(other.fileSystems.size());
      for (java.util.Map.Entry<FileSystems, java.lang.String> other_element : other.fileSystems.entrySet()) {

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

        FileSystems __this__fileSystems_copy_key = other_element_key;

        java.lang.String __this__fileSystems_copy_value = other_element_value;

        __this__fileSystems.put(__this__fileSystems_copy_key, __this__fileSystems_copy_value);
      }
      this.fileSystems = __this__fileSystems;
    }
    if (other.isSetJobSubmissionInterfaces()) {
      java.util.List<JobSubmissionInterface> __this__jobSubmissionInterfaces = new java.util.ArrayList<JobSubmissionInterface>(other.jobSubmissionInterfaces.size());
      for (JobSubmissionInterface other_element : other.jobSubmissionInterfaces) {
        __this__jobSubmissionInterfaces.add(new JobSubmissionInterface(other_element));
      }
      this.jobSubmissionInterfaces = __this__jobSubmissionInterfaces;
    }
    if (other.isSetDataMovementInterfaces()) {
      java.util.List<org.apache.airavata.model.data.movement.DataMovementInterface> __this__dataMovementInterfaces = new java.util.ArrayList<org.apache.airavata.model.data.movement.DataMovementInterface>(other.dataMovementInterfaces.size());
      for (org.apache.airavata.model.data.movement.DataMovementInterface other_element : other.dataMovementInterfaces) {
        __this__dataMovementInterfaces.add(new org.apache.airavata.model.data.movement.DataMovementInterface(other_element));
      }
      this.dataMovementInterfaces = __this__dataMovementInterfaces;
    }
    this.maxMemoryPerNode = other.maxMemoryPerNode;
    this.gatewayUsageReporting = other.gatewayUsageReporting;
    if (other.isSetGatewayUsageModuleLoadCommand()) {
      this.gatewayUsageModuleLoadCommand = other.gatewayUsageModuleLoadCommand;
    }
    if (other.isSetGatewayUsageExecutable()) {
      this.gatewayUsageExecutable = other.gatewayUsageExecutable;
    }
    this.cpusPerNode = other.cpusPerNode;
    this.defaultNodeCount = other.defaultNodeCount;
    this.defaultCPUCount = other.defaultCPUCount;
    this.defaultWalltime = other.defaultWalltime;
  }

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

  @Override
  public void clear() {
    this.computeResourceId = "DO_NOT_SET_AT_CLIENTS";

    this.hostName = null;
    this.hostAliases = null;
    this.ipAddresses = null;
    this.resourceDescription = null;
    setEnabledIsSet(false);
    this.enabled = false;
    this.batchQueues = null;
    this.fileSystems = null;
    this.jobSubmissionInterfaces = null;
    this.dataMovementInterfaces = null;
    setMaxMemoryPerNodeIsSet(false);
    this.maxMemoryPerNode = 0;
    setGatewayUsageReportingIsSet(false);
    this.gatewayUsageReporting = false;
    this.gatewayUsageModuleLoadCommand = null;
    this.gatewayUsageExecutable = null;
    setCpusPerNodeIsSet(false);
    this.cpusPerNode = 0;
    setDefaultNodeCountIsSet(false);
    this.defaultNodeCount = 0;
    setDefaultCPUCountIsSet(false);
    this.defaultCPUCount = 0;
    setDefaultWalltimeIsSet(false);
    this.defaultWalltime = 0;
  }

  public java.lang.String getComputeResourceId() {
    return this.computeResourceId;
  }

  public void setComputeResourceId(java.lang.String computeResourceId) {
    this.computeResourceId = computeResourceId;
  }

  public void unsetComputeResourceId() {
    this.computeResourceId = null;
  }

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

  public void setComputeResourceIdIsSet(boolean value) {
    if (!value) {
      this.computeResourceId = null;
    }
  }

  public java.lang.String getHostName() {
    return this.hostName;
  }

  public void setHostName(java.lang.String hostName) {
    this.hostName = hostName;
  }

  public void unsetHostName() {
    this.hostName = null;
  }

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

  public void setHostNameIsSet(boolean value) {
    if (!value) {
      this.hostName = null;
    }
  }

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

  public java.util.Iterator<java.lang.String> getHostAliasesIterator() {
    return (this.hostAliases == null) ? null : this.hostAliases.iterator();
  }

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

  public java.util.List<java.lang.String> getHostAliases() {
    return this.hostAliases;
  }

  public void setHostAliases(java.util.List<java.lang.String> hostAliases) {
    this.hostAliases = hostAliases;
  }

  public void unsetHostAliases() {
    this.hostAliases = null;
  }

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

  public void setHostAliasesIsSet(boolean value) {
    if (!value) {
      this.hostAliases = null;
    }
  }

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

  public java.util.Iterator<java.lang.String> getIpAddressesIterator() {
    return (this.ipAddresses == null) ? null : this.ipAddresses.iterator();
  }

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

  public java.util.List<java.lang.String> getIpAddresses() {
    return this.ipAddresses;
  }

  public void setIpAddresses(java.util.List<java.lang.String> ipAddresses) {
    this.ipAddresses = ipAddresses;
  }

  public void unsetIpAddresses() {
    this.ipAddresses = null;
  }

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

  public void setIpAddressesIsSet(boolean value) {
    if (!value) {
      this.ipAddresses = null;
    }
  }

  public java.lang.String getResourceDescription() {
    return this.resourceDescription;
  }

  public void setResourceDescription(java.lang.String resourceDescription) {
    this.resourceDescription = resourceDescription;
  }

  public void unsetResourceDescription() {
    this.resourceDescription = null;
  }

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

  public void setResourceDescriptionIsSet(boolean value) {
    if (!value) {
      this.resourceDescription = null;
    }
  }

  public boolean isEnabled() {
    return this.enabled;
  }

  public void setEnabled(boolean enabled) {
    this.enabled = enabled;
    setEnabledIsSet(true);
  }

  public void unsetEnabled() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __ENABLED_ISSET_ID);
  }

  /** Returns true if field enabled is set (has been assigned a value) and false otherwise */
  public boolean isSetEnabled() {
    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __ENABLED_ISSET_ID);
  }

  public void setEnabledIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __ENABLED_ISSET_ID, value);
  }

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

  public java.util.Iterator<BatchQueue> getBatchQueuesIterator() {
    return (this.batchQueues == null) ? null : this.batchQueues.iterator();
  }

  public void addToBatchQueues(BatchQueue elem) {
    if (this.batchQueues == null) {
      this.batchQueues = new java.util.ArrayList<BatchQueue>();
    }
    this.batchQueues.add(elem);
  }

  public java.util.List<BatchQueue> getBatchQueues() {
    return this.batchQueues;
  }

  public void setBatchQueues(java.util.List<BatchQueue> batchQueues) {
    this.batchQueues = batchQueues;
  }

  public void unsetBatchQueues() {
    this.batchQueues = null;
  }

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

  public void setBatchQueuesIsSet(boolean value) {
    if (!value) {
      this.batchQueues = null;
    }
  }

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

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

  public java.util.Map<FileSystems,java.lang.String> getFileSystems() {
    return this.fileSystems;
  }

  public void setFileSystems(java.util.Map<FileSystems,java.lang.String> fileSystems) {
    this.fileSystems = fileSystems;
  }

  public void unsetFileSystems() {
    this.fileSystems = null;
  }

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

  public void setFileSystemsIsSet(boolean value) {
    if (!value) {
      this.fileSystems = null;
    }
  }

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

  public java.util.Iterator<JobSubmissionInterface> getJobSubmissionInterfacesIterator() {
    return (this.jobSubmissionInterfaces == null) ? null : this.jobSubmissionInterfaces.iterator();
  }

  public void addToJobSubmissionInterfaces(JobSubmissionInterface elem) {
    if (this.jobSubmissionInterfaces == null) {
      this.jobSubmissionInterfaces = new java.util.ArrayList<JobSubmissionInterface>();
    }
    this.jobSubmissionInterfaces.add(elem);
  }

  public java.util.List<JobSubmissionInterface> getJobSubmissionInterfaces() {
    return this.jobSubmissionInterfaces;
  }

  public void setJobSubmissionInterfaces(java.util.List<JobSubmissionInterface> jobSubmissionInterfaces) {
    this.jobSubmissionInterfaces = jobSubmissionInterfaces;
  }

  public void unsetJobSubmissionInterfaces() {
    this.jobSubmissionInterfaces = null;
  }

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

  public void setJobSubmissionInterfacesIsSet(boolean value) {
    if (!value) {
      this.jobSubmissionInterfaces = null;
    }
  }

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

  public java.util.Iterator<org.apache.airavata.model.data.movement.DataMovementInterface> getDataMovementInterfacesIterator() {
    return (this.dataMovementInterfaces == null) ? null : this.dataMovementInterfaces.iterator();
  }

  public void addToDataMovementInterfaces(org.apache.airavata.model.data.movement.DataMovementInterface elem) {
    if (this.dataMovementInterfaces == null) {
      this.dataMovementInterfaces = new java.util.ArrayList<org.apache.airavata.model.data.movement.DataMovementInterface>();
    }
    this.dataMovementInterfaces.add(elem);
  }

  public java.util.List<org.apache.airavata.model.data.movement.DataMovementInterface> getDataMovementInterfaces() {
    return this.dataMovementInterfaces;
  }

  public void setDataMovementInterfaces(java.util.List<org.apache.airavata.model.data.movement.DataMovementInterface> dataMovementInterfaces) {
    this.dataMovementInterfaces = dataMovementInterfaces;
  }

  public void unsetDataMovementInterfaces() {
    this.dataMovementInterfaces = null;
  }

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

  public void setDataMovementInterfacesIsSet(boolean value) {
    if (!value) {
      this.dataMovementInterfaces = null;
    }
  }

  public int getMaxMemoryPerNode() {
    return this.maxMemoryPerNode;
  }

  public void setMaxMemoryPerNode(int maxMemoryPerNode) {
    this.maxMemoryPerNode = maxMemoryPerNode;
    setMaxMemoryPerNodeIsSet(true);
  }

  public void unsetMaxMemoryPerNode() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __MAXMEMORYPERNODE_ISSET_ID);
  }

  /** Returns true if field maxMemoryPerNode is set (has been assigned a value) and false otherwise */
  public boolean isSetMaxMemoryPerNode() {
    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __MAXMEMORYPERNODE_ISSET_ID);
  }

  public void setMaxMemoryPerNodeIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __MAXMEMORYPERNODE_ISSET_ID, value);
  }

  public boolean isGatewayUsageReporting() {
    return this.gatewayUsageReporting;
  }

  public void setGatewayUsageReporting(boolean gatewayUsageReporting) {
    this.gatewayUsageReporting = gatewayUsageReporting;
    setGatewayUsageReportingIsSet(true);
  }

  public void unsetGatewayUsageReporting() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __GATEWAYUSAGEREPORTING_ISSET_ID);
  }

  /** Returns true if field gatewayUsageReporting is set (has been assigned a value) and false otherwise */
  public boolean isSetGatewayUsageReporting() {
    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __GATEWAYUSAGEREPORTING_ISSET_ID);
  }

  public void setGatewayUsageReportingIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __GATEWAYUSAGEREPORTING_ISSET_ID, value);
  }

  public java.lang.String getGatewayUsageModuleLoadCommand() {
    return this.gatewayUsageModuleLoadCommand;
  }

  public void setGatewayUsageModuleLoadCommand(java.lang.String gatewayUsageModuleLoadCommand) {
    this.gatewayUsageModuleLoadCommand = gatewayUsageModuleLoadCommand;
  }

  public void unsetGatewayUsageModuleLoadCommand() {
    this.gatewayUsageModuleLoadCommand = null;
  }

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

  public void setGatewayUsageModuleLoadCommandIsSet(boolean value) {
    if (!value) {
      this.gatewayUsageModuleLoadCommand = null;
    }
  }

  public java.lang.String getGatewayUsageExecutable() {
    return this.gatewayUsageExecutable;
  }

  public void setGatewayUsageExecutable(java.lang.String gatewayUsageExecutable) {
    this.gatewayUsageExecutable = gatewayUsageExecutable;
  }

  public void unsetGatewayUsageExecutable() {
    this.gatewayUsageExecutable = null;
  }

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

  public void setGatewayUsageExecutableIsSet(boolean value) {
    if (!value) {
      this.gatewayUsageExecutable = null;
    }
  }

  public int getCpusPerNode() {
    return this.cpusPerNode;
  }

  public void setCpusPerNode(int cpusPerNode) {
    this.cpusPerNode = cpusPerNode;
    setCpusPerNodeIsSet(true);
  }

  public void unsetCpusPerNode() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __CPUSPERNODE_ISSET_ID);
  }

  /** Returns true if field cpusPerNode is set (has been assigned a value) and false otherwise */
  public boolean isSetCpusPerNode() {
    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __CPUSPERNODE_ISSET_ID);
  }

  public void setCpusPerNodeIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __CPUSPERNODE_ISSET_ID, value);
  }

  public int getDefaultNodeCount() {
    return this.defaultNodeCount;
  }

  public void setDefaultNodeCount(int defaultNodeCount) {
    this.defaultNodeCount = defaultNodeCount;
    setDefaultNodeCountIsSet(true);
  }

  public void unsetDefaultNodeCount() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __DEFAULTNODECOUNT_ISSET_ID);
  }

  /** Returns true if field defaultNodeCount is set (has been assigned a value) and false otherwise */
  public boolean isSetDefaultNodeCount() {
    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __DEFAULTNODECOUNT_ISSET_ID);
  }

  public void setDefaultNodeCountIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __DEFAULTNODECOUNT_ISSET_ID, value);
  }

  public int getDefaultCPUCount() {
    return this.defaultCPUCount;
  }

  public void setDefaultCPUCount(int defaultCPUCount) {
    this.defaultCPUCount = defaultCPUCount;
    setDefaultCPUCountIsSet(true);
  }

  public void unsetDefaultCPUCount() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __DEFAULTCPUCOUNT_ISSET_ID);
  }

  /** Returns true if field defaultCPUCount is set (has been assigned a value) and false otherwise */
  public boolean isSetDefaultCPUCount() {
    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __DEFAULTCPUCOUNT_ISSET_ID);
  }

  public void setDefaultCPUCountIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __DEFAULTCPUCOUNT_ISSET_ID, value);
  }

  public int getDefaultWalltime() {
    return this.defaultWalltime;
  }

  public void setDefaultWalltime(int defaultWalltime) {
    this.defaultWalltime = defaultWalltime;
    setDefaultWalltimeIsSet(true);
  }

  public void unsetDefaultWalltime() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __DEFAULTWALLTIME_ISSET_ID);
  }

  /** Returns true if field defaultWalltime is set (has been assigned a value) and false otherwise */
  public boolean isSetDefaultWalltime() {
    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __DEFAULTWALLTIME_ISSET_ID);
  }

  public void setDefaultWalltimeIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __DEFAULTWALLTIME_ISSET_ID, value);
  }

  public void setFieldValue(_Fields field, java.lang.Object value) {
    switch (field) {
    case COMPUTE_RESOURCE_ID:
      if (value == null) {
        unsetComputeResourceId();
      } else {
        setComputeResourceId((java.lang.String)value);
      }
      break;

    case HOST_NAME:
      if (value == null) {
        unsetHostName();
      } else {
        setHostName((java.lang.String)value);
      }
      break;

    case HOST_ALIASES:
      if (value == null) {
        unsetHostAliases();
      } else {
        setHostAliases((java.util.List<java.lang.String>)value);
      }
      break;

    case IP_ADDRESSES:
      if (value == null) {
        unsetIpAddresses();
      } else {
        setIpAddresses((java.util.List<java.lang.String>)value);
      }
      break;

    case RESOURCE_DESCRIPTION:
      if (value == null) {
        unsetResourceDescription();
      } else {
        setResourceDescription((java.lang.String)value);
      }
      break;

    case ENABLED:
      if (value == null) {
        unsetEnabled();
      } else {
        setEnabled((java.lang.Boolean)value);
      }
      break;

    case BATCH_QUEUES:
      if (value == null) {
        unsetBatchQueues();
      } else {
        setBatchQueues((java.util.List<BatchQueue>)value);
      }
      break;

    case FILE_SYSTEMS:
      if (value == null) {
        unsetFileSystems();
      } else {
        setFileSystems((java.util.Map<FileSystems,java.lang.String>)value);
      }
      break;

    case JOB_SUBMISSION_INTERFACES:
      if (value == null) {
        unsetJobSubmissionInterfaces();
      } else {
        setJobSubmissionInterfaces((java.util.List<JobSubmissionInterface>)value);
      }
      break;

    case DATA_MOVEMENT_INTERFACES:
      if (value == null) {
        unsetDataMovementInterfaces();
      } else {
        setDataMovementInterfaces((java.util.List<org.apache.airavata.model.data.movement.DataMovementInterface>)value);
      }
      break;

    case MAX_MEMORY_PER_NODE:
      if (value == null) {
        unsetMaxMemoryPerNode();
      } else {
        setMaxMemoryPerNode((java.lang.Integer)value);
      }
      break;

    case GATEWAY_USAGE_REPORTING:
      if (value == null) {
        unsetGatewayUsageReporting();
      } else {
        setGatewayUsageReporting((java.lang.Boolean)value);
      }
      break;

    case GATEWAY_USAGE_MODULE_LOAD_COMMAND:
      if (value == null) {
        unsetGatewayUsageModuleLoadCommand();
      } else {
        setGatewayUsageModuleLoadCommand((java.lang.String)value);
      }
      break;

    case GATEWAY_USAGE_EXECUTABLE:
      if (value == null) {
        unsetGatewayUsageExecutable();
      } else {
        setGatewayUsageExecutable((java.lang.String)value);
      }
      break;

    case CPUS_PER_NODE:
      if (value == null) {
        unsetCpusPerNode();
      } else {
        setCpusPerNode((java.lang.Integer)value);
      }
      break;

    case DEFAULT_NODE_COUNT:
      if (value == null) {
        unsetDefaultNodeCount();
      } else {
        setDefaultNodeCount((java.lang.Integer)value);
      }
      break;

    case DEFAULT_CPUCOUNT:
      if (value == null) {
        unsetDefaultCPUCount();
      } else {
        setDefaultCPUCount((java.lang.Integer)value);
      }
      break;

    case DEFAULT_WALLTIME:
      if (value == null) {
        unsetDefaultWalltime();
      } else {
        setDefaultWalltime((java.lang.Integer)value);
      }
      break;

    }
  }

  public java.lang.Object getFieldValue(_Fields field) {
    switch (field) {
    case COMPUTE_RESOURCE_ID:
      return getComputeResourceId();

    case HOST_NAME:
      return getHostName();

    case HOST_ALIASES:
      return getHostAliases();

    case IP_ADDRESSES:
      return getIpAddresses();

    case RESOURCE_DESCRIPTION:
      return getResourceDescription();

    case ENABLED:
      return isEnabled();

    case BATCH_QUEUES:
      return getBatchQueues();

    case FILE_SYSTEMS:
      return getFileSystems();

    case JOB_SUBMISSION_INTERFACES:
      return getJobSubmissionInterfaces();

    case DATA_MOVEMENT_INTERFACES:
      return getDataMovementInterfaces();

    case MAX_MEMORY_PER_NODE:
      return getMaxMemoryPerNode();

    case GATEWAY_USAGE_REPORTING:
      return isGatewayUsageReporting();

    case GATEWAY_USAGE_MODULE_LOAD_COMMAND:
      return getGatewayUsageModuleLoadCommand();

    case GATEWAY_USAGE_EXECUTABLE:
      return getGatewayUsageExecutable();

    case CPUS_PER_NODE:
      return getCpusPerNode();

    case DEFAULT_NODE_COUNT:
      return getDefaultNodeCount();

    case DEFAULT_CPUCOUNT:
      return getDefaultCPUCount();

    case DEFAULT_WALLTIME:
      return getDefaultWalltime();

    }
    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 COMPUTE_RESOURCE_ID:
      return isSetComputeResourceId();
    case HOST_NAME:
      return isSetHostName();
    case HOST_ALIASES:
      return isSetHostAliases();
    case IP_ADDRESSES:
      return isSetIpAddresses();
    case RESOURCE_DESCRIPTION:
      return isSetResourceDescription();
    case ENABLED:
      return isSetEnabled();
    case BATCH_QUEUES:
      return isSetBatchQueues();
    case FILE_SYSTEMS:
      return isSetFileSystems();
    case JOB_SUBMISSION_INTERFACES:
      return isSetJobSubmissionInterfaces();
    case DATA_MOVEMENT_INTERFACES:
      return isSetDataMovementInterfaces();
    case MAX_MEMORY_PER_NODE:
      return isSetMaxMemoryPerNode();
    case GATEWAY_USAGE_REPORTING:
      return isSetGatewayUsageReporting();
    case GATEWAY_USAGE_MODULE_LOAD_COMMAND:
      return isSetGatewayUsageModuleLoadCommand();
    case GATEWAY_USAGE_EXECUTABLE:
      return isSetGatewayUsageExecutable();
    case CPUS_PER_NODE:
      return isSetCpusPerNode();
    case DEFAULT_NODE_COUNT:
      return isSetDefaultNodeCount();
    case DEFAULT_CPUCOUNT:
      return isSetDefaultCPUCount();
    case DEFAULT_WALLTIME:
      return isSetDefaultWalltime();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_computeResourceId = true && this.isSetComputeResourceId();
    boolean that_present_computeResourceId = true && that.isSetComputeResourceId();
    if (this_present_computeResourceId || that_present_computeResourceId) {
      if (!(this_present_computeResourceId && that_present_computeResourceId))
        return false;
      if (!this.computeResourceId.equals(that.computeResourceId))
        return false;
    }

    boolean this_present_hostName = true && this.isSetHostName();
    boolean that_present_hostName = true && that.isSetHostName();
    if (this_present_hostName || that_present_hostName) {
      if (!(this_present_hostName && that_present_hostName))
        return false;
      if (!this.hostName.equals(that.hostName))
        return false;
    }

    boolean this_present_hostAliases = true && this.isSetHostAliases();
    boolean that_present_hostAliases = true && that.isSetHostAliases();
    if (this_present_hostAliases || that_present_hostAliases) {
      if (!(this_present_hostAliases && that_present_hostAliases))
        return false;
      if (!this.hostAliases.equals(that.hostAliases))
        return false;
    }

    boolean this_present_ipAddresses = true && this.isSetIpAddresses();
    boolean that_present_ipAddresses = true && that.isSetIpAddresses();
    if (this_present_ipAddresses || that_present_ipAddresses) {
      if (!(this_present_ipAddresses && that_present_ipAddresses))
        return false;
      if (!this.ipAddresses.equals(that.ipAddresses))
        return false;
    }

    boolean this_present_resourceDescription = true && this.isSetResourceDescription();
    boolean that_present_resourceDescription = true && that.isSetResourceDescription();
    if (this_present_resourceDescription || that_present_resourceDescription) {
      if (!(this_present_resourceDescription && that_present_resourceDescription))
        return false;
      if (!this.resourceDescription.equals(that.resourceDescription))
        return false;
    }

    boolean this_present_enabled = true && this.isSetEnabled();
    boolean that_present_enabled = true && that.isSetEnabled();
    if (this_present_enabled || that_present_enabled) {
      if (!(this_present_enabled && that_present_enabled))
        return false;
      if (this.enabled != that.enabled)
        return false;
    }

    boolean this_present_batchQueues = true && this.isSetBatchQueues();
    boolean that_present_batchQueues = true && that.isSetBatchQueues();
    if (this_present_batchQueues || that_present_batchQueues) {
      if (!(this_present_batchQueues && that_present_batchQueues))
        return false;
      if (!this.batchQueues.equals(that.batchQueues))
        return false;
    }

    boolean this_present_fileSystems = true && this.isSetFileSystems();
    boolean that_present_fileSystems = true && that.isSetFileSystems();
    if (this_present_fileSystems || that_present_fileSystems) {
      if (!(this_present_fileSystems && that_present_fileSystems))
        return false;
      if (!this.fileSystems.equals(that.fileSystems))
        return false;
    }

    boolean this_present_jobSubmissionInterfaces = true && this.isSetJobSubmissionInterfaces();
    boolean that_present_jobSubmissionInterfaces = true && that.isSetJobSubmissionInterfaces();
    if (this_present_jobSubmissionInterfaces || that_present_jobSubmissionInterfaces) {
      if (!(this_present_jobSubmissionInterfaces && that_present_jobSubmissionInterfaces))
        return false;
      if (!this.jobSubmissionInterfaces.equals(that.jobSubmissionInterfaces))
        return false;
    }

    boolean this_present_dataMovementInterfaces = true && this.isSetDataMovementInterfaces();
    boolean that_present_dataMovementInterfaces = true && that.isSetDataMovementInterfaces();
    if (this_present_dataMovementInterfaces || that_present_dataMovementInterfaces) {
      if (!(this_present_dataMovementInterfaces && that_present_dataMovementInterfaces))
        return false;
      if (!this.dataMovementInterfaces.equals(that.dataMovementInterfaces))
        return false;
    }

    boolean this_present_maxMemoryPerNode = true && this.isSetMaxMemoryPerNode();
    boolean that_present_maxMemoryPerNode = true && that.isSetMaxMemoryPerNode();
    if (this_present_maxMemoryPerNode || that_present_maxMemoryPerNode) {
      if (!(this_present_maxMemoryPerNode && that_present_maxMemoryPerNode))
        return false;
      if (this.maxMemoryPerNode != that.maxMemoryPerNode)
        return false;
    }

    boolean this_present_gatewayUsageReporting = true && this.isSetGatewayUsageReporting();
    boolean that_present_gatewayUsageReporting = true && that.isSetGatewayUsageReporting();
    if (this_present_gatewayUsageReporting || that_present_gatewayUsageReporting) {
      if (!(this_present_gatewayUsageReporting && that_present_gatewayUsageReporting))
        return false;
      if (this.gatewayUsageReporting != that.gatewayUsageReporting)
        return false;
    }

    boolean this_present_gatewayUsageModuleLoadCommand = true && this.isSetGatewayUsageModuleLoadCommand();
    boolean that_present_gatewayUsageModuleLoadCommand = true && that.isSetGatewayUsageModuleLoadCommand();
    if (this_present_gatewayUsageModuleLoadCommand || that_present_gatewayUsageModuleLoadCommand) {
      if (!(this_present_gatewayUsageModuleLoadCommand && that_present_gatewayUsageModuleLoadCommand))
        return false;
      if (!this.gatewayUsageModuleLoadCommand.equals(that.gatewayUsageModuleLoadCommand))
        return false;
    }

    boolean this_present_gatewayUsageExecutable = true && this.isSetGatewayUsageExecutable();
    boolean that_present_gatewayUsageExecutable = true && that.isSetGatewayUsageExecutable();
    if (this_present_gatewayUsageExecutable || that_present_gatewayUsageExecutable) {
      if (!(this_present_gatewayUsageExecutable && that_present_gatewayUsageExecutable))
        return false;
      if (!this.gatewayUsageExecutable.equals(that.gatewayUsageExecutable))
        return false;
    }

    boolean this_present_cpusPerNode = true && this.isSetCpusPerNode();
    boolean that_present_cpusPerNode = true && that.isSetCpusPerNode();
    if (this_present_cpusPerNode || that_present_cpusPerNode) {
      if (!(this_present_cpusPerNode && that_present_cpusPerNode))
        return false;
      if (this.cpusPerNode != that.cpusPerNode)
        return false;
    }

    boolean this_present_defaultNodeCount = true && this.isSetDefaultNodeCount();
    boolean that_present_defaultNodeCount = true && that.isSetDefaultNodeCount();
    if (this_present_defaultNodeCount || that_present_defaultNodeCount) {
      if (!(this_present_defaultNodeCount && that_present_defaultNodeCount))
        return false;
      if (this.defaultNodeCount != that.defaultNodeCount)
        return false;
    }

    boolean this_present_defaultCPUCount = true && this.isSetDefaultCPUCount();
    boolean that_present_defaultCPUCount = true && that.isSetDefaultCPUCount();
    if (this_present_defaultCPUCount || that_present_defaultCPUCount) {
      if (!(this_present_defaultCPUCount && that_present_defaultCPUCount))
        return false;
      if (this.defaultCPUCount != that.defaultCPUCount)
        return false;
    }

    boolean this_present_defaultWalltime = true && this.isSetDefaultWalltime();
    boolean that_present_defaultWalltime = true && that.isSetDefaultWalltime();
    if (this_present_defaultWalltime || that_present_defaultWalltime) {
      if (!(this_present_defaultWalltime && that_present_defaultWalltime))
        return false;
      if (this.defaultWalltime != that.defaultWalltime)
        return false;
    }

    return true;
  }

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

    hashCode = hashCode * 8191 + ((isSetComputeResourceId()) ? 131071 : 524287);
    if (isSetComputeResourceId())
      hashCode = hashCode * 8191 + computeResourceId.hashCode();

    hashCode = hashCode * 8191 + ((isSetHostName()) ? 131071 : 524287);
    if (isSetHostName())
      hashCode = hashCode * 8191 + hostName.hashCode();

    hashCode = hashCode * 8191 + ((isSetHostAliases()) ? 131071 : 524287);
    if (isSetHostAliases())
      hashCode = hashCode * 8191 + hostAliases.hashCode();

    hashCode = hashCode * 8191 + ((isSetIpAddresses()) ? 131071 : 524287);
    if (isSetIpAddresses())
      hashCode = hashCode * 8191 + ipAddresses.hashCode();

    hashCode = hashCode * 8191 + ((isSetResourceDescription()) ? 131071 : 524287);
    if (isSetResourceDescription())
      hashCode = hashCode * 8191 + resourceDescription.hashCode();

    hashCode = hashCode * 8191 + ((isSetEnabled()) ? 131071 : 524287);
    if (isSetEnabled())
      hashCode = hashCode * 8191 + ((enabled) ? 131071 : 524287);

    hashCode = hashCode * 8191 + ((isSetBatchQueues()) ? 131071 : 524287);
    if (isSetBatchQueues())
      hashCode = hashCode * 8191 + batchQueues.hashCode();

    hashCode = hashCode * 8191 + ((isSetFileSystems()) ? 131071 : 524287);
    if (isSetFileSystems())
      hashCode = hashCode * 8191 + fileSystems.hashCode();

    hashCode = hashCode * 8191 + ((isSetJobSubmissionInterfaces()) ? 131071 : 524287);
    if (isSetJobSubmissionInterfaces())
      hashCode = hashCode * 8191 + jobSubmissionInterfaces.hashCode();

    hashCode = hashCode * 8191 + ((isSetDataMovementInterfaces()) ? 131071 : 524287);
    if (isSetDataMovementInterfaces())
      hashCode = hashCode * 8191 + dataMovementInterfaces.hashCode();

    hashCode = hashCode * 8191 + ((isSetMaxMemoryPerNode()) ? 131071 : 524287);
    if (isSetMaxMemoryPerNode())
      hashCode = hashCode * 8191 + maxMemoryPerNode;

    hashCode = hashCode * 8191 + ((isSetGatewayUsageReporting()) ? 131071 : 524287);
    if (isSetGatewayUsageReporting())
      hashCode = hashCode * 8191 + ((gatewayUsageReporting) ? 131071 : 524287);

    hashCode = hashCode * 8191 + ((isSetGatewayUsageModuleLoadCommand()) ? 131071 : 524287);
    if (isSetGatewayUsageModuleLoadCommand())
      hashCode = hashCode * 8191 + gatewayUsageModuleLoadCommand.hashCode();

    hashCode = hashCode * 8191 + ((isSetGatewayUsageExecutable()) ? 131071 : 524287);
    if (isSetGatewayUsageExecutable())
      hashCode = hashCode * 8191 + gatewayUsageExecutable.hashCode();

    hashCode = hashCode * 8191 + ((isSetCpusPerNode()) ? 131071 : 524287);
    if (isSetCpusPerNode())
      hashCode = hashCode * 8191 + cpusPerNode;

    hashCode = hashCode * 8191 + ((isSetDefaultNodeCount()) ? 131071 : 524287);
    if (isSetDefaultNodeCount())
      hashCode = hashCode * 8191 + defaultNodeCount;

    hashCode = hashCode * 8191 + ((isSetDefaultCPUCount()) ? 131071 : 524287);
    if (isSetDefaultCPUCount())
      hashCode = hashCode * 8191 + defaultCPUCount;

    hashCode = hashCode * 8191 + ((isSetDefaultWalltime()) ? 131071 : 524287);
    if (isSetDefaultWalltime())
      hashCode = hashCode * 8191 + defaultWalltime;

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetComputeResourceId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetHostName()).compareTo(other.isSetHostName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetHostName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.hostName, other.hostName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetHostAliases()).compareTo(other.isSetHostAliases());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetHostAliases()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.hostAliases, other.hostAliases);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetIpAddresses()).compareTo(other.isSetIpAddresses());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetIpAddresses()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ipAddresses, other.ipAddresses);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetResourceDescription()).compareTo(other.isSetResourceDescription());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetResourceDescription()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.resourceDescription, other.resourceDescription);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetEnabled()).compareTo(other.isSetEnabled());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetEnabled()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.enabled, other.enabled);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetBatchQueues()).compareTo(other.isSetBatchQueues());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetBatchQueues()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.batchQueues, other.batchQueues);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetFileSystems()).compareTo(other.isSetFileSystems());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetFileSystems()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.fileSystems, other.fileSystems);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetJobSubmissionInterfaces()).compareTo(other.isSetJobSubmissionInterfaces());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetJobSubmissionInterfaces()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jobSubmissionInterfaces, other.jobSubmissionInterfaces);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetDataMovementInterfaces()).compareTo(other.isSetDataMovementInterfaces());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetDataMovementInterfaces()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataMovementInterfaces, other.dataMovementInterfaces);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetMaxMemoryPerNode()).compareTo(other.isSetMaxMemoryPerNode());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetMaxMemoryPerNode()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.maxMemoryPerNode, other.maxMemoryPerNode);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetGatewayUsageReporting()).compareTo(other.isSetGatewayUsageReporting());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetGatewayUsageReporting()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.gatewayUsageReporting, other.gatewayUsageReporting);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetGatewayUsageModuleLoadCommand()).compareTo(other.isSetGatewayUsageModuleLoadCommand());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetGatewayUsageModuleLoadCommand()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.gatewayUsageModuleLoadCommand, other.gatewayUsageModuleLoadCommand);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetGatewayUsageExecutable()).compareTo(other.isSetGatewayUsageExecutable());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetGatewayUsageExecutable()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.gatewayUsageExecutable, other.gatewayUsageExecutable);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetCpusPerNode()).compareTo(other.isSetCpusPerNode());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetCpusPerNode()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cpusPerNode, other.cpusPerNode);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetDefaultNodeCount()).compareTo(other.isSetDefaultNodeCount());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetDefaultNodeCount()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.defaultNodeCount, other.defaultNodeCount);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetDefaultCPUCount()).compareTo(other.isSetDefaultCPUCount());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetDefaultCPUCount()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.defaultCPUCount, other.defaultCPUCount);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetDefaultWalltime()).compareTo(other.isSetDefaultWalltime());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetDefaultWalltime()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.defaultWalltime, other.defaultWalltime);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

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

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

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

  @Override
  public java.lang.String toString() {
    java.lang.StringBuilder sb = new java.lang.StringBuilder("ComputeResourceDescription(");
    boolean first = true;

    sb.append("computeResourceId:");
    if (this.computeResourceId == null) {
      sb.append("null");
    } else {
      sb.append(this.computeResourceId);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("hostName:");
    if (this.hostName == null) {
      sb.append("null");
    } else {
      sb.append(this.hostName);
    }
    first = false;
    if (isSetHostAliases()) {
      if (!first) sb.append(", ");
      sb.append("hostAliases:");
      if (this.hostAliases == null) {
        sb.append("null");
      } else {
        sb.append(this.hostAliases);
      }
      first = false;
    }
    if (isSetIpAddresses()) {
      if (!first) sb.append(", ");
      sb.append("ipAddresses:");
      if (this.ipAddresses == null) {
        sb.append("null");
      } else {
        sb.append(this.ipAddresses);
      }
      first = false;
    }
    if (isSetResourceDescription()) {
      if (!first) sb.append(", ");
      sb.append("resourceDescription:");
      if (this.resourceDescription == null) {
        sb.append("null");
      } else {
        sb.append(this.resourceDescription);
      }
      first = false;
    }
    if (isSetEnabled()) {
      if (!first) sb.append(", ");
      sb.append("enabled:");
      sb.append(this.enabled);
      first = false;
    }
    if (isSetBatchQueues()) {
      if (!first) sb.append(", ");
      sb.append("batchQueues:");
      if (this.batchQueues == null) {
        sb.append("null");
      } else {
        sb.append(this.batchQueues);
      }
      first = false;
    }
    if (isSetFileSystems()) {
      if (!first) sb.append(", ");
      sb.append("fileSystems:");
      if (this.fileSystems == null) {
        sb.append("null");
      } else {
        sb.append(this.fileSystems);
      }
      first = false;
    }
    if (isSetJobSubmissionInterfaces()) {
      if (!first) sb.append(", ");
      sb.append("jobSubmissionInterfaces:");
      if (this.jobSubmissionInterfaces == null) {
        sb.append("null");
      } else {
        sb.append(this.jobSubmissionInterfaces);
      }
      first = false;
    }
    if (isSetDataMovementInterfaces()) {
      if (!first) sb.append(", ");
      sb.append("dataMovementInterfaces:");
      if (this.dataMovementInterfaces == null) {
        sb.append("null");
      } else {
        sb.append(this.dataMovementInterfaces);
      }
      first = false;
    }
    if (isSetMaxMemoryPerNode()) {
      if (!first) sb.append(", ");
      sb.append("maxMemoryPerNode:");
      sb.append(this.maxMemoryPerNode);
      first = false;
    }
    if (isSetGatewayUsageReporting()) {
      if (!first) sb.append(", ");
      sb.append("gatewayUsageReporting:");
      sb.append(this.gatewayUsageReporting);
      first = false;
    }
    if (isSetGatewayUsageModuleLoadCommand()) {
      if (!first) sb.append(", ");
      sb.append("gatewayUsageModuleLoadCommand:");
      if (this.gatewayUsageModuleLoadCommand == null) {
        sb.append("null");
      } else {
        sb.append(this.gatewayUsageModuleLoadCommand);
      }
      first = false;
    }
    if (isSetGatewayUsageExecutable()) {
      if (!first) sb.append(", ");
      sb.append("gatewayUsageExecutable:");
      if (this.gatewayUsageExecutable == null) {
        sb.append("null");
      } else {
        sb.append(this.gatewayUsageExecutable);
      }
      first = false;
    }
    if (isSetCpusPerNode()) {
      if (!first) sb.append(", ");
      sb.append("cpusPerNode:");
      sb.append(this.cpusPerNode);
      first = false;
    }
    if (isSetDefaultNodeCount()) {
      if (!first) sb.append(", ");
      sb.append("defaultNodeCount:");
      sb.append(this.defaultNodeCount);
      first = false;
    }
    if (isSetDefaultCPUCount()) {
      if (!first) sb.append(", ");
      sb.append("defaultCPUCount:");
      sb.append(this.defaultCPUCount);
      first = false;
    }
    if (isSetDefaultWalltime()) {
      if (!first) sb.append(", ");
      sb.append("defaultWalltime:");
      sb.append(this.defaultWalltime);
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

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

    // check for sub-struct validity
  }

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

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

  private static class ComputeResourceDescriptionStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public ComputeResourceDescriptionStandardScheme getScheme() {
      return new ComputeResourceDescriptionStandardScheme();
    }
  }

  private static class ComputeResourceDescriptionStandardScheme extends org.apache.thrift.scheme.StandardScheme<ComputeResourceDescription> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, ComputeResourceDescription struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TField schemeField;
      iprot.readStructBegin();
      while (true)
      {
        schemeField = iprot.readFieldBegin();
        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
          break;
        }
        switch (schemeField.id) {
          case 1: // COMPUTE_RESOURCE_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.computeResourceId = iprot.readString();
              struct.setComputeResourceIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // HOST_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.hostName = iprot.readString();
              struct.setHostNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // HOST_ALIASES
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list36 = iprot.readListBegin();
                struct.hostAliases = new java.util.ArrayList<java.lang.String>(_list36.size);
                java.lang.String _elem37;
                for (int _i38 = 0; _i38 < _list36.size; ++_i38)
                {
                  _elem37 = iprot.readString();
                  struct.hostAliases.add(_elem37);
                }
                iprot.readListEnd();
              }
              struct.setHostAliasesIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // IP_ADDRESSES
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list39 = iprot.readListBegin();
                struct.ipAddresses = new java.util.ArrayList<java.lang.String>(_list39.size);
                java.lang.String _elem40;
                for (int _i41 = 0; _i41 < _list39.size; ++_i41)
                {
                  _elem40 = iprot.readString();
                  struct.ipAddresses.add(_elem40);
                }
                iprot.readListEnd();
              }
              struct.setIpAddressesIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // RESOURCE_DESCRIPTION
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.resourceDescription = iprot.readString();
              struct.setResourceDescriptionIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // ENABLED
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.enabled = iprot.readBool();
              struct.setEnabledIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // BATCH_QUEUES
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list42 = iprot.readListBegin();
                struct.batchQueues = new java.util.ArrayList<BatchQueue>(_list42.size);
                BatchQueue _elem43;
                for (int _i44 = 0; _i44 < _list42.size; ++_i44)
                {
                  _elem43 = new BatchQueue();
                  _elem43.read(iprot);
                  struct.batchQueues.add(_elem43);
                }
                iprot.readListEnd();
              }
              struct.setBatchQueuesIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // FILE_SYSTEMS
            if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
              {
                org.apache.thrift.protocol.TMap _map45 = iprot.readMapBegin();
                struct.fileSystems = new java.util.HashMap<FileSystems,java.lang.String>(2*_map45.size);
                FileSystems _key46;
                java.lang.String _val47;
                for (int _i48 = 0; _i48 < _map45.size; ++_i48)
                {
                  _key46 = org.apache.airavata.model.appcatalog.computeresource.FileSystems.findByValue(iprot.readI32());
                  _val47 = iprot.readString();
                  struct.fileSystems.put(_key46, _val47);
                }
                iprot.readMapEnd();
              }
              struct.setFileSystemsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // JOB_SUBMISSION_INTERFACES
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list49 = iprot.readListBegin();
                struct.jobSubmissionInterfaces = new java.util.ArrayList<JobSubmissionInterface>(_list49.size);
                JobSubmissionInterface _elem50;
                for (int _i51 = 0; _i51 < _list49.size; ++_i51)
                {
                  _elem50 = new JobSubmissionInterface();
                  _elem50.read(iprot);
                  struct.jobSubmissionInterfaces.add(_elem50);
                }
                iprot.readListEnd();
              }
              struct.setJobSubmissionInterfacesIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // DATA_MOVEMENT_INTERFACES
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list52 = iprot.readListBegin();
                struct.dataMovementInterfaces = new java.util.ArrayList<org.apache.airavata.model.data.movement.DataMovementInterface>(_list52.size);
                org.apache.airavata.model.data.movement.DataMovementInterface _elem53;
                for (int _i54 = 0; _i54 < _list52.size; ++_i54)
                {
                  _elem53 = new org.apache.airavata.model.data.movement.DataMovementInterface();
                  _elem53.read(iprot);
                  struct.dataMovementInterfaces.add(_elem53);
                }
                iprot.readListEnd();
              }
              struct.setDataMovementInterfacesIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 11: // MAX_MEMORY_PER_NODE
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.maxMemoryPerNode = iprot.readI32();
              struct.setMaxMemoryPerNodeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 12: // GATEWAY_USAGE_REPORTING
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.gatewayUsageReporting = iprot.readBool();
              struct.setGatewayUsageReportingIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 13: // GATEWAY_USAGE_MODULE_LOAD_COMMAND
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.gatewayUsageModuleLoadCommand = iprot.readString();
              struct.setGatewayUsageModuleLoadCommandIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 14: // GATEWAY_USAGE_EXECUTABLE
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.gatewayUsageExecutable = iprot.readString();
              struct.setGatewayUsageExecutableIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 15: // CPUS_PER_NODE
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.cpusPerNode = iprot.readI32();
              struct.setCpusPerNodeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 16: // DEFAULT_NODE_COUNT
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.defaultNodeCount = iprot.readI32();
              struct.setDefaultNodeCountIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 17: // DEFAULT_CPUCOUNT
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.defaultCPUCount = iprot.readI32();
              struct.setDefaultCPUCountIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 18: // DEFAULT_WALLTIME
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.defaultWalltime = iprot.readI32();
              struct.setDefaultWalltimeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          default:
            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
      struct.validate();
    }

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

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.computeResourceId != null) {
        oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
        oprot.writeString(struct.computeResourceId);
        oprot.writeFieldEnd();
      }
      if (struct.hostName != null) {
        oprot.writeFieldBegin(HOST_NAME_FIELD_DESC);
        oprot.writeString(struct.hostName);
        oprot.writeFieldEnd();
      }
      if (struct.hostAliases != null) {
        if (struct.isSetHostAliases()) {
          oprot.writeFieldBegin(HOST_ALIASES_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.hostAliases.size()));
            for (java.lang.String _iter55 : struct.hostAliases)
            {
              oprot.writeString(_iter55);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.ipAddresses != null) {
        if (struct.isSetIpAddresses()) {
          oprot.writeFieldBegin(IP_ADDRESSES_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.ipAddresses.size()));
            for (java.lang.String _iter56 : struct.ipAddresses)
            {
              oprot.writeString(_iter56);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.resourceDescription != null) {
        if (struct.isSetResourceDescription()) {
          oprot.writeFieldBegin(RESOURCE_DESCRIPTION_FIELD_DESC);
          oprot.writeString(struct.resourceDescription);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetEnabled()) {
        oprot.writeFieldBegin(ENABLED_FIELD_DESC);
        oprot.writeBool(struct.enabled);
        oprot.writeFieldEnd();
      }
      if (struct.batchQueues != null) {
        if (struct.isSetBatchQueues()) {
          oprot.writeFieldBegin(BATCH_QUEUES_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.batchQueues.size()));
            for (BatchQueue _iter57 : struct.batchQueues)
            {
              _iter57.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.fileSystems != null) {
        if (struct.isSetFileSystems()) {
          oprot.writeFieldBegin(FILE_SYSTEMS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.I32, org.apache.thrift.protocol.TType.STRING, struct.fileSystems.size()));
            for (java.util.Map.Entry<FileSystems, java.lang.String> _iter58 : struct.fileSystems.entrySet())
            {
              oprot.writeI32(_iter58.getKey().getValue());
              oprot.writeString(_iter58.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.jobSubmissionInterfaces != null) {
        if (struct.isSetJobSubmissionInterfaces()) {
          oprot.writeFieldBegin(JOB_SUBMISSION_INTERFACES_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.jobSubmissionInterfaces.size()));
            for (JobSubmissionInterface _iter59 : struct.jobSubmissionInterfaces)
            {
              _iter59.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.dataMovementInterfaces != null) {
        if (struct.isSetDataMovementInterfaces()) {
          oprot.writeFieldBegin(DATA_MOVEMENT_INTERFACES_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.dataMovementInterfaces.size()));
            for (org.apache.airavata.model.data.movement.DataMovementInterface _iter60 : struct.dataMovementInterfaces)
            {
              _iter60.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetMaxMemoryPerNode()) {
        oprot.writeFieldBegin(MAX_MEMORY_PER_NODE_FIELD_DESC);
        oprot.writeI32(struct.maxMemoryPerNode);
        oprot.writeFieldEnd();
      }
      if (struct.isSetGatewayUsageReporting()) {
        oprot.writeFieldBegin(GATEWAY_USAGE_REPORTING_FIELD_DESC);
        oprot.writeBool(struct.gatewayUsageReporting);
        oprot.writeFieldEnd();
      }
      if (struct.gatewayUsageModuleLoadCommand != null) {
        if (struct.isSetGatewayUsageModuleLoadCommand()) {
          oprot.writeFieldBegin(GATEWAY_USAGE_MODULE_LOAD_COMMAND_FIELD_DESC);
          oprot.writeString(struct.gatewayUsageModuleLoadCommand);
          oprot.writeFieldEnd();
        }
      }
      if (struct.gatewayUsageExecutable != null) {
        if (struct.isSetGatewayUsageExecutable()) {
          oprot.writeFieldBegin(GATEWAY_USAGE_EXECUTABLE_FIELD_DESC);
          oprot.writeString(struct.gatewayUsageExecutable);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetCpusPerNode()) {
        oprot.writeFieldBegin(CPUS_PER_NODE_FIELD_DESC);
        oprot.writeI32(struct.cpusPerNode);
        oprot.writeFieldEnd();
      }
      if (struct.isSetDefaultNodeCount()) {
        oprot.writeFieldBegin(DEFAULT_NODE_COUNT_FIELD_DESC);
        oprot.writeI32(struct.defaultNodeCount);
        oprot.writeFieldEnd();
      }
      if (struct.isSetDefaultCPUCount()) {
        oprot.writeFieldBegin(DEFAULT_CPUCOUNT_FIELD_DESC);
        oprot.writeI32(struct.defaultCPUCount);
        oprot.writeFieldEnd();
      }
      if (struct.isSetDefaultWalltime()) {
        oprot.writeFieldBegin(DEFAULT_WALLTIME_FIELD_DESC);
        oprot.writeI32(struct.defaultWalltime);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class ComputeResourceDescriptionTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public ComputeResourceDescriptionTupleScheme getScheme() {
      return new ComputeResourceDescriptionTupleScheme();
    }
  }

  private static class ComputeResourceDescriptionTupleScheme extends org.apache.thrift.scheme.TupleScheme<ComputeResourceDescription> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, ComputeResourceDescription struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      oprot.writeString(struct.computeResourceId);
      oprot.writeString(struct.hostName);
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.isSetHostAliases()) {
        optionals.set(0);
      }
      if (struct.isSetIpAddresses()) {
        optionals.set(1);
      }
      if (struct.isSetResourceDescription()) {
        optionals.set(2);
      }
      if (struct.isSetEnabled()) {
        optionals.set(3);
      }
      if (struct.isSetBatchQueues()) {
        optionals.set(4);
      }
      if (struct.isSetFileSystems()) {
        optionals.set(5);
      }
      if (struct.isSetJobSubmissionInterfaces()) {
        optionals.set(6);
      }
      if (struct.isSetDataMovementInterfaces()) {
        optionals.set(7);
      }
      if (struct.isSetMaxMemoryPerNode()) {
        optionals.set(8);
      }
      if (struct.isSetGatewayUsageReporting()) {
        optionals.set(9);
      }
      if (struct.isSetGatewayUsageModuleLoadCommand()) {
        optionals.set(10);
      }
      if (struct.isSetGatewayUsageExecutable()) {
        optionals.set(11);
      }
      if (struct.isSetCpusPerNode()) {
        optionals.set(12);
      }
      if (struct.isSetDefaultNodeCount()) {
        optionals.set(13);
      }
      if (struct.isSetDefaultCPUCount()) {
        optionals.set(14);
      }
      if (struct.isSetDefaultWalltime()) {
        optionals.set(15);
      }
      oprot.writeBitSet(optionals, 16);
      if (struct.isSetHostAliases()) {
        {
          oprot.writeI32(struct.hostAliases.size());
          for (java.lang.String _iter61 : struct.hostAliases)
          {
            oprot.writeString(_iter61);
          }
        }
      }
      if (struct.isSetIpAddresses()) {
        {
          oprot.writeI32(struct.ipAddresses.size());
          for (java.lang.String _iter62 : struct.ipAddresses)
          {
            oprot.writeString(_iter62);
          }
        }
      }
      if (struct.isSetResourceDescription()) {
        oprot.writeString(struct.resourceDescription);
      }
      if (struct.isSetEnabled()) {
        oprot.writeBool(struct.enabled);
      }
      if (struct.isSetBatchQueues()) {
        {
          oprot.writeI32(struct.batchQueues.size());
          for (BatchQueue _iter63 : struct.batchQueues)
          {
            _iter63.write(oprot);
          }
        }
      }
      if (struct.isSetFileSystems()) {
        {
          oprot.writeI32(struct.fileSystems.size());
          for (java.util.Map.Entry<FileSystems, java.lang.String> _iter64 : struct.fileSystems.entrySet())
          {
            oprot.writeI32(_iter64.getKey().getValue());
            oprot.writeString(_iter64.getValue());
          }
        }
      }
      if (struct.isSetJobSubmissionInterfaces()) {
        {
          oprot.writeI32(struct.jobSubmissionInterfaces.size());
          for (JobSubmissionInterface _iter65 : struct.jobSubmissionInterfaces)
          {
            _iter65.write(oprot);
          }
        }
      }
      if (struct.isSetDataMovementInterfaces()) {
        {
          oprot.writeI32(struct.dataMovementInterfaces.size());
          for (org.apache.airavata.model.data.movement.DataMovementInterface _iter66 : struct.dataMovementInterfaces)
          {
            _iter66.write(oprot);
          }
        }
      }
      if (struct.isSetMaxMemoryPerNode()) {
        oprot.writeI32(struct.maxMemoryPerNode);
      }
      if (struct.isSetGatewayUsageReporting()) {
        oprot.writeBool(struct.gatewayUsageReporting);
      }
      if (struct.isSetGatewayUsageModuleLoadCommand()) {
        oprot.writeString(struct.gatewayUsageModuleLoadCommand);
      }
      if (struct.isSetGatewayUsageExecutable()) {
        oprot.writeString(struct.gatewayUsageExecutable);
      }
      if (struct.isSetCpusPerNode()) {
        oprot.writeI32(struct.cpusPerNode);
      }
      if (struct.isSetDefaultNodeCount()) {
        oprot.writeI32(struct.defaultNodeCount);
      }
      if (struct.isSetDefaultCPUCount()) {
        oprot.writeI32(struct.defaultCPUCount);
      }
      if (struct.isSetDefaultWalltime()) {
        oprot.writeI32(struct.defaultWalltime);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, ComputeResourceDescription struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      struct.computeResourceId = iprot.readString();
      struct.setComputeResourceIdIsSet(true);
      struct.hostName = iprot.readString();
      struct.setHostNameIsSet(true);
      java.util.BitSet incoming = iprot.readBitSet(16);
      if (incoming.get(0)) {
        {
          org.apache.thrift.protocol.TList _list67 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.hostAliases = new java.util.ArrayList<java.lang.String>(_list67.size);
          java.lang.String _elem68;
          for (int _i69 = 0; _i69 < _list67.size; ++_i69)
          {
            _elem68 = iprot.readString();
            struct.hostAliases.add(_elem68);
          }
        }
        struct.setHostAliasesIsSet(true);
      }
      if (incoming.get(1)) {
        {
          org.apache.thrift.protocol.TList _list70 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.ipAddresses = new java.util.ArrayList<java.lang.String>(_list70.size);
          java.lang.String _elem71;
          for (int _i72 = 0; _i72 < _list70.size; ++_i72)
          {
            _elem71 = iprot.readString();
            struct.ipAddresses.add(_elem71);
          }
        }
        struct.setIpAddressesIsSet(true);
      }
      if (incoming.get(2)) {
        struct.resourceDescription = iprot.readString();
        struct.setResourceDescriptionIsSet(true);
      }
      if (incoming.get(3)) {
        struct.enabled = iprot.readBool();
        struct.setEnabledIsSet(true);
      }
      if (incoming.get(4)) {
        {
          org.apache.thrift.protocol.TList _list73 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.batchQueues = new java.util.ArrayList<BatchQueue>(_list73.size);
          BatchQueue _elem74;
          for (int _i75 = 0; _i75 < _list73.size; ++_i75)
          {
            _elem74 = new BatchQueue();
            _elem74.read(iprot);
            struct.batchQueues.add(_elem74);
          }
        }
        struct.setBatchQueuesIsSet(true);
      }
      if (incoming.get(5)) {
        {
          org.apache.thrift.protocol.TMap _map76 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.I32, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.fileSystems = new java.util.HashMap<FileSystems,java.lang.String>(2*_map76.size);
          FileSystems _key77;
          java.lang.String _val78;
          for (int _i79 = 0; _i79 < _map76.size; ++_i79)
          {
            _key77 = org.apache.airavata.model.appcatalog.computeresource.FileSystems.findByValue(iprot.readI32());
            _val78 = iprot.readString();
            struct.fileSystems.put(_key77, _val78);
          }
        }
        struct.setFileSystemsIsSet(true);
      }
      if (incoming.get(6)) {
        {
          org.apache.thrift.protocol.TList _list80 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.jobSubmissionInterfaces = new java.util.ArrayList<JobSubmissionInterface>(_list80.size);
          JobSubmissionInterface _elem81;
          for (int _i82 = 0; _i82 < _list80.size; ++_i82)
          {
            _elem81 = new JobSubmissionInterface();
            _elem81.read(iprot);
            struct.jobSubmissionInterfaces.add(_elem81);
          }
        }
        struct.setJobSubmissionInterfacesIsSet(true);
      }
      if (incoming.get(7)) {
        {
          org.apache.thrift.protocol.TList _list83 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.dataMovementInterfaces = new java.util.ArrayList<org.apache.airavata.model.data.movement.DataMovementInterface>(_list83.size);
          org.apache.airavata.model.data.movement.DataMovementInterface _elem84;
          for (int _i85 = 0; _i85 < _list83.size; ++_i85)
          {
            _elem84 = new org.apache.airavata.model.data.movement.DataMovementInterface();
            _elem84.read(iprot);
            struct.dataMovementInterfaces.add(_elem84);
          }
        }
        struct.setDataMovementInterfacesIsSet(true);
      }
      if (incoming.get(8)) {
        struct.maxMemoryPerNode = iprot.readI32();
        struct.setMaxMemoryPerNodeIsSet(true);
      }
      if (incoming.get(9)) {
        struct.gatewayUsageReporting = iprot.readBool();
        struct.setGatewayUsageReportingIsSet(true);
      }
      if (incoming.get(10)) {
        struct.gatewayUsageModuleLoadCommand = iprot.readString();
        struct.setGatewayUsageModuleLoadCommandIsSet(true);
      }
      if (incoming.get(11)) {
        struct.gatewayUsageExecutable = iprot.readString();
        struct.setGatewayUsageExecutableIsSet(true);
      }
      if (incoming.get(12)) {
        struct.cpusPerNode = iprot.readI32();
        struct.setCpusPerNodeIsSet(true);
      }
      if (incoming.get(13)) {
        struct.defaultNodeCount = iprot.readI32();
        struct.setDefaultNodeCountIsSet(true);
      }
      if (incoming.get(14)) {
        struct.defaultCPUCount = iprot.readI32();
        struct.setDefaultCPUCountIsSet(true);
      }
      if (incoming.get(15)) {
        struct.defaultWalltime = iprot.readI32();
        struct.setDefaultWalltimeIsSet(true);
      }
    }
  }

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

