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

/**
 * 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.
 * 
 */
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.18.1)")
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 @org.apache.thrift.annotation.Nullable java.lang.String computeResourceId; // required
  private boolean overridebyAiravata; // required
  private @org.apache.thrift.annotation.Nullable java.lang.String loginUserName; // optional
  private @org.apache.thrift.annotation.Nullable org.apache.airavata.model.appcatalog.computeresource.JobSubmissionProtocol preferredJobSubmissionProtocol; // optional
  private @org.apache.thrift.annotation.Nullable org.apache.airavata.model.data.movement.DataMovementProtocol preferredDataMovementProtocol; // optional
  private @org.apache.thrift.annotation.Nullable java.lang.String preferredBatchQueue; // optional
  private @org.apache.thrift.annotation.Nullable java.lang.String scratchLocation; // optional
  private @org.apache.thrift.annotation.Nullable java.lang.String allocationProjectNumber; // optional
  private @org.apache.thrift.annotation.Nullable java.lang.String resourceSpecificCredentialStoreToken; // optional
  private @org.apache.thrift.annotation.Nullable java.lang.String usageReportingGatewayId; // optional
  private @org.apache.thrift.annotation.Nullable java.lang.String qualityOfService; // optional
  private @org.apache.thrift.annotation.Nullable java.lang.String reservation; // optional
  private long reservationStartTime; // optional
  private long reservationEndTime; // optional
  private @org.apache.thrift.annotation.Nullable java.lang.String sshAccountProvisioner; // optional
  private @org.apache.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.String> sshAccountProvisionerConfig; // optional
  private @org.apache.thrift.annotation.Nullable 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.
     */
    @org.apache.thrift.annotation.Nullable
    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.
     */
    @org.apache.thrift.annotation.Nullable
    public static _Fields findByName(java.lang.String name) {
      return byName.get(name);
    }

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

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

    @Override
    public short getThriftFieldId() {
      return _thriftId;
    }

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

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

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getComputeResourceId() {
    return this.computeResourceId;
  }

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

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getLoginUserName() {
    return this.loginUserName;
  }

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

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getPreferredBatchQueue() {
    return this.preferredBatchQueue;
  }

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

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getScratchLocation() {
    return this.scratchLocation;
  }

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

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getAllocationProjectNumber() {
    return this.allocationProjectNumber;
  }

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

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getResourceSpecificCredentialStoreToken() {
    return this.resourceSpecificCredentialStoreToken;
  }

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

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getUsageReportingGatewayId() {
    return this.usageReportingGatewayId;
  }

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

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getQualityOfService() {
    return this.qualityOfService;
  }

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

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getReservation() {
    return this.reservation;
  }

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

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getSshAccountProvisioner() {
    return this.sshAccountProvisioner;
  }

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

  @org.apache.thrift.annotation.Nullable
  public java.util.Map<java.lang.String,java.lang.String> getSshAccountProvisionerConfig() {
    return this.sshAccountProvisionerConfig;
  }

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

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getSshAccountProvisionerAdditionalInfo() {
    return this.sshAccountProvisionerAdditionalInfo;
  }

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

  @Override
  public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable 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;

    }
  }

  @org.apache.thrift.annotation.Nullable
  @Override
  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 */
  @Override
  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 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.compare(isSetComputeResourceId(), 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.compare(isSetOverridebyAiravata(), 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.compare(isSetLoginUserName(), 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.compare(isSetPreferredJobSubmissionProtocol(), 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.compare(isSetPreferredDataMovementProtocol(), 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.compare(isSetPreferredBatchQueue(), 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.compare(isSetScratchLocation(), 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.compare(isSetAllocationProjectNumber(), 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.compare(isSetResourceSpecificCredentialStoreToken(), 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.compare(isSetUsageReportingGatewayId(), 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.compare(isSetQualityOfService(), 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.compare(isSetReservation(), 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.compare(isSetReservationStartTime(), 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.compare(isSetReservationEndTime(), 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.compare(isSetSshAccountProvisioner(), 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.compare(isSetSshAccountProvisionerConfig(), 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.compare(isSetSshAccountProvisionerAdditionalInfo(), 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;
  }

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

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

  @Override
  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 {
    @Override
    public ComputeResourcePreferenceStandardScheme getScheme() {
      return new ComputeResourcePreferenceStandardScheme();
    }
  }

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

    @Override
    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);
                @org.apache.thrift.annotation.Nullable java.lang.String _key1;
                @org.apache.thrift.annotation.Nullable 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();
    }

    @Override
    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 {
    @Override
    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 = iprot.readMapBegin(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING); 
          struct.sshAccountProvisionerConfig = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map6.size);
          @org.apache.thrift.annotation.Nullable java.lang.String _key7;
          @org.apache.thrift.annotation.Nullable 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();
  }
}

