/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Autogenerated by Thrift Compiler (0.9.3)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.airavata.model.appcatalog.computeresource;

import org.apache.thrift.scheme.IScheme;
import org.apache.thrift.scheme.SchemeFactory;
import org.apache.thrift.scheme.StandardScheme;

import org.apache.thrift.scheme.TupleScheme;
import org.apache.thrift.protocol.TTupleProtocol;
import org.apache.thrift.protocol.TProtocolException;
import org.apache.thrift.EncodingUtils;
import org.apache.thrift.TException;
import org.apache.thrift.async.AsyncMethodCallback;
import org.apache.thrift.server.AbstractNonblockingServer.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.Set;
import java.util.HashSet;
import java.util.EnumSet;
import java.util.Collections;
import java.util.BitSet;
import java.nio.ByteBuffer;
import java.util.Arrays;
import javax.annotation.Generated;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
/**
 * 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.
 * 
 */
@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
  static {
    schemes.put(StandardScheme.class, new ComputeResourceDescriptionStandardSchemeFactory());
    schemes.put(TupleScheme.class, new ComputeResourceDescriptionTupleSchemeFactory());
  }

  private String computeResourceId; // required
  private String hostName; // required
  private List<String> hostAliases; // optional
  private List<String> ipAddresses; // optional
  private String resourceDescription; // optional
  private boolean enabled; // optional
  private List<BatchQueue> batchQueues; // optional
  private Map<FileSystems,String> fileSystems; // optional
  private List<JobSubmissionInterface> jobSubmissionInterfaces; // optional
  private List<org.apache.airavata.model.data.movement.DataMovementInterface> dataMovementInterfaces; // optional
  private int maxMemoryPerNode; // optional
  private boolean gatewayUsageReporting; // optional
  private String gatewayUsageModuleLoadCommand; // optional
  private String gatewayUsageExecutable; // 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");

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

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

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

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

    /**
     * Find the _Fields constant that matches name, or null if its not found.
     */
    public static _Fields findByName(String name) {
      return byName.get(name);
    }

    private final short _thriftId;
    private final String _fieldName;

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

    public short getThriftFieldId() {
      return _thriftId;
    }

    public String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final int __ENABLED_ISSET_ID = 0;
  private static final int __MAXMEMORYPERNODE_ISSET_ID = 1;
  private static final int __GATEWAYUSAGEREPORTING_ISSET_ID = 2;
  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};
  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.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)));
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ComputeResourceDescription.class, metaDataMap);
  }

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

  }

  public ComputeResourceDescription(
    String computeResourceId,
    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()) {
      List<String> __this__hostAliases = new ArrayList<String>(other.hostAliases);
      this.hostAliases = __this__hostAliases;
    }
    if (other.isSetIpAddresses()) {
      List<String> __this__ipAddresses = new ArrayList<String>(other.ipAddresses);
      this.ipAddresses = __this__ipAddresses;
    }
    if (other.isSetResourceDescription()) {
      this.resourceDescription = other.resourceDescription;
    }
    this.enabled = other.enabled;
    if (other.isSetBatchQueues()) {
      List<BatchQueue> __this__batchQueues = new 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()) {
      Map<FileSystems,String> __this__fileSystems = new HashMap<FileSystems,String>(other.fileSystems.size());
      for (Map.Entry<FileSystems, String> other_element : other.fileSystems.entrySet()) {

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

        FileSystems __this__fileSystems_copy_key = other_element_key;

        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()) {
      List<JobSubmissionInterface> __this__jobSubmissionInterfaces = new 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()) {
      List<org.apache.airavata.model.data.movement.DataMovementInterface> __this__dataMovementInterfaces = new 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;
    }
  }

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

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

  public void setComputeResourceId(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 String getHostName() {
    return this.hostName;
  }

  public void setHostName(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<String> getHostAliasesIterator() {
    return (this.hostAliases == null) ? null : this.hostAliases.iterator();
  }

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

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

  public void setHostAliases(List<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<String> getIpAddressesIterator() {
    return (this.ipAddresses == null) ? null : this.ipAddresses.iterator();
  }

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

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

  public void setIpAddresses(List<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 String getResourceDescription() {
    return this.resourceDescription;
  }

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

  public void setEnabledIsSet(boolean value) {
    __isset_bitfield = 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 ArrayList<BatchQueue>();
    }
    this.batchQueues.add(elem);
  }

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

  public void setBatchQueues(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, String val) {
    if (this.fileSystems == null) {
      this.fileSystems = new HashMap<FileSystems,String>();
    }
    this.fileSystems.put(key, val);
  }

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

  public void setFileSystems(Map<FileSystems,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 ArrayList<JobSubmissionInterface>();
    }
    this.jobSubmissionInterfaces.add(elem);
  }

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

  public void setJobSubmissionInterfaces(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 ArrayList<org.apache.airavata.model.data.movement.DataMovementInterface>();
    }
    this.dataMovementInterfaces.add(elem);
  }

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

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

  public void setMaxMemoryPerNodeIsSet(boolean value) {
    __isset_bitfield = 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 = 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 EncodingUtils.testBit(__isset_bitfield, __GATEWAYUSAGEREPORTING_ISSET_ID);
  }

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

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

  public void setGatewayUsageModuleLoadCommand(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 String getGatewayUsageExecutable() {
    return this.gatewayUsageExecutable;
  }

  public void setGatewayUsageExecutable(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 void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case COMPUTE_RESOURCE_ID:
      if (value == null) {
        unsetComputeResourceId();
      } else {
        setComputeResourceId((String)value);
      }
      break;

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

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

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

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

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

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

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

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

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

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

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

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

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

    }
  }

  public 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();

    }
    throw new IllegalStateException();
  }

  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
  public boolean isSet(_Fields field) {
    if (field == null) {
      throw new IllegalArgumentException();
    }

    switch (field) {
    case 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();
    }
    throw new IllegalStateException();
  }

  @Override
  public boolean equals(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;

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

    return true;
  }

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

    boolean present_computeResourceId = true && (isSetComputeResourceId());
    list.add(present_computeResourceId);
    if (present_computeResourceId)
      list.add(computeResourceId);

    boolean present_hostName = true && (isSetHostName());
    list.add(present_hostName);
    if (present_hostName)
      list.add(hostName);

    boolean present_hostAliases = true && (isSetHostAliases());
    list.add(present_hostAliases);
    if (present_hostAliases)
      list.add(hostAliases);

    boolean present_ipAddresses = true && (isSetIpAddresses());
    list.add(present_ipAddresses);
    if (present_ipAddresses)
      list.add(ipAddresses);

    boolean present_resourceDescription = true && (isSetResourceDescription());
    list.add(present_resourceDescription);
    if (present_resourceDescription)
      list.add(resourceDescription);

    boolean present_enabled = true && (isSetEnabled());
    list.add(present_enabled);
    if (present_enabled)
      list.add(enabled);

    boolean present_batchQueues = true && (isSetBatchQueues());
    list.add(present_batchQueues);
    if (present_batchQueues)
      list.add(batchQueues);

    boolean present_fileSystems = true && (isSetFileSystems());
    list.add(present_fileSystems);
    if (present_fileSystems)
      list.add(fileSystems);

    boolean present_jobSubmissionInterfaces = true && (isSetJobSubmissionInterfaces());
    list.add(present_jobSubmissionInterfaces);
    if (present_jobSubmissionInterfaces)
      list.add(jobSubmissionInterfaces);

    boolean present_dataMovementInterfaces = true && (isSetDataMovementInterfaces());
    list.add(present_dataMovementInterfaces);
    if (present_dataMovementInterfaces)
      list.add(dataMovementInterfaces);

    boolean present_maxMemoryPerNode = true && (isSetMaxMemoryPerNode());
    list.add(present_maxMemoryPerNode);
    if (present_maxMemoryPerNode)
      list.add(maxMemoryPerNode);

    boolean present_gatewayUsageReporting = true && (isSetGatewayUsageReporting());
    list.add(present_gatewayUsageReporting);
    if (present_gatewayUsageReporting)
      list.add(gatewayUsageReporting);

    boolean present_gatewayUsageModuleLoadCommand = true && (isSetGatewayUsageModuleLoadCommand());
    list.add(present_gatewayUsageModuleLoadCommand);
    if (present_gatewayUsageModuleLoadCommand)
      list.add(gatewayUsageModuleLoadCommand);

    boolean present_gatewayUsageExecutable = true && (isSetGatewayUsageExecutable());
    list.add(present_gatewayUsageExecutable);
    if (present_gatewayUsageExecutable)
      list.add(gatewayUsageExecutable);

    return list.hashCode();
  }

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

    int lastComparison = 0;

    lastComparison = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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;
      }
    }
    return 0;
  }

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

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

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

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder("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;
    }
    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, 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 SchemeFactory {
    public ComputeResourceDescriptionStandardScheme getScheme() {
      return new ComputeResourceDescriptionStandardScheme();
    }
  }

  private static class ComputeResourceDescriptionStandardScheme extends 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 ArrayList<String>(_list36.size);
                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 ArrayList<String>(_list39.size);
                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 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 HashMap<FileSystems,String>(2*_map45.size);
                FileSystems _key46;
                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 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 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;
          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 (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 (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 (Map.Entry<FileSystems, 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();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class ComputeResourceDescriptionTupleSchemeFactory implements SchemeFactory {
    public ComputeResourceDescriptionTupleScheme getScheme() {
      return new ComputeResourceDescriptionTupleScheme();
    }
  }

  private static class ComputeResourceDescriptionTupleScheme extends TupleScheme<ComputeResourceDescription> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, ComputeResourceDescription struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      oprot.writeString(struct.computeResourceId);
      oprot.writeString(struct.hostName);
      BitSet optionals = new 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);
      }
      oprot.writeBitSet(optionals, 12);
      if (struct.isSetHostAliases()) {
        {
          oprot.writeI32(struct.hostAliases.size());
          for (String _iter61 : struct.hostAliases)
          {
            oprot.writeString(_iter61);
          }
        }
      }
      if (struct.isSetIpAddresses()) {
        {
          oprot.writeI32(struct.ipAddresses.size());
          for (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 (Map.Entry<FileSystems, 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);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, ComputeResourceDescription struct) throws org.apache.thrift.TException {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      struct.computeResourceId = iprot.readString();
      struct.setComputeResourceIdIsSet(true);
      struct.hostName = iprot.readString();
      struct.setHostNameIsSet(true);
      BitSet incoming = iprot.readBitSet(12);
      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 ArrayList<String>(_list67.size);
          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 ArrayList<String>(_list70.size);
          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 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 HashMap<FileSystems,String>(2*_map76.size);
          FileSystems _key77;
          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 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 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);
      }
    }
  }

}

