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

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

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
/**
 * User specific preferences for a Computer Resource
 * 
 * computeResourceId:
 *   Corelate the preference to a compute resource.
 * 
 * 
 * loginUserName:
 *   If turned true, Airavata will override the preferences of better alternatives exist.
 * 
 * 
 * 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.
 * 
 * validated:
 *  If true the the configuration has been validated in the sense that the username and credential can be used to
 *  login to the remote host and the scratchLocation is a valid location that the user has permission to write to.
 *  Should be treated as read-only and only mutated by Airavata middleware.
 * 
 */
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
public class UserComputeResourcePreference implements org.apache.thrift.TBase<UserComputeResourcePreference, UserComputeResourcePreference._Fields>, java.io.Serializable, Cloneable, Comparable<UserComputeResourcePreference> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("UserComputeResourcePreference");

  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 LOGIN_USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("loginUserName", org.apache.thrift.protocol.TType.STRING, (short)2);
  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)3);
  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)4);
  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)5);
  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)6);
  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)7);
  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)8);
  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)9);
  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)10);
  private static final org.apache.thrift.protocol.TField VALIDATED_FIELD_DESC = new org.apache.thrift.protocol.TField("validated", org.apache.thrift.protocol.TType.BOOL, (short)11);

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

  private java.lang.String computeResourceId; // required
  private java.lang.String loginUserName; // optional
  private java.lang.String preferredBatchQueue; // optional
  private java.lang.String scratchLocation; // optional
  private java.lang.String allocationProjectNumber; // optional
  private java.lang.String resourceSpecificCredentialStoreToken; // optional
  private java.lang.String qualityOfService; // optional
  private java.lang.String reservation; // optional
  private long reservationStartTime; // optional
  private long reservationEndTime; // optional
  private boolean validated; // 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"),
    LOGIN_USER_NAME((short)2, "loginUserName"),
    PREFERRED_BATCH_QUEUE((short)3, "preferredBatchQueue"),
    SCRATCH_LOCATION((short)4, "scratchLocation"),
    ALLOCATION_PROJECT_NUMBER((short)5, "allocationProjectNumber"),
    RESOURCE_SPECIFIC_CREDENTIAL_STORE_TOKEN((short)6, "resourceSpecificCredentialStoreToken"),
    QUALITY_OF_SERVICE((short)7, "qualityOfService"),
    RESERVATION((short)8, "reservation"),
    RESERVATION_START_TIME((short)9, "reservationStartTime"),
    RESERVATION_END_TIME((short)10, "reservationEndTime"),
    VALIDATED((short)11, "validated");

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

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

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // COMPUTE_RESOURCE_ID
          return COMPUTE_RESOURCE_ID;
        case 2: // LOGIN_USER_NAME
          return LOGIN_USER_NAME;
        case 3: // PREFERRED_BATCH_QUEUE
          return PREFERRED_BATCH_QUEUE;
        case 4: // SCRATCH_LOCATION
          return SCRATCH_LOCATION;
        case 5: // ALLOCATION_PROJECT_NUMBER
          return ALLOCATION_PROJECT_NUMBER;
        case 6: // RESOURCE_SPECIFIC_CREDENTIAL_STORE_TOKEN
          return RESOURCE_SPECIFIC_CREDENTIAL_STORE_TOKEN;
        case 7: // QUALITY_OF_SERVICE
          return QUALITY_OF_SERVICE;
        case 8: // RESERVATION
          return RESERVATION;
        case 9: // RESERVATION_START_TIME
          return RESERVATION_START_TIME;
        case 10: // RESERVATION_END_TIME
          return RESERVATION_END_TIME;
        case 11: // VALIDATED
          return VALIDATED;
        default:
          return null;
      }
    }

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

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

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

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

    public short getThriftFieldId() {
      return _thriftId;
    }

    public java.lang.String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final int __RESERVATIONSTARTTIME_ISSET_ID = 0;
  private static final int __RESERVATIONENDTIME_ISSET_ID = 1;
  private static final int __VALIDATED_ISSET_ID = 2;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.LOGIN_USER_NAME,_Fields.PREFERRED_BATCH_QUEUE,_Fields.SCRATCH_LOCATION,_Fields.ALLOCATION_PROJECT_NUMBER,_Fields.RESOURCE_SPECIFIC_CREDENTIAL_STORE_TOKEN,_Fields.QUALITY_OF_SERVICE,_Fields.RESERVATION,_Fields.RESERVATION_START_TIME,_Fields.RESERVATION_END_TIME,_Fields.VALIDATED};
  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.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_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.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.VALIDATED, new org.apache.thrift.meta_data.FieldMetaData("validated", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(UserComputeResourcePreference.class, metaDataMap);
  }

  public UserComputeResourcePreference() {
    this.validated = false;

  }

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

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public UserComputeResourcePreference(UserComputeResourcePreference other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetComputeResourceId()) {
      this.computeResourceId = other.computeResourceId;
    }
    if (other.isSetLoginUserName()) {
      this.loginUserName = other.loginUserName;
    }
    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.isSetQualityOfService()) {
      this.qualityOfService = other.qualityOfService;
    }
    if (other.isSetReservation()) {
      this.reservation = other.reservation;
    }
    this.reservationStartTime = other.reservationStartTime;
    this.reservationEndTime = other.reservationEndTime;
    this.validated = other.validated;
  }

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

  @Override
  public void clear() {
    this.computeResourceId = null;
    this.loginUserName = null;
    this.preferredBatchQueue = null;
    this.scratchLocation = null;
    this.allocationProjectNumber = null;
    this.resourceSpecificCredentialStoreToken = null;
    this.qualityOfService = null;
    this.reservation = null;
    setReservationStartTimeIsSet(false);
    this.reservationStartTime = 0;
    setReservationEndTimeIsSet(false);
    this.reservationEndTime = 0;
    this.validated = false;

  }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  public boolean isValidated() {
    return this.validated;
  }

  public void setValidated(boolean validated) {
    this.validated = validated;
    setValidatedIsSet(true);
  }

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

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

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

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

    case LOGIN_USER_NAME:
      if (value == null) {
        unsetLoginUserName();
      } else {
        setLoginUserName((java.lang.String)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 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 VALIDATED:
      if (value == null) {
        unsetValidated();
      } else {
        setValidated((java.lang.Boolean)value);
      }
      break;

    }
  }

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

    case LOGIN_USER_NAME:
      return getLoginUserName();

    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 QUALITY_OF_SERVICE:
      return getQualityOfService();

    case RESERVATION:
      return getReservation();

    case RESERVATION_START_TIME:
      return getReservationStartTime();

    case RESERVATION_END_TIME:
      return getReservationEndTime();

    case VALIDATED:
      return isValidated();

    }
    throw new java.lang.IllegalStateException();
  }

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

    switch (field) {
    case COMPUTE_RESOURCE_ID:
      return isSetComputeResourceId();
    case LOGIN_USER_NAME:
      return isSetLoginUserName();
    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 QUALITY_OF_SERVICE:
      return isSetQualityOfService();
    case RESERVATION:
      return isSetReservation();
    case RESERVATION_START_TIME:
      return isSetReservationStartTime();
    case RESERVATION_END_TIME:
      return isSetReservationEndTime();
    case VALIDATED:
      return isSetValidated();
    }
    throw new java.lang.IllegalStateException();
  }

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

  public boolean equals(UserComputeResourcePreference 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_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_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_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_validated = true && this.isSetValidated();
    boolean that_present_validated = true && that.isSetValidated();
    if (this_present_validated || that_present_validated) {
      if (!(this_present_validated && that_present_validated))
        return false;
      if (this.validated != that.validated)
        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 + ((isSetLoginUserName()) ? 131071 : 524287);
    if (isSetLoginUserName())
      hashCode = hashCode * 8191 + loginUserName.hashCode();

    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 + ((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 + ((isSetValidated()) ? 131071 : 524287);
    if (isSetValidated())
      hashCode = hashCode * 8191 + ((validated) ? 131071 : 524287);

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetComputeResourceId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetLoginUserName()).compareTo(other.isSetLoginUserName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetLoginUserName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.loginUserName, other.loginUserName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetPreferredBatchQueue()).compareTo(other.isSetPreferredBatchQueue());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetPreferredBatchQueue()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.preferredBatchQueue, other.preferredBatchQueue);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetScratchLocation()).compareTo(other.isSetScratchLocation());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetScratchLocation()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scratchLocation, other.scratchLocation);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetAllocationProjectNumber()).compareTo(other.isSetAllocationProjectNumber());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetAllocationProjectNumber()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.allocationProjectNumber, other.allocationProjectNumber);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetResourceSpecificCredentialStoreToken()).compareTo(other.isSetResourceSpecificCredentialStoreToken());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetResourceSpecificCredentialStoreToken()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.resourceSpecificCredentialStoreToken, other.resourceSpecificCredentialStoreToken);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetQualityOfService()).compareTo(other.isSetQualityOfService());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetQualityOfService()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.qualityOfService, other.qualityOfService);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetReservation()).compareTo(other.isSetReservation());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetReservation()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.reservation, other.reservation);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetReservationStartTime()).compareTo(other.isSetReservationStartTime());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetReservationStartTime()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.reservationStartTime, other.reservationStartTime);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetReservationEndTime()).compareTo(other.isSetReservationEndTime());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetReservationEndTime()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.reservationEndTime, other.reservationEndTime);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetValidated()).compareTo(other.isSetValidated());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetValidated()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.validated, other.validated);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

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

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

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

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

    sb.append("computeResourceId:");
    if (this.computeResourceId == null) {
      sb.append("null");
    } else {
      sb.append(this.computeResourceId);
    }
    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 (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 (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 (isSetValidated()) {
      if (!first) sb.append(", ");
      sb.append("validated:");
      sb.append(this.validated);
      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());
    }

    // 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 UserComputeResourcePreferenceStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public UserComputeResourcePreferenceStandardScheme getScheme() {
      return new UserComputeResourcePreferenceStandardScheme();
    }
  }

  private static class UserComputeResourcePreferenceStandardScheme extends org.apache.thrift.scheme.StandardScheme<UserComputeResourcePreference> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, UserComputeResourcePreference 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: // 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 3: // 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 4: // 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 5: // 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 6: // 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 7: // 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 8: // 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 9: // 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 10: // 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 11: // VALIDATED
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.validated = iprot.readBool();
              struct.setValidatedIsSet(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, UserComputeResourcePreference struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.computeResourceId != null) {
        oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
        oprot.writeString(struct.computeResourceId);
        oprot.writeFieldEnd();
      }
      if (struct.loginUserName != null) {
        if (struct.isSetLoginUserName()) {
          oprot.writeFieldBegin(LOGIN_USER_NAME_FIELD_DESC);
          oprot.writeString(struct.loginUserName);
          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.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.isSetValidated()) {
        oprot.writeFieldBegin(VALIDATED_FIELD_DESC);
        oprot.writeBool(struct.validated);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

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

  private static class UserComputeResourcePreferenceTupleScheme extends org.apache.thrift.scheme.TupleScheme<UserComputeResourcePreference> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, UserComputeResourcePreference struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      oprot.writeString(struct.computeResourceId);
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.isSetLoginUserName()) {
        optionals.set(0);
      }
      if (struct.isSetPreferredBatchQueue()) {
        optionals.set(1);
      }
      if (struct.isSetScratchLocation()) {
        optionals.set(2);
      }
      if (struct.isSetAllocationProjectNumber()) {
        optionals.set(3);
      }
      if (struct.isSetResourceSpecificCredentialStoreToken()) {
        optionals.set(4);
      }
      if (struct.isSetQualityOfService()) {
        optionals.set(5);
      }
      if (struct.isSetReservation()) {
        optionals.set(6);
      }
      if (struct.isSetReservationStartTime()) {
        optionals.set(7);
      }
      if (struct.isSetReservationEndTime()) {
        optionals.set(8);
      }
      if (struct.isSetValidated()) {
        optionals.set(9);
      }
      oprot.writeBitSet(optionals, 10);
      if (struct.isSetLoginUserName()) {
        oprot.writeString(struct.loginUserName);
      }
      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.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.isSetValidated()) {
        oprot.writeBool(struct.validated);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, UserComputeResourcePreference 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);
      java.util.BitSet incoming = iprot.readBitSet(10);
      if (incoming.get(0)) {
        struct.loginUserName = iprot.readString();
        struct.setLoginUserNameIsSet(true);
      }
      if (incoming.get(1)) {
        struct.preferredBatchQueue = iprot.readString();
        struct.setPreferredBatchQueueIsSet(true);
      }
      if (incoming.get(2)) {
        struct.scratchLocation = iprot.readString();
        struct.setScratchLocationIsSet(true);
      }
      if (incoming.get(3)) {
        struct.allocationProjectNumber = iprot.readString();
        struct.setAllocationProjectNumberIsSet(true);
      }
      if (incoming.get(4)) {
        struct.resourceSpecificCredentialStoreToken = iprot.readString();
        struct.setResourceSpecificCredentialStoreTokenIsSet(true);
      }
      if (incoming.get(5)) {
        struct.qualityOfService = iprot.readString();
        struct.setQualityOfServiceIsSet(true);
      }
      if (incoming.get(6)) {
        struct.reservation = iprot.readString();
        struct.setReservationIsSet(true);
      }
      if (incoming.get(7)) {
        struct.reservationStartTime = iprot.readI64();
        struct.setReservationStartTimeIsSet(true);
      }
      if (incoming.get(8)) {
        struct.reservationEndTime = iprot.readI64();
        struct.setReservationEndTimeIsSet(true);
      }
      if (incoming.get(9)) {
        struct.validated = iprot.readBool();
        struct.setValidatedIsSet(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();
  }
}

