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

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"})
/**
 * A structure holding the experiment configuration.
 * 
 * 
 */
@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
public class UserConfigurationDataModel implements org.apache.thrift.TBase<UserConfigurationDataModel, UserConfigurationDataModel._Fields>, java.io.Serializable, Cloneable, Comparable<UserConfigurationDataModel> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("UserConfigurationDataModel");

  private static final org.apache.thrift.protocol.TField AIRAVATA_AUTO_SCHEDULE_FIELD_DESC = new org.apache.thrift.protocol.TField("airavataAutoSchedule", org.apache.thrift.protocol.TType.BOOL, (short)1);
  private static final org.apache.thrift.protocol.TField OVERRIDE_MANUAL_SCHEDULED_PARAMS_FIELD_DESC = new org.apache.thrift.protocol.TField("overrideManualScheduledParams", org.apache.thrift.protocol.TType.BOOL, (short)2);
  private static final org.apache.thrift.protocol.TField SHARE_EXPERIMENT_PUBLICLY_FIELD_DESC = new org.apache.thrift.protocol.TField("shareExperimentPublicly", org.apache.thrift.protocol.TType.BOOL, (short)3);
  private static final org.apache.thrift.protocol.TField COMPUTATIONAL_RESOURCE_SCHEDULING_FIELD_DESC = new org.apache.thrift.protocol.TField("computationalResourceScheduling", org.apache.thrift.protocol.TType.STRUCT, (short)4);
  private static final org.apache.thrift.protocol.TField THROTTLE_RESOURCES_FIELD_DESC = new org.apache.thrift.protocol.TField("throttleResources", org.apache.thrift.protocol.TType.BOOL, (short)5);
  private static final org.apache.thrift.protocol.TField USER_DN_FIELD_DESC = new org.apache.thrift.protocol.TField("userDN", org.apache.thrift.protocol.TType.STRING, (short)6);
  private static final org.apache.thrift.protocol.TField GENERATE_CERT_FIELD_DESC = new org.apache.thrift.protocol.TField("generateCert", org.apache.thrift.protocol.TType.BOOL, (short)7);
  private static final org.apache.thrift.protocol.TField STORAGE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("storageId", org.apache.thrift.protocol.TType.STRING, (short)8);
  private static final org.apache.thrift.protocol.TField EXPERIMENT_DATA_DIR_FIELD_DESC = new org.apache.thrift.protocol.TField("experimentDataDir", org.apache.thrift.protocol.TType.STRING, (short)9);

  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
  static {
    schemes.put(StandardScheme.class, new UserConfigurationDataModelStandardSchemeFactory());
    schemes.put(TupleScheme.class, new UserConfigurationDataModelTupleSchemeFactory());
  }

  private boolean airavataAutoSchedule; // required
  private boolean overrideManualScheduledParams; // required
  private boolean shareExperimentPublicly; // optional
  private org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel computationalResourceScheduling; // optional
  private boolean throttleResources; // optional
  private String userDN; // optional
  private boolean generateCert; // optional
  private String storageId; // optional
  private String experimentDataDir; // 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 {
    AIRAVATA_AUTO_SCHEDULE((short)1, "airavataAutoSchedule"),
    OVERRIDE_MANUAL_SCHEDULED_PARAMS((short)2, "overrideManualScheduledParams"),
    SHARE_EXPERIMENT_PUBLICLY((short)3, "shareExperimentPublicly"),
    COMPUTATIONAL_RESOURCE_SCHEDULING((short)4, "computationalResourceScheduling"),
    THROTTLE_RESOURCES((short)5, "throttleResources"),
    USER_DN((short)6, "userDN"),
    GENERATE_CERT((short)7, "generateCert"),
    STORAGE_ID((short)8, "storageId"),
    EXPERIMENT_DATA_DIR((short)9, "experimentDataDir");

    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: // AIRAVATA_AUTO_SCHEDULE
          return AIRAVATA_AUTO_SCHEDULE;
        case 2: // OVERRIDE_MANUAL_SCHEDULED_PARAMS
          return OVERRIDE_MANUAL_SCHEDULED_PARAMS;
        case 3: // SHARE_EXPERIMENT_PUBLICLY
          return SHARE_EXPERIMENT_PUBLICLY;
        case 4: // COMPUTATIONAL_RESOURCE_SCHEDULING
          return COMPUTATIONAL_RESOURCE_SCHEDULING;
        case 5: // THROTTLE_RESOURCES
          return THROTTLE_RESOURCES;
        case 6: // USER_DN
          return USER_DN;
        case 7: // GENERATE_CERT
          return GENERATE_CERT;
        case 8: // STORAGE_ID
          return STORAGE_ID;
        case 9: // EXPERIMENT_DATA_DIR
          return EXPERIMENT_DATA_DIR;
        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 __AIRAVATAAUTOSCHEDULE_ISSET_ID = 0;
  private static final int __OVERRIDEMANUALSCHEDULEDPARAMS_ISSET_ID = 1;
  private static final int __SHAREEXPERIMENTPUBLICLY_ISSET_ID = 2;
  private static final int __THROTTLERESOURCES_ISSET_ID = 3;
  private static final int __GENERATECERT_ISSET_ID = 4;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.SHARE_EXPERIMENT_PUBLICLY,_Fields.COMPUTATIONAL_RESOURCE_SCHEDULING,_Fields.THROTTLE_RESOURCES,_Fields.USER_DN,_Fields.GENERATE_CERT,_Fields.STORAGE_ID,_Fields.EXPERIMENT_DATA_DIR};
  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.AIRAVATA_AUTO_SCHEDULE, new org.apache.thrift.meta_data.FieldMetaData("airavataAutoSchedule", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.OVERRIDE_MANUAL_SCHEDULED_PARAMS, new org.apache.thrift.meta_data.FieldMetaData("overrideManualScheduledParams", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.SHARE_EXPERIMENT_PUBLICLY, new org.apache.thrift.meta_data.FieldMetaData("shareExperimentPublicly", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.COMPUTATIONAL_RESOURCE_SCHEDULING, new org.apache.thrift.meta_data.FieldMetaData("computationalResourceScheduling", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel.class)));
    tmpMap.put(_Fields.THROTTLE_RESOURCES, new org.apache.thrift.meta_data.FieldMetaData("throttleResources", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.USER_DN, new org.apache.thrift.meta_data.FieldMetaData("userDN", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.GENERATE_CERT, new org.apache.thrift.meta_data.FieldMetaData("generateCert", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.STORAGE_ID, new org.apache.thrift.meta_data.FieldMetaData("storageId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.EXPERIMENT_DATA_DIR, new org.apache.thrift.meta_data.FieldMetaData("experimentDataDir", 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(UserConfigurationDataModel.class, metaDataMap);
  }

  public UserConfigurationDataModel() {
    this.airavataAutoSchedule = false;

    this.overrideManualScheduledParams = false;

    this.shareExperimentPublicly = false;

    this.throttleResources = false;

    this.generateCert = false;

  }

  public UserConfigurationDataModel(
    boolean airavataAutoSchedule,
    boolean overrideManualScheduledParams)
  {
    this();
    this.airavataAutoSchedule = airavataAutoSchedule;
    setAiravataAutoScheduleIsSet(true);
    this.overrideManualScheduledParams = overrideManualScheduledParams;
    setOverrideManualScheduledParamsIsSet(true);
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public UserConfigurationDataModel(UserConfigurationDataModel other) {
    __isset_bitfield = other.__isset_bitfield;
    this.airavataAutoSchedule = other.airavataAutoSchedule;
    this.overrideManualScheduledParams = other.overrideManualScheduledParams;
    this.shareExperimentPublicly = other.shareExperimentPublicly;
    if (other.isSetComputationalResourceScheduling()) {
      this.computationalResourceScheduling = new org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel(other.computationalResourceScheduling);
    }
    this.throttleResources = other.throttleResources;
    if (other.isSetUserDN()) {
      this.userDN = other.userDN;
    }
    this.generateCert = other.generateCert;
    if (other.isSetStorageId()) {
      this.storageId = other.storageId;
    }
    if (other.isSetExperimentDataDir()) {
      this.experimentDataDir = other.experimentDataDir;
    }
  }

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

  @Override
  public void clear() {
    this.airavataAutoSchedule = false;

    this.overrideManualScheduledParams = false;

    this.shareExperimentPublicly = false;

    this.computationalResourceScheduling = null;
    this.throttleResources = false;

    this.userDN = null;
    this.generateCert = false;

    this.storageId = null;
    this.experimentDataDir = null;
  }

  public boolean isAiravataAutoSchedule() {
    return this.airavataAutoSchedule;
  }

  public void setAiravataAutoSchedule(boolean airavataAutoSchedule) {
    this.airavataAutoSchedule = airavataAutoSchedule;
    setAiravataAutoScheduleIsSet(true);
  }

  public void unsetAiravataAutoSchedule() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __AIRAVATAAUTOSCHEDULE_ISSET_ID);
  }

  /** Returns true if field airavataAutoSchedule is set (has been assigned a value) and false otherwise */
  public boolean isSetAiravataAutoSchedule() {
    return EncodingUtils.testBit(__isset_bitfield, __AIRAVATAAUTOSCHEDULE_ISSET_ID);
  }

  public void setAiravataAutoScheduleIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __AIRAVATAAUTOSCHEDULE_ISSET_ID, value);
  }

  public boolean isOverrideManualScheduledParams() {
    return this.overrideManualScheduledParams;
  }

  public void setOverrideManualScheduledParams(boolean overrideManualScheduledParams) {
    this.overrideManualScheduledParams = overrideManualScheduledParams;
    setOverrideManualScheduledParamsIsSet(true);
  }

  public void unsetOverrideManualScheduledParams() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __OVERRIDEMANUALSCHEDULEDPARAMS_ISSET_ID);
  }

  /** Returns true if field overrideManualScheduledParams is set (has been assigned a value) and false otherwise */
  public boolean isSetOverrideManualScheduledParams() {
    return EncodingUtils.testBit(__isset_bitfield, __OVERRIDEMANUALSCHEDULEDPARAMS_ISSET_ID);
  }

  public void setOverrideManualScheduledParamsIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __OVERRIDEMANUALSCHEDULEDPARAMS_ISSET_ID, value);
  }

  public boolean isShareExperimentPublicly() {
    return this.shareExperimentPublicly;
  }

  public void setShareExperimentPublicly(boolean shareExperimentPublicly) {
    this.shareExperimentPublicly = shareExperimentPublicly;
    setShareExperimentPubliclyIsSet(true);
  }

  public void unsetShareExperimentPublicly() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SHAREEXPERIMENTPUBLICLY_ISSET_ID);
  }

  /** Returns true if field shareExperimentPublicly is set (has been assigned a value) and false otherwise */
  public boolean isSetShareExperimentPublicly() {
    return EncodingUtils.testBit(__isset_bitfield, __SHAREEXPERIMENTPUBLICLY_ISSET_ID);
  }

  public void setShareExperimentPubliclyIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SHAREEXPERIMENTPUBLICLY_ISSET_ID, value);
  }

  public org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel getComputationalResourceScheduling() {
    return this.computationalResourceScheduling;
  }

  public void setComputationalResourceScheduling(org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel computationalResourceScheduling) {
    this.computationalResourceScheduling = computationalResourceScheduling;
  }

  public void unsetComputationalResourceScheduling() {
    this.computationalResourceScheduling = null;
  }

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

  public void setComputationalResourceSchedulingIsSet(boolean value) {
    if (!value) {
      this.computationalResourceScheduling = null;
    }
  }

  public boolean isThrottleResources() {
    return this.throttleResources;
  }

  public void setThrottleResources(boolean throttleResources) {
    this.throttleResources = throttleResources;
    setThrottleResourcesIsSet(true);
  }

  public void unsetThrottleResources() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __THROTTLERESOURCES_ISSET_ID);
  }

  /** Returns true if field throttleResources is set (has been assigned a value) and false otherwise */
  public boolean isSetThrottleResources() {
    return EncodingUtils.testBit(__isset_bitfield, __THROTTLERESOURCES_ISSET_ID);
  }

  public void setThrottleResourcesIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __THROTTLERESOURCES_ISSET_ID, value);
  }

  public String getUserDN() {
    return this.userDN;
  }

  public void setUserDN(String userDN) {
    this.userDN = userDN;
  }

  public void unsetUserDN() {
    this.userDN = null;
  }

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

  public void setUserDNIsSet(boolean value) {
    if (!value) {
      this.userDN = null;
    }
  }

  public boolean isGenerateCert() {
    return this.generateCert;
  }

  public void setGenerateCert(boolean generateCert) {
    this.generateCert = generateCert;
    setGenerateCertIsSet(true);
  }

  public void unsetGenerateCert() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __GENERATECERT_ISSET_ID);
  }

  /** Returns true if field generateCert is set (has been assigned a value) and false otherwise */
  public boolean isSetGenerateCert() {
    return EncodingUtils.testBit(__isset_bitfield, __GENERATECERT_ISSET_ID);
  }

  public void setGenerateCertIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __GENERATECERT_ISSET_ID, value);
  }

  public String getStorageId() {
    return this.storageId;
  }

  public void setStorageId(String storageId) {
    this.storageId = storageId;
  }

  public void unsetStorageId() {
    this.storageId = null;
  }

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

  public void setStorageIdIsSet(boolean value) {
    if (!value) {
      this.storageId = null;
    }
  }

  public String getExperimentDataDir() {
    return this.experimentDataDir;
  }

  public void setExperimentDataDir(String experimentDataDir) {
    this.experimentDataDir = experimentDataDir;
  }

  public void unsetExperimentDataDir() {
    this.experimentDataDir = null;
  }

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

  public void setExperimentDataDirIsSet(boolean value) {
    if (!value) {
      this.experimentDataDir = null;
    }
  }

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case AIRAVATA_AUTO_SCHEDULE:
      if (value == null) {
        unsetAiravataAutoSchedule();
      } else {
        setAiravataAutoSchedule((Boolean)value);
      }
      break;

    case OVERRIDE_MANUAL_SCHEDULED_PARAMS:
      if (value == null) {
        unsetOverrideManualScheduledParams();
      } else {
        setOverrideManualScheduledParams((Boolean)value);
      }
      break;

    case SHARE_EXPERIMENT_PUBLICLY:
      if (value == null) {
        unsetShareExperimentPublicly();
      } else {
        setShareExperimentPublicly((Boolean)value);
      }
      break;

    case COMPUTATIONAL_RESOURCE_SCHEDULING:
      if (value == null) {
        unsetComputationalResourceScheduling();
      } else {
        setComputationalResourceScheduling((org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel)value);
      }
      break;

    case THROTTLE_RESOURCES:
      if (value == null) {
        unsetThrottleResources();
      } else {
        setThrottleResources((Boolean)value);
      }
      break;

    case USER_DN:
      if (value == null) {
        unsetUserDN();
      } else {
        setUserDN((String)value);
      }
      break;

    case GENERATE_CERT:
      if (value == null) {
        unsetGenerateCert();
      } else {
        setGenerateCert((Boolean)value);
      }
      break;

    case STORAGE_ID:
      if (value == null) {
        unsetStorageId();
      } else {
        setStorageId((String)value);
      }
      break;

    case EXPERIMENT_DATA_DIR:
      if (value == null) {
        unsetExperimentDataDir();
      } else {
        setExperimentDataDir((String)value);
      }
      break;

    }
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case AIRAVATA_AUTO_SCHEDULE:
      return isAiravataAutoSchedule();

    case OVERRIDE_MANUAL_SCHEDULED_PARAMS:
      return isOverrideManualScheduledParams();

    case SHARE_EXPERIMENT_PUBLICLY:
      return isShareExperimentPublicly();

    case COMPUTATIONAL_RESOURCE_SCHEDULING:
      return getComputationalResourceScheduling();

    case THROTTLE_RESOURCES:
      return isThrottleResources();

    case USER_DN:
      return getUserDN();

    case GENERATE_CERT:
      return isGenerateCert();

    case STORAGE_ID:
      return getStorageId();

    case EXPERIMENT_DATA_DIR:
      return getExperimentDataDir();

    }
    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 AIRAVATA_AUTO_SCHEDULE:
      return isSetAiravataAutoSchedule();
    case OVERRIDE_MANUAL_SCHEDULED_PARAMS:
      return isSetOverrideManualScheduledParams();
    case SHARE_EXPERIMENT_PUBLICLY:
      return isSetShareExperimentPublicly();
    case COMPUTATIONAL_RESOURCE_SCHEDULING:
      return isSetComputationalResourceScheduling();
    case THROTTLE_RESOURCES:
      return isSetThrottleResources();
    case USER_DN:
      return isSetUserDN();
    case GENERATE_CERT:
      return isSetGenerateCert();
    case STORAGE_ID:
      return isSetStorageId();
    case EXPERIMENT_DATA_DIR:
      return isSetExperimentDataDir();
    }
    throw new IllegalStateException();
  }

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

  public boolean equals(UserConfigurationDataModel that) {
    if (that == null)
      return false;

    boolean this_present_airavataAutoSchedule = true;
    boolean that_present_airavataAutoSchedule = true;
    if (this_present_airavataAutoSchedule || that_present_airavataAutoSchedule) {
      if (!(this_present_airavataAutoSchedule && that_present_airavataAutoSchedule))
        return false;
      if (this.airavataAutoSchedule != that.airavataAutoSchedule)
        return false;
    }

    boolean this_present_overrideManualScheduledParams = true;
    boolean that_present_overrideManualScheduledParams = true;
    if (this_present_overrideManualScheduledParams || that_present_overrideManualScheduledParams) {
      if (!(this_present_overrideManualScheduledParams && that_present_overrideManualScheduledParams))
        return false;
      if (this.overrideManualScheduledParams != that.overrideManualScheduledParams)
        return false;
    }

    boolean this_present_shareExperimentPublicly = true && this.isSetShareExperimentPublicly();
    boolean that_present_shareExperimentPublicly = true && that.isSetShareExperimentPublicly();
    if (this_present_shareExperimentPublicly || that_present_shareExperimentPublicly) {
      if (!(this_present_shareExperimentPublicly && that_present_shareExperimentPublicly))
        return false;
      if (this.shareExperimentPublicly != that.shareExperimentPublicly)
        return false;
    }

    boolean this_present_computationalResourceScheduling = true && this.isSetComputationalResourceScheduling();
    boolean that_present_computationalResourceScheduling = true && that.isSetComputationalResourceScheduling();
    if (this_present_computationalResourceScheduling || that_present_computationalResourceScheduling) {
      if (!(this_present_computationalResourceScheduling && that_present_computationalResourceScheduling))
        return false;
      if (!this.computationalResourceScheduling.equals(that.computationalResourceScheduling))
        return false;
    }

    boolean this_present_throttleResources = true && this.isSetThrottleResources();
    boolean that_present_throttleResources = true && that.isSetThrottleResources();
    if (this_present_throttleResources || that_present_throttleResources) {
      if (!(this_present_throttleResources && that_present_throttleResources))
        return false;
      if (this.throttleResources != that.throttleResources)
        return false;
    }

    boolean this_present_userDN = true && this.isSetUserDN();
    boolean that_present_userDN = true && that.isSetUserDN();
    if (this_present_userDN || that_present_userDN) {
      if (!(this_present_userDN && that_present_userDN))
        return false;
      if (!this.userDN.equals(that.userDN))
        return false;
    }

    boolean this_present_generateCert = true && this.isSetGenerateCert();
    boolean that_present_generateCert = true && that.isSetGenerateCert();
    if (this_present_generateCert || that_present_generateCert) {
      if (!(this_present_generateCert && that_present_generateCert))
        return false;
      if (this.generateCert != that.generateCert)
        return false;
    }

    boolean this_present_storageId = true && this.isSetStorageId();
    boolean that_present_storageId = true && that.isSetStorageId();
    if (this_present_storageId || that_present_storageId) {
      if (!(this_present_storageId && that_present_storageId))
        return false;
      if (!this.storageId.equals(that.storageId))
        return false;
    }

    boolean this_present_experimentDataDir = true && this.isSetExperimentDataDir();
    boolean that_present_experimentDataDir = true && that.isSetExperimentDataDir();
    if (this_present_experimentDataDir || that_present_experimentDataDir) {
      if (!(this_present_experimentDataDir && that_present_experimentDataDir))
        return false;
      if (!this.experimentDataDir.equals(that.experimentDataDir))
        return false;
    }

    return true;
  }

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

    boolean present_airavataAutoSchedule = true;
    list.add(present_airavataAutoSchedule);
    if (present_airavataAutoSchedule)
      list.add(airavataAutoSchedule);

    boolean present_overrideManualScheduledParams = true;
    list.add(present_overrideManualScheduledParams);
    if (present_overrideManualScheduledParams)
      list.add(overrideManualScheduledParams);

    boolean present_shareExperimentPublicly = true && (isSetShareExperimentPublicly());
    list.add(present_shareExperimentPublicly);
    if (present_shareExperimentPublicly)
      list.add(shareExperimentPublicly);

    boolean present_computationalResourceScheduling = true && (isSetComputationalResourceScheduling());
    list.add(present_computationalResourceScheduling);
    if (present_computationalResourceScheduling)
      list.add(computationalResourceScheduling);

    boolean present_throttleResources = true && (isSetThrottleResources());
    list.add(present_throttleResources);
    if (present_throttleResources)
      list.add(throttleResources);

    boolean present_userDN = true && (isSetUserDN());
    list.add(present_userDN);
    if (present_userDN)
      list.add(userDN);

    boolean present_generateCert = true && (isSetGenerateCert());
    list.add(present_generateCert);
    if (present_generateCert)
      list.add(generateCert);

    boolean present_storageId = true && (isSetStorageId());
    list.add(present_storageId);
    if (present_storageId)
      list.add(storageId);

    boolean present_experimentDataDir = true && (isSetExperimentDataDir());
    list.add(present_experimentDataDir);
    if (present_experimentDataDir)
      list.add(experimentDataDir);

    return list.hashCode();
  }

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

    int lastComparison = 0;

    lastComparison = Boolean.valueOf(isSetAiravataAutoSchedule()).compareTo(other.isSetAiravataAutoSchedule());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetAiravataAutoSchedule()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.airavataAutoSchedule, other.airavataAutoSchedule);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetOverrideManualScheduledParams()).compareTo(other.isSetOverrideManualScheduledParams());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetOverrideManualScheduledParams()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.overrideManualScheduledParams, other.overrideManualScheduledParams);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetShareExperimentPublicly()).compareTo(other.isSetShareExperimentPublicly());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetShareExperimentPublicly()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.shareExperimentPublicly, other.shareExperimentPublicly);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetComputationalResourceScheduling()).compareTo(other.isSetComputationalResourceScheduling());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetComputationalResourceScheduling()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computationalResourceScheduling, other.computationalResourceScheduling);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetThrottleResources()).compareTo(other.isSetThrottleResources());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetThrottleResources()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.throttleResources, other.throttleResources);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetUserDN()).compareTo(other.isSetUserDN());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetUserDN()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userDN, other.userDN);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetGenerateCert()).compareTo(other.isSetGenerateCert());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetGenerateCert()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.generateCert, other.generateCert);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetStorageId()).compareTo(other.isSetStorageId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetStorageId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.storageId, other.storageId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetExperimentDataDir()).compareTo(other.isSetExperimentDataDir());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetExperimentDataDir()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.experimentDataDir, other.experimentDataDir);
      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("UserConfigurationDataModel(");
    boolean first = true;

    sb.append("airavataAutoSchedule:");
    sb.append(this.airavataAutoSchedule);
    first = false;
    if (!first) sb.append(", ");
    sb.append("overrideManualScheduledParams:");
    sb.append(this.overrideManualScheduledParams);
    first = false;
    if (isSetShareExperimentPublicly()) {
      if (!first) sb.append(", ");
      sb.append("shareExperimentPublicly:");
      sb.append(this.shareExperimentPublicly);
      first = false;
    }
    if (isSetComputationalResourceScheduling()) {
      if (!first) sb.append(", ");
      sb.append("computationalResourceScheduling:");
      if (this.computationalResourceScheduling == null) {
        sb.append("null");
      } else {
        sb.append(this.computationalResourceScheduling);
      }
      first = false;
    }
    if (isSetThrottleResources()) {
      if (!first) sb.append(", ");
      sb.append("throttleResources:");
      sb.append(this.throttleResources);
      first = false;
    }
    if (isSetUserDN()) {
      if (!first) sb.append(", ");
      sb.append("userDN:");
      if (this.userDN == null) {
        sb.append("null");
      } else {
        sb.append(this.userDN);
      }
      first = false;
    }
    if (isSetGenerateCert()) {
      if (!first) sb.append(", ");
      sb.append("generateCert:");
      sb.append(this.generateCert);
      first = false;
    }
    if (isSetStorageId()) {
      if (!first) sb.append(", ");
      sb.append("storageId:");
      if (this.storageId == null) {
        sb.append("null");
      } else {
        sb.append(this.storageId);
      }
      first = false;
    }
    if (isSetExperimentDataDir()) {
      if (!first) sb.append(", ");
      sb.append("experimentDataDir:");
      if (this.experimentDataDir == null) {
        sb.append("null");
      } else {
        sb.append(this.experimentDataDir);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.thrift.TException {
    // check for required fields
    if (!isSetAiravataAutoSchedule()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'airavataAutoSchedule' is unset! Struct:" + toString());
    }

    if (!isSetOverrideManualScheduledParams()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'overrideManualScheduledParams' is unset! Struct:" + toString());
    }

    // check for sub-struct validity
    if (computationalResourceScheduling != null) {
      computationalResourceScheduling.validate();
    }
  }

  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 UserConfigurationDataModelStandardSchemeFactory implements SchemeFactory {
    public UserConfigurationDataModelStandardScheme getScheme() {
      return new UserConfigurationDataModelStandardScheme();
    }
  }

  private static class UserConfigurationDataModelStandardScheme extends StandardScheme<UserConfigurationDataModel> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, UserConfigurationDataModel 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: // AIRAVATA_AUTO_SCHEDULE
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.airavataAutoSchedule = iprot.readBool();
              struct.setAiravataAutoScheduleIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // OVERRIDE_MANUAL_SCHEDULED_PARAMS
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.overrideManualScheduledParams = iprot.readBool();
              struct.setOverrideManualScheduledParamsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // SHARE_EXPERIMENT_PUBLICLY
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.shareExperimentPublicly = iprot.readBool();
              struct.setShareExperimentPubliclyIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // COMPUTATIONAL_RESOURCE_SCHEDULING
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.computationalResourceScheduling = new org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel();
              struct.computationalResourceScheduling.read(iprot);
              struct.setComputationalResourceSchedulingIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // THROTTLE_RESOURCES
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.throttleResources = iprot.readBool();
              struct.setThrottleResourcesIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // USER_DN
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.userDN = iprot.readString();
              struct.setUserDNIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // GENERATE_CERT
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.generateCert = iprot.readBool();
              struct.setGenerateCertIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // STORAGE_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.storageId = iprot.readString();
              struct.setStorageIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // EXPERIMENT_DATA_DIR
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.experimentDataDir = iprot.readString();
              struct.setExperimentDataDirIsSet(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, UserConfigurationDataModel struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      oprot.writeFieldBegin(AIRAVATA_AUTO_SCHEDULE_FIELD_DESC);
      oprot.writeBool(struct.airavataAutoSchedule);
      oprot.writeFieldEnd();
      oprot.writeFieldBegin(OVERRIDE_MANUAL_SCHEDULED_PARAMS_FIELD_DESC);
      oprot.writeBool(struct.overrideManualScheduledParams);
      oprot.writeFieldEnd();
      if (struct.isSetShareExperimentPublicly()) {
        oprot.writeFieldBegin(SHARE_EXPERIMENT_PUBLICLY_FIELD_DESC);
        oprot.writeBool(struct.shareExperimentPublicly);
        oprot.writeFieldEnd();
      }
      if (struct.computationalResourceScheduling != null) {
        if (struct.isSetComputationalResourceScheduling()) {
          oprot.writeFieldBegin(COMPUTATIONAL_RESOURCE_SCHEDULING_FIELD_DESC);
          struct.computationalResourceScheduling.write(oprot);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetThrottleResources()) {
        oprot.writeFieldBegin(THROTTLE_RESOURCES_FIELD_DESC);
        oprot.writeBool(struct.throttleResources);
        oprot.writeFieldEnd();
      }
      if (struct.userDN != null) {
        if (struct.isSetUserDN()) {
          oprot.writeFieldBegin(USER_DN_FIELD_DESC);
          oprot.writeString(struct.userDN);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetGenerateCert()) {
        oprot.writeFieldBegin(GENERATE_CERT_FIELD_DESC);
        oprot.writeBool(struct.generateCert);
        oprot.writeFieldEnd();
      }
      if (struct.storageId != null) {
        if (struct.isSetStorageId()) {
          oprot.writeFieldBegin(STORAGE_ID_FIELD_DESC);
          oprot.writeString(struct.storageId);
          oprot.writeFieldEnd();
        }
      }
      if (struct.experimentDataDir != null) {
        if (struct.isSetExperimentDataDir()) {
          oprot.writeFieldBegin(EXPERIMENT_DATA_DIR_FIELD_DESC);
          oprot.writeString(struct.experimentDataDir);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class UserConfigurationDataModelTupleSchemeFactory implements SchemeFactory {
    public UserConfigurationDataModelTupleScheme getScheme() {
      return new UserConfigurationDataModelTupleScheme();
    }
  }

  private static class UserConfigurationDataModelTupleScheme extends TupleScheme<UserConfigurationDataModel> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, UserConfigurationDataModel struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      oprot.writeBool(struct.airavataAutoSchedule);
      oprot.writeBool(struct.overrideManualScheduledParams);
      BitSet optionals = new BitSet();
      if (struct.isSetShareExperimentPublicly()) {
        optionals.set(0);
      }
      if (struct.isSetComputationalResourceScheduling()) {
        optionals.set(1);
      }
      if (struct.isSetThrottleResources()) {
        optionals.set(2);
      }
      if (struct.isSetUserDN()) {
        optionals.set(3);
      }
      if (struct.isSetGenerateCert()) {
        optionals.set(4);
      }
      if (struct.isSetStorageId()) {
        optionals.set(5);
      }
      if (struct.isSetExperimentDataDir()) {
        optionals.set(6);
      }
      oprot.writeBitSet(optionals, 7);
      if (struct.isSetShareExperimentPublicly()) {
        oprot.writeBool(struct.shareExperimentPublicly);
      }
      if (struct.isSetComputationalResourceScheduling()) {
        struct.computationalResourceScheduling.write(oprot);
      }
      if (struct.isSetThrottleResources()) {
        oprot.writeBool(struct.throttleResources);
      }
      if (struct.isSetUserDN()) {
        oprot.writeString(struct.userDN);
      }
      if (struct.isSetGenerateCert()) {
        oprot.writeBool(struct.generateCert);
      }
      if (struct.isSetStorageId()) {
        oprot.writeString(struct.storageId);
      }
      if (struct.isSetExperimentDataDir()) {
        oprot.writeString(struct.experimentDataDir);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, UserConfigurationDataModel struct) throws org.apache.thrift.TException {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      struct.airavataAutoSchedule = iprot.readBool();
      struct.setAiravataAutoScheduleIsSet(true);
      struct.overrideManualScheduledParams = iprot.readBool();
      struct.setOverrideManualScheduledParamsIsSet(true);
      BitSet incoming = iprot.readBitSet(7);
      if (incoming.get(0)) {
        struct.shareExperimentPublicly = iprot.readBool();
        struct.setShareExperimentPubliclyIsSet(true);
      }
      if (incoming.get(1)) {
        struct.computationalResourceScheduling = new org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel();
        struct.computationalResourceScheduling.read(iprot);
        struct.setComputationalResourceSchedulingIsSet(true);
      }
      if (incoming.get(2)) {
        struct.throttleResources = iprot.readBool();
        struct.setThrottleResourcesIsSet(true);
      }
      if (incoming.get(3)) {
        struct.userDN = iprot.readString();
        struct.setUserDNIsSet(true);
      }
      if (incoming.get(4)) {
        struct.generateCert = iprot.readBool();
        struct.setGenerateCertIsSet(true);
      }
      if (incoming.get(5)) {
        struct.storageId = iprot.readString();
        struct.setStorageIdIsSet(true);
      }
      if (incoming.get(6)) {
        struct.experimentDataDir = iprot.readString();
        struct.setExperimentDataDirIsSet(true);
      }
    }
  }

}

