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

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

  private String applicationInterfaceId; // required
  private String applicationName; // required
  private String applicationDescription; // optional
  private List<String> applicationModules; // optional
  private List<org.apache.airavata.model.application.io.InputDataObjectType> applicationInputs; // optional
  private 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 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: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
      return fields;
    }

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

    private final short _thriftId;
    private final String _fieldName;

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

    public short getThriftFieldId() {
      return _thriftId;
    }

    public String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final int __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 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.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 = 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(
    String applicationInterfaceId,
    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()) {
      List<String> __this__applicationModules = new ArrayList<String>(other.applicationModules);
      this.applicationModules = __this__applicationModules;
    }
    if (other.isSetApplicationInputs()) {
      List<org.apache.airavata.model.application.io.InputDataObjectType> __this__applicationInputs = new 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()) {
      List<org.apache.airavata.model.application.io.OutputDataObjectType> __this__applicationOutputs = new 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 String getApplicationInterfaceId() {
    return this.applicationInterfaceId;
  }

  public void setApplicationInterfaceId(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 String getApplicationName() {
    return this.applicationName;
  }

  public void setApplicationName(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 String getApplicationDescription() {
    return this.applicationDescription;
  }

  public void setApplicationDescription(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<String> getApplicationModulesIterator() {
    return (this.applicationModules == null) ? null : this.applicationModules.iterator();
  }

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

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

  public void setApplicationModules(List<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 ArrayList<org.apache.airavata.model.application.io.InputDataObjectType>();
    }
    this.applicationInputs.add(elem);
  }

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

  public void setApplicationInputs(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 ArrayList<org.apache.airavata.model.application.io.OutputDataObjectType>();
    }
    this.applicationOutputs.add(elem);
  }

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

  public void setApplicationOutputs(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 = 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 EncodingUtils.testBit(__isset_bitfield, __ARCHIVEWORKINGDIRECTORY_ISSET_ID);
  }

  public void setArchiveWorkingDirectoryIsSet(boolean value) {
    __isset_bitfield = 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 = 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 EncodingUtils.testBit(__isset_bitfield, __HASOPTIONALFILEINPUTS_ISSET_ID);
  }

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

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

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

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

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

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

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

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

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

    }
  }

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

  @Override
  public boolean equals(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;

    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() {
    List<Object> list = new ArrayList<Object>();

    boolean present_applicationInterfaceId = true && (isSetApplicationInterfaceId());
    list.add(present_applicationInterfaceId);
    if (present_applicationInterfaceId)
      list.add(applicationInterfaceId);

    boolean present_applicationName = true && (isSetApplicationName());
    list.add(present_applicationName);
    if (present_applicationName)
      list.add(applicationName);

    boolean present_applicationDescription = true && (isSetApplicationDescription());
    list.add(present_applicationDescription);
    if (present_applicationDescription)
      list.add(applicationDescription);

    boolean present_applicationModules = true && (isSetApplicationModules());
    list.add(present_applicationModules);
    if (present_applicationModules)
      list.add(applicationModules);

    boolean present_applicationInputs = true && (isSetApplicationInputs());
    list.add(present_applicationInputs);
    if (present_applicationInputs)
      list.add(applicationInputs);

    boolean present_applicationOutputs = true && (isSetApplicationOutputs());
    list.add(present_applicationOutputs);
    if (present_applicationOutputs)
      list.add(applicationOutputs);

    boolean present_archiveWorkingDirectory = true && (isSetArchiveWorkingDirectory());
    list.add(present_archiveWorkingDirectory);
    if (present_archiveWorkingDirectory)
      list.add(archiveWorkingDirectory);

    boolean present_hasOptionalFileInputs = true && (isSetHasOptionalFileInputs());
    list.add(present_hasOptionalFileInputs);
    if (present_hasOptionalFileInputs)
      list.add(hasOptionalFileInputs);

    return list.hashCode();
  }

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

    int lastComparison = 0;

    lastComparison = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 {
    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("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, 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 SchemeFactory {
    public ApplicationInterfaceDescriptionStandardScheme getScheme() {
      return new ApplicationInterfaceDescriptionStandardScheme();
    }
  }

  private static class ApplicationInterfaceDescriptionStandardScheme extends 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 ArrayList<String>(_list0.size);
                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 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 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 (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 SchemeFactory {
    public ApplicationInterfaceDescriptionTupleScheme getScheme() {
      return new ApplicationInterfaceDescriptionTupleScheme();
    }
  }

  private static class ApplicationInterfaceDescriptionTupleScheme extends TupleScheme<ApplicationInterfaceDescription> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, ApplicationInterfaceDescription struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      oprot.writeString(struct.applicationInterfaceId);
      oprot.writeString(struct.applicationName);
      BitSet optionals = new 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 (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 {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      struct.applicationInterfaceId = iprot.readString();
      struct.setApplicationInterfaceIdIsSet(true);
      struct.applicationName = iprot.readString();
      struct.setApplicationNameIsSet(true);
      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 ArrayList<String>(_list15.size);
          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 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 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);
      }
    }
  }

}

