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

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

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

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

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

  private String appDeploymentId; // required
  private String appModuleId; // required
  private String computeHostId; // required
  private String executablePath; // required
  private org.apache.airavata.model.parallelism.ApplicationParallelismType parallelism; // required
  private String appDeploymentDescription; // optional
  private List<CommandObject> moduleLoadCmds; // optional
  private List<SetEnvPaths> libPrependPaths; // optional
  private List<SetEnvPaths> libAppendPaths; // optional
  private List<SetEnvPaths> setEnvironment; // optional
  private List<CommandObject> preJobCommands; // optional
  private List<CommandObject> postJobCommands; // 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");

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

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

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

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

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

    private final short _thriftId;
    private final String _fieldName;

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

    public short getThriftFieldId() {
      return _thriftId;
    }

    public String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final _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};
  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.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))));
    metaDataMap = 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(
    String appDeploymentId,
    String appModuleId,
    String computeHostId,
    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) {
    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()) {
      List<CommandObject> __this__moduleLoadCmds = new 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()) {
      List<SetEnvPaths> __this__libPrependPaths = new 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()) {
      List<SetEnvPaths> __this__libAppendPaths = new 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()) {
      List<SetEnvPaths> __this__setEnvironment = new 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()) {
      List<CommandObject> __this__preJobCommands = new 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()) {
      List<CommandObject> __this__postJobCommands = new ArrayList<CommandObject>(other.postJobCommands.size());
      for (CommandObject other_element : other.postJobCommands) {
        __this__postJobCommands.add(new CommandObject(other_element));
      }
      this.postJobCommands = __this__postJobCommands;
    }
  }

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

  public String getAppDeploymentId() {
    return this.appDeploymentId;
  }

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

  public String getAppModuleId() {
    return this.appModuleId;
  }

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

  public String getComputeHostId() {
    return this.computeHostId;
  }

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

  public String getExecutablePath() {
    return this.executablePath;
  }

  public void setExecutablePath(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
   */
  public org.apache.airavata.model.parallelism.ApplicationParallelismType getParallelism() {
    return this.parallelism;
  }

  /**
   * 
   * @see org.apache.airavata.model.parallelism.ApplicationParallelismType
   */
  public void setParallelism(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;
    }
  }

  public String getAppDeploymentDescription() {
    return this.appDeploymentDescription;
  }

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

  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 ArrayList<CommandObject>();
    }
    this.moduleLoadCmds.add(elem);
  }

  public List<CommandObject> getModuleLoadCmds() {
    return this.moduleLoadCmds;
  }

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

  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 ArrayList<SetEnvPaths>();
    }
    this.libPrependPaths.add(elem);
  }

  public List<SetEnvPaths> getLibPrependPaths() {
    return this.libPrependPaths;
  }

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

  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 ArrayList<SetEnvPaths>();
    }
    this.libAppendPaths.add(elem);
  }

  public List<SetEnvPaths> getLibAppendPaths() {
    return this.libAppendPaths;
  }

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

  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 ArrayList<SetEnvPaths>();
    }
    this.setEnvironment.add(elem);
  }

  public List<SetEnvPaths> getSetEnvironment() {
    return this.setEnvironment;
  }

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

  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 ArrayList<CommandObject>();
    }
    this.preJobCommands.add(elem);
  }

  public List<CommandObject> getPreJobCommands() {
    return this.preJobCommands;
  }

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

  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 ArrayList<CommandObject>();
    }
    this.postJobCommands.add(elem);
  }

  public List<CommandObject> getPostJobCommands() {
    return this.postJobCommands;
  }

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

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case APP_DEPLOYMENT_ID:
      if (value == null) {
        unsetAppDeploymentId();
      } else {
        setAppDeploymentId((String)value);
      }
      break;

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

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

    case EXECUTABLE_PATH:
      if (value == null) {
        unsetExecutablePath();
      } else {
        setExecutablePath((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((String)value);
      }
      break;

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

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

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

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

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

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

    }
  }

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

    }
    throw new IllegalStateException();
  }

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

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

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

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

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

    return true;
  }

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

    boolean present_appDeploymentId = true && (isSetAppDeploymentId());
    list.add(present_appDeploymentId);
    if (present_appDeploymentId)
      list.add(appDeploymentId);

    boolean present_appModuleId = true && (isSetAppModuleId());
    list.add(present_appModuleId);
    if (present_appModuleId)
      list.add(appModuleId);

    boolean present_computeHostId = true && (isSetComputeHostId());
    list.add(present_computeHostId);
    if (present_computeHostId)
      list.add(computeHostId);

    boolean present_executablePath = true && (isSetExecutablePath());
    list.add(present_executablePath);
    if (present_executablePath)
      list.add(executablePath);

    boolean present_parallelism = true && (isSetParallelism());
    list.add(present_parallelism);
    if (present_parallelism)
      list.add(parallelism.getValue());

    boolean present_appDeploymentDescription = true && (isSetAppDeploymentDescription());
    list.add(present_appDeploymentDescription);
    if (present_appDeploymentDescription)
      list.add(appDeploymentDescription);

    boolean present_moduleLoadCmds = true && (isSetModuleLoadCmds());
    list.add(present_moduleLoadCmds);
    if (present_moduleLoadCmds)
      list.add(moduleLoadCmds);

    boolean present_libPrependPaths = true && (isSetLibPrependPaths());
    list.add(present_libPrependPaths);
    if (present_libPrependPaths)
      list.add(libPrependPaths);

    boolean present_libAppendPaths = true && (isSetLibAppendPaths());
    list.add(present_libAppendPaths);
    if (present_libAppendPaths)
      list.add(libAppendPaths);

    boolean present_setEnvironment = true && (isSetSetEnvironment());
    list.add(present_setEnvironment);
    if (present_setEnvironment)
      list.add(setEnvironment);

    boolean present_preJobCommands = true && (isSetPreJobCommands());
    list.add(present_preJobCommands);
    if (present_preJobCommands)
      list.add(preJobCommands);

    boolean present_postJobCommands = true && (isSetPostJobCommands());
    list.add(present_postJobCommands);
    if (present_postJobCommands)
      list.add(postJobCommands);

    return list.hashCode();
  }

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

    int lastComparison = 0;

    lastComparison = Boolean.valueOf(isSetAppDeploymentId()).compareTo(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 = Boolean.valueOf(isSetAppModuleId()).compareTo(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 = Boolean.valueOf(isSetComputeHostId()).compareTo(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 = Boolean.valueOf(isSetExecutablePath()).compareTo(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 = Boolean.valueOf(isSetParallelism()).compareTo(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 = Boolean.valueOf(isSetAppDeploymentDescription()).compareTo(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 = Boolean.valueOf(isSetModuleLoadCmds()).compareTo(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 = Boolean.valueOf(isSetLibPrependPaths()).compareTo(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 = Boolean.valueOf(isSetLibAppendPaths()).compareTo(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 = Boolean.valueOf(isSetSetEnvironment()).compareTo(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 = Boolean.valueOf(isSetPreJobCommands()).compareTo(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 = Boolean.valueOf(isSetPostJobCommands()).compareTo(other.isSetPostJobCommands());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetPostJobCommands()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.postJobCommands, other.postJobCommands);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

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

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

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

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

  private static class ApplicationDeploymentDescriptionStandardScheme extends StandardScheme<ApplicationDeploymentDescription> {

    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 ArrayList<CommandObject>(_list0.size);
                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 ArrayList<SetEnvPaths>(_list3.size);
                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 ArrayList<SetEnvPaths>(_list6.size);
                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 ArrayList<SetEnvPaths>(_list9.size);
                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 ArrayList<CommandObject>(_list12.size);
                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 ArrayList<CommandObject>(_list15.size);
                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;
          default:
            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
      struct.validate();
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot, 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();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class ApplicationDeploymentDescriptionTupleSchemeFactory implements SchemeFactory {
    public ApplicationDeploymentDescriptionTupleScheme getScheme() {
      return new ApplicationDeploymentDescriptionTupleScheme();
    }
  }

  private static class ApplicationDeploymentDescriptionTupleScheme extends TupleScheme<ApplicationDeploymentDescription> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, ApplicationDeploymentDescription struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      oprot.writeString(struct.appDeploymentId);
      oprot.writeString(struct.appModuleId);
      oprot.writeString(struct.computeHostId);
      oprot.writeString(struct.executablePath);
      oprot.writeI32(struct.parallelism.getValue());
      BitSet optionals = new 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);
      }
      oprot.writeBitSet(optionals, 7);
      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);
          }
        }
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, ApplicationDeploymentDescription struct) throws org.apache.thrift.TException {
      TTupleProtocol iprot = (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);
      BitSet incoming = iprot.readBitSet(7);
      if (incoming.get(0)) {
        struct.appDeploymentDescription = iprot.readString();
        struct.setAppDeploymentDescriptionIsSet(true);
      }
      if (incoming.get(1)) {
        {
          org.apache.thrift.protocol.TList _list30 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.moduleLoadCmds = new ArrayList<CommandObject>(_list30.size);
          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 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.libPrependPaths = new ArrayList<SetEnvPaths>(_list33.size);
          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 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.libAppendPaths = new ArrayList<SetEnvPaths>(_list36.size);
          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 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.setEnvironment = new ArrayList<SetEnvPaths>(_list39.size);
          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 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.preJobCommands = new ArrayList<CommandObject>(_list42.size);
          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 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.postJobCommands = new ArrayList<CommandObject>(_list45.size);
          CommandObject _elem46;
          for (int _i47 = 0; _i47 < _list45.size; ++_i47)
          {
            _elem46 = new CommandObject();
            _elem46.read(iprot);
            struct.postJobCommands.add(_elem46);
          }
        }
        struct.setPostJobCommandsIsSet(true);
      }
    }
  }

}

