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

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

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
/**
 * Application Interface Description
 * 
 * applicationModules:
 *   Associate all application modules with versions which interface is applicable to.
 * 
 * applicationInputs:
 *   Inputs to be passed to the application
 * 
 * applicationOutputs:
 *   Outputs generated from the application
 * 
 */
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
public class ApplicationInterfaceDescription implements org.apache.thrift.TBase<ApplicationInterfaceDescription, ApplicationInterfaceDescription._Fields>, java.io.Serializable, Cloneable, Comparable<ApplicationInterfaceDescription> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ApplicationInterfaceDescription");

  private static final org.apache.thrift.protocol.TField APPLICATION_INTERFACE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationInterfaceId", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField APPLICATION_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationName", org.apache.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.thrift.protocol.TField APPLICATION_DESCRIPTION_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationDescription", org.apache.thrift.protocol.TType.STRING, (short)3);
  private static final org.apache.thrift.protocol.TField APPLICATION_MODULES_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationModules", org.apache.thrift.protocol.TType.LIST, (short)4);
  private static final org.apache.thrift.protocol.TField APPLICATION_INPUTS_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationInputs", org.apache.thrift.protocol.TType.LIST, (short)5);
  private static final org.apache.thrift.protocol.TField APPLICATION_OUTPUTS_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationOutputs", org.apache.thrift.protocol.TType.LIST, (short)6);
  private static final org.apache.thrift.protocol.TField ARCHIVE_WORKING_DIRECTORY_FIELD_DESC = new org.apache.thrift.protocol.TField("archiveWorkingDirectory", org.apache.thrift.protocol.TType.BOOL, (short)7);
  private static final org.apache.thrift.protocol.TField HAS_OPTIONAL_FILE_INPUTS_FIELD_DESC = new org.apache.thrift.protocol.TField("hasOptionalFileInputs", org.apache.thrift.protocol.TType.BOOL, (short)8);

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

  private java.lang.String applicationInterfaceId; // required
  private java.lang.String applicationName; // required
  private java.lang.String applicationDescription; // optional
  private java.util.List<java.lang.String> applicationModules; // optional
  private java.util.List<org.apache.airavata.model.application.io.InputDataObjectType> applicationInputs; // optional
  private java.util.List<org.apache.airavata.model.application.io.OutputDataObjectType> applicationOutputs; // optional
  private boolean archiveWorkingDirectory; // optional
  private boolean hasOptionalFileInputs; // 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 {
    APPLICATION_INTERFACE_ID((short)1, "applicationInterfaceId"),
    APPLICATION_NAME((short)2, "applicationName"),
    APPLICATION_DESCRIPTION((short)3, "applicationDescription"),
    APPLICATION_MODULES((short)4, "applicationModules"),
    APPLICATION_INPUTS((short)5, "applicationInputs"),
    APPLICATION_OUTPUTS((short)6, "applicationOutputs"),
    ARCHIVE_WORKING_DIRECTORY((short)7, "archiveWorkingDirectory"),
    HAS_OPTIONAL_FILE_INPUTS((short)8, "hasOptionalFileInputs");

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

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

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // APPLICATION_INTERFACE_ID
          return APPLICATION_INTERFACE_ID;
        case 2: // APPLICATION_NAME
          return APPLICATION_NAME;
        case 3: // APPLICATION_DESCRIPTION
          return APPLICATION_DESCRIPTION;
        case 4: // APPLICATION_MODULES
          return APPLICATION_MODULES;
        case 5: // APPLICATION_INPUTS
          return APPLICATION_INPUTS;
        case 6: // APPLICATION_OUTPUTS
          return APPLICATION_OUTPUTS;
        case 7: // ARCHIVE_WORKING_DIRECTORY
          return ARCHIVE_WORKING_DIRECTORY;
        case 8: // HAS_OPTIONAL_FILE_INPUTS
          return HAS_OPTIONAL_FILE_INPUTS;
        default:
          return null;
      }
    }

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

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

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

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

    public short getThriftFieldId() {
      return _thriftId;
    }

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

  // isset id assignments
  private static final int __ARCHIVEWORKINGDIRECTORY_ISSET_ID = 0;
  private static final int __HASOPTIONALFILEINPUTS_ISSET_ID = 1;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.APPLICATION_DESCRIPTION,_Fields.APPLICATION_MODULES,_Fields.APPLICATION_INPUTS,_Fields.APPLICATION_OUTPUTS,_Fields.ARCHIVE_WORKING_DIRECTORY,_Fields.HAS_OPTIONAL_FILE_INPUTS};
  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.APPLICATION_INTERFACE_ID, new org.apache.thrift.meta_data.FieldMetaData("applicationInterfaceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.APPLICATION_NAME, new org.apache.thrift.meta_data.FieldMetaData("applicationName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.APPLICATION_DESCRIPTION, new org.apache.thrift.meta_data.FieldMetaData("applicationDescription", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.APPLICATION_MODULES, new org.apache.thrift.meta_data.FieldMetaData("applicationModules", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
    tmpMap.put(_Fields.APPLICATION_INPUTS, new org.apache.thrift.meta_data.FieldMetaData("applicationInputs", 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, org.apache.airavata.model.application.io.InputDataObjectType.class))));
    tmpMap.put(_Fields.APPLICATION_OUTPUTS, new org.apache.thrift.meta_data.FieldMetaData("applicationOutputs", 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, org.apache.airavata.model.application.io.OutputDataObjectType.class))));
    tmpMap.put(_Fields.ARCHIVE_WORKING_DIRECTORY, new org.apache.thrift.meta_data.FieldMetaData("archiveWorkingDirectory", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.HAS_OPTIONAL_FILE_INPUTS, new org.apache.thrift.meta_data.FieldMetaData("hasOptionalFileInputs", 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(ApplicationInterfaceDescription.class, metaDataMap);
  }

  public ApplicationInterfaceDescription() {
    this.applicationInterfaceId = "DO_NOT_SET_AT_CLIENTS";

    this.archiveWorkingDirectory = false;

  }

  public ApplicationInterfaceDescription(
    java.lang.String applicationInterfaceId,
    java.lang.String applicationName)
  {
    this();
    this.applicationInterfaceId = applicationInterfaceId;
    this.applicationName = applicationName;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public ApplicationInterfaceDescription(ApplicationInterfaceDescription other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetApplicationInterfaceId()) {
      this.applicationInterfaceId = other.applicationInterfaceId;
    }
    if (other.isSetApplicationName()) {
      this.applicationName = other.applicationName;
    }
    if (other.isSetApplicationDescription()) {
      this.applicationDescription = other.applicationDescription;
    }
    if (other.isSetApplicationModules()) {
      java.util.List<java.lang.String> __this__applicationModules = new java.util.ArrayList<java.lang.String>(other.applicationModules);
      this.applicationModules = __this__applicationModules;
    }
    if (other.isSetApplicationInputs()) {
      java.util.List<org.apache.airavata.model.application.io.InputDataObjectType> __this__applicationInputs = new java.util.ArrayList<org.apache.airavata.model.application.io.InputDataObjectType>(other.applicationInputs.size());
      for (org.apache.airavata.model.application.io.InputDataObjectType other_element : other.applicationInputs) {
        __this__applicationInputs.add(new org.apache.airavata.model.application.io.InputDataObjectType(other_element));
      }
      this.applicationInputs = __this__applicationInputs;
    }
    if (other.isSetApplicationOutputs()) {
      java.util.List<org.apache.airavata.model.application.io.OutputDataObjectType> __this__applicationOutputs = new java.util.ArrayList<org.apache.airavata.model.application.io.OutputDataObjectType>(other.applicationOutputs.size());
      for (org.apache.airavata.model.application.io.OutputDataObjectType other_element : other.applicationOutputs) {
        __this__applicationOutputs.add(new org.apache.airavata.model.application.io.OutputDataObjectType(other_element));
      }
      this.applicationOutputs = __this__applicationOutputs;
    }
    this.archiveWorkingDirectory = other.archiveWorkingDirectory;
    this.hasOptionalFileInputs = other.hasOptionalFileInputs;
  }

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

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

    this.applicationName = null;
    this.applicationDescription = null;
    this.applicationModules = null;
    this.applicationInputs = null;
    this.applicationOutputs = null;
    this.archiveWorkingDirectory = false;

    setHasOptionalFileInputsIsSet(false);
    this.hasOptionalFileInputs = false;
  }

  public java.lang.String getApplicationInterfaceId() {
    return this.applicationInterfaceId;
  }

  public void setApplicationInterfaceId(java.lang.String applicationInterfaceId) {
    this.applicationInterfaceId = applicationInterfaceId;
  }

  public void unsetApplicationInterfaceId() {
    this.applicationInterfaceId = null;
  }

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

  public void setApplicationInterfaceIdIsSet(boolean value) {
    if (!value) {
      this.applicationInterfaceId = null;
    }
  }

  public java.lang.String getApplicationName() {
    return this.applicationName;
  }

  public void setApplicationName(java.lang.String applicationName) {
    this.applicationName = applicationName;
  }

  public void unsetApplicationName() {
    this.applicationName = null;
  }

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

  public void setApplicationNameIsSet(boolean value) {
    if (!value) {
      this.applicationName = null;
    }
  }

  public java.lang.String getApplicationDescription() {
    return this.applicationDescription;
  }

  public void setApplicationDescription(java.lang.String applicationDescription) {
    this.applicationDescription = applicationDescription;
  }

  public void unsetApplicationDescription() {
    this.applicationDescription = null;
  }

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

  public void setApplicationDescriptionIsSet(boolean value) {
    if (!value) {
      this.applicationDescription = null;
    }
  }

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

  public java.util.Iterator<java.lang.String> getApplicationModulesIterator() {
    return (this.applicationModules == null) ? null : this.applicationModules.iterator();
  }

  public void addToApplicationModules(java.lang.String elem) {
    if (this.applicationModules == null) {
      this.applicationModules = new java.util.ArrayList<java.lang.String>();
    }
    this.applicationModules.add(elem);
  }

  public java.util.List<java.lang.String> getApplicationModules() {
    return this.applicationModules;
  }

  public void setApplicationModules(java.util.List<java.lang.String> applicationModules) {
    this.applicationModules = applicationModules;
  }

  public void unsetApplicationModules() {
    this.applicationModules = null;
  }

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

  public void setApplicationModulesIsSet(boolean value) {
    if (!value) {
      this.applicationModules = null;
    }
  }

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

  public java.util.Iterator<org.apache.airavata.model.application.io.InputDataObjectType> getApplicationInputsIterator() {
    return (this.applicationInputs == null) ? null : this.applicationInputs.iterator();
  }

  public void addToApplicationInputs(org.apache.airavata.model.application.io.InputDataObjectType elem) {
    if (this.applicationInputs == null) {
      this.applicationInputs = new java.util.ArrayList<org.apache.airavata.model.application.io.InputDataObjectType>();
    }
    this.applicationInputs.add(elem);
  }

  public java.util.List<org.apache.airavata.model.application.io.InputDataObjectType> getApplicationInputs() {
    return this.applicationInputs;
  }

  public void setApplicationInputs(java.util.List<org.apache.airavata.model.application.io.InputDataObjectType> applicationInputs) {
    this.applicationInputs = applicationInputs;
  }

  public void unsetApplicationInputs() {
    this.applicationInputs = null;
  }

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

  public void setApplicationInputsIsSet(boolean value) {
    if (!value) {
      this.applicationInputs = null;
    }
  }

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

  public java.util.Iterator<org.apache.airavata.model.application.io.OutputDataObjectType> getApplicationOutputsIterator() {
    return (this.applicationOutputs == null) ? null : this.applicationOutputs.iterator();
  }

  public void addToApplicationOutputs(org.apache.airavata.model.application.io.OutputDataObjectType elem) {
    if (this.applicationOutputs == null) {
      this.applicationOutputs = new java.util.ArrayList<org.apache.airavata.model.application.io.OutputDataObjectType>();
    }
    this.applicationOutputs.add(elem);
  }

  public java.util.List<org.apache.airavata.model.application.io.OutputDataObjectType> getApplicationOutputs() {
    return this.applicationOutputs;
  }

  public void setApplicationOutputs(java.util.List<org.apache.airavata.model.application.io.OutputDataObjectType> applicationOutputs) {
    this.applicationOutputs = applicationOutputs;
  }

  public void unsetApplicationOutputs() {
    this.applicationOutputs = null;
  }

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

  public void setApplicationOutputsIsSet(boolean value) {
    if (!value) {
      this.applicationOutputs = null;
    }
  }

  public boolean isArchiveWorkingDirectory() {
    return this.archiveWorkingDirectory;
  }

  public void setArchiveWorkingDirectory(boolean archiveWorkingDirectory) {
    this.archiveWorkingDirectory = archiveWorkingDirectory;
    setArchiveWorkingDirectoryIsSet(true);
  }

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

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

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

  public boolean isHasOptionalFileInputs() {
    return this.hasOptionalFileInputs;
  }

  public void setHasOptionalFileInputs(boolean hasOptionalFileInputs) {
    this.hasOptionalFileInputs = hasOptionalFileInputs;
    setHasOptionalFileInputsIsSet(true);
  }

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

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

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

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

    case APPLICATION_NAME:
      if (value == null) {
        unsetApplicationName();
      } else {
        setApplicationName((java.lang.String)value);
      }
      break;

    case APPLICATION_DESCRIPTION:
      if (value == null) {
        unsetApplicationDescription();
      } else {
        setApplicationDescription((java.lang.String)value);
      }
      break;

    case APPLICATION_MODULES:
      if (value == null) {
        unsetApplicationModules();
      } else {
        setApplicationModules((java.util.List<java.lang.String>)value);
      }
      break;

    case APPLICATION_INPUTS:
      if (value == null) {
        unsetApplicationInputs();
      } else {
        setApplicationInputs((java.util.List<org.apache.airavata.model.application.io.InputDataObjectType>)value);
      }
      break;

    case APPLICATION_OUTPUTS:
      if (value == null) {
        unsetApplicationOutputs();
      } else {
        setApplicationOutputs((java.util.List<org.apache.airavata.model.application.io.OutputDataObjectType>)value);
      }
      break;

    case ARCHIVE_WORKING_DIRECTORY:
      if (value == null) {
        unsetArchiveWorkingDirectory();
      } else {
        setArchiveWorkingDirectory((java.lang.Boolean)value);
      }
      break;

    case HAS_OPTIONAL_FILE_INPUTS:
      if (value == null) {
        unsetHasOptionalFileInputs();
      } else {
        setHasOptionalFileInputs((java.lang.Boolean)value);
      }
      break;

    }
  }

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

    case APPLICATION_NAME:
      return getApplicationName();

    case APPLICATION_DESCRIPTION:
      return getApplicationDescription();

    case APPLICATION_MODULES:
      return getApplicationModules();

    case APPLICATION_INPUTS:
      return getApplicationInputs();

    case APPLICATION_OUTPUTS:
      return getApplicationOutputs();

    case ARCHIVE_WORKING_DIRECTORY:
      return isArchiveWorkingDirectory();

    case HAS_OPTIONAL_FILE_INPUTS:
      return isHasOptionalFileInputs();

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

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

    switch (field) {
    case APPLICATION_INTERFACE_ID:
      return isSetApplicationInterfaceId();
    case APPLICATION_NAME:
      return isSetApplicationName();
    case APPLICATION_DESCRIPTION:
      return isSetApplicationDescription();
    case APPLICATION_MODULES:
      return isSetApplicationModules();
    case APPLICATION_INPUTS:
      return isSetApplicationInputs();
    case APPLICATION_OUTPUTS:
      return isSetApplicationOutputs();
    case ARCHIVE_WORKING_DIRECTORY:
      return isSetArchiveWorkingDirectory();
    case HAS_OPTIONAL_FILE_INPUTS:
      return isSetHasOptionalFileInputs();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_applicationInterfaceId = true && this.isSetApplicationInterfaceId();
    boolean that_present_applicationInterfaceId = true && that.isSetApplicationInterfaceId();
    if (this_present_applicationInterfaceId || that_present_applicationInterfaceId) {
      if (!(this_present_applicationInterfaceId && that_present_applicationInterfaceId))
        return false;
      if (!this.applicationInterfaceId.equals(that.applicationInterfaceId))
        return false;
    }

    boolean this_present_applicationName = true && this.isSetApplicationName();
    boolean that_present_applicationName = true && that.isSetApplicationName();
    if (this_present_applicationName || that_present_applicationName) {
      if (!(this_present_applicationName && that_present_applicationName))
        return false;
      if (!this.applicationName.equals(that.applicationName))
        return false;
    }

    boolean this_present_applicationDescription = true && this.isSetApplicationDescription();
    boolean that_present_applicationDescription = true && that.isSetApplicationDescription();
    if (this_present_applicationDescription || that_present_applicationDescription) {
      if (!(this_present_applicationDescription && that_present_applicationDescription))
        return false;
      if (!this.applicationDescription.equals(that.applicationDescription))
        return false;
    }

    boolean this_present_applicationModules = true && this.isSetApplicationModules();
    boolean that_present_applicationModules = true && that.isSetApplicationModules();
    if (this_present_applicationModules || that_present_applicationModules) {
      if (!(this_present_applicationModules && that_present_applicationModules))
        return false;
      if (!this.applicationModules.equals(that.applicationModules))
        return false;
    }

    boolean this_present_applicationInputs = true && this.isSetApplicationInputs();
    boolean that_present_applicationInputs = true && that.isSetApplicationInputs();
    if (this_present_applicationInputs || that_present_applicationInputs) {
      if (!(this_present_applicationInputs && that_present_applicationInputs))
        return false;
      if (!this.applicationInputs.equals(that.applicationInputs))
        return false;
    }

    boolean this_present_applicationOutputs = true && this.isSetApplicationOutputs();
    boolean that_present_applicationOutputs = true && that.isSetApplicationOutputs();
    if (this_present_applicationOutputs || that_present_applicationOutputs) {
      if (!(this_present_applicationOutputs && that_present_applicationOutputs))
        return false;
      if (!this.applicationOutputs.equals(that.applicationOutputs))
        return false;
    }

    boolean this_present_archiveWorkingDirectory = true && this.isSetArchiveWorkingDirectory();
    boolean that_present_archiveWorkingDirectory = true && that.isSetArchiveWorkingDirectory();
    if (this_present_archiveWorkingDirectory || that_present_archiveWorkingDirectory) {
      if (!(this_present_archiveWorkingDirectory && that_present_archiveWorkingDirectory))
        return false;
      if (this.archiveWorkingDirectory != that.archiveWorkingDirectory)
        return false;
    }

    boolean this_present_hasOptionalFileInputs = true && this.isSetHasOptionalFileInputs();
    boolean that_present_hasOptionalFileInputs = true && that.isSetHasOptionalFileInputs();
    if (this_present_hasOptionalFileInputs || that_present_hasOptionalFileInputs) {
      if (!(this_present_hasOptionalFileInputs && that_present_hasOptionalFileInputs))
        return false;
      if (this.hasOptionalFileInputs != that.hasOptionalFileInputs)
        return false;
    }

    return true;
  }

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

    hashCode = hashCode * 8191 + ((isSetApplicationInterfaceId()) ? 131071 : 524287);
    if (isSetApplicationInterfaceId())
      hashCode = hashCode * 8191 + applicationInterfaceId.hashCode();

    hashCode = hashCode * 8191 + ((isSetApplicationName()) ? 131071 : 524287);
    if (isSetApplicationName())
      hashCode = hashCode * 8191 + applicationName.hashCode();

    hashCode = hashCode * 8191 + ((isSetApplicationDescription()) ? 131071 : 524287);
    if (isSetApplicationDescription())
      hashCode = hashCode * 8191 + applicationDescription.hashCode();

    hashCode = hashCode * 8191 + ((isSetApplicationModules()) ? 131071 : 524287);
    if (isSetApplicationModules())
      hashCode = hashCode * 8191 + applicationModules.hashCode();

    hashCode = hashCode * 8191 + ((isSetApplicationInputs()) ? 131071 : 524287);
    if (isSetApplicationInputs())
      hashCode = hashCode * 8191 + applicationInputs.hashCode();

    hashCode = hashCode * 8191 + ((isSetApplicationOutputs()) ? 131071 : 524287);
    if (isSetApplicationOutputs())
      hashCode = hashCode * 8191 + applicationOutputs.hashCode();

    hashCode = hashCode * 8191 + ((isSetArchiveWorkingDirectory()) ? 131071 : 524287);
    if (isSetArchiveWorkingDirectory())
      hashCode = hashCode * 8191 + ((archiveWorkingDirectory) ? 131071 : 524287);

    hashCode = hashCode * 8191 + ((isSetHasOptionalFileInputs()) ? 131071 : 524287);
    if (isSetHasOptionalFileInputs())
      hashCode = hashCode * 8191 + ((hasOptionalFileInputs) ? 131071 : 524287);

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(isSetApplicationInterfaceId()).compareTo(other.isSetApplicationInterfaceId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetApplicationInterfaceId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationInterfaceId, other.applicationInterfaceId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetApplicationName()).compareTo(other.isSetApplicationName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetApplicationName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationName, other.applicationName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetApplicationDescription()).compareTo(other.isSetApplicationDescription());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetApplicationDescription()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationDescription, other.applicationDescription);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetApplicationModules()).compareTo(other.isSetApplicationModules());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetApplicationModules()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationModules, other.applicationModules);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetApplicationInputs()).compareTo(other.isSetApplicationInputs());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetApplicationInputs()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationInputs, other.applicationInputs);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetApplicationOutputs()).compareTo(other.isSetApplicationOutputs());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetApplicationOutputs()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationOutputs, other.applicationOutputs);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetArchiveWorkingDirectory()).compareTo(other.isSetArchiveWorkingDirectory());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetArchiveWorkingDirectory()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.archiveWorkingDirectory, other.archiveWorkingDirectory);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetHasOptionalFileInputs()).compareTo(other.isSetHasOptionalFileInputs());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetHasOptionalFileInputs()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.hasOptionalFileInputs, other.hasOptionalFileInputs);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

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

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

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

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

    sb.append("applicationInterfaceId:");
    if (this.applicationInterfaceId == null) {
      sb.append("null");
    } else {
      sb.append(this.applicationInterfaceId);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("applicationName:");
    if (this.applicationName == null) {
      sb.append("null");
    } else {
      sb.append(this.applicationName);
    }
    first = false;
    if (isSetApplicationDescription()) {
      if (!first) sb.append(", ");
      sb.append("applicationDescription:");
      if (this.applicationDescription == null) {
        sb.append("null");
      } else {
        sb.append(this.applicationDescription);
      }
      first = false;
    }
    if (isSetApplicationModules()) {
      if (!first) sb.append(", ");
      sb.append("applicationModules:");
      if (this.applicationModules == null) {
        sb.append("null");
      } else {
        sb.append(this.applicationModules);
      }
      first = false;
    }
    if (isSetApplicationInputs()) {
      if (!first) sb.append(", ");
      sb.append("applicationInputs:");
      if (this.applicationInputs == null) {
        sb.append("null");
      } else {
        sb.append(this.applicationInputs);
      }
      first = false;
    }
    if (isSetApplicationOutputs()) {
      if (!first) sb.append(", ");
      sb.append("applicationOutputs:");
      if (this.applicationOutputs == null) {
        sb.append("null");
      } else {
        sb.append(this.applicationOutputs);
      }
      first = false;
    }
    if (isSetArchiveWorkingDirectory()) {
      if (!first) sb.append(", ");
      sb.append("archiveWorkingDirectory:");
      sb.append(this.archiveWorkingDirectory);
      first = false;
    }
    if (isSetHasOptionalFileInputs()) {
      if (!first) sb.append(", ");
      sb.append("hasOptionalFileInputs:");
      sb.append(this.hasOptionalFileInputs);
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

    if (!isSetApplicationName()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'applicationName' 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 ApplicationInterfaceDescriptionStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public ApplicationInterfaceDescriptionStandardScheme getScheme() {
      return new ApplicationInterfaceDescriptionStandardScheme();
    }
  }

  private static class ApplicationInterfaceDescriptionStandardScheme extends org.apache.thrift.scheme.StandardScheme<ApplicationInterfaceDescription> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, ApplicationInterfaceDescription 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: // APPLICATION_INTERFACE_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.applicationInterfaceId = iprot.readString();
              struct.setApplicationInterfaceIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // APPLICATION_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.applicationName = iprot.readString();
              struct.setApplicationNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // APPLICATION_DESCRIPTION
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.applicationDescription = iprot.readString();
              struct.setApplicationDescriptionIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // APPLICATION_MODULES
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list0 = iprot.readListBegin();
                struct.applicationModules = new java.util.ArrayList<java.lang.String>(_list0.size);
                java.lang.String _elem1;
                for (int _i2 = 0; _i2 < _list0.size; ++_i2)
                {
                  _elem1 = iprot.readString();
                  struct.applicationModules.add(_elem1);
                }
                iprot.readListEnd();
              }
              struct.setApplicationModulesIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // APPLICATION_INPUTS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list3 = iprot.readListBegin();
                struct.applicationInputs = new java.util.ArrayList<org.apache.airavata.model.application.io.InputDataObjectType>(_list3.size);
                org.apache.airavata.model.application.io.InputDataObjectType _elem4;
                for (int _i5 = 0; _i5 < _list3.size; ++_i5)
                {
                  _elem4 = new org.apache.airavata.model.application.io.InputDataObjectType();
                  _elem4.read(iprot);
                  struct.applicationInputs.add(_elem4);
                }
                iprot.readListEnd();
              }
              struct.setApplicationInputsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // APPLICATION_OUTPUTS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list6 = iprot.readListBegin();
                struct.applicationOutputs = new java.util.ArrayList<org.apache.airavata.model.application.io.OutputDataObjectType>(_list6.size);
                org.apache.airavata.model.application.io.OutputDataObjectType _elem7;
                for (int _i8 = 0; _i8 < _list6.size; ++_i8)
                {
                  _elem7 = new org.apache.airavata.model.application.io.OutputDataObjectType();
                  _elem7.read(iprot);
                  struct.applicationOutputs.add(_elem7);
                }
                iprot.readListEnd();
              }
              struct.setApplicationOutputsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // ARCHIVE_WORKING_DIRECTORY
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.archiveWorkingDirectory = iprot.readBool();
              struct.setArchiveWorkingDirectoryIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // HAS_OPTIONAL_FILE_INPUTS
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.hasOptionalFileInputs = iprot.readBool();
              struct.setHasOptionalFileInputsIsSet(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, ApplicationInterfaceDescription struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.applicationInterfaceId != null) {
        oprot.writeFieldBegin(APPLICATION_INTERFACE_ID_FIELD_DESC);
        oprot.writeString(struct.applicationInterfaceId);
        oprot.writeFieldEnd();
      }
      if (struct.applicationName != null) {
        oprot.writeFieldBegin(APPLICATION_NAME_FIELD_DESC);
        oprot.writeString(struct.applicationName);
        oprot.writeFieldEnd();
      }
      if (struct.applicationDescription != null) {
        if (struct.isSetApplicationDescription()) {
          oprot.writeFieldBegin(APPLICATION_DESCRIPTION_FIELD_DESC);
          oprot.writeString(struct.applicationDescription);
          oprot.writeFieldEnd();
        }
      }
      if (struct.applicationModules != null) {
        if (struct.isSetApplicationModules()) {
          oprot.writeFieldBegin(APPLICATION_MODULES_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.applicationModules.size()));
            for (java.lang.String _iter9 : struct.applicationModules)
            {
              oprot.writeString(_iter9);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.applicationInputs != null) {
        if (struct.isSetApplicationInputs()) {
          oprot.writeFieldBegin(APPLICATION_INPUTS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.applicationInputs.size()));
            for (org.apache.airavata.model.application.io.InputDataObjectType _iter10 : struct.applicationInputs)
            {
              _iter10.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.applicationOutputs != null) {
        if (struct.isSetApplicationOutputs()) {
          oprot.writeFieldBegin(APPLICATION_OUTPUTS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.applicationOutputs.size()));
            for (org.apache.airavata.model.application.io.OutputDataObjectType _iter11 : struct.applicationOutputs)
            {
              _iter11.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetArchiveWorkingDirectory()) {
        oprot.writeFieldBegin(ARCHIVE_WORKING_DIRECTORY_FIELD_DESC);
        oprot.writeBool(struct.archiveWorkingDirectory);
        oprot.writeFieldEnd();
      }
      if (struct.isSetHasOptionalFileInputs()) {
        oprot.writeFieldBegin(HAS_OPTIONAL_FILE_INPUTS_FIELD_DESC);
        oprot.writeBool(struct.hasOptionalFileInputs);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

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

  private static class ApplicationInterfaceDescriptionTupleScheme extends org.apache.thrift.scheme.TupleScheme<ApplicationInterfaceDescription> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, ApplicationInterfaceDescription struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      oprot.writeString(struct.applicationInterfaceId);
      oprot.writeString(struct.applicationName);
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.isSetApplicationDescription()) {
        optionals.set(0);
      }
      if (struct.isSetApplicationModules()) {
        optionals.set(1);
      }
      if (struct.isSetApplicationInputs()) {
        optionals.set(2);
      }
      if (struct.isSetApplicationOutputs()) {
        optionals.set(3);
      }
      if (struct.isSetArchiveWorkingDirectory()) {
        optionals.set(4);
      }
      if (struct.isSetHasOptionalFileInputs()) {
        optionals.set(5);
      }
      oprot.writeBitSet(optionals, 6);
      if (struct.isSetApplicationDescription()) {
        oprot.writeString(struct.applicationDescription);
      }
      if (struct.isSetApplicationModules()) {
        {
          oprot.writeI32(struct.applicationModules.size());
          for (java.lang.String _iter12 : struct.applicationModules)
          {
            oprot.writeString(_iter12);
          }
        }
      }
      if (struct.isSetApplicationInputs()) {
        {
          oprot.writeI32(struct.applicationInputs.size());
          for (org.apache.airavata.model.application.io.InputDataObjectType _iter13 : struct.applicationInputs)
          {
            _iter13.write(oprot);
          }
        }
      }
      if (struct.isSetApplicationOutputs()) {
        {
          oprot.writeI32(struct.applicationOutputs.size());
          for (org.apache.airavata.model.application.io.OutputDataObjectType _iter14 : struct.applicationOutputs)
          {
            _iter14.write(oprot);
          }
        }
      }
      if (struct.isSetArchiveWorkingDirectory()) {
        oprot.writeBool(struct.archiveWorkingDirectory);
      }
      if (struct.isSetHasOptionalFileInputs()) {
        oprot.writeBool(struct.hasOptionalFileInputs);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, ApplicationInterfaceDescription struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      struct.applicationInterfaceId = iprot.readString();
      struct.setApplicationInterfaceIdIsSet(true);
      struct.applicationName = iprot.readString();
      struct.setApplicationNameIsSet(true);
      java.util.BitSet incoming = iprot.readBitSet(6);
      if (incoming.get(0)) {
        struct.applicationDescription = iprot.readString();
        struct.setApplicationDescriptionIsSet(true);
      }
      if (incoming.get(1)) {
        {
          org.apache.thrift.protocol.TList _list15 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.applicationModules = new java.util.ArrayList<java.lang.String>(_list15.size);
          java.lang.String _elem16;
          for (int _i17 = 0; _i17 < _list15.size; ++_i17)
          {
            _elem16 = iprot.readString();
            struct.applicationModules.add(_elem16);
          }
        }
        struct.setApplicationModulesIsSet(true);
      }
      if (incoming.get(2)) {
        {
          org.apache.thrift.protocol.TList _list18 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.applicationInputs = new java.util.ArrayList<org.apache.airavata.model.application.io.InputDataObjectType>(_list18.size);
          org.apache.airavata.model.application.io.InputDataObjectType _elem19;
          for (int _i20 = 0; _i20 < _list18.size; ++_i20)
          {
            _elem19 = new org.apache.airavata.model.application.io.InputDataObjectType();
            _elem19.read(iprot);
            struct.applicationInputs.add(_elem19);
          }
        }
        struct.setApplicationInputsIsSet(true);
      }
      if (incoming.get(3)) {
        {
          org.apache.thrift.protocol.TList _list21 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.applicationOutputs = new java.util.ArrayList<org.apache.airavata.model.application.io.OutputDataObjectType>(_list21.size);
          org.apache.airavata.model.application.io.OutputDataObjectType _elem22;
          for (int _i23 = 0; _i23 < _list21.size; ++_i23)
          {
            _elem22 = new org.apache.airavata.model.application.io.OutputDataObjectType();
            _elem22.read(iprot);
            struct.applicationOutputs.add(_elem22);
          }
        }
        struct.setApplicationOutputsIsSet(true);
      }
      if (incoming.get(4)) {
        struct.archiveWorkingDirectory = iprot.readBool();
        struct.setArchiveWorkingDirectoryIsSet(true);
      }
      if (incoming.get(5)) {
        struct.hasOptionalFileInputs = iprot.readBool();
        struct.setHasOptionalFileInputsIsSet(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();
  }
}

