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

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

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

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

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

  private String computeResourceId; // required
  private boolean overridebyAiravata; // required
  private String loginUserName; // optional
  private org.apache.airavata.model.appcatalog.computeresource.JobSubmissionProtocol preferredJobSubmissionProtocol; // optional
  private org.apache.airavata.model.data.movement.DataMovementProtocol preferredDataMovementProtocol; // optional
  private String preferredBatchQueue; // optional
  private String scratchLocation; // optional
  private String allocationProjectNumber; // optional
  private String resourceSpecificCredentialStoreToken; // optional
  private String usageReportingGatewayId; // 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");

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

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

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

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

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

    private final short _thriftId;
    private final String _fieldName;

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

    public short getThriftFieldId() {
      return _thriftId;
    }

    public String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final int __OVERRIDEBYAIRAVATA_ISSET_ID = 0;
  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};
  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.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)));
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ComputeResourcePreference.class, metaDataMap);
  }

  public ComputeResourcePreference() {
    this.overridebyAiravata = true;

  }

  public ComputeResourcePreference(
    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;
    }
  }

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

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

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

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

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

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

  public boolean isOverridebyAiravata() {
    return this.overridebyAiravata;
  }

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

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

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

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

  public void setLoginUserName(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 String getPreferredBatchQueue() {
    return this.preferredBatchQueue;
  }

  public void setPreferredBatchQueue(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 String getScratchLocation() {
    return this.scratchLocation;
  }

  public void setScratchLocation(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 String getAllocationProjectNumber() {
    return this.allocationProjectNumber;
  }

  public void setAllocationProjectNumber(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 String getResourceSpecificCredentialStoreToken() {
    return this.resourceSpecificCredentialStoreToken;
  }

  public void setResourceSpecificCredentialStoreToken(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 String getUsageReportingGatewayId() {
    return this.usageReportingGatewayId;
  }

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

    case OVERRIDEBY_AIRAVATA:
      if (value == null) {
        unsetOverridebyAiravata();
      } else {
        setOverridebyAiravata((Boolean)value);
      }
      break;

    case LOGIN_USER_NAME:
      if (value == null) {
        unsetLoginUserName();
      } else {
        setLoginUserName((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((String)value);
      }
      break;

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

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

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

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

    }
  }

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

    }
    throw new IllegalStateException();
  }

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

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

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

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

    return true;
  }

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

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

    boolean present_overridebyAiravata = true;
    list.add(present_overridebyAiravata);
    if (present_overridebyAiravata)
      list.add(overridebyAiravata);

    boolean present_loginUserName = true && (isSetLoginUserName());
    list.add(present_loginUserName);
    if (present_loginUserName)
      list.add(loginUserName);

    boolean present_preferredJobSubmissionProtocol = true && (isSetPreferredJobSubmissionProtocol());
    list.add(present_preferredJobSubmissionProtocol);
    if (present_preferredJobSubmissionProtocol)
      list.add(preferredJobSubmissionProtocol.getValue());

    boolean present_preferredDataMovementProtocol = true && (isSetPreferredDataMovementProtocol());
    list.add(present_preferredDataMovementProtocol);
    if (present_preferredDataMovementProtocol)
      list.add(preferredDataMovementProtocol.getValue());

    boolean present_preferredBatchQueue = true && (isSetPreferredBatchQueue());
    list.add(present_preferredBatchQueue);
    if (present_preferredBatchQueue)
      list.add(preferredBatchQueue);

    boolean present_scratchLocation = true && (isSetScratchLocation());
    list.add(present_scratchLocation);
    if (present_scratchLocation)
      list.add(scratchLocation);

    boolean present_allocationProjectNumber = true && (isSetAllocationProjectNumber());
    list.add(present_allocationProjectNumber);
    if (present_allocationProjectNumber)
      list.add(allocationProjectNumber);

    boolean present_resourceSpecificCredentialStoreToken = true && (isSetResourceSpecificCredentialStoreToken());
    list.add(present_resourceSpecificCredentialStoreToken);
    if (present_resourceSpecificCredentialStoreToken)
      list.add(resourceSpecificCredentialStoreToken);

    boolean present_usageReportingGatewayId = true && (isSetUsageReportingGatewayId());
    list.add(present_usageReportingGatewayId);
    if (present_usageReportingGatewayId)
      list.add(usageReportingGatewayId);

    return list.hashCode();
  }

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

    int lastComparison = 0;

    lastComparison = Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetComputeResourceId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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;
      }
    }
    return 0;
  }

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

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

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

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

  private static class ComputeResourcePreferenceStandardScheme extends 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;
          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();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class ComputeResourcePreferenceTupleSchemeFactory implements SchemeFactory {
    public ComputeResourcePreferenceTupleScheme getScheme() {
      return new ComputeResourcePreferenceTupleScheme();
    }
  }

  private static class ComputeResourcePreferenceTupleScheme extends TupleScheme<ComputeResourcePreference> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, ComputeResourcePreference struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      oprot.writeString(struct.computeResourceId);
      oprot.writeBool(struct.overridebyAiravata);
      BitSet optionals = new 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);
      }
      oprot.writeBitSet(optionals, 8);
      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);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, ComputeResourcePreference struct) throws org.apache.thrift.TException {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      struct.computeResourceId = iprot.readString();
      struct.setComputeResourceIdIsSet(true);
      struct.overridebyAiravata = iprot.readBool();
      struct.setOverridebyAiravataIsSet(true);
      BitSet incoming = iprot.readBitSet(8);
      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);
      }
    }
  }

}

