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

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 Inputs. The paramters describe how inputs are passed to the application.
 * 
 * name:
 *   Name of the parameter.
 * 
 * value:
 *   Value of the parameter. A default value could be set during registration.
 * 
 * type:
 *   Data type of the parameter
 * 
 * applicationArguement:
 *   The argument flag sent to the application. Such as -p pressure.
 * 
 * standardInput:
 *   When this value is set, the parameter is sent as standard input rather than a parameter.
 *   Typically this is passed using redirection operator ">".
 * 
 * userFriendlyDescription:
 *   Description to be displayed at the user interface.
 * 
 * metaData:
 *   Any metadat. This is typically ignore by Airavata and is used by gateways for application configuration.
 * 
 */
@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
public class InputDataObjectType implements org.apache.thrift.TBase<InputDataObjectType, InputDataObjectType._Fields>, java.io.Serializable, Cloneable, Comparable<InputDataObjectType> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("InputDataObjectType");

  private static final org.apache.thrift.protocol.TField NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("name", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("value", org.apache.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.thrift.protocol.TField TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("type", org.apache.thrift.protocol.TType.I32, (short)3);
  private static final org.apache.thrift.protocol.TField APPLICATION_ARGUMENT_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationArgument", org.apache.thrift.protocol.TType.STRING, (short)4);
  private static final org.apache.thrift.protocol.TField STANDARD_INPUT_FIELD_DESC = new org.apache.thrift.protocol.TField("standardInput", org.apache.thrift.protocol.TType.BOOL, (short)5);
  private static final org.apache.thrift.protocol.TField USER_FRIENDLY_DESCRIPTION_FIELD_DESC = new org.apache.thrift.protocol.TField("userFriendlyDescription", org.apache.thrift.protocol.TType.STRING, (short)6);
  private static final org.apache.thrift.protocol.TField META_DATA_FIELD_DESC = new org.apache.thrift.protocol.TField("metaData", org.apache.thrift.protocol.TType.STRING, (short)7);
  private static final org.apache.thrift.protocol.TField INPUT_ORDER_FIELD_DESC = new org.apache.thrift.protocol.TField("inputOrder", org.apache.thrift.protocol.TType.I32, (short)8);
  private static final org.apache.thrift.protocol.TField IS_REQUIRED_FIELD_DESC = new org.apache.thrift.protocol.TField("isRequired", org.apache.thrift.protocol.TType.BOOL, (short)9);
  private static final org.apache.thrift.protocol.TField REQUIRED_TO_ADDED_TO_COMMAND_LINE_FIELD_DESC = new org.apache.thrift.protocol.TField("requiredToAddedToCommandLine", org.apache.thrift.protocol.TType.BOOL, (short)10);
  private static final org.apache.thrift.protocol.TField DATA_STAGED_FIELD_DESC = new org.apache.thrift.protocol.TField("dataStaged", org.apache.thrift.protocol.TType.BOOL, (short)11);
  private static final org.apache.thrift.protocol.TField STORAGE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("storageResourceId", org.apache.thrift.protocol.TType.STRING, (short)12);

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

  private String name; // required
  private String value; // optional
  private DataType type; // optional
  private String applicationArgument; // optional
  private boolean standardInput; // optional
  private String userFriendlyDescription; // optional
  private String metaData; // optional
  private int inputOrder; // optional
  private boolean isRequired; // optional
  private boolean requiredToAddedToCommandLine; // optional
  private boolean dataStaged; // optional
  private String storageResourceId; // 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 {
    NAME((short)1, "name"),
    VALUE((short)2, "value"),
    /**
     * 
     * @see DataType
     */
    TYPE((short)3, "type"),
    APPLICATION_ARGUMENT((short)4, "applicationArgument"),
    STANDARD_INPUT((short)5, "standardInput"),
    USER_FRIENDLY_DESCRIPTION((short)6, "userFriendlyDescription"),
    META_DATA((short)7, "metaData"),
    INPUT_ORDER((short)8, "inputOrder"),
    IS_REQUIRED((short)9, "isRequired"),
    REQUIRED_TO_ADDED_TO_COMMAND_LINE((short)10, "requiredToAddedToCommandLine"),
    DATA_STAGED((short)11, "dataStaged"),
    STORAGE_RESOURCE_ID((short)12, "storageResourceId");

    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: // NAME
          return NAME;
        case 2: // VALUE
          return VALUE;
        case 3: // TYPE
          return TYPE;
        case 4: // APPLICATION_ARGUMENT
          return APPLICATION_ARGUMENT;
        case 5: // STANDARD_INPUT
          return STANDARD_INPUT;
        case 6: // USER_FRIENDLY_DESCRIPTION
          return USER_FRIENDLY_DESCRIPTION;
        case 7: // META_DATA
          return META_DATA;
        case 8: // INPUT_ORDER
          return INPUT_ORDER;
        case 9: // IS_REQUIRED
          return IS_REQUIRED;
        case 10: // REQUIRED_TO_ADDED_TO_COMMAND_LINE
          return REQUIRED_TO_ADDED_TO_COMMAND_LINE;
        case 11: // DATA_STAGED
          return DATA_STAGED;
        case 12: // STORAGE_RESOURCE_ID
          return STORAGE_RESOURCE_ID;
        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 __STANDARDINPUT_ISSET_ID = 0;
  private static final int __INPUTORDER_ISSET_ID = 1;
  private static final int __ISREQUIRED_ISSET_ID = 2;
  private static final int __REQUIREDTOADDEDTOCOMMANDLINE_ISSET_ID = 3;
  private static final int __DATASTAGED_ISSET_ID = 4;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.VALUE,_Fields.TYPE,_Fields.APPLICATION_ARGUMENT,_Fields.STANDARD_INPUT,_Fields.USER_FRIENDLY_DESCRIPTION,_Fields.META_DATA,_Fields.INPUT_ORDER,_Fields.IS_REQUIRED,_Fields.REQUIRED_TO_ADDED_TO_COMMAND_LINE,_Fields.DATA_STAGED,_Fields.STORAGE_RESOURCE_ID};
  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.NAME, new org.apache.thrift.meta_data.FieldMetaData("name", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.TYPE, new org.apache.thrift.meta_data.FieldMetaData("type", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, DataType.class)));
    tmpMap.put(_Fields.APPLICATION_ARGUMENT, new org.apache.thrift.meta_data.FieldMetaData("applicationArgument", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.STANDARD_INPUT, new org.apache.thrift.meta_data.FieldMetaData("standardInput", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.USER_FRIENDLY_DESCRIPTION, new org.apache.thrift.meta_data.FieldMetaData("userFriendlyDescription", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.META_DATA, new org.apache.thrift.meta_data.FieldMetaData("metaData", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.INPUT_ORDER, new org.apache.thrift.meta_data.FieldMetaData("inputOrder", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.IS_REQUIRED, new org.apache.thrift.meta_data.FieldMetaData("isRequired", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.REQUIRED_TO_ADDED_TO_COMMAND_LINE, new org.apache.thrift.meta_data.FieldMetaData("requiredToAddedToCommandLine", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.DATA_STAGED, new org.apache.thrift.meta_data.FieldMetaData("dataStaged", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.STORAGE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("storageResourceId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(InputDataObjectType.class, metaDataMap);
  }

  public InputDataObjectType() {
  }

  public InputDataObjectType(
    String name)
  {
    this();
    this.name = name;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public InputDataObjectType(InputDataObjectType other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetName()) {
      this.name = other.name;
    }
    if (other.isSetValue()) {
      this.value = other.value;
    }
    if (other.isSetType()) {
      this.type = other.type;
    }
    if (other.isSetApplicationArgument()) {
      this.applicationArgument = other.applicationArgument;
    }
    this.standardInput = other.standardInput;
    if (other.isSetUserFriendlyDescription()) {
      this.userFriendlyDescription = other.userFriendlyDescription;
    }
    if (other.isSetMetaData()) {
      this.metaData = other.metaData;
    }
    this.inputOrder = other.inputOrder;
    this.isRequired = other.isRequired;
    this.requiredToAddedToCommandLine = other.requiredToAddedToCommandLine;
    this.dataStaged = other.dataStaged;
    if (other.isSetStorageResourceId()) {
      this.storageResourceId = other.storageResourceId;
    }
  }

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

  @Override
  public void clear() {
    this.name = null;
    this.value = null;
    this.type = null;
    this.applicationArgument = null;
    setStandardInputIsSet(false);
    this.standardInput = false;
    this.userFriendlyDescription = null;
    this.metaData = null;
    setInputOrderIsSet(false);
    this.inputOrder = 0;
    setIsRequiredIsSet(false);
    this.isRequired = false;
    setRequiredToAddedToCommandLineIsSet(false);
    this.requiredToAddedToCommandLine = false;
    setDataStagedIsSet(false);
    this.dataStaged = false;
    this.storageResourceId = null;
  }

  public String getName() {
    return this.name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public void unsetName() {
    this.name = null;
  }

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

  public void setNameIsSet(boolean value) {
    if (!value) {
      this.name = null;
    }
  }

  public String getValue() {
    return this.value;
  }

  public void setValue(String value) {
    this.value = value;
  }

  public void unsetValue() {
    this.value = null;
  }

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

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

  /**
   * 
   * @see DataType
   */
  public DataType getType() {
    return this.type;
  }

  /**
   * 
   * @see DataType
   */
  public void setType(DataType type) {
    this.type = type;
  }

  public void unsetType() {
    this.type = null;
  }

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

  public void setTypeIsSet(boolean value) {
    if (!value) {
      this.type = null;
    }
  }

  public String getApplicationArgument() {
    return this.applicationArgument;
  }

  public void setApplicationArgument(String applicationArgument) {
    this.applicationArgument = applicationArgument;
  }

  public void unsetApplicationArgument() {
    this.applicationArgument = null;
  }

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

  public void setApplicationArgumentIsSet(boolean value) {
    if (!value) {
      this.applicationArgument = null;
    }
  }

  public boolean isStandardInput() {
    return this.standardInput;
  }

  public void setStandardInput(boolean standardInput) {
    this.standardInput = standardInput;
    setStandardInputIsSet(true);
  }

  public void unsetStandardInput() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __STANDARDINPUT_ISSET_ID);
  }

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

  public void setStandardInputIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __STANDARDINPUT_ISSET_ID, value);
  }

  public String getUserFriendlyDescription() {
    return this.userFriendlyDescription;
  }

  public void setUserFriendlyDescription(String userFriendlyDescription) {
    this.userFriendlyDescription = userFriendlyDescription;
  }

  public void unsetUserFriendlyDescription() {
    this.userFriendlyDescription = null;
  }

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

  public void setUserFriendlyDescriptionIsSet(boolean value) {
    if (!value) {
      this.userFriendlyDescription = null;
    }
  }

  public String getMetaData() {
    return this.metaData;
  }

  public void setMetaData(String metaData) {
    this.metaData = metaData;
  }

  public void unsetMetaData() {
    this.metaData = null;
  }

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

  public void setMetaDataIsSet(boolean value) {
    if (!value) {
      this.metaData = null;
    }
  }

  public int getInputOrder() {
    return this.inputOrder;
  }

  public void setInputOrder(int inputOrder) {
    this.inputOrder = inputOrder;
    setInputOrderIsSet(true);
  }

  public void unsetInputOrder() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __INPUTORDER_ISSET_ID);
  }

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

  public void setInputOrderIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __INPUTORDER_ISSET_ID, value);
  }

  public boolean isIsRequired() {
    return this.isRequired;
  }

  public void setIsRequired(boolean isRequired) {
    this.isRequired = isRequired;
    setIsRequiredIsSet(true);
  }

  public void unsetIsRequired() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ISREQUIRED_ISSET_ID);
  }

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

  public void setIsRequiredIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ISREQUIRED_ISSET_ID, value);
  }

  public boolean isRequiredToAddedToCommandLine() {
    return this.requiredToAddedToCommandLine;
  }

  public void setRequiredToAddedToCommandLine(boolean requiredToAddedToCommandLine) {
    this.requiredToAddedToCommandLine = requiredToAddedToCommandLine;
    setRequiredToAddedToCommandLineIsSet(true);
  }

  public void unsetRequiredToAddedToCommandLine() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __REQUIREDTOADDEDTOCOMMANDLINE_ISSET_ID);
  }

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

  public void setRequiredToAddedToCommandLineIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __REQUIREDTOADDEDTOCOMMANDLINE_ISSET_ID, value);
  }

  public boolean isDataStaged() {
    return this.dataStaged;
  }

  public void setDataStaged(boolean dataStaged) {
    this.dataStaged = dataStaged;
    setDataStagedIsSet(true);
  }

  public void unsetDataStaged() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __DATASTAGED_ISSET_ID);
  }

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

  public void setDataStagedIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __DATASTAGED_ISSET_ID, value);
  }

  public String getStorageResourceId() {
    return this.storageResourceId;
  }

  public void setStorageResourceId(String storageResourceId) {
    this.storageResourceId = storageResourceId;
  }

  public void unsetStorageResourceId() {
    this.storageResourceId = null;
  }

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

  public void setStorageResourceIdIsSet(boolean value) {
    if (!value) {
      this.storageResourceId = null;
    }
  }

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case NAME:
      if (value == null) {
        unsetName();
      } else {
        setName((String)value);
      }
      break;

    case VALUE:
      if (value == null) {
        unsetValue();
      } else {
        setValue((String)value);
      }
      break;

    case TYPE:
      if (value == null) {
        unsetType();
      } else {
        setType((DataType)value);
      }
      break;

    case APPLICATION_ARGUMENT:
      if (value == null) {
        unsetApplicationArgument();
      } else {
        setApplicationArgument((String)value);
      }
      break;

    case STANDARD_INPUT:
      if (value == null) {
        unsetStandardInput();
      } else {
        setStandardInput((Boolean)value);
      }
      break;

    case USER_FRIENDLY_DESCRIPTION:
      if (value == null) {
        unsetUserFriendlyDescription();
      } else {
        setUserFriendlyDescription((String)value);
      }
      break;

    case META_DATA:
      if (value == null) {
        unsetMetaData();
      } else {
        setMetaData((String)value);
      }
      break;

    case INPUT_ORDER:
      if (value == null) {
        unsetInputOrder();
      } else {
        setInputOrder((Integer)value);
      }
      break;

    case IS_REQUIRED:
      if (value == null) {
        unsetIsRequired();
      } else {
        setIsRequired((Boolean)value);
      }
      break;

    case REQUIRED_TO_ADDED_TO_COMMAND_LINE:
      if (value == null) {
        unsetRequiredToAddedToCommandLine();
      } else {
        setRequiredToAddedToCommandLine((Boolean)value);
      }
      break;

    case DATA_STAGED:
      if (value == null) {
        unsetDataStaged();
      } else {
        setDataStaged((Boolean)value);
      }
      break;

    case STORAGE_RESOURCE_ID:
      if (value == null) {
        unsetStorageResourceId();
      } else {
        setStorageResourceId((String)value);
      }
      break;

    }
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case NAME:
      return getName();

    case VALUE:
      return getValue();

    case TYPE:
      return getType();

    case APPLICATION_ARGUMENT:
      return getApplicationArgument();

    case STANDARD_INPUT:
      return isStandardInput();

    case USER_FRIENDLY_DESCRIPTION:
      return getUserFriendlyDescription();

    case META_DATA:
      return getMetaData();

    case INPUT_ORDER:
      return getInputOrder();

    case IS_REQUIRED:
      return isIsRequired();

    case REQUIRED_TO_ADDED_TO_COMMAND_LINE:
      return isRequiredToAddedToCommandLine();

    case DATA_STAGED:
      return isDataStaged();

    case STORAGE_RESOURCE_ID:
      return getStorageResourceId();

    }
    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 NAME:
      return isSetName();
    case VALUE:
      return isSetValue();
    case TYPE:
      return isSetType();
    case APPLICATION_ARGUMENT:
      return isSetApplicationArgument();
    case STANDARD_INPUT:
      return isSetStandardInput();
    case USER_FRIENDLY_DESCRIPTION:
      return isSetUserFriendlyDescription();
    case META_DATA:
      return isSetMetaData();
    case INPUT_ORDER:
      return isSetInputOrder();
    case IS_REQUIRED:
      return isSetIsRequired();
    case REQUIRED_TO_ADDED_TO_COMMAND_LINE:
      return isSetRequiredToAddedToCommandLine();
    case DATA_STAGED:
      return isSetDataStaged();
    case STORAGE_RESOURCE_ID:
      return isSetStorageResourceId();
    }
    throw new IllegalStateException();
  }

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

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

    boolean this_present_name = true && this.isSetName();
    boolean that_present_name = true && that.isSetName();
    if (this_present_name || that_present_name) {
      if (!(this_present_name && that_present_name))
        return false;
      if (!this.name.equals(that.name))
        return false;
    }

    boolean this_present_value = true && this.isSetValue();
    boolean that_present_value = true && that.isSetValue();
    if (this_present_value || that_present_value) {
      if (!(this_present_value && that_present_value))
        return false;
      if (!this.value.equals(that.value))
        return false;
    }

    boolean this_present_type = true && this.isSetType();
    boolean that_present_type = true && that.isSetType();
    if (this_present_type || that_present_type) {
      if (!(this_present_type && that_present_type))
        return false;
      if (!this.type.equals(that.type))
        return false;
    }

    boolean this_present_applicationArgument = true && this.isSetApplicationArgument();
    boolean that_present_applicationArgument = true && that.isSetApplicationArgument();
    if (this_present_applicationArgument || that_present_applicationArgument) {
      if (!(this_present_applicationArgument && that_present_applicationArgument))
        return false;
      if (!this.applicationArgument.equals(that.applicationArgument))
        return false;
    }

    boolean this_present_standardInput = true && this.isSetStandardInput();
    boolean that_present_standardInput = true && that.isSetStandardInput();
    if (this_present_standardInput || that_present_standardInput) {
      if (!(this_present_standardInput && that_present_standardInput))
        return false;
      if (this.standardInput != that.standardInput)
        return false;
    }

    boolean this_present_userFriendlyDescription = true && this.isSetUserFriendlyDescription();
    boolean that_present_userFriendlyDescription = true && that.isSetUserFriendlyDescription();
    if (this_present_userFriendlyDescription || that_present_userFriendlyDescription) {
      if (!(this_present_userFriendlyDescription && that_present_userFriendlyDescription))
        return false;
      if (!this.userFriendlyDescription.equals(that.userFriendlyDescription))
        return false;
    }

    boolean this_present_metaData = true && this.isSetMetaData();
    boolean that_present_metaData = true && that.isSetMetaData();
    if (this_present_metaData || that_present_metaData) {
      if (!(this_present_metaData && that_present_metaData))
        return false;
      if (!this.metaData.equals(that.metaData))
        return false;
    }

    boolean this_present_inputOrder = true && this.isSetInputOrder();
    boolean that_present_inputOrder = true && that.isSetInputOrder();
    if (this_present_inputOrder || that_present_inputOrder) {
      if (!(this_present_inputOrder && that_present_inputOrder))
        return false;
      if (this.inputOrder != that.inputOrder)
        return false;
    }

    boolean this_present_isRequired = true && this.isSetIsRequired();
    boolean that_present_isRequired = true && that.isSetIsRequired();
    if (this_present_isRequired || that_present_isRequired) {
      if (!(this_present_isRequired && that_present_isRequired))
        return false;
      if (this.isRequired != that.isRequired)
        return false;
    }

    boolean this_present_requiredToAddedToCommandLine = true && this.isSetRequiredToAddedToCommandLine();
    boolean that_present_requiredToAddedToCommandLine = true && that.isSetRequiredToAddedToCommandLine();
    if (this_present_requiredToAddedToCommandLine || that_present_requiredToAddedToCommandLine) {
      if (!(this_present_requiredToAddedToCommandLine && that_present_requiredToAddedToCommandLine))
        return false;
      if (this.requiredToAddedToCommandLine != that.requiredToAddedToCommandLine)
        return false;
    }

    boolean this_present_dataStaged = true && this.isSetDataStaged();
    boolean that_present_dataStaged = true && that.isSetDataStaged();
    if (this_present_dataStaged || that_present_dataStaged) {
      if (!(this_present_dataStaged && that_present_dataStaged))
        return false;
      if (this.dataStaged != that.dataStaged)
        return false;
    }

    boolean this_present_storageResourceId = true && this.isSetStorageResourceId();
    boolean that_present_storageResourceId = true && that.isSetStorageResourceId();
    if (this_present_storageResourceId || that_present_storageResourceId) {
      if (!(this_present_storageResourceId && that_present_storageResourceId))
        return false;
      if (!this.storageResourceId.equals(that.storageResourceId))
        return false;
    }

    return true;
  }

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

    boolean present_name = true && (isSetName());
    list.add(present_name);
    if (present_name)
      list.add(name);

    boolean present_value = true && (isSetValue());
    list.add(present_value);
    if (present_value)
      list.add(value);

    boolean present_type = true && (isSetType());
    list.add(present_type);
    if (present_type)
      list.add(type.getValue());

    boolean present_applicationArgument = true && (isSetApplicationArgument());
    list.add(present_applicationArgument);
    if (present_applicationArgument)
      list.add(applicationArgument);

    boolean present_standardInput = true && (isSetStandardInput());
    list.add(present_standardInput);
    if (present_standardInput)
      list.add(standardInput);

    boolean present_userFriendlyDescription = true && (isSetUserFriendlyDescription());
    list.add(present_userFriendlyDescription);
    if (present_userFriendlyDescription)
      list.add(userFriendlyDescription);

    boolean present_metaData = true && (isSetMetaData());
    list.add(present_metaData);
    if (present_metaData)
      list.add(metaData);

    boolean present_inputOrder = true && (isSetInputOrder());
    list.add(present_inputOrder);
    if (present_inputOrder)
      list.add(inputOrder);

    boolean present_isRequired = true && (isSetIsRequired());
    list.add(present_isRequired);
    if (present_isRequired)
      list.add(isRequired);

    boolean present_requiredToAddedToCommandLine = true && (isSetRequiredToAddedToCommandLine());
    list.add(present_requiredToAddedToCommandLine);
    if (present_requiredToAddedToCommandLine)
      list.add(requiredToAddedToCommandLine);

    boolean present_dataStaged = true && (isSetDataStaged());
    list.add(present_dataStaged);
    if (present_dataStaged)
      list.add(dataStaged);

    boolean present_storageResourceId = true && (isSetStorageResourceId());
    list.add(present_storageResourceId);
    if (present_storageResourceId)
      list.add(storageResourceId);

    return list.hashCode();
  }

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

    int lastComparison = 0;

    lastComparison = Boolean.valueOf(isSetName()).compareTo(other.isSetName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.name, other.name);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetValue()).compareTo(other.isSetValue());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetValue()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.value, other.value);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetType()).compareTo(other.isSetType());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetType()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.type, other.type);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetApplicationArgument()).compareTo(other.isSetApplicationArgument());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetApplicationArgument()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationArgument, other.applicationArgument);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetStandardInput()).compareTo(other.isSetStandardInput());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetStandardInput()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.standardInput, other.standardInput);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetUserFriendlyDescription()).compareTo(other.isSetUserFriendlyDescription());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetUserFriendlyDescription()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userFriendlyDescription, other.userFriendlyDescription);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetMetaData()).compareTo(other.isSetMetaData());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetMetaData()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.metaData, other.metaData);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetInputOrder()).compareTo(other.isSetInputOrder());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetInputOrder()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.inputOrder, other.inputOrder);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetIsRequired()).compareTo(other.isSetIsRequired());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetIsRequired()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.isRequired, other.isRequired);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetRequiredToAddedToCommandLine()).compareTo(other.isSetRequiredToAddedToCommandLine());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetRequiredToAddedToCommandLine()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.requiredToAddedToCommandLine, other.requiredToAddedToCommandLine);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetDataStaged()).compareTo(other.isSetDataStaged());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetDataStaged()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataStaged, other.dataStaged);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetStorageResourceId()).compareTo(other.isSetStorageResourceId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetStorageResourceId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.storageResourceId, other.storageResourceId);
      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("InputDataObjectType(");
    boolean first = true;

    sb.append("name:");
    if (this.name == null) {
      sb.append("null");
    } else {
      sb.append(this.name);
    }
    first = false;
    if (isSetValue()) {
      if (!first) sb.append(", ");
      sb.append("value:");
      if (this.value == null) {
        sb.append("null");
      } else {
        sb.append(this.value);
      }
      first = false;
    }
    if (isSetType()) {
      if (!first) sb.append(", ");
      sb.append("type:");
      if (this.type == null) {
        sb.append("null");
      } else {
        sb.append(this.type);
      }
      first = false;
    }
    if (isSetApplicationArgument()) {
      if (!first) sb.append(", ");
      sb.append("applicationArgument:");
      if (this.applicationArgument == null) {
        sb.append("null");
      } else {
        sb.append(this.applicationArgument);
      }
      first = false;
    }
    if (isSetStandardInput()) {
      if (!first) sb.append(", ");
      sb.append("standardInput:");
      sb.append(this.standardInput);
      first = false;
    }
    if (isSetUserFriendlyDescription()) {
      if (!first) sb.append(", ");
      sb.append("userFriendlyDescription:");
      if (this.userFriendlyDescription == null) {
        sb.append("null");
      } else {
        sb.append(this.userFriendlyDescription);
      }
      first = false;
    }
    if (isSetMetaData()) {
      if (!first) sb.append(", ");
      sb.append("metaData:");
      if (this.metaData == null) {
        sb.append("null");
      } else {
        sb.append(this.metaData);
      }
      first = false;
    }
    if (isSetInputOrder()) {
      if (!first) sb.append(", ");
      sb.append("inputOrder:");
      sb.append(this.inputOrder);
      first = false;
    }
    if (isSetIsRequired()) {
      if (!first) sb.append(", ");
      sb.append("isRequired:");
      sb.append(this.isRequired);
      first = false;
    }
    if (isSetRequiredToAddedToCommandLine()) {
      if (!first) sb.append(", ");
      sb.append("requiredToAddedToCommandLine:");
      sb.append(this.requiredToAddedToCommandLine);
      first = false;
    }
    if (isSetDataStaged()) {
      if (!first) sb.append(", ");
      sb.append("dataStaged:");
      sb.append(this.dataStaged);
      first = false;
    }
    if (isSetStorageResourceId()) {
      if (!first) sb.append(", ");
      sb.append("storageResourceId:");
      if (this.storageResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.storageResourceId);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.thrift.TException {
    // check for required fields
    if (!isSetName()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'name' 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 InputDataObjectTypeStandardSchemeFactory implements SchemeFactory {
    public InputDataObjectTypeStandardScheme getScheme() {
      return new InputDataObjectTypeStandardScheme();
    }
  }

  private static class InputDataObjectTypeStandardScheme extends StandardScheme<InputDataObjectType> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, InputDataObjectType 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: // NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.name = iprot.readString();
              struct.setNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // VALUE
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.value = iprot.readString();
              struct.setValueIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // TYPE
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.type = org.apache.airavata.model.application.io.DataType.findByValue(iprot.readI32());
              struct.setTypeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // APPLICATION_ARGUMENT
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.applicationArgument = iprot.readString();
              struct.setApplicationArgumentIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // STANDARD_INPUT
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.standardInput = iprot.readBool();
              struct.setStandardInputIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // USER_FRIENDLY_DESCRIPTION
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.userFriendlyDescription = iprot.readString();
              struct.setUserFriendlyDescriptionIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // META_DATA
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.metaData = iprot.readString();
              struct.setMetaDataIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // INPUT_ORDER
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.inputOrder = iprot.readI32();
              struct.setInputOrderIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // IS_REQUIRED
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.isRequired = iprot.readBool();
              struct.setIsRequiredIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // REQUIRED_TO_ADDED_TO_COMMAND_LINE
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.requiredToAddedToCommandLine = iprot.readBool();
              struct.setRequiredToAddedToCommandLineIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 11: // DATA_STAGED
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.dataStaged = iprot.readBool();
              struct.setDataStagedIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 12: // STORAGE_RESOURCE_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.storageResourceId = iprot.readString();
              struct.setStorageResourceIdIsSet(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, InputDataObjectType struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.name != null) {
        oprot.writeFieldBegin(NAME_FIELD_DESC);
        oprot.writeString(struct.name);
        oprot.writeFieldEnd();
      }
      if (struct.value != null) {
        if (struct.isSetValue()) {
          oprot.writeFieldBegin(VALUE_FIELD_DESC);
          oprot.writeString(struct.value);
          oprot.writeFieldEnd();
        }
      }
      if (struct.type != null) {
        if (struct.isSetType()) {
          oprot.writeFieldBegin(TYPE_FIELD_DESC);
          oprot.writeI32(struct.type.getValue());
          oprot.writeFieldEnd();
        }
      }
      if (struct.applicationArgument != null) {
        if (struct.isSetApplicationArgument()) {
          oprot.writeFieldBegin(APPLICATION_ARGUMENT_FIELD_DESC);
          oprot.writeString(struct.applicationArgument);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetStandardInput()) {
        oprot.writeFieldBegin(STANDARD_INPUT_FIELD_DESC);
        oprot.writeBool(struct.standardInput);
        oprot.writeFieldEnd();
      }
      if (struct.userFriendlyDescription != null) {
        if (struct.isSetUserFriendlyDescription()) {
          oprot.writeFieldBegin(USER_FRIENDLY_DESCRIPTION_FIELD_DESC);
          oprot.writeString(struct.userFriendlyDescription);
          oprot.writeFieldEnd();
        }
      }
      if (struct.metaData != null) {
        if (struct.isSetMetaData()) {
          oprot.writeFieldBegin(META_DATA_FIELD_DESC);
          oprot.writeString(struct.metaData);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetInputOrder()) {
        oprot.writeFieldBegin(INPUT_ORDER_FIELD_DESC);
        oprot.writeI32(struct.inputOrder);
        oprot.writeFieldEnd();
      }
      if (struct.isSetIsRequired()) {
        oprot.writeFieldBegin(IS_REQUIRED_FIELD_DESC);
        oprot.writeBool(struct.isRequired);
        oprot.writeFieldEnd();
      }
      if (struct.isSetRequiredToAddedToCommandLine()) {
        oprot.writeFieldBegin(REQUIRED_TO_ADDED_TO_COMMAND_LINE_FIELD_DESC);
        oprot.writeBool(struct.requiredToAddedToCommandLine);
        oprot.writeFieldEnd();
      }
      if (struct.isSetDataStaged()) {
        oprot.writeFieldBegin(DATA_STAGED_FIELD_DESC);
        oprot.writeBool(struct.dataStaged);
        oprot.writeFieldEnd();
      }
      if (struct.storageResourceId != null) {
        if (struct.isSetStorageResourceId()) {
          oprot.writeFieldBegin(STORAGE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.storageResourceId);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class InputDataObjectTypeTupleSchemeFactory implements SchemeFactory {
    public InputDataObjectTypeTupleScheme getScheme() {
      return new InputDataObjectTypeTupleScheme();
    }
  }

  private static class InputDataObjectTypeTupleScheme extends TupleScheme<InputDataObjectType> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, InputDataObjectType struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      oprot.writeString(struct.name);
      BitSet optionals = new BitSet();
      if (struct.isSetValue()) {
        optionals.set(0);
      }
      if (struct.isSetType()) {
        optionals.set(1);
      }
      if (struct.isSetApplicationArgument()) {
        optionals.set(2);
      }
      if (struct.isSetStandardInput()) {
        optionals.set(3);
      }
      if (struct.isSetUserFriendlyDescription()) {
        optionals.set(4);
      }
      if (struct.isSetMetaData()) {
        optionals.set(5);
      }
      if (struct.isSetInputOrder()) {
        optionals.set(6);
      }
      if (struct.isSetIsRequired()) {
        optionals.set(7);
      }
      if (struct.isSetRequiredToAddedToCommandLine()) {
        optionals.set(8);
      }
      if (struct.isSetDataStaged()) {
        optionals.set(9);
      }
      if (struct.isSetStorageResourceId()) {
        optionals.set(10);
      }
      oprot.writeBitSet(optionals, 11);
      if (struct.isSetValue()) {
        oprot.writeString(struct.value);
      }
      if (struct.isSetType()) {
        oprot.writeI32(struct.type.getValue());
      }
      if (struct.isSetApplicationArgument()) {
        oprot.writeString(struct.applicationArgument);
      }
      if (struct.isSetStandardInput()) {
        oprot.writeBool(struct.standardInput);
      }
      if (struct.isSetUserFriendlyDescription()) {
        oprot.writeString(struct.userFriendlyDescription);
      }
      if (struct.isSetMetaData()) {
        oprot.writeString(struct.metaData);
      }
      if (struct.isSetInputOrder()) {
        oprot.writeI32(struct.inputOrder);
      }
      if (struct.isSetIsRequired()) {
        oprot.writeBool(struct.isRequired);
      }
      if (struct.isSetRequiredToAddedToCommandLine()) {
        oprot.writeBool(struct.requiredToAddedToCommandLine);
      }
      if (struct.isSetDataStaged()) {
        oprot.writeBool(struct.dataStaged);
      }
      if (struct.isSetStorageResourceId()) {
        oprot.writeString(struct.storageResourceId);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, InputDataObjectType struct) throws org.apache.thrift.TException {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      struct.name = iprot.readString();
      struct.setNameIsSet(true);
      BitSet incoming = iprot.readBitSet(11);
      if (incoming.get(0)) {
        struct.value = iprot.readString();
        struct.setValueIsSet(true);
      }
      if (incoming.get(1)) {
        struct.type = org.apache.airavata.model.application.io.DataType.findByValue(iprot.readI32());
        struct.setTypeIsSet(true);
      }
      if (incoming.get(2)) {
        struct.applicationArgument = iprot.readString();
        struct.setApplicationArgumentIsSet(true);
      }
      if (incoming.get(3)) {
        struct.standardInput = iprot.readBool();
        struct.setStandardInputIsSet(true);
      }
      if (incoming.get(4)) {
        struct.userFriendlyDescription = iprot.readString();
        struct.setUserFriendlyDescriptionIsSet(true);
      }
      if (incoming.get(5)) {
        struct.metaData = iprot.readString();
        struct.setMetaDataIsSet(true);
      }
      if (incoming.get(6)) {
        struct.inputOrder = iprot.readI32();
        struct.setInputOrderIsSet(true);
      }
      if (incoming.get(7)) {
        struct.isRequired = iprot.readBool();
        struct.setIsRequiredIsSet(true);
      }
      if (incoming.get(8)) {
        struct.requiredToAddedToCommandLine = iprot.readBool();
        struct.setRequiredToAddedToCommandLineIsSet(true);
      }
      if (incoming.get(9)) {
        struct.dataStaged = iprot.readBool();
        struct.setDataStagedIsSet(true);
      }
      if (incoming.get(10)) {
        struct.storageResourceId = iprot.readString();
        struct.setStorageResourceIdIsSet(true);
      }
    }
  }

}

