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

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

/**
 * Application Deployment Description
 * 
 * appDeploymentId: Airavata Internal Unique Job ID. This is set by the registry.
 * 
 * appModuleName:
 *   Application Module Name. This has to be precise describing the binary.
 * 
 * computeHostId:
 *   This ID maps application deployment to a particular resource previously described within Airavata.
 *   Example: Stampede is first registered and refered when registering WRF.
 * 
 * moduleLoadCmd:
 *  Command string to load modules. This will be placed in the job submisison
 *  Ex: module load amber
 * 
 * libPrependPaths:
 *  prepend to a path variable the value
 * 
 * libAppendPaths:
 *  append to a path variable the value
 * 
 * setEnvironment:
 *  assigns to the environment variable "NAME" the value
 * 
 */
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.18.1)")
public class ApplicationDeploymentDescription implements org.apache.thrift.TBase<ApplicationDeploymentDescription, ApplicationDeploymentDescription._Fields>, java.io.Serializable, Cloneable, Comparable<ApplicationDeploymentDescription> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ApplicationDeploymentDescription");

  private static final org.apache.thrift.protocol.TField APP_DEPLOYMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("appDeploymentId", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField APP_MODULE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("appModuleId", org.apache.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.thrift.protocol.TField COMPUTE_HOST_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeHostId", org.apache.thrift.protocol.TType.STRING, (short)3);
  private static final org.apache.thrift.protocol.TField EXECUTABLE_PATH_FIELD_DESC = new org.apache.thrift.protocol.TField("executablePath", org.apache.thrift.protocol.TType.STRING, (short)4);
  private static final org.apache.thrift.protocol.TField PARALLELISM_FIELD_DESC = new org.apache.thrift.protocol.TField("parallelism", org.apache.thrift.protocol.TType.I32, (short)5);
  private static final org.apache.thrift.protocol.TField APP_DEPLOYMENT_DESCRIPTION_FIELD_DESC = new org.apache.thrift.protocol.TField("appDeploymentDescription", org.apache.thrift.protocol.TType.STRING, (short)6);
  private static final org.apache.thrift.protocol.TField MODULE_LOAD_CMDS_FIELD_DESC = new org.apache.thrift.protocol.TField("moduleLoadCmds", org.apache.thrift.protocol.TType.LIST, (short)7);
  private static final org.apache.thrift.protocol.TField LIB_PREPEND_PATHS_FIELD_DESC = new org.apache.thrift.protocol.TField("libPrependPaths", org.apache.thrift.protocol.TType.LIST, (short)8);
  private static final org.apache.thrift.protocol.TField LIB_APPEND_PATHS_FIELD_DESC = new org.apache.thrift.protocol.TField("libAppendPaths", org.apache.thrift.protocol.TType.LIST, (short)9);
  private static final org.apache.thrift.protocol.TField SET_ENVIRONMENT_FIELD_DESC = new org.apache.thrift.protocol.TField("setEnvironment", org.apache.thrift.protocol.TType.LIST, (short)10);
  private static final org.apache.thrift.protocol.TField PRE_JOB_COMMANDS_FIELD_DESC = new org.apache.thrift.protocol.TField("preJobCommands", org.apache.thrift.protocol.TType.LIST, (short)11);
  private static final org.apache.thrift.protocol.TField POST_JOB_COMMANDS_FIELD_DESC = new org.apache.thrift.protocol.TField("postJobCommands", org.apache.thrift.protocol.TType.LIST, (short)12);
  private static final org.apache.thrift.protocol.TField DEFAULT_QUEUE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("defaultQueueName", org.apache.thrift.protocol.TType.STRING, (short)13);
  private static final org.apache.thrift.protocol.TField DEFAULT_NODE_COUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("defaultNodeCount", org.apache.thrift.protocol.TType.I32, (short)14);
  private static final org.apache.thrift.protocol.TField DEFAULT_CPUCOUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("defaultCPUCount", org.apache.thrift.protocol.TType.I32, (short)15);
  private static final org.apache.thrift.protocol.TField DEFAULT_WALLTIME_FIELD_DESC = new org.apache.thrift.protocol.TField("defaultWalltime", org.apache.thrift.protocol.TType.I32, (short)16);
  private static final org.apache.thrift.protocol.TField EDITABLE_BY_USER_FIELD_DESC = new org.apache.thrift.protocol.TField("editableByUser", org.apache.thrift.protocol.TType.BOOL, (short)17);

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

  private @org.apache.thrift.annotation.Nullable java.lang.String appDeploymentId; // required
  private @org.apache.thrift.annotation.Nullable java.lang.String appModuleId; // required
  private @org.apache.thrift.annotation.Nullable java.lang.String computeHostId; // required
  private @org.apache.thrift.annotation.Nullable java.lang.String executablePath; // required
  private @org.apache.thrift.annotation.Nullable org.apache.airavata.model.parallelism.ApplicationParallelismType parallelism; // required
  private @org.apache.thrift.annotation.Nullable java.lang.String appDeploymentDescription; // optional
  private @org.apache.thrift.annotation.Nullable java.util.List<CommandObject> moduleLoadCmds; // optional
  private @org.apache.thrift.annotation.Nullable java.util.List<SetEnvPaths> libPrependPaths; // optional
  private @org.apache.thrift.annotation.Nullable java.util.List<SetEnvPaths> libAppendPaths; // optional
  private @org.apache.thrift.annotation.Nullable java.util.List<SetEnvPaths> setEnvironment; // optional
  private @org.apache.thrift.annotation.Nullable java.util.List<CommandObject> preJobCommands; // optional
  private @org.apache.thrift.annotation.Nullable java.util.List<CommandObject> postJobCommands; // optional
  private @org.apache.thrift.annotation.Nullable java.lang.String defaultQueueName; // optional
  private int defaultNodeCount; // optional
  private int defaultCPUCount; // optional
  private int defaultWalltime; // optional
  private boolean editableByUser; // 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 {
    APP_DEPLOYMENT_ID((short)1, "appDeploymentId"),
    APP_MODULE_ID((short)2, "appModuleId"),
    COMPUTE_HOST_ID((short)3, "computeHostId"),
    EXECUTABLE_PATH((short)4, "executablePath"),
    /**
     * 
     * @see org.apache.airavata.model.parallelism.ApplicationParallelismType
     */
    PARALLELISM((short)5, "parallelism"),
    APP_DEPLOYMENT_DESCRIPTION((short)6, "appDeploymentDescription"),
    MODULE_LOAD_CMDS((short)7, "moduleLoadCmds"),
    LIB_PREPEND_PATHS((short)8, "libPrependPaths"),
    LIB_APPEND_PATHS((short)9, "libAppendPaths"),
    SET_ENVIRONMENT((short)10, "setEnvironment"),
    PRE_JOB_COMMANDS((short)11, "preJobCommands"),
    POST_JOB_COMMANDS((short)12, "postJobCommands"),
    DEFAULT_QUEUE_NAME((short)13, "defaultQueueName"),
    DEFAULT_NODE_COUNT((short)14, "defaultNodeCount"),
    DEFAULT_CPUCOUNT((short)15, "defaultCPUCount"),
    DEFAULT_WALLTIME((short)16, "defaultWalltime"),
    EDITABLE_BY_USER((short)17, "editableByUser");

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

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

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    @org.apache.thrift.annotation.Nullable
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // APP_DEPLOYMENT_ID
          return APP_DEPLOYMENT_ID;
        case 2: // APP_MODULE_ID
          return APP_MODULE_ID;
        case 3: // COMPUTE_HOST_ID
          return COMPUTE_HOST_ID;
        case 4: // EXECUTABLE_PATH
          return EXECUTABLE_PATH;
        case 5: // PARALLELISM
          return PARALLELISM;
        case 6: // APP_DEPLOYMENT_DESCRIPTION
          return APP_DEPLOYMENT_DESCRIPTION;
        case 7: // MODULE_LOAD_CMDS
          return MODULE_LOAD_CMDS;
        case 8: // LIB_PREPEND_PATHS
          return LIB_PREPEND_PATHS;
        case 9: // LIB_APPEND_PATHS
          return LIB_APPEND_PATHS;
        case 10: // SET_ENVIRONMENT
          return SET_ENVIRONMENT;
        case 11: // PRE_JOB_COMMANDS
          return PRE_JOB_COMMANDS;
        case 12: // POST_JOB_COMMANDS
          return POST_JOB_COMMANDS;
        case 13: // DEFAULT_QUEUE_NAME
          return DEFAULT_QUEUE_NAME;
        case 14: // DEFAULT_NODE_COUNT
          return DEFAULT_NODE_COUNT;
        case 15: // DEFAULT_CPUCOUNT
          return DEFAULT_CPUCOUNT;
        case 16: // DEFAULT_WALLTIME
          return DEFAULT_WALLTIME;
        case 17: // EDITABLE_BY_USER
          return EDITABLE_BY_USER;
        default:
          return null;
      }
    }

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

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

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

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

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

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

  // isset id assignments
  private static final int __DEFAULTNODECOUNT_ISSET_ID = 0;
  private static final int __DEFAULTCPUCOUNT_ISSET_ID = 1;
  private static final int __DEFAULTWALLTIME_ISSET_ID = 2;
  private static final int __EDITABLEBYUSER_ISSET_ID = 3;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.APP_DEPLOYMENT_DESCRIPTION,_Fields.MODULE_LOAD_CMDS,_Fields.LIB_PREPEND_PATHS,_Fields.LIB_APPEND_PATHS,_Fields.SET_ENVIRONMENT,_Fields.PRE_JOB_COMMANDS,_Fields.POST_JOB_COMMANDS,_Fields.DEFAULT_QUEUE_NAME,_Fields.DEFAULT_NODE_COUNT,_Fields.DEFAULT_CPUCOUNT,_Fields.DEFAULT_WALLTIME,_Fields.EDITABLE_BY_USER};
  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.APP_DEPLOYMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("appDeploymentId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.APP_MODULE_ID, new org.apache.thrift.meta_data.FieldMetaData("appModuleId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.COMPUTE_HOST_ID, new org.apache.thrift.meta_data.FieldMetaData("computeHostId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.EXECUTABLE_PATH, new org.apache.thrift.meta_data.FieldMetaData("executablePath", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.PARALLELISM, new org.apache.thrift.meta_data.FieldMetaData("parallelism", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, org.apache.airavata.model.parallelism.ApplicationParallelismType.class)));
    tmpMap.put(_Fields.APP_DEPLOYMENT_DESCRIPTION, new org.apache.thrift.meta_data.FieldMetaData("appDeploymentDescription", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.MODULE_LOAD_CMDS, new org.apache.thrift.meta_data.FieldMetaData("moduleLoadCmds", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, CommandObject.class))));
    tmpMap.put(_Fields.LIB_PREPEND_PATHS, new org.apache.thrift.meta_data.FieldMetaData("libPrependPaths", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SetEnvPaths.class))));
    tmpMap.put(_Fields.LIB_APPEND_PATHS, new org.apache.thrift.meta_data.FieldMetaData("libAppendPaths", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SetEnvPaths.class))));
    tmpMap.put(_Fields.SET_ENVIRONMENT, new org.apache.thrift.meta_data.FieldMetaData("setEnvironment", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SetEnvPaths.class))));
    tmpMap.put(_Fields.PRE_JOB_COMMANDS, new org.apache.thrift.meta_data.FieldMetaData("preJobCommands", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, CommandObject.class))));
    tmpMap.put(_Fields.POST_JOB_COMMANDS, new org.apache.thrift.meta_data.FieldMetaData("postJobCommands", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, CommandObject.class))));
    tmpMap.put(_Fields.DEFAULT_QUEUE_NAME, new org.apache.thrift.meta_data.FieldMetaData("defaultQueueName", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.DEFAULT_NODE_COUNT, new org.apache.thrift.meta_data.FieldMetaData("defaultNodeCount", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.DEFAULT_CPUCOUNT, new org.apache.thrift.meta_data.FieldMetaData("defaultCPUCount", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.DEFAULT_WALLTIME, new org.apache.thrift.meta_data.FieldMetaData("defaultWalltime", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.EDITABLE_BY_USER, new org.apache.thrift.meta_data.FieldMetaData("editableByUser", 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(ApplicationDeploymentDescription.class, metaDataMap);
  }

  public ApplicationDeploymentDescription() {
    this.appDeploymentId = "DO_NOT_SET_AT_CLIENTS";

    this.parallelism = org.apache.airavata.model.parallelism.ApplicationParallelismType.SERIAL;

  }

  public ApplicationDeploymentDescription(
    java.lang.String appDeploymentId,
    java.lang.String appModuleId,
    java.lang.String computeHostId,
    java.lang.String executablePath,
    org.apache.airavata.model.parallelism.ApplicationParallelismType parallelism)
  {
    this();
    this.appDeploymentId = appDeploymentId;
    this.appModuleId = appModuleId;
    this.computeHostId = computeHostId;
    this.executablePath = executablePath;
    this.parallelism = parallelism;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public ApplicationDeploymentDescription(ApplicationDeploymentDescription other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetAppDeploymentId()) {
      this.appDeploymentId = other.appDeploymentId;
    }
    if (other.isSetAppModuleId()) {
      this.appModuleId = other.appModuleId;
    }
    if (other.isSetComputeHostId()) {
      this.computeHostId = other.computeHostId;
    }
    if (other.isSetExecutablePath()) {
      this.executablePath = other.executablePath;
    }
    if (other.isSetParallelism()) {
      this.parallelism = other.parallelism;
    }
    if (other.isSetAppDeploymentDescription()) {
      this.appDeploymentDescription = other.appDeploymentDescription;
    }
    if (other.isSetModuleLoadCmds()) {
      java.util.List<CommandObject> __this__moduleLoadCmds = new java.util.ArrayList<CommandObject>(other.moduleLoadCmds.size());
      for (CommandObject other_element : other.moduleLoadCmds) {
        __this__moduleLoadCmds.add(new CommandObject(other_element));
      }
      this.moduleLoadCmds = __this__moduleLoadCmds;
    }
    if (other.isSetLibPrependPaths()) {
      java.util.List<SetEnvPaths> __this__libPrependPaths = new java.util.ArrayList<SetEnvPaths>(other.libPrependPaths.size());
      for (SetEnvPaths other_element : other.libPrependPaths) {
        __this__libPrependPaths.add(new SetEnvPaths(other_element));
      }
      this.libPrependPaths = __this__libPrependPaths;
    }
    if (other.isSetLibAppendPaths()) {
      java.util.List<SetEnvPaths> __this__libAppendPaths = new java.util.ArrayList<SetEnvPaths>(other.libAppendPaths.size());
      for (SetEnvPaths other_element : other.libAppendPaths) {
        __this__libAppendPaths.add(new SetEnvPaths(other_element));
      }
      this.libAppendPaths = __this__libAppendPaths;
    }
    if (other.isSetSetEnvironment()) {
      java.util.List<SetEnvPaths> __this__setEnvironment = new java.util.ArrayList<SetEnvPaths>(other.setEnvironment.size());
      for (SetEnvPaths other_element : other.setEnvironment) {
        __this__setEnvironment.add(new SetEnvPaths(other_element));
      }
      this.setEnvironment = __this__setEnvironment;
    }
    if (other.isSetPreJobCommands()) {
      java.util.List<CommandObject> __this__preJobCommands = new java.util.ArrayList<CommandObject>(other.preJobCommands.size());
      for (CommandObject other_element : other.preJobCommands) {
        __this__preJobCommands.add(new CommandObject(other_element));
      }
      this.preJobCommands = __this__preJobCommands;
    }
    if (other.isSetPostJobCommands()) {
      java.util.List<CommandObject> __this__postJobCommands = new java.util.ArrayList<CommandObject>(other.postJobCommands.size());
      for (CommandObject other_element : other.postJobCommands) {
        __this__postJobCommands.add(new CommandObject(other_element));
      }
      this.postJobCommands = __this__postJobCommands;
    }
    if (other.isSetDefaultQueueName()) {
      this.defaultQueueName = other.defaultQueueName;
    }
    this.defaultNodeCount = other.defaultNodeCount;
    this.defaultCPUCount = other.defaultCPUCount;
    this.defaultWalltime = other.defaultWalltime;
    this.editableByUser = other.editableByUser;
  }

  @Override
  public ApplicationDeploymentDescription deepCopy() {
    return new ApplicationDeploymentDescription(this);
  }

  @Override
  public void clear() {
    this.appDeploymentId = "DO_NOT_SET_AT_CLIENTS";

    this.appModuleId = null;
    this.computeHostId = null;
    this.executablePath = null;
    this.parallelism = org.apache.airavata.model.parallelism.ApplicationParallelismType.SERIAL;

    this.appDeploymentDescription = null;
    this.moduleLoadCmds = null;
    this.libPrependPaths = null;
    this.libAppendPaths = null;
    this.setEnvironment = null;
    this.preJobCommands = null;
    this.postJobCommands = null;
    this.defaultQueueName = null;
    setDefaultNodeCountIsSet(false);
    this.defaultNodeCount = 0;
    setDefaultCPUCountIsSet(false);
    this.defaultCPUCount = 0;
    setDefaultWalltimeIsSet(false);
    this.defaultWalltime = 0;
    setEditableByUserIsSet(false);
    this.editableByUser = false;
  }

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

  public void setAppDeploymentId(@org.apache.thrift.annotation.Nullable java.lang.String appDeploymentId) {
    this.appDeploymentId = appDeploymentId;
  }

  public void unsetAppDeploymentId() {
    this.appDeploymentId = null;
  }

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

  public void setAppDeploymentIdIsSet(boolean value) {
    if (!value) {
      this.appDeploymentId = null;
    }
  }

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

  public void setAppModuleId(@org.apache.thrift.annotation.Nullable java.lang.String appModuleId) {
    this.appModuleId = appModuleId;
  }

  public void unsetAppModuleId() {
    this.appModuleId = null;
  }

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

  public void setAppModuleIdIsSet(boolean value) {
    if (!value) {
      this.appModuleId = null;
    }
  }

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

  public void setComputeHostId(@org.apache.thrift.annotation.Nullable java.lang.String computeHostId) {
    this.computeHostId = computeHostId;
  }

  public void unsetComputeHostId() {
    this.computeHostId = null;
  }

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

  public void setComputeHostIdIsSet(boolean value) {
    if (!value) {
      this.computeHostId = null;
    }
  }

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

  public void setExecutablePath(@org.apache.thrift.annotation.Nullable java.lang.String executablePath) {
    this.executablePath = executablePath;
  }

  public void unsetExecutablePath() {
    this.executablePath = null;
  }

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

  public void setExecutablePathIsSet(boolean value) {
    if (!value) {
      this.executablePath = null;
    }
  }

  /**
   * 
   * @see org.apache.airavata.model.parallelism.ApplicationParallelismType
   */
  @org.apache.thrift.annotation.Nullable
  public org.apache.airavata.model.parallelism.ApplicationParallelismType getParallelism() {
    return this.parallelism;
  }

  /**
   * 
   * @see org.apache.airavata.model.parallelism.ApplicationParallelismType
   */
  public void setParallelism(@org.apache.thrift.annotation.Nullable org.apache.airavata.model.parallelism.ApplicationParallelismType parallelism) {
    this.parallelism = parallelism;
  }

  public void unsetParallelism() {
    this.parallelism = null;
  }

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

  public void setParallelismIsSet(boolean value) {
    if (!value) {
      this.parallelism = null;
    }
  }

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

  public void setAppDeploymentDescription(@org.apache.thrift.annotation.Nullable java.lang.String appDeploymentDescription) {
    this.appDeploymentDescription = appDeploymentDescription;
  }

  public void unsetAppDeploymentDescription() {
    this.appDeploymentDescription = null;
  }

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

  public void setAppDeploymentDescriptionIsSet(boolean value) {
    if (!value) {
      this.appDeploymentDescription = null;
    }
  }

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

  @org.apache.thrift.annotation.Nullable
  public java.util.Iterator<CommandObject> getModuleLoadCmdsIterator() {
    return (this.moduleLoadCmds == null) ? null : this.moduleLoadCmds.iterator();
  }

  public void addToModuleLoadCmds(CommandObject elem) {
    if (this.moduleLoadCmds == null) {
      this.moduleLoadCmds = new java.util.ArrayList<CommandObject>();
    }
    this.moduleLoadCmds.add(elem);
  }

  @org.apache.thrift.annotation.Nullable
  public java.util.List<CommandObject> getModuleLoadCmds() {
    return this.moduleLoadCmds;
  }

  public void setModuleLoadCmds(@org.apache.thrift.annotation.Nullable java.util.List<CommandObject> moduleLoadCmds) {
    this.moduleLoadCmds = moduleLoadCmds;
  }

  public void unsetModuleLoadCmds() {
    this.moduleLoadCmds = null;
  }

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

  public void setModuleLoadCmdsIsSet(boolean value) {
    if (!value) {
      this.moduleLoadCmds = null;
    }
  }

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

  @org.apache.thrift.annotation.Nullable
  public java.util.Iterator<SetEnvPaths> getLibPrependPathsIterator() {
    return (this.libPrependPaths == null) ? null : this.libPrependPaths.iterator();
  }

  public void addToLibPrependPaths(SetEnvPaths elem) {
    if (this.libPrependPaths == null) {
      this.libPrependPaths = new java.util.ArrayList<SetEnvPaths>();
    }
    this.libPrependPaths.add(elem);
  }

  @org.apache.thrift.annotation.Nullable
  public java.util.List<SetEnvPaths> getLibPrependPaths() {
    return this.libPrependPaths;
  }

  public void setLibPrependPaths(@org.apache.thrift.annotation.Nullable java.util.List<SetEnvPaths> libPrependPaths) {
    this.libPrependPaths = libPrependPaths;
  }

  public void unsetLibPrependPaths() {
    this.libPrependPaths = null;
  }

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

  public void setLibPrependPathsIsSet(boolean value) {
    if (!value) {
      this.libPrependPaths = null;
    }
  }

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

  @org.apache.thrift.annotation.Nullable
  public java.util.Iterator<SetEnvPaths> getLibAppendPathsIterator() {
    return (this.libAppendPaths == null) ? null : this.libAppendPaths.iterator();
  }

  public void addToLibAppendPaths(SetEnvPaths elem) {
    if (this.libAppendPaths == null) {
      this.libAppendPaths = new java.util.ArrayList<SetEnvPaths>();
    }
    this.libAppendPaths.add(elem);
  }

  @org.apache.thrift.annotation.Nullable
  public java.util.List<SetEnvPaths> getLibAppendPaths() {
    return this.libAppendPaths;
  }

  public void setLibAppendPaths(@org.apache.thrift.annotation.Nullable java.util.List<SetEnvPaths> libAppendPaths) {
    this.libAppendPaths = libAppendPaths;
  }

  public void unsetLibAppendPaths() {
    this.libAppendPaths = null;
  }

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

  public void setLibAppendPathsIsSet(boolean value) {
    if (!value) {
      this.libAppendPaths = null;
    }
  }

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

  @org.apache.thrift.annotation.Nullable
  public java.util.Iterator<SetEnvPaths> getSetEnvironmentIterator() {
    return (this.setEnvironment == null) ? null : this.setEnvironment.iterator();
  }

  public void addToSetEnvironment(SetEnvPaths elem) {
    if (this.setEnvironment == null) {
      this.setEnvironment = new java.util.ArrayList<SetEnvPaths>();
    }
    this.setEnvironment.add(elem);
  }

  @org.apache.thrift.annotation.Nullable
  public java.util.List<SetEnvPaths> getSetEnvironment() {
    return this.setEnvironment;
  }

  public void setSetEnvironment(@org.apache.thrift.annotation.Nullable java.util.List<SetEnvPaths> setEnvironment) {
    this.setEnvironment = setEnvironment;
  }

  public void unsetSetEnvironment() {
    this.setEnvironment = null;
  }

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

  public void setSetEnvironmentIsSet(boolean value) {
    if (!value) {
      this.setEnvironment = null;
    }
  }

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

  @org.apache.thrift.annotation.Nullable
  public java.util.Iterator<CommandObject> getPreJobCommandsIterator() {
    return (this.preJobCommands == null) ? null : this.preJobCommands.iterator();
  }

  public void addToPreJobCommands(CommandObject elem) {
    if (this.preJobCommands == null) {
      this.preJobCommands = new java.util.ArrayList<CommandObject>();
    }
    this.preJobCommands.add(elem);
  }

  @org.apache.thrift.annotation.Nullable
  public java.util.List<CommandObject> getPreJobCommands() {
    return this.preJobCommands;
  }

  public void setPreJobCommands(@org.apache.thrift.annotation.Nullable java.util.List<CommandObject> preJobCommands) {
    this.preJobCommands = preJobCommands;
  }

  public void unsetPreJobCommands() {
    this.preJobCommands = null;
  }

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

  public void setPreJobCommandsIsSet(boolean value) {
    if (!value) {
      this.preJobCommands = null;
    }
  }

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

  @org.apache.thrift.annotation.Nullable
  public java.util.Iterator<CommandObject> getPostJobCommandsIterator() {
    return (this.postJobCommands == null) ? null : this.postJobCommands.iterator();
  }

  public void addToPostJobCommands(CommandObject elem) {
    if (this.postJobCommands == null) {
      this.postJobCommands = new java.util.ArrayList<CommandObject>();
    }
    this.postJobCommands.add(elem);
  }

  @org.apache.thrift.annotation.Nullable
  public java.util.List<CommandObject> getPostJobCommands() {
    return this.postJobCommands;
  }

  public void setPostJobCommands(@org.apache.thrift.annotation.Nullable java.util.List<CommandObject> postJobCommands) {
    this.postJobCommands = postJobCommands;
  }

  public void unsetPostJobCommands() {
    this.postJobCommands = null;
  }

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

  public void setPostJobCommandsIsSet(boolean value) {
    if (!value) {
      this.postJobCommands = null;
    }
  }

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

  public void setDefaultQueueName(@org.apache.thrift.annotation.Nullable java.lang.String defaultQueueName) {
    this.defaultQueueName = defaultQueueName;
  }

  public void unsetDefaultQueueName() {
    this.defaultQueueName = null;
  }

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

  public void setDefaultQueueNameIsSet(boolean value) {
    if (!value) {
      this.defaultQueueName = null;
    }
  }

  public int getDefaultNodeCount() {
    return this.defaultNodeCount;
  }

  public void setDefaultNodeCount(int defaultNodeCount) {
    this.defaultNodeCount = defaultNodeCount;
    setDefaultNodeCountIsSet(true);
  }

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

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

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

  public int getDefaultCPUCount() {
    return this.defaultCPUCount;
  }

  public void setDefaultCPUCount(int defaultCPUCount) {
    this.defaultCPUCount = defaultCPUCount;
    setDefaultCPUCountIsSet(true);
  }

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

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

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

  public int getDefaultWalltime() {
    return this.defaultWalltime;
  }

  public void setDefaultWalltime(int defaultWalltime) {
    this.defaultWalltime = defaultWalltime;
    setDefaultWalltimeIsSet(true);
  }

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

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

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

  public boolean isEditableByUser() {
    return this.editableByUser;
  }

  public void setEditableByUser(boolean editableByUser) {
    this.editableByUser = editableByUser;
    setEditableByUserIsSet(true);
  }

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

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

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

  @Override
  public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
    switch (field) {
    case APP_DEPLOYMENT_ID:
      if (value == null) {
        unsetAppDeploymentId();
      } else {
        setAppDeploymentId((java.lang.String)value);
      }
      break;

    case APP_MODULE_ID:
      if (value == null) {
        unsetAppModuleId();
      } else {
        setAppModuleId((java.lang.String)value);
      }
      break;

    case COMPUTE_HOST_ID:
      if (value == null) {
        unsetComputeHostId();
      } else {
        setComputeHostId((java.lang.String)value);
      }
      break;

    case EXECUTABLE_PATH:
      if (value == null) {
        unsetExecutablePath();
      } else {
        setExecutablePath((java.lang.String)value);
      }
      break;

    case PARALLELISM:
      if (value == null) {
        unsetParallelism();
      } else {
        setParallelism((org.apache.airavata.model.parallelism.ApplicationParallelismType)value);
      }
      break;

    case APP_DEPLOYMENT_DESCRIPTION:
      if (value == null) {
        unsetAppDeploymentDescription();
      } else {
        setAppDeploymentDescription((java.lang.String)value);
      }
      break;

    case MODULE_LOAD_CMDS:
      if (value == null) {
        unsetModuleLoadCmds();
      } else {
        setModuleLoadCmds((java.util.List<CommandObject>)value);
      }
      break;

    case LIB_PREPEND_PATHS:
      if (value == null) {
        unsetLibPrependPaths();
      } else {
        setLibPrependPaths((java.util.List<SetEnvPaths>)value);
      }
      break;

    case LIB_APPEND_PATHS:
      if (value == null) {
        unsetLibAppendPaths();
      } else {
        setLibAppendPaths((java.util.List<SetEnvPaths>)value);
      }
      break;

    case SET_ENVIRONMENT:
      if (value == null) {
        unsetSetEnvironment();
      } else {
        setSetEnvironment((java.util.List<SetEnvPaths>)value);
      }
      break;

    case PRE_JOB_COMMANDS:
      if (value == null) {
        unsetPreJobCommands();
      } else {
        setPreJobCommands((java.util.List<CommandObject>)value);
      }
      break;

    case POST_JOB_COMMANDS:
      if (value == null) {
        unsetPostJobCommands();
      } else {
        setPostJobCommands((java.util.List<CommandObject>)value);
      }
      break;

    case DEFAULT_QUEUE_NAME:
      if (value == null) {
        unsetDefaultQueueName();
      } else {
        setDefaultQueueName((java.lang.String)value);
      }
      break;

    case DEFAULT_NODE_COUNT:
      if (value == null) {
        unsetDefaultNodeCount();
      } else {
        setDefaultNodeCount((java.lang.Integer)value);
      }
      break;

    case DEFAULT_CPUCOUNT:
      if (value == null) {
        unsetDefaultCPUCount();
      } else {
        setDefaultCPUCount((java.lang.Integer)value);
      }
      break;

    case DEFAULT_WALLTIME:
      if (value == null) {
        unsetDefaultWalltime();
      } else {
        setDefaultWalltime((java.lang.Integer)value);
      }
      break;

    case EDITABLE_BY_USER:
      if (value == null) {
        unsetEditableByUser();
      } else {
        setEditableByUser((java.lang.Boolean)value);
      }
      break;

    }
  }

  @org.apache.thrift.annotation.Nullable
  @Override
  public java.lang.Object getFieldValue(_Fields field) {
    switch (field) {
    case APP_DEPLOYMENT_ID:
      return getAppDeploymentId();

    case APP_MODULE_ID:
      return getAppModuleId();

    case COMPUTE_HOST_ID:
      return getComputeHostId();

    case EXECUTABLE_PATH:
      return getExecutablePath();

    case PARALLELISM:
      return getParallelism();

    case APP_DEPLOYMENT_DESCRIPTION:
      return getAppDeploymentDescription();

    case MODULE_LOAD_CMDS:
      return getModuleLoadCmds();

    case LIB_PREPEND_PATHS:
      return getLibPrependPaths();

    case LIB_APPEND_PATHS:
      return getLibAppendPaths();

    case SET_ENVIRONMENT:
      return getSetEnvironment();

    case PRE_JOB_COMMANDS:
      return getPreJobCommands();

    case POST_JOB_COMMANDS:
      return getPostJobCommands();

    case DEFAULT_QUEUE_NAME:
      return getDefaultQueueName();

    case DEFAULT_NODE_COUNT:
      return getDefaultNodeCount();

    case DEFAULT_CPUCOUNT:
      return getDefaultCPUCount();

    case DEFAULT_WALLTIME:
      return getDefaultWalltime();

    case EDITABLE_BY_USER:
      return isEditableByUser();

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

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

    switch (field) {
    case APP_DEPLOYMENT_ID:
      return isSetAppDeploymentId();
    case APP_MODULE_ID:
      return isSetAppModuleId();
    case COMPUTE_HOST_ID:
      return isSetComputeHostId();
    case EXECUTABLE_PATH:
      return isSetExecutablePath();
    case PARALLELISM:
      return isSetParallelism();
    case APP_DEPLOYMENT_DESCRIPTION:
      return isSetAppDeploymentDescription();
    case MODULE_LOAD_CMDS:
      return isSetModuleLoadCmds();
    case LIB_PREPEND_PATHS:
      return isSetLibPrependPaths();
    case LIB_APPEND_PATHS:
      return isSetLibAppendPaths();
    case SET_ENVIRONMENT:
      return isSetSetEnvironment();
    case PRE_JOB_COMMANDS:
      return isSetPreJobCommands();
    case POST_JOB_COMMANDS:
      return isSetPostJobCommands();
    case DEFAULT_QUEUE_NAME:
      return isSetDefaultQueueName();
    case DEFAULT_NODE_COUNT:
      return isSetDefaultNodeCount();
    case DEFAULT_CPUCOUNT:
      return isSetDefaultCPUCount();
    case DEFAULT_WALLTIME:
      return isSetDefaultWalltime();
    case EDITABLE_BY_USER:
      return isSetEditableByUser();
    }
    throw new java.lang.IllegalStateException();
  }

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

  public boolean equals(ApplicationDeploymentDescription that) {
    if (that == null)
      return false;
    if (this == that)
      return true;

    boolean this_present_appDeploymentId = true && this.isSetAppDeploymentId();
    boolean that_present_appDeploymentId = true && that.isSetAppDeploymentId();
    if (this_present_appDeploymentId || that_present_appDeploymentId) {
      if (!(this_present_appDeploymentId && that_present_appDeploymentId))
        return false;
      if (!this.appDeploymentId.equals(that.appDeploymentId))
        return false;
    }

    boolean this_present_appModuleId = true && this.isSetAppModuleId();
    boolean that_present_appModuleId = true && that.isSetAppModuleId();
    if (this_present_appModuleId || that_present_appModuleId) {
      if (!(this_present_appModuleId && that_present_appModuleId))
        return false;
      if (!this.appModuleId.equals(that.appModuleId))
        return false;
    }

    boolean this_present_computeHostId = true && this.isSetComputeHostId();
    boolean that_present_computeHostId = true && that.isSetComputeHostId();
    if (this_present_computeHostId || that_present_computeHostId) {
      if (!(this_present_computeHostId && that_present_computeHostId))
        return false;
      if (!this.computeHostId.equals(that.computeHostId))
        return false;
    }

    boolean this_present_executablePath = true && this.isSetExecutablePath();
    boolean that_present_executablePath = true && that.isSetExecutablePath();
    if (this_present_executablePath || that_present_executablePath) {
      if (!(this_present_executablePath && that_present_executablePath))
        return false;
      if (!this.executablePath.equals(that.executablePath))
        return false;
    }

    boolean this_present_parallelism = true && this.isSetParallelism();
    boolean that_present_parallelism = true && that.isSetParallelism();
    if (this_present_parallelism || that_present_parallelism) {
      if (!(this_present_parallelism && that_present_parallelism))
        return false;
      if (!this.parallelism.equals(that.parallelism))
        return false;
    }

    boolean this_present_appDeploymentDescription = true && this.isSetAppDeploymentDescription();
    boolean that_present_appDeploymentDescription = true && that.isSetAppDeploymentDescription();
    if (this_present_appDeploymentDescription || that_present_appDeploymentDescription) {
      if (!(this_present_appDeploymentDescription && that_present_appDeploymentDescription))
        return false;
      if (!this.appDeploymentDescription.equals(that.appDeploymentDescription))
        return false;
    }

    boolean this_present_moduleLoadCmds = true && this.isSetModuleLoadCmds();
    boolean that_present_moduleLoadCmds = true && that.isSetModuleLoadCmds();
    if (this_present_moduleLoadCmds || that_present_moduleLoadCmds) {
      if (!(this_present_moduleLoadCmds && that_present_moduleLoadCmds))
        return false;
      if (!this.moduleLoadCmds.equals(that.moduleLoadCmds))
        return false;
    }

    boolean this_present_libPrependPaths = true && this.isSetLibPrependPaths();
    boolean that_present_libPrependPaths = true && that.isSetLibPrependPaths();
    if (this_present_libPrependPaths || that_present_libPrependPaths) {
      if (!(this_present_libPrependPaths && that_present_libPrependPaths))
        return false;
      if (!this.libPrependPaths.equals(that.libPrependPaths))
        return false;
    }

    boolean this_present_libAppendPaths = true && this.isSetLibAppendPaths();
    boolean that_present_libAppendPaths = true && that.isSetLibAppendPaths();
    if (this_present_libAppendPaths || that_present_libAppendPaths) {
      if (!(this_present_libAppendPaths && that_present_libAppendPaths))
        return false;
      if (!this.libAppendPaths.equals(that.libAppendPaths))
        return false;
    }

    boolean this_present_setEnvironment = true && this.isSetSetEnvironment();
    boolean that_present_setEnvironment = true && that.isSetSetEnvironment();
    if (this_present_setEnvironment || that_present_setEnvironment) {
      if (!(this_present_setEnvironment && that_present_setEnvironment))
        return false;
      if (!this.setEnvironment.equals(that.setEnvironment))
        return false;
    }

    boolean this_present_preJobCommands = true && this.isSetPreJobCommands();
    boolean that_present_preJobCommands = true && that.isSetPreJobCommands();
    if (this_present_preJobCommands || that_present_preJobCommands) {
      if (!(this_present_preJobCommands && that_present_preJobCommands))
        return false;
      if (!this.preJobCommands.equals(that.preJobCommands))
        return false;
    }

    boolean this_present_postJobCommands = true && this.isSetPostJobCommands();
    boolean that_present_postJobCommands = true && that.isSetPostJobCommands();
    if (this_present_postJobCommands || that_present_postJobCommands) {
      if (!(this_present_postJobCommands && that_present_postJobCommands))
        return false;
      if (!this.postJobCommands.equals(that.postJobCommands))
        return false;
    }

    boolean this_present_defaultQueueName = true && this.isSetDefaultQueueName();
    boolean that_present_defaultQueueName = true && that.isSetDefaultQueueName();
    if (this_present_defaultQueueName || that_present_defaultQueueName) {
      if (!(this_present_defaultQueueName && that_present_defaultQueueName))
        return false;
      if (!this.defaultQueueName.equals(that.defaultQueueName))
        return false;
    }

    boolean this_present_defaultNodeCount = true && this.isSetDefaultNodeCount();
    boolean that_present_defaultNodeCount = true && that.isSetDefaultNodeCount();
    if (this_present_defaultNodeCount || that_present_defaultNodeCount) {
      if (!(this_present_defaultNodeCount && that_present_defaultNodeCount))
        return false;
      if (this.defaultNodeCount != that.defaultNodeCount)
        return false;
    }

    boolean this_present_defaultCPUCount = true && this.isSetDefaultCPUCount();
    boolean that_present_defaultCPUCount = true && that.isSetDefaultCPUCount();
    if (this_present_defaultCPUCount || that_present_defaultCPUCount) {
      if (!(this_present_defaultCPUCount && that_present_defaultCPUCount))
        return false;
      if (this.defaultCPUCount != that.defaultCPUCount)
        return false;
    }

    boolean this_present_defaultWalltime = true && this.isSetDefaultWalltime();
    boolean that_present_defaultWalltime = true && that.isSetDefaultWalltime();
    if (this_present_defaultWalltime || that_present_defaultWalltime) {
      if (!(this_present_defaultWalltime && that_present_defaultWalltime))
        return false;
      if (this.defaultWalltime != that.defaultWalltime)
        return false;
    }

    boolean this_present_editableByUser = true && this.isSetEditableByUser();
    boolean that_present_editableByUser = true && that.isSetEditableByUser();
    if (this_present_editableByUser || that_present_editableByUser) {
      if (!(this_present_editableByUser && that_present_editableByUser))
        return false;
      if (this.editableByUser != that.editableByUser)
        return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    int hashCode = 1;

    hashCode = hashCode * 8191 + ((isSetAppDeploymentId()) ? 131071 : 524287);
    if (isSetAppDeploymentId())
      hashCode = hashCode * 8191 + appDeploymentId.hashCode();

    hashCode = hashCode * 8191 + ((isSetAppModuleId()) ? 131071 : 524287);
    if (isSetAppModuleId())
      hashCode = hashCode * 8191 + appModuleId.hashCode();

    hashCode = hashCode * 8191 + ((isSetComputeHostId()) ? 131071 : 524287);
    if (isSetComputeHostId())
      hashCode = hashCode * 8191 + computeHostId.hashCode();

    hashCode = hashCode * 8191 + ((isSetExecutablePath()) ? 131071 : 524287);
    if (isSetExecutablePath())
      hashCode = hashCode * 8191 + executablePath.hashCode();

    hashCode = hashCode * 8191 + ((isSetParallelism()) ? 131071 : 524287);
    if (isSetParallelism())
      hashCode = hashCode * 8191 + parallelism.getValue();

    hashCode = hashCode * 8191 + ((isSetAppDeploymentDescription()) ? 131071 : 524287);
    if (isSetAppDeploymentDescription())
      hashCode = hashCode * 8191 + appDeploymentDescription.hashCode();

    hashCode = hashCode * 8191 + ((isSetModuleLoadCmds()) ? 131071 : 524287);
    if (isSetModuleLoadCmds())
      hashCode = hashCode * 8191 + moduleLoadCmds.hashCode();

    hashCode = hashCode * 8191 + ((isSetLibPrependPaths()) ? 131071 : 524287);
    if (isSetLibPrependPaths())
      hashCode = hashCode * 8191 + libPrependPaths.hashCode();

    hashCode = hashCode * 8191 + ((isSetLibAppendPaths()) ? 131071 : 524287);
    if (isSetLibAppendPaths())
      hashCode = hashCode * 8191 + libAppendPaths.hashCode();

    hashCode = hashCode * 8191 + ((isSetSetEnvironment()) ? 131071 : 524287);
    if (isSetSetEnvironment())
      hashCode = hashCode * 8191 + setEnvironment.hashCode();

    hashCode = hashCode * 8191 + ((isSetPreJobCommands()) ? 131071 : 524287);
    if (isSetPreJobCommands())
      hashCode = hashCode * 8191 + preJobCommands.hashCode();

    hashCode = hashCode * 8191 + ((isSetPostJobCommands()) ? 131071 : 524287);
    if (isSetPostJobCommands())
      hashCode = hashCode * 8191 + postJobCommands.hashCode();

    hashCode = hashCode * 8191 + ((isSetDefaultQueueName()) ? 131071 : 524287);
    if (isSetDefaultQueueName())
      hashCode = hashCode * 8191 + defaultQueueName.hashCode();

    hashCode = hashCode * 8191 + ((isSetDefaultNodeCount()) ? 131071 : 524287);
    if (isSetDefaultNodeCount())
      hashCode = hashCode * 8191 + defaultNodeCount;

    hashCode = hashCode * 8191 + ((isSetDefaultCPUCount()) ? 131071 : 524287);
    if (isSetDefaultCPUCount())
      hashCode = hashCode * 8191 + defaultCPUCount;

    hashCode = hashCode * 8191 + ((isSetDefaultWalltime()) ? 131071 : 524287);
    if (isSetDefaultWalltime())
      hashCode = hashCode * 8191 + defaultWalltime;

    hashCode = hashCode * 8191 + ((isSetEditableByUser()) ? 131071 : 524287);
    if (isSetEditableByUser())
      hashCode = hashCode * 8191 + ((editableByUser) ? 131071 : 524287);

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.compare(isSetAppDeploymentId(), other.isSetAppDeploymentId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetAppDeploymentId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.appDeploymentId, other.appDeploymentId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetAppModuleId(), other.isSetAppModuleId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetAppModuleId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.appModuleId, other.appModuleId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetComputeHostId(), other.isSetComputeHostId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetComputeHostId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeHostId, other.computeHostId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetExecutablePath(), other.isSetExecutablePath());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetExecutablePath()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.executablePath, other.executablePath);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetParallelism(), other.isSetParallelism());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetParallelism()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.parallelism, other.parallelism);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetAppDeploymentDescription(), other.isSetAppDeploymentDescription());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetAppDeploymentDescription()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.appDeploymentDescription, other.appDeploymentDescription);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetModuleLoadCmds(), other.isSetModuleLoadCmds());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetModuleLoadCmds()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.moduleLoadCmds, other.moduleLoadCmds);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetLibPrependPaths(), other.isSetLibPrependPaths());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetLibPrependPaths()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.libPrependPaths, other.libPrependPaths);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetLibAppendPaths(), other.isSetLibAppendPaths());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetLibAppendPaths()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.libAppendPaths, other.libAppendPaths);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetSetEnvironment(), other.isSetSetEnvironment());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetSetEnvironment()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.setEnvironment, other.setEnvironment);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetPreJobCommands(), other.isSetPreJobCommands());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetPreJobCommands()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.preJobCommands, other.preJobCommands);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetPostJobCommands(), other.isSetPostJobCommands());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetPostJobCommands()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.postJobCommands, other.postJobCommands);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetDefaultQueueName(), other.isSetDefaultQueueName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetDefaultQueueName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.defaultQueueName, other.defaultQueueName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetDefaultNodeCount(), other.isSetDefaultNodeCount());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetDefaultNodeCount()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.defaultNodeCount, other.defaultNodeCount);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetDefaultCPUCount(), other.isSetDefaultCPUCount());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetDefaultCPUCount()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.defaultCPUCount, other.defaultCPUCount);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetDefaultWalltime(), other.isSetDefaultWalltime());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetDefaultWalltime()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.defaultWalltime, other.defaultWalltime);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetEditableByUser(), other.isSetEditableByUser());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetEditableByUser()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.editableByUser, other.editableByUser);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

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

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

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

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

    sb.append("appDeploymentId:");
    if (this.appDeploymentId == null) {
      sb.append("null");
    } else {
      sb.append(this.appDeploymentId);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("appModuleId:");
    if (this.appModuleId == null) {
      sb.append("null");
    } else {
      sb.append(this.appModuleId);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("computeHostId:");
    if (this.computeHostId == null) {
      sb.append("null");
    } else {
      sb.append(this.computeHostId);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("executablePath:");
    if (this.executablePath == null) {
      sb.append("null");
    } else {
      sb.append(this.executablePath);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("parallelism:");
    if (this.parallelism == null) {
      sb.append("null");
    } else {
      sb.append(this.parallelism);
    }
    first = false;
    if (isSetAppDeploymentDescription()) {
      if (!first) sb.append(", ");
      sb.append("appDeploymentDescription:");
      if (this.appDeploymentDescription == null) {
        sb.append("null");
      } else {
        sb.append(this.appDeploymentDescription);
      }
      first = false;
    }
    if (isSetModuleLoadCmds()) {
      if (!first) sb.append(", ");
      sb.append("moduleLoadCmds:");
      if (this.moduleLoadCmds == null) {
        sb.append("null");
      } else {
        sb.append(this.moduleLoadCmds);
      }
      first = false;
    }
    if (isSetLibPrependPaths()) {
      if (!first) sb.append(", ");
      sb.append("libPrependPaths:");
      if (this.libPrependPaths == null) {
        sb.append("null");
      } else {
        sb.append(this.libPrependPaths);
      }
      first = false;
    }
    if (isSetLibAppendPaths()) {
      if (!first) sb.append(", ");
      sb.append("libAppendPaths:");
      if (this.libAppendPaths == null) {
        sb.append("null");
      } else {
        sb.append(this.libAppendPaths);
      }
      first = false;
    }
    if (isSetSetEnvironment()) {
      if (!first) sb.append(", ");
      sb.append("setEnvironment:");
      if (this.setEnvironment == null) {
        sb.append("null");
      } else {
        sb.append(this.setEnvironment);
      }
      first = false;
    }
    if (isSetPreJobCommands()) {
      if (!first) sb.append(", ");
      sb.append("preJobCommands:");
      if (this.preJobCommands == null) {
        sb.append("null");
      } else {
        sb.append(this.preJobCommands);
      }
      first = false;
    }
    if (isSetPostJobCommands()) {
      if (!first) sb.append(", ");
      sb.append("postJobCommands:");
      if (this.postJobCommands == null) {
        sb.append("null");
      } else {
        sb.append(this.postJobCommands);
      }
      first = false;
    }
    if (isSetDefaultQueueName()) {
      if (!first) sb.append(", ");
      sb.append("defaultQueueName:");
      if (this.defaultQueueName == null) {
        sb.append("null");
      } else {
        sb.append(this.defaultQueueName);
      }
      first = false;
    }
    if (isSetDefaultNodeCount()) {
      if (!first) sb.append(", ");
      sb.append("defaultNodeCount:");
      sb.append(this.defaultNodeCount);
      first = false;
    }
    if (isSetDefaultCPUCount()) {
      if (!first) sb.append(", ");
      sb.append("defaultCPUCount:");
      sb.append(this.defaultCPUCount);
      first = false;
    }
    if (isSetDefaultWalltime()) {
      if (!first) sb.append(", ");
      sb.append("defaultWalltime:");
      sb.append(this.defaultWalltime);
      first = false;
    }
    if (isSetEditableByUser()) {
      if (!first) sb.append(", ");
      sb.append("editableByUser:");
      sb.append(this.editableByUser);
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

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

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

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

    if (!isSetParallelism()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'parallelism' 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 ApplicationDeploymentDescriptionStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    @Override
    public ApplicationDeploymentDescriptionStandardScheme getScheme() {
      return new ApplicationDeploymentDescriptionStandardScheme();
    }
  }

  private static class ApplicationDeploymentDescriptionStandardScheme extends org.apache.thrift.scheme.StandardScheme<ApplicationDeploymentDescription> {

    @Override
    public void read(org.apache.thrift.protocol.TProtocol iprot, ApplicationDeploymentDescription 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: // APP_DEPLOYMENT_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.appDeploymentId = iprot.readString();
              struct.setAppDeploymentIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // APP_MODULE_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.appModuleId = iprot.readString();
              struct.setAppModuleIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // COMPUTE_HOST_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.computeHostId = iprot.readString();
              struct.setComputeHostIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // EXECUTABLE_PATH
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.executablePath = iprot.readString();
              struct.setExecutablePathIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // PARALLELISM
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.parallelism = org.apache.airavata.model.parallelism.ApplicationParallelismType.findByValue(iprot.readI32());
              struct.setParallelismIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // APP_DEPLOYMENT_DESCRIPTION
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.appDeploymentDescription = iprot.readString();
              struct.setAppDeploymentDescriptionIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // MODULE_LOAD_CMDS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list0 = iprot.readListBegin();
                struct.moduleLoadCmds = new java.util.ArrayList<CommandObject>(_list0.size);
                @org.apache.thrift.annotation.Nullable CommandObject _elem1;
                for (int _i2 = 0; _i2 < _list0.size; ++_i2)
                {
                  _elem1 = new CommandObject();
                  _elem1.read(iprot);
                  struct.moduleLoadCmds.add(_elem1);
                }
                iprot.readListEnd();
              }
              struct.setModuleLoadCmdsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // LIB_PREPEND_PATHS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list3 = iprot.readListBegin();
                struct.libPrependPaths = new java.util.ArrayList<SetEnvPaths>(_list3.size);
                @org.apache.thrift.annotation.Nullable SetEnvPaths _elem4;
                for (int _i5 = 0; _i5 < _list3.size; ++_i5)
                {
                  _elem4 = new SetEnvPaths();
                  _elem4.read(iprot);
                  struct.libPrependPaths.add(_elem4);
                }
                iprot.readListEnd();
              }
              struct.setLibPrependPathsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // LIB_APPEND_PATHS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list6 = iprot.readListBegin();
                struct.libAppendPaths = new java.util.ArrayList<SetEnvPaths>(_list6.size);
                @org.apache.thrift.annotation.Nullable SetEnvPaths _elem7;
                for (int _i8 = 0; _i8 < _list6.size; ++_i8)
                {
                  _elem7 = new SetEnvPaths();
                  _elem7.read(iprot);
                  struct.libAppendPaths.add(_elem7);
                }
                iprot.readListEnd();
              }
              struct.setLibAppendPathsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // SET_ENVIRONMENT
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list9 = iprot.readListBegin();
                struct.setEnvironment = new java.util.ArrayList<SetEnvPaths>(_list9.size);
                @org.apache.thrift.annotation.Nullable SetEnvPaths _elem10;
                for (int _i11 = 0; _i11 < _list9.size; ++_i11)
                {
                  _elem10 = new SetEnvPaths();
                  _elem10.read(iprot);
                  struct.setEnvironment.add(_elem10);
                }
                iprot.readListEnd();
              }
              struct.setSetEnvironmentIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 11: // PRE_JOB_COMMANDS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list12 = iprot.readListBegin();
                struct.preJobCommands = new java.util.ArrayList<CommandObject>(_list12.size);
                @org.apache.thrift.annotation.Nullable CommandObject _elem13;
                for (int _i14 = 0; _i14 < _list12.size; ++_i14)
                {
                  _elem13 = new CommandObject();
                  _elem13.read(iprot);
                  struct.preJobCommands.add(_elem13);
                }
                iprot.readListEnd();
              }
              struct.setPreJobCommandsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 12: // POST_JOB_COMMANDS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list15 = iprot.readListBegin();
                struct.postJobCommands = new java.util.ArrayList<CommandObject>(_list15.size);
                @org.apache.thrift.annotation.Nullable CommandObject _elem16;
                for (int _i17 = 0; _i17 < _list15.size; ++_i17)
                {
                  _elem16 = new CommandObject();
                  _elem16.read(iprot);
                  struct.postJobCommands.add(_elem16);
                }
                iprot.readListEnd();
              }
              struct.setPostJobCommandsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 13: // DEFAULT_QUEUE_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.defaultQueueName = iprot.readString();
              struct.setDefaultQueueNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 14: // DEFAULT_NODE_COUNT
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.defaultNodeCount = iprot.readI32();
              struct.setDefaultNodeCountIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 15: // DEFAULT_CPUCOUNT
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.defaultCPUCount = iprot.readI32();
              struct.setDefaultCPUCountIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 16: // DEFAULT_WALLTIME
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.defaultWalltime = iprot.readI32();
              struct.setDefaultWalltimeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 17: // EDITABLE_BY_USER
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.editableByUser = iprot.readBool();
              struct.setEditableByUserIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          default:
            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
      struct.validate();
    }

    @Override
    public void write(org.apache.thrift.protocol.TProtocol oprot, ApplicationDeploymentDescription struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.appDeploymentId != null) {
        oprot.writeFieldBegin(APP_DEPLOYMENT_ID_FIELD_DESC);
        oprot.writeString(struct.appDeploymentId);
        oprot.writeFieldEnd();
      }
      if (struct.appModuleId != null) {
        oprot.writeFieldBegin(APP_MODULE_ID_FIELD_DESC);
        oprot.writeString(struct.appModuleId);
        oprot.writeFieldEnd();
      }
      if (struct.computeHostId != null) {
        oprot.writeFieldBegin(COMPUTE_HOST_ID_FIELD_DESC);
        oprot.writeString(struct.computeHostId);
        oprot.writeFieldEnd();
      }
      if (struct.executablePath != null) {
        oprot.writeFieldBegin(EXECUTABLE_PATH_FIELD_DESC);
        oprot.writeString(struct.executablePath);
        oprot.writeFieldEnd();
      }
      if (struct.parallelism != null) {
        oprot.writeFieldBegin(PARALLELISM_FIELD_DESC);
        oprot.writeI32(struct.parallelism.getValue());
        oprot.writeFieldEnd();
      }
      if (struct.appDeploymentDescription != null) {
        if (struct.isSetAppDeploymentDescription()) {
          oprot.writeFieldBegin(APP_DEPLOYMENT_DESCRIPTION_FIELD_DESC);
          oprot.writeString(struct.appDeploymentDescription);
          oprot.writeFieldEnd();
        }
      }
      if (struct.moduleLoadCmds != null) {
        if (struct.isSetModuleLoadCmds()) {
          oprot.writeFieldBegin(MODULE_LOAD_CMDS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.moduleLoadCmds.size()));
            for (CommandObject _iter18 : struct.moduleLoadCmds)
            {
              _iter18.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.libPrependPaths != null) {
        if (struct.isSetLibPrependPaths()) {
          oprot.writeFieldBegin(LIB_PREPEND_PATHS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.libPrependPaths.size()));
            for (SetEnvPaths _iter19 : struct.libPrependPaths)
            {
              _iter19.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.libAppendPaths != null) {
        if (struct.isSetLibAppendPaths()) {
          oprot.writeFieldBegin(LIB_APPEND_PATHS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.libAppendPaths.size()));
            for (SetEnvPaths _iter20 : struct.libAppendPaths)
            {
              _iter20.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.setEnvironment != null) {
        if (struct.isSetSetEnvironment()) {
          oprot.writeFieldBegin(SET_ENVIRONMENT_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.setEnvironment.size()));
            for (SetEnvPaths _iter21 : struct.setEnvironment)
            {
              _iter21.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.preJobCommands != null) {
        if (struct.isSetPreJobCommands()) {
          oprot.writeFieldBegin(PRE_JOB_COMMANDS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.preJobCommands.size()));
            for (CommandObject _iter22 : struct.preJobCommands)
            {
              _iter22.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.postJobCommands != null) {
        if (struct.isSetPostJobCommands()) {
          oprot.writeFieldBegin(POST_JOB_COMMANDS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.postJobCommands.size()));
            for (CommandObject _iter23 : struct.postJobCommands)
            {
              _iter23.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.defaultQueueName != null) {
        if (struct.isSetDefaultQueueName()) {
          oprot.writeFieldBegin(DEFAULT_QUEUE_NAME_FIELD_DESC);
          oprot.writeString(struct.defaultQueueName);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetDefaultNodeCount()) {
        oprot.writeFieldBegin(DEFAULT_NODE_COUNT_FIELD_DESC);
        oprot.writeI32(struct.defaultNodeCount);
        oprot.writeFieldEnd();
      }
      if (struct.isSetDefaultCPUCount()) {
        oprot.writeFieldBegin(DEFAULT_CPUCOUNT_FIELD_DESC);
        oprot.writeI32(struct.defaultCPUCount);
        oprot.writeFieldEnd();
      }
      if (struct.isSetDefaultWalltime()) {
        oprot.writeFieldBegin(DEFAULT_WALLTIME_FIELD_DESC);
        oprot.writeI32(struct.defaultWalltime);
        oprot.writeFieldEnd();
      }
      if (struct.isSetEditableByUser()) {
        oprot.writeFieldBegin(EDITABLE_BY_USER_FIELD_DESC);
        oprot.writeBool(struct.editableByUser);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class ApplicationDeploymentDescriptionTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    @Override
    public ApplicationDeploymentDescriptionTupleScheme getScheme() {
      return new ApplicationDeploymentDescriptionTupleScheme();
    }
  }

  private static class ApplicationDeploymentDescriptionTupleScheme extends org.apache.thrift.scheme.TupleScheme<ApplicationDeploymentDescription> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, ApplicationDeploymentDescription struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      oprot.writeString(struct.appDeploymentId);
      oprot.writeString(struct.appModuleId);
      oprot.writeString(struct.computeHostId);
      oprot.writeString(struct.executablePath);
      oprot.writeI32(struct.parallelism.getValue());
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.isSetAppDeploymentDescription()) {
        optionals.set(0);
      }
      if (struct.isSetModuleLoadCmds()) {
        optionals.set(1);
      }
      if (struct.isSetLibPrependPaths()) {
        optionals.set(2);
      }
      if (struct.isSetLibAppendPaths()) {
        optionals.set(3);
      }
      if (struct.isSetSetEnvironment()) {
        optionals.set(4);
      }
      if (struct.isSetPreJobCommands()) {
        optionals.set(5);
      }
      if (struct.isSetPostJobCommands()) {
        optionals.set(6);
      }
      if (struct.isSetDefaultQueueName()) {
        optionals.set(7);
      }
      if (struct.isSetDefaultNodeCount()) {
        optionals.set(8);
      }
      if (struct.isSetDefaultCPUCount()) {
        optionals.set(9);
      }
      if (struct.isSetDefaultWalltime()) {
        optionals.set(10);
      }
      if (struct.isSetEditableByUser()) {
        optionals.set(11);
      }
      oprot.writeBitSet(optionals, 12);
      if (struct.isSetAppDeploymentDescription()) {
        oprot.writeString(struct.appDeploymentDescription);
      }
      if (struct.isSetModuleLoadCmds()) {
        {
          oprot.writeI32(struct.moduleLoadCmds.size());
          for (CommandObject _iter24 : struct.moduleLoadCmds)
          {
            _iter24.write(oprot);
          }
        }
      }
      if (struct.isSetLibPrependPaths()) {
        {
          oprot.writeI32(struct.libPrependPaths.size());
          for (SetEnvPaths _iter25 : struct.libPrependPaths)
          {
            _iter25.write(oprot);
          }
        }
      }
      if (struct.isSetLibAppendPaths()) {
        {
          oprot.writeI32(struct.libAppendPaths.size());
          for (SetEnvPaths _iter26 : struct.libAppendPaths)
          {
            _iter26.write(oprot);
          }
        }
      }
      if (struct.isSetSetEnvironment()) {
        {
          oprot.writeI32(struct.setEnvironment.size());
          for (SetEnvPaths _iter27 : struct.setEnvironment)
          {
            _iter27.write(oprot);
          }
        }
      }
      if (struct.isSetPreJobCommands()) {
        {
          oprot.writeI32(struct.preJobCommands.size());
          for (CommandObject _iter28 : struct.preJobCommands)
          {
            _iter28.write(oprot);
          }
        }
      }
      if (struct.isSetPostJobCommands()) {
        {
          oprot.writeI32(struct.postJobCommands.size());
          for (CommandObject _iter29 : struct.postJobCommands)
          {
            _iter29.write(oprot);
          }
        }
      }
      if (struct.isSetDefaultQueueName()) {
        oprot.writeString(struct.defaultQueueName);
      }
      if (struct.isSetDefaultNodeCount()) {
        oprot.writeI32(struct.defaultNodeCount);
      }
      if (struct.isSetDefaultCPUCount()) {
        oprot.writeI32(struct.defaultCPUCount);
      }
      if (struct.isSetDefaultWalltime()) {
        oprot.writeI32(struct.defaultWalltime);
      }
      if (struct.isSetEditableByUser()) {
        oprot.writeBool(struct.editableByUser);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, ApplicationDeploymentDescription struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      struct.appDeploymentId = iprot.readString();
      struct.setAppDeploymentIdIsSet(true);
      struct.appModuleId = iprot.readString();
      struct.setAppModuleIdIsSet(true);
      struct.computeHostId = iprot.readString();
      struct.setComputeHostIdIsSet(true);
      struct.executablePath = iprot.readString();
      struct.setExecutablePathIsSet(true);
      struct.parallelism = org.apache.airavata.model.parallelism.ApplicationParallelismType.findByValue(iprot.readI32());
      struct.setParallelismIsSet(true);
      java.util.BitSet incoming = iprot.readBitSet(12);
      if (incoming.get(0)) {
        struct.appDeploymentDescription = iprot.readString();
        struct.setAppDeploymentDescriptionIsSet(true);
      }
      if (incoming.get(1)) {
        {
          org.apache.thrift.protocol.TList _list30 = iprot.readListBegin(org.apache.thrift.protocol.TType.STRUCT);
          struct.moduleLoadCmds = new java.util.ArrayList<CommandObject>(_list30.size);
          @org.apache.thrift.annotation.Nullable CommandObject _elem31;
          for (int _i32 = 0; _i32 < _list30.size; ++_i32)
          {
            _elem31 = new CommandObject();
            _elem31.read(iprot);
            struct.moduleLoadCmds.add(_elem31);
          }
        }
        struct.setModuleLoadCmdsIsSet(true);
      }
      if (incoming.get(2)) {
        {
          org.apache.thrift.protocol.TList _list33 = iprot.readListBegin(org.apache.thrift.protocol.TType.STRUCT);
          struct.libPrependPaths = new java.util.ArrayList<SetEnvPaths>(_list33.size);
          @org.apache.thrift.annotation.Nullable SetEnvPaths _elem34;
          for (int _i35 = 0; _i35 < _list33.size; ++_i35)
          {
            _elem34 = new SetEnvPaths();
            _elem34.read(iprot);
            struct.libPrependPaths.add(_elem34);
          }
        }
        struct.setLibPrependPathsIsSet(true);
      }
      if (incoming.get(3)) {
        {
          org.apache.thrift.protocol.TList _list36 = iprot.readListBegin(org.apache.thrift.protocol.TType.STRUCT);
          struct.libAppendPaths = new java.util.ArrayList<SetEnvPaths>(_list36.size);
          @org.apache.thrift.annotation.Nullable SetEnvPaths _elem37;
          for (int _i38 = 0; _i38 < _list36.size; ++_i38)
          {
            _elem37 = new SetEnvPaths();
            _elem37.read(iprot);
            struct.libAppendPaths.add(_elem37);
          }
        }
        struct.setLibAppendPathsIsSet(true);
      }
      if (incoming.get(4)) {
        {
          org.apache.thrift.protocol.TList _list39 = iprot.readListBegin(org.apache.thrift.protocol.TType.STRUCT);
          struct.setEnvironment = new java.util.ArrayList<SetEnvPaths>(_list39.size);
          @org.apache.thrift.annotation.Nullable SetEnvPaths _elem40;
          for (int _i41 = 0; _i41 < _list39.size; ++_i41)
          {
            _elem40 = new SetEnvPaths();
            _elem40.read(iprot);
            struct.setEnvironment.add(_elem40);
          }
        }
        struct.setSetEnvironmentIsSet(true);
      }
      if (incoming.get(5)) {
        {
          org.apache.thrift.protocol.TList _list42 = iprot.readListBegin(org.apache.thrift.protocol.TType.STRUCT);
          struct.preJobCommands = new java.util.ArrayList<CommandObject>(_list42.size);
          @org.apache.thrift.annotation.Nullable CommandObject _elem43;
          for (int _i44 = 0; _i44 < _list42.size; ++_i44)
          {
            _elem43 = new CommandObject();
            _elem43.read(iprot);
            struct.preJobCommands.add(_elem43);
          }
        }
        struct.setPreJobCommandsIsSet(true);
      }
      if (incoming.get(6)) {
        {
          org.apache.thrift.protocol.TList _list45 = iprot.readListBegin(org.apache.thrift.protocol.TType.STRUCT);
          struct.postJobCommands = new java.util.ArrayList<CommandObject>(_list45.size);
          @org.apache.thrift.annotation.Nullable CommandObject _elem46;
          for (int _i47 = 0; _i47 < _list45.size; ++_i47)
          {
            _elem46 = new CommandObject();
            _elem46.read(iprot);
            struct.postJobCommands.add(_elem46);
          }
        }
        struct.setPostJobCommandsIsSet(true);
      }
      if (incoming.get(7)) {
        struct.defaultQueueName = iprot.readString();
        struct.setDefaultQueueNameIsSet(true);
      }
      if (incoming.get(8)) {
        struct.defaultNodeCount = iprot.readI32();
        struct.setDefaultNodeCountIsSet(true);
      }
      if (incoming.get(9)) {
        struct.defaultCPUCount = iprot.readI32();
        struct.setDefaultCPUCountIsSet(true);
      }
      if (incoming.get(10)) {
        struct.defaultWalltime = iprot.readI32();
        struct.setDefaultWalltimeIsSet(true);
      }
      if (incoming.get(11)) {
        struct.editableByUser = iprot.readBool();
        struct.setEditableByUserIsSet(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();
  }
}

