/**
 * 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.gatewayprofile;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
/**
 * Gateway specific preferences for a Computer Resource
 * 
 * computeResourceId:
 *   Corelate the preference to a compute resource.
 * 
 * overridebyAiravata:
 *   If turned true, Airavata will override the preferences of better alternatives exist.
 * 
 * loginUserName:
 *   If turned true, Airavata will override the preferences of better alternatives exist.
 * 
 * preferredJobSubmissionProtocol:
 *   For resources with multiple job submission protocols, the gateway can pick a preferred option.
 * 
 * preferredDataMovementProtocol:
 *   For resources with multiple data movement protocols, the gateway can pick a preferred option.
 * 
 * preferredBatchQueue:
 *  Gateways can choose a defualt batch queue based on average job dimention, reservations or other metrics.
 * 
 * scratchLocation:
 *  Path to the local scratch space on a HPC cluster. Typically used to create working directory for job execution.
 * 
 * allocationProjectNumber:
 *  Typically used on HPC machines to charge computing usage to a account number. For instance, on XSEDE once an
 *    allocation is approved, an allocation number is assigned. Before passing this number with job submittions, the
 *    account to be used has to be added to the allocation.
 * 
 * resourceSpecificCredentialStoreToken:
 *  Resource specific credential store token. If this token is specified, then it is superceeded by the gateway's
 *   default credential store.
 * 
 */
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
public class ComputeResourcePreference implements org.apache.thrift.TBase<ComputeResourcePreference, ComputeResourcePreference._Fields>, java.io.Serializable, Cloneable, Comparable<ComputeResourcePreference> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ComputeResourcePreference");

  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 OVERRIDEBY_AIRAVATA_FIELD_DESC = new org.apache.thrift.protocol.TField("overridebyAiravata", org.apache.thrift.protocol.TType.BOOL, (short)2);
  private static final org.apache.thrift.protocol.TField LOGIN_USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("loginUserName", org.apache.thrift.protocol.TType.STRING, (short)3);
  private static final org.apache.thrift.protocol.TField PREFERRED_JOB_SUBMISSION_PROTOCOL_FIELD_DESC = new org.apache.thrift.protocol.TField("preferredJobSubmissionProtocol", org.apache.thrift.protocol.TType.I32, (short)4);
  private static final org.apache.thrift.protocol.TField PREFERRED_DATA_MOVEMENT_PROTOCOL_FIELD_DESC = new org.apache.thrift.protocol.TField("preferredDataMovementProtocol", org.apache.thrift.protocol.TType.I32, (short)5);
  private static final org.apache.thrift.protocol.TField PREFERRED_BATCH_QUEUE_FIELD_DESC = new org.apache.thrift.protocol.TField("preferredBatchQueue", org.apache.thrift.protocol.TType.STRING, (short)6);
  private static final org.apache.thrift.protocol.TField SCRATCH_LOCATION_FIELD_DESC = new org.apache.thrift.protocol.TField("scratchLocation", org.apache.thrift.protocol.TType.STRING, (short)7);
  private static final org.apache.thrift.protocol.TField ALLOCATION_PROJECT_NUMBER_FIELD_DESC = new org.apache.thrift.protocol.TField("allocationProjectNumber", org.apache.thrift.protocol.TType.STRING, (short)8);
  private static final org.apache.thrift.protocol.TField RESOURCE_SPECIFIC_CREDENTIAL_STORE_TOKEN_FIELD_DESC = new org.apache.thrift.protocol.TField("resourceSpecificCredentialStoreToken", org.apache.thrift.protocol.TType.STRING, (short)9);
  private static final org.apache.thrift.protocol.TField USAGE_REPORTING_GATEWAY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("usageReportingGatewayId", org.apache.thrift.protocol.TType.STRING, (short)10);
  private static final org.apache.thrift.protocol.TField QUALITY_OF_SERVICE_FIELD_DESC = new org.apache.thrift.protocol.TField("qualityOfService", org.apache.thrift.protocol.TType.STRING, (short)11);
  private static final org.apache.thrift.protocol.TField RESERVATION_FIELD_DESC = new org.apache.thrift.protocol.TField("reservation", org.apache.thrift.protocol.TType.STRING, (short)12);
  private static final org.apache.thrift.protocol.TField RESERVATION_START_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("reservationStartTime", org.apache.thrift.protocol.TType.I64, (short)13);
  private static final org.apache.thrift.protocol.TField RESERVATION_END_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("reservationEndTime", org.apache.thrift.protocol.TType.I64, (short)14);
  private static final org.apache.thrift.protocol.TField SSH_ACCOUNT_PROVISIONER_FIELD_DESC = new org.apache.thrift.protocol.TField("sshAccountProvisioner", org.apache.thrift.protocol.TType.STRING, (short)15);
  private static final org.apache.thrift.protocol.TField SSH_ACCOUNT_PROVISIONER_CONFIG_FIELD_DESC = new org.apache.thrift.protocol.TField("sshAccountProvisionerConfig", org.apache.thrift.protocol.TType.MAP, (short)16);
  private static final org.apache.thrift.protocol.TField SSH_ACCOUNT_PROVISIONER_ADDITIONAL_INFO_FIELD_DESC = new org.apache.thrift.protocol.TField("sshAccountProvisionerAdditionalInfo", org.apache.thrift.protocol.TType.STRING, (short)17);

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

  private java.lang.String computeResourceId; // required
  private boolean overridebyAiravata; // required
  private java.lang.String loginUserName; // optional
  private org.apache.airavata.model.appcatalog.computeresource.JobSubmissionProtocol preferredJobSubmissionProtocol; // optional
  private org.apache.airavata.model.data.movement.DataMovementProtocol preferredDataMovementProtocol; // optional
  private java.lang.String preferredBatchQueue; // optional
  private java.lang.String scratchLocation; // optional
  private java.lang.String allocationProjectNumber; // optional
  private java.lang.String resourceSpecificCredentialStoreToken; // optional
  private java.lang.String usageReportingGatewayId; // optional
  private java.lang.String qualityOfService; // optional
  private java.lang.String reservation; // optional
  private long reservationStartTime; // optional
  private long reservationEndTime; // optional
  private java.lang.String sshAccountProvisioner; // optional
  private java.util.Map<java.lang.String,java.lang.String> sshAccountProvisionerConfig; // optional
  private java.lang.String sshAccountProvisionerAdditionalInfo; // 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"),
    OVERRIDEBY_AIRAVATA((short)2, "overridebyAiravata"),
    LOGIN_USER_NAME((short)3, "loginUserName"),
    /**
     * 
     * @see org.apache.airavata.model.appcatalog.computeresource.JobSubmissionProtocol
     */
    PREFERRED_JOB_SUBMISSION_PROTOCOL((short)4, "preferredJobSubmissionProtocol"),
    /**
     * 
     * @see org.apache.airavata.model.data.movement.DataMovementProtocol
     */
    PREFERRED_DATA_MOVEMENT_PROTOCOL((short)5, "preferredDataMovementProtocol"),
    PREFERRED_BATCH_QUEUE((short)6, "preferredBatchQueue"),
    SCRATCH_LOCATION((short)7, "scratchLocation"),
    ALLOCATION_PROJECT_NUMBER((short)8, "allocationProjectNumber"),
    RESOURCE_SPECIFIC_CREDENTIAL_STORE_TOKEN((short)9, "resourceSpecificCredentialStoreToken"),
    USAGE_REPORTING_GATEWAY_ID((short)10, "usageReportingGatewayId"),
    QUALITY_OF_SERVICE((short)11, "qualityOfService"),
    RESERVATION((short)12, "reservation"),
    RESERVATION_START_TIME((short)13, "reservationStartTime"),
    RESERVATION_END_TIME((short)14, "reservationEndTime"),
    SSH_ACCOUNT_PROVISIONER((short)15, "sshAccountProvisioner"),
    SSH_ACCOUNT_PROVISIONER_CONFIG((short)16, "sshAccountProvisionerConfig"),
    SSH_ACCOUNT_PROVISIONER_ADDITIONAL_INFO((short)17, "sshAccountProvisionerAdditionalInfo");

    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: // OVERRIDEBY_AIRAVATA
          return OVERRIDEBY_AIRAVATA;
        case 3: // LOGIN_USER_NAME
          return LOGIN_USER_NAME;
        case 4: // PREFERRED_JOB_SUBMISSION_PROTOCOL
          return PREFERRED_JOB_SUBMISSION_PROTOCOL;
        case 5: // PREFERRED_DATA_MOVEMENT_PROTOCOL
          return PREFERRED_DATA_MOVEMENT_PROTOCOL;
        case 6: // PREFERRED_BATCH_QUEUE
          return PREFERRED_BATCH_QUEUE;
        case 7: // SCRATCH_LOCATION
          return SCRATCH_LOCATION;
        case 8: // ALLOCATION_PROJECT_NUMBER
          return ALLOCATION_PROJECT_NUMBER;
        case 9: // RESOURCE_SPECIFIC_CREDENTIAL_STORE_TOKEN
          return RESOURCE_SPECIFIC_CREDENTIAL_STORE_TOKEN;
        case 10: // USAGE_REPORTING_GATEWAY_ID
          return USAGE_REPORTING_GATEWAY_ID;
        case 11: // QUALITY_OF_SERVICE
          return QUALITY_OF_SERVICE;
        case 12: // RESERVATION
          return RESERVATION;
        case 13: // RESERVATION_START_TIME
          return RESERVATION_START_TIME;
        case 14: // RESERVATION_END_TIME
          return RESERVATION_END_TIME;
        case 15: // SSH_ACCOUNT_PROVISIONER
          return SSH_ACCOUNT_PROVISIONER;
        case 16: // SSH_ACCOUNT_PROVISIONER_CONFIG
          return SSH_ACCOUNT_PROVISIONER_CONFIG;
        case 17: // SSH_ACCOUNT_PROVISIONER_ADDITIONAL_INFO
          return SSH_ACCOUNT_PROVISIONER_ADDITIONAL_INFO;
        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 __OVERRIDEBYAIRAVATA_ISSET_ID = 0;
  private static final int __RESERVATIONSTARTTIME_ISSET_ID = 1;
  private static final int __RESERVATIONENDTIME_ISSET_ID = 2;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.LOGIN_USER_NAME,_Fields.PREFERRED_JOB_SUBMISSION_PROTOCOL,_Fields.PREFERRED_DATA_MOVEMENT_PROTOCOL,_Fields.PREFERRED_BATCH_QUEUE,_Fields.SCRATCH_LOCATION,_Fields.ALLOCATION_PROJECT_NUMBER,_Fields.RESOURCE_SPECIFIC_CREDENTIAL_STORE_TOKEN,_Fields.USAGE_REPORTING_GATEWAY_ID,_Fields.QUALITY_OF_SERVICE,_Fields.RESERVATION,_Fields.RESERVATION_START_TIME,_Fields.RESERVATION_END_TIME,_Fields.SSH_ACCOUNT_PROVISIONER,_Fields.SSH_ACCOUNT_PROVISIONER_CONFIG,_Fields.SSH_ACCOUNT_PROVISIONER_ADDITIONAL_INFO};
  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.OVERRIDEBY_AIRAVATA, new org.apache.thrift.meta_data.FieldMetaData("overridebyAiravata", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.LOGIN_USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("loginUserName", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.PREFERRED_JOB_SUBMISSION_PROTOCOL, new org.apache.thrift.meta_data.FieldMetaData("preferredJobSubmissionProtocol", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, org.apache.airavata.model.appcatalog.computeresource.JobSubmissionProtocol.class)));
    tmpMap.put(_Fields.PREFERRED_DATA_MOVEMENT_PROTOCOL, new org.apache.thrift.meta_data.FieldMetaData("preferredDataMovementProtocol", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, org.apache.airavata.model.data.movement.DataMovementProtocol.class)));
    tmpMap.put(_Fields.PREFERRED_BATCH_QUEUE, new org.apache.thrift.meta_data.FieldMetaData("preferredBatchQueue", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.SCRATCH_LOCATION, new org.apache.thrift.meta_data.FieldMetaData("scratchLocation", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.ALLOCATION_PROJECT_NUMBER, new org.apache.thrift.meta_data.FieldMetaData("allocationProjectNumber", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.RESOURCE_SPECIFIC_CREDENTIAL_STORE_TOKEN, new org.apache.thrift.meta_data.FieldMetaData("resourceSpecificCredentialStoreToken", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.USAGE_REPORTING_GATEWAY_ID, new org.apache.thrift.meta_data.FieldMetaData("usageReportingGatewayId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.QUALITY_OF_SERVICE, new org.apache.thrift.meta_data.FieldMetaData("qualityOfService", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.RESERVATION, new org.apache.thrift.meta_data.FieldMetaData("reservation", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.RESERVATION_START_TIME, new org.apache.thrift.meta_data.FieldMetaData("reservationStartTime", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.RESERVATION_END_TIME, new org.apache.thrift.meta_data.FieldMetaData("reservationEndTime", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.SSH_ACCOUNT_PROVISIONER, new org.apache.thrift.meta_data.FieldMetaData("sshAccountProvisioner", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.SSH_ACCOUNT_PROVISIONER_CONFIG, new org.apache.thrift.meta_data.FieldMetaData("sshAccountProvisionerConfig", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
    tmpMap.put(_Fields.SSH_ACCOUNT_PROVISIONER_ADDITIONAL_INFO, new org.apache.thrift.meta_data.FieldMetaData("sshAccountProvisionerAdditionalInfo", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ComputeResourcePreference.class, metaDataMap);
  }

  public ComputeResourcePreference() {
    this.overridebyAiravata = true;

  }

  public ComputeResourcePreference(
    java.lang.String computeResourceId,
    boolean overridebyAiravata)
  {
    this();
    this.computeResourceId = computeResourceId;
    this.overridebyAiravata = overridebyAiravata;
    setOverridebyAiravataIsSet(true);
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public ComputeResourcePreference(ComputeResourcePreference other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetComputeResourceId()) {
      this.computeResourceId = other.computeResourceId;
    }
    this.overridebyAiravata = other.overridebyAiravata;
    if (other.isSetLoginUserName()) {
      this.loginUserName = other.loginUserName;
    }
    if (other.isSetPreferredJobSubmissionProtocol()) {
      this.preferredJobSubmissionProtocol = other.preferredJobSubmissionProtocol;
    }
    if (other.isSetPreferredDataMovementProtocol()) {
      this.preferredDataMovementProtocol = other.preferredDataMovementProtocol;
    }
    if (other.isSetPreferredBatchQueue()) {
      this.preferredBatchQueue = other.preferredBatchQueue;
    }
    if (other.isSetScratchLocation()) {
      this.scratchLocation = other.scratchLocation;
    }
    if (other.isSetAllocationProjectNumber()) {
      this.allocationProjectNumber = other.allocationProjectNumber;
    }
    if (other.isSetResourceSpecificCredentialStoreToken()) {
      this.resourceSpecificCredentialStoreToken = other.resourceSpecificCredentialStoreToken;
    }
    if (other.isSetUsageReportingGatewayId()) {
      this.usageReportingGatewayId = other.usageReportingGatewayId;
    }
    if (other.isSetQualityOfService()) {
      this.qualityOfService = other.qualityOfService;
    }
    if (other.isSetReservation()) {
      this.reservation = other.reservation;
    }
    this.reservationStartTime = other.reservationStartTime;
    this.reservationEndTime = other.reservationEndTime;
    if (other.isSetSshAccountProvisioner()) {
      this.sshAccountProvisioner = other.sshAccountProvisioner;
    }
    if (other.isSetSshAccountProvisionerConfig()) {
      java.util.Map<java.lang.String,java.lang.String> __this__sshAccountProvisionerConfig = new java.util.HashMap<java.lang.String,java.lang.String>(other.sshAccountProvisionerConfig);
      this.sshAccountProvisionerConfig = __this__sshAccountProvisionerConfig;
    }
    if (other.isSetSshAccountProvisionerAdditionalInfo()) {
      this.sshAccountProvisionerAdditionalInfo = other.sshAccountProvisionerAdditionalInfo;
    }
  }

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

  @Override
  public void clear() {
    this.computeResourceId = null;
    this.overridebyAiravata = true;

    this.loginUserName = null;
    this.preferredJobSubmissionProtocol = null;
    this.preferredDataMovementProtocol = null;
    this.preferredBatchQueue = null;
    this.scratchLocation = null;
    this.allocationProjectNumber = null;
    this.resourceSpecificCredentialStoreToken = null;
    this.usageReportingGatewayId = null;
    this.qualityOfService = null;
    this.reservation = null;
    setReservationStartTimeIsSet(false);
    this.reservationStartTime = 0;
    setReservationEndTimeIsSet(false);
    this.reservationEndTime = 0;
    this.sshAccountProvisioner = null;
    this.sshAccountProvisionerConfig = null;
    this.sshAccountProvisionerAdditionalInfo = null;
  }

  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 boolean isOverridebyAiravata() {
    return this.overridebyAiravata;
  }

  public void setOverridebyAiravata(boolean overridebyAiravata) {
    this.overridebyAiravata = overridebyAiravata;
    setOverridebyAiravataIsSet(true);
  }

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

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

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

  public java.lang.String getLoginUserName() {
    return this.loginUserName;
  }

  public void setLoginUserName(java.lang.String loginUserName) {
    this.loginUserName = loginUserName;
  }

  public void unsetLoginUserName() {
    this.loginUserName = null;
  }

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

  public void setLoginUserNameIsSet(boolean value) {
    if (!value) {
      this.loginUserName = null;
    }
  }

  /**
   * 
   * @see org.apache.airavata.model.appcatalog.computeresource.JobSubmissionProtocol
   */
  public org.apache.airavata.model.appcatalog.computeresource.JobSubmissionProtocol getPreferredJobSubmissionProtocol() {
    return this.preferredJobSubmissionProtocol;
  }

  /**
   * 
   * @see org.apache.airavata.model.appcatalog.computeresource.JobSubmissionProtocol
   */
  public void setPreferredJobSubmissionProtocol(org.apache.airavata.model.appcatalog.computeresource.JobSubmissionProtocol preferredJobSubmissionProtocol) {
    this.preferredJobSubmissionProtocol = preferredJobSubmissionProtocol;
  }

  public void unsetPreferredJobSubmissionProtocol() {
    this.preferredJobSubmissionProtocol = null;
  }

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

  public void setPreferredJobSubmissionProtocolIsSet(boolean value) {
    if (!value) {
      this.preferredJobSubmissionProtocol = null;
    }
  }

  /**
   * 
   * @see org.apache.airavata.model.data.movement.DataMovementProtocol
   */
  public org.apache.airavata.model.data.movement.DataMovementProtocol getPreferredDataMovementProtocol() {
    return this.preferredDataMovementProtocol;
  }

  /**
   * 
   * @see org.apache.airavata.model.data.movement.DataMovementProtocol
   */
  public void setPreferredDataMovementProtocol(org.apache.airavata.model.data.movement.DataMovementProtocol preferredDataMovementProtocol) {
    this.preferredDataMovementProtocol = preferredDataMovementProtocol;
  }

  public void unsetPreferredDataMovementProtocol() {
    this.preferredDataMovementProtocol = null;
  }

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

  public void setPreferredDataMovementProtocolIsSet(boolean value) {
    if (!value) {
      this.preferredDataMovementProtocol = null;
    }
  }

  public java.lang.String getPreferredBatchQueue() {
    return this.preferredBatchQueue;
  }

  public void setPreferredBatchQueue(java.lang.String preferredBatchQueue) {
    this.preferredBatchQueue = preferredBatchQueue;
  }

  public void unsetPreferredBatchQueue() {
    this.preferredBatchQueue = null;
  }

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

  public void setPreferredBatchQueueIsSet(boolean value) {
    if (!value) {
      this.preferredBatchQueue = null;
    }
  }

  public java.lang.String getScratchLocation() {
    return this.scratchLocation;
  }

  public void setScratchLocation(java.lang.String scratchLocation) {
    this.scratchLocation = scratchLocation;
  }

  public void unsetScratchLocation() {
    this.scratchLocation = null;
  }

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

  public void setScratchLocationIsSet(boolean value) {
    if (!value) {
      this.scratchLocation = null;
    }
  }

  public java.lang.String getAllocationProjectNumber() {
    return this.allocationProjectNumber;
  }

  public void setAllocationProjectNumber(java.lang.String allocationProjectNumber) {
    this.allocationProjectNumber = allocationProjectNumber;
  }

  public void unsetAllocationProjectNumber() {
    this.allocationProjectNumber = null;
  }

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

  public void setAllocationProjectNumberIsSet(boolean value) {
    if (!value) {
      this.allocationProjectNumber = null;
    }
  }

  public java.lang.String getResourceSpecificCredentialStoreToken() {
    return this.resourceSpecificCredentialStoreToken;
  }

  public void setResourceSpecificCredentialStoreToken(java.lang.String resourceSpecificCredentialStoreToken) {
    this.resourceSpecificCredentialStoreToken = resourceSpecificCredentialStoreToken;
  }

  public void unsetResourceSpecificCredentialStoreToken() {
    this.resourceSpecificCredentialStoreToken = null;
  }

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

  public void setResourceSpecificCredentialStoreTokenIsSet(boolean value) {
    if (!value) {
      this.resourceSpecificCredentialStoreToken = null;
    }
  }

  public java.lang.String getUsageReportingGatewayId() {
    return this.usageReportingGatewayId;
  }

  public void setUsageReportingGatewayId(java.lang.String usageReportingGatewayId) {
    this.usageReportingGatewayId = usageReportingGatewayId;
  }

  public void unsetUsageReportingGatewayId() {
    this.usageReportingGatewayId = null;
  }

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

  public void setUsageReportingGatewayIdIsSet(boolean value) {
    if (!value) {
      this.usageReportingGatewayId = null;
    }
  }

  public java.lang.String getQualityOfService() {
    return this.qualityOfService;
  }

  public void setQualityOfService(java.lang.String qualityOfService) {
    this.qualityOfService = qualityOfService;
  }

  public void unsetQualityOfService() {
    this.qualityOfService = null;
  }

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

  public void setQualityOfServiceIsSet(boolean value) {
    if (!value) {
      this.qualityOfService = null;
    }
  }

  public java.lang.String getReservation() {
    return this.reservation;
  }

  public void setReservation(java.lang.String reservation) {
    this.reservation = reservation;
  }

  public void unsetReservation() {
    this.reservation = null;
  }

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

  public void setReservationIsSet(boolean value) {
    if (!value) {
      this.reservation = null;
    }
  }

  public long getReservationStartTime() {
    return this.reservationStartTime;
  }

  public void setReservationStartTime(long reservationStartTime) {
    this.reservationStartTime = reservationStartTime;
    setReservationStartTimeIsSet(true);
  }

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

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

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

  public long getReservationEndTime() {
    return this.reservationEndTime;
  }

  public void setReservationEndTime(long reservationEndTime) {
    this.reservationEndTime = reservationEndTime;
    setReservationEndTimeIsSet(true);
  }

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

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

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

  public java.lang.String getSshAccountProvisioner() {
    return this.sshAccountProvisioner;
  }

  public void setSshAccountProvisioner(java.lang.String sshAccountProvisioner) {
    this.sshAccountProvisioner = sshAccountProvisioner;
  }

  public void unsetSshAccountProvisioner() {
    this.sshAccountProvisioner = null;
  }

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

  public void setSshAccountProvisionerIsSet(boolean value) {
    if (!value) {
      this.sshAccountProvisioner = null;
    }
  }

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

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

  public java.util.Map<java.lang.String,java.lang.String> getSshAccountProvisionerConfig() {
    return this.sshAccountProvisionerConfig;
  }

  public void setSshAccountProvisionerConfig(java.util.Map<java.lang.String,java.lang.String> sshAccountProvisionerConfig) {
    this.sshAccountProvisionerConfig = sshAccountProvisionerConfig;
  }

  public void unsetSshAccountProvisionerConfig() {
    this.sshAccountProvisionerConfig = null;
  }

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

  public void setSshAccountProvisionerConfigIsSet(boolean value) {
    if (!value) {
      this.sshAccountProvisionerConfig = null;
    }
  }

  public java.lang.String getSshAccountProvisionerAdditionalInfo() {
    return this.sshAccountProvisionerAdditionalInfo;
  }

  public void setSshAccountProvisionerAdditionalInfo(java.lang.String sshAccountProvisionerAdditionalInfo) {
    this.sshAccountProvisionerAdditionalInfo = sshAccountProvisionerAdditionalInfo;
  }

  public void unsetSshAccountProvisionerAdditionalInfo() {
    this.sshAccountProvisionerAdditionalInfo = null;
  }

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

  public void setSshAccountProvisionerAdditionalInfoIsSet(boolean value) {
    if (!value) {
      this.sshAccountProvisionerAdditionalInfo = null;
    }
  }

  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 OVERRIDEBY_AIRAVATA:
      if (value == null) {
        unsetOverridebyAiravata();
      } else {
        setOverridebyAiravata((java.lang.Boolean)value);
      }
      break;

    case LOGIN_USER_NAME:
      if (value == null) {
        unsetLoginUserName();
      } else {
        setLoginUserName((java.lang.String)value);
      }
      break;

    case PREFERRED_JOB_SUBMISSION_PROTOCOL:
      if (value == null) {
        unsetPreferredJobSubmissionProtocol();
      } else {
        setPreferredJobSubmissionProtocol((org.apache.airavata.model.appcatalog.computeresource.JobSubmissionProtocol)value);
      }
      break;

    case PREFERRED_DATA_MOVEMENT_PROTOCOL:
      if (value == null) {
        unsetPreferredDataMovementProtocol();
      } else {
        setPreferredDataMovementProtocol((org.apache.airavata.model.data.movement.DataMovementProtocol)value);
      }
      break;

    case PREFERRED_BATCH_QUEUE:
      if (value == null) {
        unsetPreferredBatchQueue();
      } else {
        setPreferredBatchQueue((java.lang.String)value);
      }
      break;

    case SCRATCH_LOCATION:
      if (value == null) {
        unsetScratchLocation();
      } else {
        setScratchLocation((java.lang.String)value);
      }
      break;

    case ALLOCATION_PROJECT_NUMBER:
      if (value == null) {
        unsetAllocationProjectNumber();
      } else {
        setAllocationProjectNumber((java.lang.String)value);
      }
      break;

    case RESOURCE_SPECIFIC_CREDENTIAL_STORE_TOKEN:
      if (value == null) {
        unsetResourceSpecificCredentialStoreToken();
      } else {
        setResourceSpecificCredentialStoreToken((java.lang.String)value);
      }
      break;

    case USAGE_REPORTING_GATEWAY_ID:
      if (value == null) {
        unsetUsageReportingGatewayId();
      } else {
        setUsageReportingGatewayId((java.lang.String)value);
      }
      break;

    case QUALITY_OF_SERVICE:
      if (value == null) {
        unsetQualityOfService();
      } else {
        setQualityOfService((java.lang.String)value);
      }
      break;

    case RESERVATION:
      if (value == null) {
        unsetReservation();
      } else {
        setReservation((java.lang.String)value);
      }
      break;

    case RESERVATION_START_TIME:
      if (value == null) {
        unsetReservationStartTime();
      } else {
        setReservationStartTime((java.lang.Long)value);
      }
      break;

    case RESERVATION_END_TIME:
      if (value == null) {
        unsetReservationEndTime();
      } else {
        setReservationEndTime((java.lang.Long)value);
      }
      break;

    case SSH_ACCOUNT_PROVISIONER:
      if (value == null) {
        unsetSshAccountProvisioner();
      } else {
        setSshAccountProvisioner((java.lang.String)value);
      }
      break;

    case SSH_ACCOUNT_PROVISIONER_CONFIG:
      if (value == null) {
        unsetSshAccountProvisionerConfig();
      } else {
        setSshAccountProvisionerConfig((java.util.Map<java.lang.String,java.lang.String>)value);
      }
      break;

    case SSH_ACCOUNT_PROVISIONER_ADDITIONAL_INFO:
      if (value == null) {
        unsetSshAccountProvisionerAdditionalInfo();
      } else {
        setSshAccountProvisionerAdditionalInfo((java.lang.String)value);
      }
      break;

    }
  }

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

    case OVERRIDEBY_AIRAVATA:
      return isOverridebyAiravata();

    case LOGIN_USER_NAME:
      return getLoginUserName();

    case PREFERRED_JOB_SUBMISSION_PROTOCOL:
      return getPreferredJobSubmissionProtocol();

    case PREFERRED_DATA_MOVEMENT_PROTOCOL:
      return getPreferredDataMovementProtocol();

    case PREFERRED_BATCH_QUEUE:
      return getPreferredBatchQueue();

    case SCRATCH_LOCATION:
      return getScratchLocation();

    case ALLOCATION_PROJECT_NUMBER:
      return getAllocationProjectNumber();

    case RESOURCE_SPECIFIC_CREDENTIAL_STORE_TOKEN:
      return getResourceSpecificCredentialStoreToken();

    case USAGE_REPORTING_GATEWAY_ID:
      return getUsageReportingGatewayId();

    case QUALITY_OF_SERVICE:
      return getQualityOfService();

    case RESERVATION:
      return getReservation();

    case RESERVATION_START_TIME:
      return getReservationStartTime();

    case RESERVATION_END_TIME:
      return getReservationEndTime();

    case SSH_ACCOUNT_PROVISIONER:
      return getSshAccountProvisioner();

    case SSH_ACCOUNT_PROVISIONER_CONFIG:
      return getSshAccountProvisionerConfig();

    case SSH_ACCOUNT_PROVISIONER_ADDITIONAL_INFO:
      return getSshAccountProvisionerAdditionalInfo();

    }
    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 OVERRIDEBY_AIRAVATA:
      return isSetOverridebyAiravata();
    case LOGIN_USER_NAME:
      return isSetLoginUserName();
    case PREFERRED_JOB_SUBMISSION_PROTOCOL:
      return isSetPreferredJobSubmissionProtocol();
    case PREFERRED_DATA_MOVEMENT_PROTOCOL:
      return isSetPreferredDataMovementProtocol();
    case PREFERRED_BATCH_QUEUE:
      return isSetPreferredBatchQueue();
    case SCRATCH_LOCATION:
      return isSetScratchLocation();
    case ALLOCATION_PROJECT_NUMBER:
      return isSetAllocationProjectNumber();
    case RESOURCE_SPECIFIC_CREDENTIAL_STORE_TOKEN:
      return isSetResourceSpecificCredentialStoreToken();
    case USAGE_REPORTING_GATEWAY_ID:
      return isSetUsageReportingGatewayId();
    case QUALITY_OF_SERVICE:
      return isSetQualityOfService();
    case RESERVATION:
      return isSetReservation();
    case RESERVATION_START_TIME:
      return isSetReservationStartTime();
    case RESERVATION_END_TIME:
      return isSetReservationEndTime();
    case SSH_ACCOUNT_PROVISIONER:
      return isSetSshAccountProvisioner();
    case SSH_ACCOUNT_PROVISIONER_CONFIG:
      return isSetSshAccountProvisionerConfig();
    case SSH_ACCOUNT_PROVISIONER_ADDITIONAL_INFO:
      return isSetSshAccountProvisionerAdditionalInfo();
    }
    throw new java.lang.IllegalStateException();
  }

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

  public boolean equals(ComputeResourcePreference 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_overridebyAiravata = true;
    boolean that_present_overridebyAiravata = true;
    if (this_present_overridebyAiravata || that_present_overridebyAiravata) {
      if (!(this_present_overridebyAiravata && that_present_overridebyAiravata))
        return false;
      if (this.overridebyAiravata != that.overridebyAiravata)
        return false;
    }

    boolean this_present_loginUserName = true && this.isSetLoginUserName();
    boolean that_present_loginUserName = true && that.isSetLoginUserName();
    if (this_present_loginUserName || that_present_loginUserName) {
      if (!(this_present_loginUserName && that_present_loginUserName))
        return false;
      if (!this.loginUserName.equals(that.loginUserName))
        return false;
    }

    boolean this_present_preferredJobSubmissionProtocol = true && this.isSetPreferredJobSubmissionProtocol();
    boolean that_present_preferredJobSubmissionProtocol = true && that.isSetPreferredJobSubmissionProtocol();
    if (this_present_preferredJobSubmissionProtocol || that_present_preferredJobSubmissionProtocol) {
      if (!(this_present_preferredJobSubmissionProtocol && that_present_preferredJobSubmissionProtocol))
        return false;
      if (!this.preferredJobSubmissionProtocol.equals(that.preferredJobSubmissionProtocol))
        return false;
    }

    boolean this_present_preferredDataMovementProtocol = true && this.isSetPreferredDataMovementProtocol();
    boolean that_present_preferredDataMovementProtocol = true && that.isSetPreferredDataMovementProtocol();
    if (this_present_preferredDataMovementProtocol || that_present_preferredDataMovementProtocol) {
      if (!(this_present_preferredDataMovementProtocol && that_present_preferredDataMovementProtocol))
        return false;
      if (!this.preferredDataMovementProtocol.equals(that.preferredDataMovementProtocol))
        return false;
    }

    boolean this_present_preferredBatchQueue = true && this.isSetPreferredBatchQueue();
    boolean that_present_preferredBatchQueue = true && that.isSetPreferredBatchQueue();
    if (this_present_preferredBatchQueue || that_present_preferredBatchQueue) {
      if (!(this_present_preferredBatchQueue && that_present_preferredBatchQueue))
        return false;
      if (!this.preferredBatchQueue.equals(that.preferredBatchQueue))
        return false;
    }

    boolean this_present_scratchLocation = true && this.isSetScratchLocation();
    boolean that_present_scratchLocation = true && that.isSetScratchLocation();
    if (this_present_scratchLocation || that_present_scratchLocation) {
      if (!(this_present_scratchLocation && that_present_scratchLocation))
        return false;
      if (!this.scratchLocation.equals(that.scratchLocation))
        return false;
    }

    boolean this_present_allocationProjectNumber = true && this.isSetAllocationProjectNumber();
    boolean that_present_allocationProjectNumber = true && that.isSetAllocationProjectNumber();
    if (this_present_allocationProjectNumber || that_present_allocationProjectNumber) {
      if (!(this_present_allocationProjectNumber && that_present_allocationProjectNumber))
        return false;
      if (!this.allocationProjectNumber.equals(that.allocationProjectNumber))
        return false;
    }

    boolean this_present_resourceSpecificCredentialStoreToken = true && this.isSetResourceSpecificCredentialStoreToken();
    boolean that_present_resourceSpecificCredentialStoreToken = true && that.isSetResourceSpecificCredentialStoreToken();
    if (this_present_resourceSpecificCredentialStoreToken || that_present_resourceSpecificCredentialStoreToken) {
      if (!(this_present_resourceSpecificCredentialStoreToken && that_present_resourceSpecificCredentialStoreToken))
        return false;
      if (!this.resourceSpecificCredentialStoreToken.equals(that.resourceSpecificCredentialStoreToken))
        return false;
    }

    boolean this_present_usageReportingGatewayId = true && this.isSetUsageReportingGatewayId();
    boolean that_present_usageReportingGatewayId = true && that.isSetUsageReportingGatewayId();
    if (this_present_usageReportingGatewayId || that_present_usageReportingGatewayId) {
      if (!(this_present_usageReportingGatewayId && that_present_usageReportingGatewayId))
        return false;
      if (!this.usageReportingGatewayId.equals(that.usageReportingGatewayId))
        return false;
    }

    boolean this_present_qualityOfService = true && this.isSetQualityOfService();
    boolean that_present_qualityOfService = true && that.isSetQualityOfService();
    if (this_present_qualityOfService || that_present_qualityOfService) {
      if (!(this_present_qualityOfService && that_present_qualityOfService))
        return false;
      if (!this.qualityOfService.equals(that.qualityOfService))
        return false;
    }

    boolean this_present_reservation = true && this.isSetReservation();
    boolean that_present_reservation = true && that.isSetReservation();
    if (this_present_reservation || that_present_reservation) {
      if (!(this_present_reservation && that_present_reservation))
        return false;
      if (!this.reservation.equals(that.reservation))
        return false;
    }

    boolean this_present_reservationStartTime = true && this.isSetReservationStartTime();
    boolean that_present_reservationStartTime = true && that.isSetReservationStartTime();
    if (this_present_reservationStartTime || that_present_reservationStartTime) {
      if (!(this_present_reservationStartTime && that_present_reservationStartTime))
        return false;
      if (this.reservationStartTime != that.reservationStartTime)
        return false;
    }

    boolean this_present_reservationEndTime = true && this.isSetReservationEndTime();
    boolean that_present_reservationEndTime = true && that.isSetReservationEndTime();
    if (this_present_reservationEndTime || that_present_reservationEndTime) {
      if (!(this_present_reservationEndTime && that_present_reservationEndTime))
        return false;
      if (this.reservationEndTime != that.reservationEndTime)
        return false;
    }

    boolean this_present_sshAccountProvisioner = true && this.isSetSshAccountProvisioner();
    boolean that_present_sshAccountProvisioner = true && that.isSetSshAccountProvisioner();
    if (this_present_sshAccountProvisioner || that_present_sshAccountProvisioner) {
      if (!(this_present_sshAccountProvisioner && that_present_sshAccountProvisioner))
        return false;
      if (!this.sshAccountProvisioner.equals(that.sshAccountProvisioner))
        return false;
    }

    boolean this_present_sshAccountProvisionerConfig = true && this.isSetSshAccountProvisionerConfig();
    boolean that_present_sshAccountProvisionerConfig = true && that.isSetSshAccountProvisionerConfig();
    if (this_present_sshAccountProvisionerConfig || that_present_sshAccountProvisionerConfig) {
      if (!(this_present_sshAccountProvisionerConfig && that_present_sshAccountProvisionerConfig))
        return false;
      if (!this.sshAccountProvisionerConfig.equals(that.sshAccountProvisionerConfig))
        return false;
    }

    boolean this_present_sshAccountProvisionerAdditionalInfo = true && this.isSetSshAccountProvisionerAdditionalInfo();
    boolean that_present_sshAccountProvisionerAdditionalInfo = true && that.isSetSshAccountProvisionerAdditionalInfo();
    if (this_present_sshAccountProvisionerAdditionalInfo || that_present_sshAccountProvisionerAdditionalInfo) {
      if (!(this_present_sshAccountProvisionerAdditionalInfo && that_present_sshAccountProvisionerAdditionalInfo))
        return false;
      if (!this.sshAccountProvisionerAdditionalInfo.equals(that.sshAccountProvisionerAdditionalInfo))
        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 + ((overridebyAiravata) ? 131071 : 524287);

    hashCode = hashCode * 8191 + ((isSetLoginUserName()) ? 131071 : 524287);
    if (isSetLoginUserName())
      hashCode = hashCode * 8191 + loginUserName.hashCode();

    hashCode = hashCode * 8191 + ((isSetPreferredJobSubmissionProtocol()) ? 131071 : 524287);
    if (isSetPreferredJobSubmissionProtocol())
      hashCode = hashCode * 8191 + preferredJobSubmissionProtocol.getValue();

    hashCode = hashCode * 8191 + ((isSetPreferredDataMovementProtocol()) ? 131071 : 524287);
    if (isSetPreferredDataMovementProtocol())
      hashCode = hashCode * 8191 + preferredDataMovementProtocol.getValue();

    hashCode = hashCode * 8191 + ((isSetPreferredBatchQueue()) ? 131071 : 524287);
    if (isSetPreferredBatchQueue())
      hashCode = hashCode * 8191 + preferredBatchQueue.hashCode();

    hashCode = hashCode * 8191 + ((isSetScratchLocation()) ? 131071 : 524287);
    if (isSetScratchLocation())
      hashCode = hashCode * 8191 + scratchLocation.hashCode();

    hashCode = hashCode * 8191 + ((isSetAllocationProjectNumber()) ? 131071 : 524287);
    if (isSetAllocationProjectNumber())
      hashCode = hashCode * 8191 + allocationProjectNumber.hashCode();

    hashCode = hashCode * 8191 + ((isSetResourceSpecificCredentialStoreToken()) ? 131071 : 524287);
    if (isSetResourceSpecificCredentialStoreToken())
      hashCode = hashCode * 8191 + resourceSpecificCredentialStoreToken.hashCode();

    hashCode = hashCode * 8191 + ((isSetUsageReportingGatewayId()) ? 131071 : 524287);
    if (isSetUsageReportingGatewayId())
      hashCode = hashCode * 8191 + usageReportingGatewayId.hashCode();

    hashCode = hashCode * 8191 + ((isSetQualityOfService()) ? 131071 : 524287);
    if (isSetQualityOfService())
      hashCode = hashCode * 8191 + qualityOfService.hashCode();

    hashCode = hashCode * 8191 + ((isSetReservation()) ? 131071 : 524287);
    if (isSetReservation())
      hashCode = hashCode * 8191 + reservation.hashCode();

    hashCode = hashCode * 8191 + ((isSetReservationStartTime()) ? 131071 : 524287);
    if (isSetReservationStartTime())
      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(reservationStartTime);

    hashCode = hashCode * 8191 + ((isSetReservationEndTime()) ? 131071 : 524287);
    if (isSetReservationEndTime())
      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(reservationEndTime);

    hashCode = hashCode * 8191 + ((isSetSshAccountProvisioner()) ? 131071 : 524287);
    if (isSetSshAccountProvisioner())
      hashCode = hashCode * 8191 + sshAccountProvisioner.hashCode();

    hashCode = hashCode * 8191 + ((isSetSshAccountProvisionerConfig()) ? 131071 : 524287);
    if (isSetSshAccountProvisionerConfig())
      hashCode = hashCode * 8191 + sshAccountProvisionerConfig.hashCode();

    hashCode = hashCode * 8191 + ((isSetSshAccountProvisionerAdditionalInfo()) ? 131071 : 524287);
    if (isSetSshAccountProvisionerAdditionalInfo())
      hashCode = hashCode * 8191 + sshAccountProvisionerAdditionalInfo.hashCode();

    return hashCode;
  }

  @Override
  public int compareTo(ComputeResourcePreference 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(isSetOverridebyAiravata()).compareTo(other.isSetOverridebyAiravata());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetOverridebyAiravata()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.overridebyAiravata, other.overridebyAiravata);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetLoginUserName()).compareTo(other.isSetLoginUserName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetLoginUserName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.loginUserName, other.loginUserName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetPreferredJobSubmissionProtocol()).compareTo(other.isSetPreferredJobSubmissionProtocol());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetPreferredJobSubmissionProtocol()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.preferredJobSubmissionProtocol, other.preferredJobSubmissionProtocol);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetPreferredDataMovementProtocol()).compareTo(other.isSetPreferredDataMovementProtocol());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetPreferredDataMovementProtocol()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.preferredDataMovementProtocol, other.preferredDataMovementProtocol);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetPreferredBatchQueue()).compareTo(other.isSetPreferredBatchQueue());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetPreferredBatchQueue()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.preferredBatchQueue, other.preferredBatchQueue);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetScratchLocation()).compareTo(other.isSetScratchLocation());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetScratchLocation()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scratchLocation, other.scratchLocation);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetAllocationProjectNumber()).compareTo(other.isSetAllocationProjectNumber());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetAllocationProjectNumber()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.allocationProjectNumber, other.allocationProjectNumber);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetResourceSpecificCredentialStoreToken()).compareTo(other.isSetResourceSpecificCredentialStoreToken());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetResourceSpecificCredentialStoreToken()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.resourceSpecificCredentialStoreToken, other.resourceSpecificCredentialStoreToken);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetUsageReportingGatewayId()).compareTo(other.isSetUsageReportingGatewayId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetUsageReportingGatewayId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.usageReportingGatewayId, other.usageReportingGatewayId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetQualityOfService()).compareTo(other.isSetQualityOfService());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetQualityOfService()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.qualityOfService, other.qualityOfService);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetReservation()).compareTo(other.isSetReservation());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetReservation()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.reservation, other.reservation);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetReservationStartTime()).compareTo(other.isSetReservationStartTime());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetReservationStartTime()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.reservationStartTime, other.reservationStartTime);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetReservationEndTime()).compareTo(other.isSetReservationEndTime());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetReservationEndTime()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.reservationEndTime, other.reservationEndTime);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetSshAccountProvisioner()).compareTo(other.isSetSshAccountProvisioner());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetSshAccountProvisioner()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sshAccountProvisioner, other.sshAccountProvisioner);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetSshAccountProvisionerConfig()).compareTo(other.isSetSshAccountProvisionerConfig());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetSshAccountProvisionerConfig()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sshAccountProvisionerConfig, other.sshAccountProvisionerConfig);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetSshAccountProvisionerAdditionalInfo()).compareTo(other.isSetSshAccountProvisionerAdditionalInfo());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetSshAccountProvisionerAdditionalInfo()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sshAccountProvisionerAdditionalInfo, other.sshAccountProvisionerAdditionalInfo);
      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("ComputeResourcePreference(");
    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("overridebyAiravata:");
    sb.append(this.overridebyAiravata);
    first = false;
    if (isSetLoginUserName()) {
      if (!first) sb.append(", ");
      sb.append("loginUserName:");
      if (this.loginUserName == null) {
        sb.append("null");
      } else {
        sb.append(this.loginUserName);
      }
      first = false;
    }
    if (isSetPreferredJobSubmissionProtocol()) {
      if (!first) sb.append(", ");
      sb.append("preferredJobSubmissionProtocol:");
      if (this.preferredJobSubmissionProtocol == null) {
        sb.append("null");
      } else {
        sb.append(this.preferredJobSubmissionProtocol);
      }
      first = false;
    }
    if (isSetPreferredDataMovementProtocol()) {
      if (!first) sb.append(", ");
      sb.append("preferredDataMovementProtocol:");
      if (this.preferredDataMovementProtocol == null) {
        sb.append("null");
      } else {
        sb.append(this.preferredDataMovementProtocol);
      }
      first = false;
    }
    if (isSetPreferredBatchQueue()) {
      if (!first) sb.append(", ");
      sb.append("preferredBatchQueue:");
      if (this.preferredBatchQueue == null) {
        sb.append("null");
      } else {
        sb.append(this.preferredBatchQueue);
      }
      first = false;
    }
    if (isSetScratchLocation()) {
      if (!first) sb.append(", ");
      sb.append("scratchLocation:");
      if (this.scratchLocation == null) {
        sb.append("null");
      } else {
        sb.append(this.scratchLocation);
      }
      first = false;
    }
    if (isSetAllocationProjectNumber()) {
      if (!first) sb.append(", ");
      sb.append("allocationProjectNumber:");
      if (this.allocationProjectNumber == null) {
        sb.append("null");
      } else {
        sb.append(this.allocationProjectNumber);
      }
      first = false;
    }
    if (isSetResourceSpecificCredentialStoreToken()) {
      if (!first) sb.append(", ");
      sb.append("resourceSpecificCredentialStoreToken:");
      if (this.resourceSpecificCredentialStoreToken == null) {
        sb.append("null");
      } else {
        sb.append(this.resourceSpecificCredentialStoreToken);
      }
      first = false;
    }
    if (isSetUsageReportingGatewayId()) {
      if (!first) sb.append(", ");
      sb.append("usageReportingGatewayId:");
      if (this.usageReportingGatewayId == null) {
        sb.append("null");
      } else {
        sb.append(this.usageReportingGatewayId);
      }
      first = false;
    }
    if (isSetQualityOfService()) {
      if (!first) sb.append(", ");
      sb.append("qualityOfService:");
      if (this.qualityOfService == null) {
        sb.append("null");
      } else {
        sb.append(this.qualityOfService);
      }
      first = false;
    }
    if (isSetReservation()) {
      if (!first) sb.append(", ");
      sb.append("reservation:");
      if (this.reservation == null) {
        sb.append("null");
      } else {
        sb.append(this.reservation);
      }
      first = false;
    }
    if (isSetReservationStartTime()) {
      if (!first) sb.append(", ");
      sb.append("reservationStartTime:");
      sb.append(this.reservationStartTime);
      first = false;
    }
    if (isSetReservationEndTime()) {
      if (!first) sb.append(", ");
      sb.append("reservationEndTime:");
      sb.append(this.reservationEndTime);
      first = false;
    }
    if (isSetSshAccountProvisioner()) {
      if (!first) sb.append(", ");
      sb.append("sshAccountProvisioner:");
      if (this.sshAccountProvisioner == null) {
        sb.append("null");
      } else {
        sb.append(this.sshAccountProvisioner);
      }
      first = false;
    }
    if (isSetSshAccountProvisionerConfig()) {
      if (!first) sb.append(", ");
      sb.append("sshAccountProvisionerConfig:");
      if (this.sshAccountProvisionerConfig == null) {
        sb.append("null");
      } else {
        sb.append(this.sshAccountProvisionerConfig);
      }
      first = false;
    }
    if (isSetSshAccountProvisionerAdditionalInfo()) {
      if (!first) sb.append(", ");
      sb.append("sshAccountProvisionerAdditionalInfo:");
      if (this.sshAccountProvisionerAdditionalInfo == null) {
        sb.append("null");
      } else {
        sb.append(this.sshAccountProvisionerAdditionalInfo);
      }
      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 (!isSetOverridebyAiravata()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'overridebyAiravata' 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 ComputeResourcePreferenceStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public ComputeResourcePreferenceStandardScheme getScheme() {
      return new ComputeResourcePreferenceStandardScheme();
    }
  }

  private static class ComputeResourcePreferenceStandardScheme extends org.apache.thrift.scheme.StandardScheme<ComputeResourcePreference> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, ComputeResourcePreference 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: // OVERRIDEBY_AIRAVATA
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.overridebyAiravata = iprot.readBool();
              struct.setOverridebyAiravataIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // LOGIN_USER_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.loginUserName = iprot.readString();
              struct.setLoginUserNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // PREFERRED_JOB_SUBMISSION_PROTOCOL
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.preferredJobSubmissionProtocol = org.apache.airavata.model.appcatalog.computeresource.JobSubmissionProtocol.findByValue(iprot.readI32());
              struct.setPreferredJobSubmissionProtocolIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // PREFERRED_DATA_MOVEMENT_PROTOCOL
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.preferredDataMovementProtocol = org.apache.airavata.model.data.movement.DataMovementProtocol.findByValue(iprot.readI32());
              struct.setPreferredDataMovementProtocolIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // PREFERRED_BATCH_QUEUE
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.preferredBatchQueue = iprot.readString();
              struct.setPreferredBatchQueueIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // SCRATCH_LOCATION
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.scratchLocation = iprot.readString();
              struct.setScratchLocationIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // ALLOCATION_PROJECT_NUMBER
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.allocationProjectNumber = iprot.readString();
              struct.setAllocationProjectNumberIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // RESOURCE_SPECIFIC_CREDENTIAL_STORE_TOKEN
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.resourceSpecificCredentialStoreToken = iprot.readString();
              struct.setResourceSpecificCredentialStoreTokenIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // USAGE_REPORTING_GATEWAY_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.usageReportingGatewayId = iprot.readString();
              struct.setUsageReportingGatewayIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 11: // QUALITY_OF_SERVICE
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.qualityOfService = iprot.readString();
              struct.setQualityOfServiceIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 12: // RESERVATION
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.reservation = iprot.readString();
              struct.setReservationIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 13: // RESERVATION_START_TIME
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.reservationStartTime = iprot.readI64();
              struct.setReservationStartTimeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 14: // RESERVATION_END_TIME
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.reservationEndTime = iprot.readI64();
              struct.setReservationEndTimeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 15: // SSH_ACCOUNT_PROVISIONER
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.sshAccountProvisioner = iprot.readString();
              struct.setSshAccountProvisionerIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 16: // SSH_ACCOUNT_PROVISIONER_CONFIG
            if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
              {
                org.apache.thrift.protocol.TMap _map0 = iprot.readMapBegin();
                struct.sshAccountProvisionerConfig = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map0.size);
                java.lang.String _key1;
                java.lang.String _val2;
                for (int _i3 = 0; _i3 < _map0.size; ++_i3)
                {
                  _key1 = iprot.readString();
                  _val2 = iprot.readString();
                  struct.sshAccountProvisionerConfig.put(_key1, _val2);
                }
                iprot.readMapEnd();
              }
              struct.setSshAccountProvisionerConfigIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 17: // SSH_ACCOUNT_PROVISIONER_ADDITIONAL_INFO
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.sshAccountProvisionerAdditionalInfo = iprot.readString();
              struct.setSshAccountProvisionerAdditionalInfoIsSet(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, ComputeResourcePreference 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();
      }
      oprot.writeFieldBegin(OVERRIDEBY_AIRAVATA_FIELD_DESC);
      oprot.writeBool(struct.overridebyAiravata);
      oprot.writeFieldEnd();
      if (struct.loginUserName != null) {
        if (struct.isSetLoginUserName()) {
          oprot.writeFieldBegin(LOGIN_USER_NAME_FIELD_DESC);
          oprot.writeString(struct.loginUserName);
          oprot.writeFieldEnd();
        }
      }
      if (struct.preferredJobSubmissionProtocol != null) {
        if (struct.isSetPreferredJobSubmissionProtocol()) {
          oprot.writeFieldBegin(PREFERRED_JOB_SUBMISSION_PROTOCOL_FIELD_DESC);
          oprot.writeI32(struct.preferredJobSubmissionProtocol.getValue());
          oprot.writeFieldEnd();
        }
      }
      if (struct.preferredDataMovementProtocol != null) {
        if (struct.isSetPreferredDataMovementProtocol()) {
          oprot.writeFieldBegin(PREFERRED_DATA_MOVEMENT_PROTOCOL_FIELD_DESC);
          oprot.writeI32(struct.preferredDataMovementProtocol.getValue());
          oprot.writeFieldEnd();
        }
      }
      if (struct.preferredBatchQueue != null) {
        if (struct.isSetPreferredBatchQueue()) {
          oprot.writeFieldBegin(PREFERRED_BATCH_QUEUE_FIELD_DESC);
          oprot.writeString(struct.preferredBatchQueue);
          oprot.writeFieldEnd();
        }
      }
      if (struct.scratchLocation != null) {
        if (struct.isSetScratchLocation()) {
          oprot.writeFieldBegin(SCRATCH_LOCATION_FIELD_DESC);
          oprot.writeString(struct.scratchLocation);
          oprot.writeFieldEnd();
        }
      }
      if (struct.allocationProjectNumber != null) {
        if (struct.isSetAllocationProjectNumber()) {
          oprot.writeFieldBegin(ALLOCATION_PROJECT_NUMBER_FIELD_DESC);
          oprot.writeString(struct.allocationProjectNumber);
          oprot.writeFieldEnd();
        }
      }
      if (struct.resourceSpecificCredentialStoreToken != null) {
        if (struct.isSetResourceSpecificCredentialStoreToken()) {
          oprot.writeFieldBegin(RESOURCE_SPECIFIC_CREDENTIAL_STORE_TOKEN_FIELD_DESC);
          oprot.writeString(struct.resourceSpecificCredentialStoreToken);
          oprot.writeFieldEnd();
        }
      }
      if (struct.usageReportingGatewayId != null) {
        if (struct.isSetUsageReportingGatewayId()) {
          oprot.writeFieldBegin(USAGE_REPORTING_GATEWAY_ID_FIELD_DESC);
          oprot.writeString(struct.usageReportingGatewayId);
          oprot.writeFieldEnd();
        }
      }
      if (struct.qualityOfService != null) {
        if (struct.isSetQualityOfService()) {
          oprot.writeFieldBegin(QUALITY_OF_SERVICE_FIELD_DESC);
          oprot.writeString(struct.qualityOfService);
          oprot.writeFieldEnd();
        }
      }
      if (struct.reservation != null) {
        if (struct.isSetReservation()) {
          oprot.writeFieldBegin(RESERVATION_FIELD_DESC);
          oprot.writeString(struct.reservation);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetReservationStartTime()) {
        oprot.writeFieldBegin(RESERVATION_START_TIME_FIELD_DESC);
        oprot.writeI64(struct.reservationStartTime);
        oprot.writeFieldEnd();
      }
      if (struct.isSetReservationEndTime()) {
        oprot.writeFieldBegin(RESERVATION_END_TIME_FIELD_DESC);
        oprot.writeI64(struct.reservationEndTime);
        oprot.writeFieldEnd();
      }
      if (struct.sshAccountProvisioner != null) {
        if (struct.isSetSshAccountProvisioner()) {
          oprot.writeFieldBegin(SSH_ACCOUNT_PROVISIONER_FIELD_DESC);
          oprot.writeString(struct.sshAccountProvisioner);
          oprot.writeFieldEnd();
        }
      }
      if (struct.sshAccountProvisionerConfig != null) {
        if (struct.isSetSshAccountProvisionerConfig()) {
          oprot.writeFieldBegin(SSH_ACCOUNT_PROVISIONER_CONFIG_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.sshAccountProvisionerConfig.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter4 : struct.sshAccountProvisionerConfig.entrySet())
            {
              oprot.writeString(_iter4.getKey());
              oprot.writeString(_iter4.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.sshAccountProvisionerAdditionalInfo != null) {
        if (struct.isSetSshAccountProvisionerAdditionalInfo()) {
          oprot.writeFieldBegin(SSH_ACCOUNT_PROVISIONER_ADDITIONAL_INFO_FIELD_DESC);
          oprot.writeString(struct.sshAccountProvisionerAdditionalInfo);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

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

  private static class ComputeResourcePreferenceTupleScheme extends org.apache.thrift.scheme.TupleScheme<ComputeResourcePreference> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, ComputeResourcePreference struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      oprot.writeString(struct.computeResourceId);
      oprot.writeBool(struct.overridebyAiravata);
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.isSetLoginUserName()) {
        optionals.set(0);
      }
      if (struct.isSetPreferredJobSubmissionProtocol()) {
        optionals.set(1);
      }
      if (struct.isSetPreferredDataMovementProtocol()) {
        optionals.set(2);
      }
      if (struct.isSetPreferredBatchQueue()) {
        optionals.set(3);
      }
      if (struct.isSetScratchLocation()) {
        optionals.set(4);
      }
      if (struct.isSetAllocationProjectNumber()) {
        optionals.set(5);
      }
      if (struct.isSetResourceSpecificCredentialStoreToken()) {
        optionals.set(6);
      }
      if (struct.isSetUsageReportingGatewayId()) {
        optionals.set(7);
      }
      if (struct.isSetQualityOfService()) {
        optionals.set(8);
      }
      if (struct.isSetReservation()) {
        optionals.set(9);
      }
      if (struct.isSetReservationStartTime()) {
        optionals.set(10);
      }
      if (struct.isSetReservationEndTime()) {
        optionals.set(11);
      }
      if (struct.isSetSshAccountProvisioner()) {
        optionals.set(12);
      }
      if (struct.isSetSshAccountProvisionerConfig()) {
        optionals.set(13);
      }
      if (struct.isSetSshAccountProvisionerAdditionalInfo()) {
        optionals.set(14);
      }
      oprot.writeBitSet(optionals, 15);
      if (struct.isSetLoginUserName()) {
        oprot.writeString(struct.loginUserName);
      }
      if (struct.isSetPreferredJobSubmissionProtocol()) {
        oprot.writeI32(struct.preferredJobSubmissionProtocol.getValue());
      }
      if (struct.isSetPreferredDataMovementProtocol()) {
        oprot.writeI32(struct.preferredDataMovementProtocol.getValue());
      }
      if (struct.isSetPreferredBatchQueue()) {
        oprot.writeString(struct.preferredBatchQueue);
      }
      if (struct.isSetScratchLocation()) {
        oprot.writeString(struct.scratchLocation);
      }
      if (struct.isSetAllocationProjectNumber()) {
        oprot.writeString(struct.allocationProjectNumber);
      }
      if (struct.isSetResourceSpecificCredentialStoreToken()) {
        oprot.writeString(struct.resourceSpecificCredentialStoreToken);
      }
      if (struct.isSetUsageReportingGatewayId()) {
        oprot.writeString(struct.usageReportingGatewayId);
      }
      if (struct.isSetQualityOfService()) {
        oprot.writeString(struct.qualityOfService);
      }
      if (struct.isSetReservation()) {
        oprot.writeString(struct.reservation);
      }
      if (struct.isSetReservationStartTime()) {
        oprot.writeI64(struct.reservationStartTime);
      }
      if (struct.isSetReservationEndTime()) {
        oprot.writeI64(struct.reservationEndTime);
      }
      if (struct.isSetSshAccountProvisioner()) {
        oprot.writeString(struct.sshAccountProvisioner);
      }
      if (struct.isSetSshAccountProvisionerConfig()) {
        {
          oprot.writeI32(struct.sshAccountProvisionerConfig.size());
          for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter5 : struct.sshAccountProvisionerConfig.entrySet())
          {
            oprot.writeString(_iter5.getKey());
            oprot.writeString(_iter5.getValue());
          }
        }
      }
      if (struct.isSetSshAccountProvisionerAdditionalInfo()) {
        oprot.writeString(struct.sshAccountProvisionerAdditionalInfo);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, ComputeResourcePreference 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.overridebyAiravata = iprot.readBool();
      struct.setOverridebyAiravataIsSet(true);
      java.util.BitSet incoming = iprot.readBitSet(15);
      if (incoming.get(0)) {
        struct.loginUserName = iprot.readString();
        struct.setLoginUserNameIsSet(true);
      }
      if (incoming.get(1)) {
        struct.preferredJobSubmissionProtocol = org.apache.airavata.model.appcatalog.computeresource.JobSubmissionProtocol.findByValue(iprot.readI32());
        struct.setPreferredJobSubmissionProtocolIsSet(true);
      }
      if (incoming.get(2)) {
        struct.preferredDataMovementProtocol = org.apache.airavata.model.data.movement.DataMovementProtocol.findByValue(iprot.readI32());
        struct.setPreferredDataMovementProtocolIsSet(true);
      }
      if (incoming.get(3)) {
        struct.preferredBatchQueue = iprot.readString();
        struct.setPreferredBatchQueueIsSet(true);
      }
      if (incoming.get(4)) {
        struct.scratchLocation = iprot.readString();
        struct.setScratchLocationIsSet(true);
      }
      if (incoming.get(5)) {
        struct.allocationProjectNumber = iprot.readString();
        struct.setAllocationProjectNumberIsSet(true);
      }
      if (incoming.get(6)) {
        struct.resourceSpecificCredentialStoreToken = iprot.readString();
        struct.setResourceSpecificCredentialStoreTokenIsSet(true);
      }
      if (incoming.get(7)) {
        struct.usageReportingGatewayId = iprot.readString();
        struct.setUsageReportingGatewayIdIsSet(true);
      }
      if (incoming.get(8)) {
        struct.qualityOfService = iprot.readString();
        struct.setQualityOfServiceIsSet(true);
      }
      if (incoming.get(9)) {
        struct.reservation = iprot.readString();
        struct.setReservationIsSet(true);
      }
      if (incoming.get(10)) {
        struct.reservationStartTime = iprot.readI64();
        struct.setReservationStartTimeIsSet(true);
      }
      if (incoming.get(11)) {
        struct.reservationEndTime = iprot.readI64();
        struct.setReservationEndTimeIsSet(true);
      }
      if (incoming.get(12)) {
        struct.sshAccountProvisioner = iprot.readString();
        struct.setSshAccountProvisionerIsSet(true);
      }
      if (incoming.get(13)) {
        {
          org.apache.thrift.protocol.TMap _map6 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.sshAccountProvisionerConfig = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map6.size);
          java.lang.String _key7;
          java.lang.String _val8;
          for (int _i9 = 0; _i9 < _map6.size; ++_i9)
          {
            _key7 = iprot.readString();
            _val8 = iprot.readString();
            struct.sshAccountProvisionerConfig.put(_key7, _val8);
          }
        }
        struct.setSshAccountProvisionerConfigIsSet(true);
      }
      if (incoming.get(14)) {
        struct.sshAccountProvisionerAdditionalInfo = iprot.readString();
        struct.setSshAccountProvisionerAdditionalInfoIsSet(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();
  }
}

