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

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

/**
 * A structure holding the experiment metadata and its child models.
 * 
 * userName:
 *   The user name of the targeted gateway end user on whose behalf the experiment is being created.
 *     the associated gateway identity can only be inferred from the security hand-shake so as to avoid
 *     authorized Airavata Clients mimicking an unauthorized request. If a gateway is not registered with
 *     Airavata, an authorization exception is thrown.
 * 
 * experimentName:
 *   The name of the experiment as defined by the user. The name need not be unique as uniqueness is enforced
 *      by the generated experiment id.
 * 
 * experimentDescription:
 *    The verbose description of the experiment. This is an optional parameter.
 */
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.18.1)")
public class ExperimentModel implements org.apache.thrift.TBase<ExperimentModel, ExperimentModel._Fields>, java.io.Serializable, Cloneable, Comparable<ExperimentModel> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ExperimentModel");

  private static final org.apache.thrift.protocol.TField EXPERIMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("experimentId", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField PROJECT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("projectId", org.apache.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.thrift.protocol.TField GATEWAY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("gatewayId", org.apache.thrift.protocol.TType.STRING, (short)3);
  private static final org.apache.thrift.protocol.TField EXPERIMENT_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("experimentType", org.apache.thrift.protocol.TType.I32, (short)4);
  private static final org.apache.thrift.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)5);
  private static final org.apache.thrift.protocol.TField EXPERIMENT_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("experimentName", org.apache.thrift.protocol.TType.STRING, (short)6);
  private static final org.apache.thrift.protocol.TField CREATION_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("creationTime", org.apache.thrift.protocol.TType.I64, (short)7);
  private static final org.apache.thrift.protocol.TField DESCRIPTION_FIELD_DESC = new org.apache.thrift.protocol.TField("description", org.apache.thrift.protocol.TType.STRING, (short)8);
  private static final org.apache.thrift.protocol.TField EXECUTION_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("executionId", org.apache.thrift.protocol.TType.STRING, (short)9);
  private static final org.apache.thrift.protocol.TField GATEWAY_EXECUTION_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("gatewayExecutionId", org.apache.thrift.protocol.TType.STRING, (short)10);
  private static final org.apache.thrift.protocol.TField GATEWAY_INSTANCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("gatewayInstanceId", org.apache.thrift.protocol.TType.STRING, (short)11);
  private static final org.apache.thrift.protocol.TField ENABLE_EMAIL_NOTIFICATION_FIELD_DESC = new org.apache.thrift.protocol.TField("enableEmailNotification", org.apache.thrift.protocol.TType.BOOL, (short)12);
  private static final org.apache.thrift.protocol.TField EMAIL_ADDRESSES_FIELD_DESC = new org.apache.thrift.protocol.TField("emailAddresses", org.apache.thrift.protocol.TType.LIST, (short)13);
  private static final org.apache.thrift.protocol.TField USER_CONFIGURATION_DATA_FIELD_DESC = new org.apache.thrift.protocol.TField("userConfigurationData", org.apache.thrift.protocol.TType.STRUCT, (short)14);
  private static final org.apache.thrift.protocol.TField EXPERIMENT_INPUTS_FIELD_DESC = new org.apache.thrift.protocol.TField("experimentInputs", org.apache.thrift.protocol.TType.LIST, (short)15);
  private static final org.apache.thrift.protocol.TField EXPERIMENT_OUTPUTS_FIELD_DESC = new org.apache.thrift.protocol.TField("experimentOutputs", org.apache.thrift.protocol.TType.LIST, (short)16);
  private static final org.apache.thrift.protocol.TField EXPERIMENT_STATUS_FIELD_DESC = new org.apache.thrift.protocol.TField("experimentStatus", org.apache.thrift.protocol.TType.LIST, (short)17);
  private static final org.apache.thrift.protocol.TField ERRORS_FIELD_DESC = new org.apache.thrift.protocol.TField("errors", org.apache.thrift.protocol.TType.LIST, (short)18);
  private static final org.apache.thrift.protocol.TField PROCESSES_FIELD_DESC = new org.apache.thrift.protocol.TField("processes", org.apache.thrift.protocol.TType.LIST, (short)19);
  private static final org.apache.thrift.protocol.TField WORKFLOW_FIELD_DESC = new org.apache.thrift.protocol.TField("workflow", org.apache.thrift.protocol.TType.STRUCT, (short)20);

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

  private @org.apache.thrift.annotation.Nullable java.lang.String experimentId; // required
  private @org.apache.thrift.annotation.Nullable java.lang.String projectId; // required
  private @org.apache.thrift.annotation.Nullable java.lang.String gatewayId; // required
  private @org.apache.thrift.annotation.Nullable ExperimentType experimentType; // required
  private @org.apache.thrift.annotation.Nullable java.lang.String userName; // required
  private @org.apache.thrift.annotation.Nullable java.lang.String experimentName; // required
  private long creationTime; // optional
  private @org.apache.thrift.annotation.Nullable java.lang.String description; // optional
  private @org.apache.thrift.annotation.Nullable java.lang.String executionId; // optional
  private @org.apache.thrift.annotation.Nullable java.lang.String gatewayExecutionId; // optional
  private @org.apache.thrift.annotation.Nullable java.lang.String gatewayInstanceId; // optional
  private boolean enableEmailNotification; // optional
  private @org.apache.thrift.annotation.Nullable java.util.List<java.lang.String> emailAddresses; // optional
  private @org.apache.thrift.annotation.Nullable UserConfigurationDataModel userConfigurationData; // optional
  private @org.apache.thrift.annotation.Nullable java.util.List<org.apache.airavata.model.application.io.InputDataObjectType> experimentInputs; // optional
  private @org.apache.thrift.annotation.Nullable java.util.List<org.apache.airavata.model.application.io.OutputDataObjectType> experimentOutputs; // optional
  private @org.apache.thrift.annotation.Nullable java.util.List<org.apache.airavata.model.status.ExperimentStatus> experimentStatus; // optional
  private @org.apache.thrift.annotation.Nullable java.util.List<org.apache.airavata.model.commons.ErrorModel> errors; // optional
  private @org.apache.thrift.annotation.Nullable java.util.List<org.apache.airavata.model.process.ProcessModel> processes; // optional
  private @org.apache.thrift.annotation.Nullable org.apache.airavata.model.workflow.AiravataWorkflow workflow; // 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 {
    EXPERIMENT_ID((short)1, "experimentId"),
    PROJECT_ID((short)2, "projectId"),
    GATEWAY_ID((short)3, "gatewayId"),
    /**
     * 
     * @see ExperimentType
     */
    EXPERIMENT_TYPE((short)4, "experimentType"),
    USER_NAME((short)5, "userName"),
    EXPERIMENT_NAME((short)6, "experimentName"),
    CREATION_TIME((short)7, "creationTime"),
    DESCRIPTION((short)8, "description"),
    EXECUTION_ID((short)9, "executionId"),
    GATEWAY_EXECUTION_ID((short)10, "gatewayExecutionId"),
    GATEWAY_INSTANCE_ID((short)11, "gatewayInstanceId"),
    ENABLE_EMAIL_NOTIFICATION((short)12, "enableEmailNotification"),
    EMAIL_ADDRESSES((short)13, "emailAddresses"),
    USER_CONFIGURATION_DATA((short)14, "userConfigurationData"),
    EXPERIMENT_INPUTS((short)15, "experimentInputs"),
    EXPERIMENT_OUTPUTS((short)16, "experimentOutputs"),
    EXPERIMENT_STATUS((short)17, "experimentStatus"),
    ERRORS((short)18, "errors"),
    PROCESSES((short)19, "processes"),
    WORKFLOW((short)20, "workflow");

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

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

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    @org.apache.thrift.annotation.Nullable
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // EXPERIMENT_ID
          return EXPERIMENT_ID;
        case 2: // PROJECT_ID
          return PROJECT_ID;
        case 3: // GATEWAY_ID
          return GATEWAY_ID;
        case 4: // EXPERIMENT_TYPE
          return EXPERIMENT_TYPE;
        case 5: // USER_NAME
          return USER_NAME;
        case 6: // EXPERIMENT_NAME
          return EXPERIMENT_NAME;
        case 7: // CREATION_TIME
          return CREATION_TIME;
        case 8: // DESCRIPTION
          return DESCRIPTION;
        case 9: // EXECUTION_ID
          return EXECUTION_ID;
        case 10: // GATEWAY_EXECUTION_ID
          return GATEWAY_EXECUTION_ID;
        case 11: // GATEWAY_INSTANCE_ID
          return GATEWAY_INSTANCE_ID;
        case 12: // ENABLE_EMAIL_NOTIFICATION
          return ENABLE_EMAIL_NOTIFICATION;
        case 13: // EMAIL_ADDRESSES
          return EMAIL_ADDRESSES;
        case 14: // USER_CONFIGURATION_DATA
          return USER_CONFIGURATION_DATA;
        case 15: // EXPERIMENT_INPUTS
          return EXPERIMENT_INPUTS;
        case 16: // EXPERIMENT_OUTPUTS
          return EXPERIMENT_OUTPUTS;
        case 17: // EXPERIMENT_STATUS
          return EXPERIMENT_STATUS;
        case 18: // ERRORS
          return ERRORS;
        case 19: // PROCESSES
          return PROCESSES;
        case 20: // WORKFLOW
          return WORKFLOW;
        default:
          return null;
      }
    }

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

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

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

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

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

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

  // isset id assignments
  private static final int __CREATIONTIME_ISSET_ID = 0;
  private static final int __ENABLEEMAILNOTIFICATION_ISSET_ID = 1;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.CREATION_TIME,_Fields.DESCRIPTION,_Fields.EXECUTION_ID,_Fields.GATEWAY_EXECUTION_ID,_Fields.GATEWAY_INSTANCE_ID,_Fields.ENABLE_EMAIL_NOTIFICATION,_Fields.EMAIL_ADDRESSES,_Fields.USER_CONFIGURATION_DATA,_Fields.EXPERIMENT_INPUTS,_Fields.EXPERIMENT_OUTPUTS,_Fields.EXPERIMENT_STATUS,_Fields.ERRORS,_Fields.PROCESSES,_Fields.WORKFLOW};
  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.EXPERIMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("experimentId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.PROJECT_ID, new org.apache.thrift.meta_data.FieldMetaData("projectId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.GATEWAY_ID, new org.apache.thrift.meta_data.FieldMetaData("gatewayId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.EXPERIMENT_TYPE, new org.apache.thrift.meta_data.FieldMetaData("experimentType", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ExperimentType.class)));
    tmpMap.put(_Fields.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.EXPERIMENT_NAME, new org.apache.thrift.meta_data.FieldMetaData("experimentName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.CREATION_TIME, new org.apache.thrift.meta_data.FieldMetaData("creationTime", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.DESCRIPTION, new org.apache.thrift.meta_data.FieldMetaData("description", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.EXECUTION_ID, new org.apache.thrift.meta_data.FieldMetaData("executionId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.GATEWAY_EXECUTION_ID, new org.apache.thrift.meta_data.FieldMetaData("gatewayExecutionId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.GATEWAY_INSTANCE_ID, new org.apache.thrift.meta_data.FieldMetaData("gatewayInstanceId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.ENABLE_EMAIL_NOTIFICATION, new org.apache.thrift.meta_data.FieldMetaData("enableEmailNotification", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.EMAIL_ADDRESSES, new org.apache.thrift.meta_data.FieldMetaData("emailAddresses", 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.USER_CONFIGURATION_DATA, new org.apache.thrift.meta_data.FieldMetaData("userConfigurationData", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, UserConfigurationDataModel.class)));
    tmpMap.put(_Fields.EXPERIMENT_INPUTS, new org.apache.thrift.meta_data.FieldMetaData("experimentInputs", 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.EXPERIMENT_OUTPUTS, new org.apache.thrift.meta_data.FieldMetaData("experimentOutputs", 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.EXPERIMENT_STATUS, new org.apache.thrift.meta_data.FieldMetaData("experimentStatus", 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.status.ExperimentStatus.class))));
    tmpMap.put(_Fields.ERRORS, new org.apache.thrift.meta_data.FieldMetaData("errors", 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.commons.ErrorModel.class))));
    tmpMap.put(_Fields.PROCESSES, new org.apache.thrift.meta_data.FieldMetaData("processes", 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.process.ProcessModel.class))));
    tmpMap.put(_Fields.WORKFLOW, new org.apache.thrift.meta_data.FieldMetaData("workflow", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.workflow.AiravataWorkflow.class)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ExperimentModel.class, metaDataMap);
  }

  public ExperimentModel() {
    this.experimentId = "DO_NOT_SET_AT_CLIENTS";

    this.experimentType = org.apache.airavata.model.experiment.ExperimentType.SINGLE_APPLICATION;

  }

  public ExperimentModel(
    java.lang.String experimentId,
    java.lang.String projectId,
    java.lang.String gatewayId,
    ExperimentType experimentType,
    java.lang.String userName,
    java.lang.String experimentName)
  {
    this();
    this.experimentId = experimentId;
    this.projectId = projectId;
    this.gatewayId = gatewayId;
    this.experimentType = experimentType;
    this.userName = userName;
    this.experimentName = experimentName;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public ExperimentModel(ExperimentModel other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetExperimentId()) {
      this.experimentId = other.experimentId;
    }
    if (other.isSetProjectId()) {
      this.projectId = other.projectId;
    }
    if (other.isSetGatewayId()) {
      this.gatewayId = other.gatewayId;
    }
    if (other.isSetExperimentType()) {
      this.experimentType = other.experimentType;
    }
    if (other.isSetUserName()) {
      this.userName = other.userName;
    }
    if (other.isSetExperimentName()) {
      this.experimentName = other.experimentName;
    }
    this.creationTime = other.creationTime;
    if (other.isSetDescription()) {
      this.description = other.description;
    }
    if (other.isSetExecutionId()) {
      this.executionId = other.executionId;
    }
    if (other.isSetGatewayExecutionId()) {
      this.gatewayExecutionId = other.gatewayExecutionId;
    }
    if (other.isSetGatewayInstanceId()) {
      this.gatewayInstanceId = other.gatewayInstanceId;
    }
    this.enableEmailNotification = other.enableEmailNotification;
    if (other.isSetEmailAddresses()) {
      java.util.List<java.lang.String> __this__emailAddresses = new java.util.ArrayList<java.lang.String>(other.emailAddresses);
      this.emailAddresses = __this__emailAddresses;
    }
    if (other.isSetUserConfigurationData()) {
      this.userConfigurationData = new UserConfigurationDataModel(other.userConfigurationData);
    }
    if (other.isSetExperimentInputs()) {
      java.util.List<org.apache.airavata.model.application.io.InputDataObjectType> __this__experimentInputs = new java.util.ArrayList<org.apache.airavata.model.application.io.InputDataObjectType>(other.experimentInputs.size());
      for (org.apache.airavata.model.application.io.InputDataObjectType other_element : other.experimentInputs) {
        __this__experimentInputs.add(new org.apache.airavata.model.application.io.InputDataObjectType(other_element));
      }
      this.experimentInputs = __this__experimentInputs;
    }
    if (other.isSetExperimentOutputs()) {
      java.util.List<org.apache.airavata.model.application.io.OutputDataObjectType> __this__experimentOutputs = new java.util.ArrayList<org.apache.airavata.model.application.io.OutputDataObjectType>(other.experimentOutputs.size());
      for (org.apache.airavata.model.application.io.OutputDataObjectType other_element : other.experimentOutputs) {
        __this__experimentOutputs.add(new org.apache.airavata.model.application.io.OutputDataObjectType(other_element));
      }
      this.experimentOutputs = __this__experimentOutputs;
    }
    if (other.isSetExperimentStatus()) {
      java.util.List<org.apache.airavata.model.status.ExperimentStatus> __this__experimentStatus = new java.util.ArrayList<org.apache.airavata.model.status.ExperimentStatus>(other.experimentStatus.size());
      for (org.apache.airavata.model.status.ExperimentStatus other_element : other.experimentStatus) {
        __this__experimentStatus.add(new org.apache.airavata.model.status.ExperimentStatus(other_element));
      }
      this.experimentStatus = __this__experimentStatus;
    }
    if (other.isSetErrors()) {
      java.util.List<org.apache.airavata.model.commons.ErrorModel> __this__errors = new java.util.ArrayList<org.apache.airavata.model.commons.ErrorModel>(other.errors.size());
      for (org.apache.airavata.model.commons.ErrorModel other_element : other.errors) {
        __this__errors.add(new org.apache.airavata.model.commons.ErrorModel(other_element));
      }
      this.errors = __this__errors;
    }
    if (other.isSetProcesses()) {
      java.util.List<org.apache.airavata.model.process.ProcessModel> __this__processes = new java.util.ArrayList<org.apache.airavata.model.process.ProcessModel>(other.processes.size());
      for (org.apache.airavata.model.process.ProcessModel other_element : other.processes) {
        __this__processes.add(new org.apache.airavata.model.process.ProcessModel(other_element));
      }
      this.processes = __this__processes;
    }
    if (other.isSetWorkflow()) {
      this.workflow = new org.apache.airavata.model.workflow.AiravataWorkflow(other.workflow);
    }
  }

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

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

    this.projectId = null;
    this.gatewayId = null;
    this.experimentType = org.apache.airavata.model.experiment.ExperimentType.SINGLE_APPLICATION;

    this.userName = null;
    this.experimentName = null;
    setCreationTimeIsSet(false);
    this.creationTime = 0;
    this.description = null;
    this.executionId = null;
    this.gatewayExecutionId = null;
    this.gatewayInstanceId = null;
    setEnableEmailNotificationIsSet(false);
    this.enableEmailNotification = false;
    this.emailAddresses = null;
    this.userConfigurationData = null;
    this.experimentInputs = null;
    this.experimentOutputs = null;
    this.experimentStatus = null;
    this.errors = null;
    this.processes = null;
    this.workflow = null;
  }

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

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

  public void unsetExperimentId() {
    this.experimentId = null;
  }

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

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

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

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

  public void unsetProjectId() {
    this.projectId = null;
  }

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

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

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

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

  public void unsetGatewayId() {
    this.gatewayId = null;
  }

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

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

  /**
   * 
   * @see ExperimentType
   */
  @org.apache.thrift.annotation.Nullable
  public ExperimentType getExperimentType() {
    return this.experimentType;
  }

  /**
   * 
   * @see ExperimentType
   */
  public void setExperimentType(@org.apache.thrift.annotation.Nullable ExperimentType experimentType) {
    this.experimentType = experimentType;
  }

  public void unsetExperimentType() {
    this.experimentType = null;
  }

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

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

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

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

  public void unsetUserName() {
    this.userName = null;
  }

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

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

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

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

  public void unsetExperimentName() {
    this.experimentName = null;
  }

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

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

  public long getCreationTime() {
    return this.creationTime;
  }

  public void setCreationTime(long creationTime) {
    this.creationTime = creationTime;
    setCreationTimeIsSet(true);
  }

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

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

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

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

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

  public void unsetDescription() {
    this.description = null;
  }

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

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

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

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

  public void unsetExecutionId() {
    this.executionId = null;
  }

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

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

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

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

  public void unsetGatewayExecutionId() {
    this.gatewayExecutionId = null;
  }

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

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

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

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

  public void unsetGatewayInstanceId() {
    this.gatewayInstanceId = null;
  }

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

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

  public boolean isEnableEmailNotification() {
    return this.enableEmailNotification;
  }

  public void setEnableEmailNotification(boolean enableEmailNotification) {
    this.enableEmailNotification = enableEmailNotification;
    setEnableEmailNotificationIsSet(true);
  }

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

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

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

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

  @org.apache.thrift.annotation.Nullable
  public java.util.Iterator<java.lang.String> getEmailAddressesIterator() {
    return (this.emailAddresses == null) ? null : this.emailAddresses.iterator();
  }

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

  @org.apache.thrift.annotation.Nullable
  public java.util.List<java.lang.String> getEmailAddresses() {
    return this.emailAddresses;
  }

  public void setEmailAddresses(@org.apache.thrift.annotation.Nullable java.util.List<java.lang.String> emailAddresses) {
    this.emailAddresses = emailAddresses;
  }

  public void unsetEmailAddresses() {
    this.emailAddresses = null;
  }

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

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

  @org.apache.thrift.annotation.Nullable
  public UserConfigurationDataModel getUserConfigurationData() {
    return this.userConfigurationData;
  }

  public void setUserConfigurationData(@org.apache.thrift.annotation.Nullable UserConfigurationDataModel userConfigurationData) {
    this.userConfigurationData = userConfigurationData;
  }

  public void unsetUserConfigurationData() {
    this.userConfigurationData = null;
  }

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

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

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

  @org.apache.thrift.annotation.Nullable
  public java.util.Iterator<org.apache.airavata.model.application.io.InputDataObjectType> getExperimentInputsIterator() {
    return (this.experimentInputs == null) ? null : this.experimentInputs.iterator();
  }

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

  @org.apache.thrift.annotation.Nullable
  public java.util.List<org.apache.airavata.model.application.io.InputDataObjectType> getExperimentInputs() {
    return this.experimentInputs;
  }

  public void setExperimentInputs(@org.apache.thrift.annotation.Nullable java.util.List<org.apache.airavata.model.application.io.InputDataObjectType> experimentInputs) {
    this.experimentInputs = experimentInputs;
  }

  public void unsetExperimentInputs() {
    this.experimentInputs = null;
  }

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

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

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

  @org.apache.thrift.annotation.Nullable
  public java.util.Iterator<org.apache.airavata.model.application.io.OutputDataObjectType> getExperimentOutputsIterator() {
    return (this.experimentOutputs == null) ? null : this.experimentOutputs.iterator();
  }

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

  @org.apache.thrift.annotation.Nullable
  public java.util.List<org.apache.airavata.model.application.io.OutputDataObjectType> getExperimentOutputs() {
    return this.experimentOutputs;
  }

  public void setExperimentOutputs(@org.apache.thrift.annotation.Nullable java.util.List<org.apache.airavata.model.application.io.OutputDataObjectType> experimentOutputs) {
    this.experimentOutputs = experimentOutputs;
  }

  public void unsetExperimentOutputs() {
    this.experimentOutputs = null;
  }

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

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

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

  @org.apache.thrift.annotation.Nullable
  public java.util.Iterator<org.apache.airavata.model.status.ExperimentStatus> getExperimentStatusIterator() {
    return (this.experimentStatus == null) ? null : this.experimentStatus.iterator();
  }

  public void addToExperimentStatus(org.apache.airavata.model.status.ExperimentStatus elem) {
    if (this.experimentStatus == null) {
      this.experimentStatus = new java.util.ArrayList<org.apache.airavata.model.status.ExperimentStatus>();
    }
    this.experimentStatus.add(elem);
  }

  @org.apache.thrift.annotation.Nullable
  public java.util.List<org.apache.airavata.model.status.ExperimentStatus> getExperimentStatus() {
    return this.experimentStatus;
  }

  public void setExperimentStatus(@org.apache.thrift.annotation.Nullable java.util.List<org.apache.airavata.model.status.ExperimentStatus> experimentStatus) {
    this.experimentStatus = experimentStatus;
  }

  public void unsetExperimentStatus() {
    this.experimentStatus = null;
  }

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

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

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

  @org.apache.thrift.annotation.Nullable
  public java.util.Iterator<org.apache.airavata.model.commons.ErrorModel> getErrorsIterator() {
    return (this.errors == null) ? null : this.errors.iterator();
  }

  public void addToErrors(org.apache.airavata.model.commons.ErrorModel elem) {
    if (this.errors == null) {
      this.errors = new java.util.ArrayList<org.apache.airavata.model.commons.ErrorModel>();
    }
    this.errors.add(elem);
  }

  @org.apache.thrift.annotation.Nullable
  public java.util.List<org.apache.airavata.model.commons.ErrorModel> getErrors() {
    return this.errors;
  }

  public void setErrors(@org.apache.thrift.annotation.Nullable java.util.List<org.apache.airavata.model.commons.ErrorModel> errors) {
    this.errors = errors;
  }

  public void unsetErrors() {
    this.errors = null;
  }

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

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

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

  @org.apache.thrift.annotation.Nullable
  public java.util.Iterator<org.apache.airavata.model.process.ProcessModel> getProcessesIterator() {
    return (this.processes == null) ? null : this.processes.iterator();
  }

  public void addToProcesses(org.apache.airavata.model.process.ProcessModel elem) {
    if (this.processes == null) {
      this.processes = new java.util.ArrayList<org.apache.airavata.model.process.ProcessModel>();
    }
    this.processes.add(elem);
  }

  @org.apache.thrift.annotation.Nullable
  public java.util.List<org.apache.airavata.model.process.ProcessModel> getProcesses() {
    return this.processes;
  }

  public void setProcesses(@org.apache.thrift.annotation.Nullable java.util.List<org.apache.airavata.model.process.ProcessModel> processes) {
    this.processes = processes;
  }

  public void unsetProcesses() {
    this.processes = null;
  }

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

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

  @org.apache.thrift.annotation.Nullable
  public org.apache.airavata.model.workflow.AiravataWorkflow getWorkflow() {
    return this.workflow;
  }

  public void setWorkflow(@org.apache.thrift.annotation.Nullable org.apache.airavata.model.workflow.AiravataWorkflow workflow) {
    this.workflow = workflow;
  }

  public void unsetWorkflow() {
    this.workflow = null;
  }

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

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

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

    case PROJECT_ID:
      if (value == null) {
        unsetProjectId();
      } else {
        setProjectId((java.lang.String)value);
      }
      break;

    case GATEWAY_ID:
      if (value == null) {
        unsetGatewayId();
      } else {
        setGatewayId((java.lang.String)value);
      }
      break;

    case EXPERIMENT_TYPE:
      if (value == null) {
        unsetExperimentType();
      } else {
        setExperimentType((ExperimentType)value);
      }
      break;

    case USER_NAME:
      if (value == null) {
        unsetUserName();
      } else {
        setUserName((java.lang.String)value);
      }
      break;

    case EXPERIMENT_NAME:
      if (value == null) {
        unsetExperimentName();
      } else {
        setExperimentName((java.lang.String)value);
      }
      break;

    case CREATION_TIME:
      if (value == null) {
        unsetCreationTime();
      } else {
        setCreationTime((java.lang.Long)value);
      }
      break;

    case DESCRIPTION:
      if (value == null) {
        unsetDescription();
      } else {
        setDescription((java.lang.String)value);
      }
      break;

    case EXECUTION_ID:
      if (value == null) {
        unsetExecutionId();
      } else {
        setExecutionId((java.lang.String)value);
      }
      break;

    case GATEWAY_EXECUTION_ID:
      if (value == null) {
        unsetGatewayExecutionId();
      } else {
        setGatewayExecutionId((java.lang.String)value);
      }
      break;

    case GATEWAY_INSTANCE_ID:
      if (value == null) {
        unsetGatewayInstanceId();
      } else {
        setGatewayInstanceId((java.lang.String)value);
      }
      break;

    case ENABLE_EMAIL_NOTIFICATION:
      if (value == null) {
        unsetEnableEmailNotification();
      } else {
        setEnableEmailNotification((java.lang.Boolean)value);
      }
      break;

    case EMAIL_ADDRESSES:
      if (value == null) {
        unsetEmailAddresses();
      } else {
        setEmailAddresses((java.util.List<java.lang.String>)value);
      }
      break;

    case USER_CONFIGURATION_DATA:
      if (value == null) {
        unsetUserConfigurationData();
      } else {
        setUserConfigurationData((UserConfigurationDataModel)value);
      }
      break;

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

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

    case EXPERIMENT_STATUS:
      if (value == null) {
        unsetExperimentStatus();
      } else {
        setExperimentStatus((java.util.List<org.apache.airavata.model.status.ExperimentStatus>)value);
      }
      break;

    case ERRORS:
      if (value == null) {
        unsetErrors();
      } else {
        setErrors((java.util.List<org.apache.airavata.model.commons.ErrorModel>)value);
      }
      break;

    case PROCESSES:
      if (value == null) {
        unsetProcesses();
      } else {
        setProcesses((java.util.List<org.apache.airavata.model.process.ProcessModel>)value);
      }
      break;

    case WORKFLOW:
      if (value == null) {
        unsetWorkflow();
      } else {
        setWorkflow((org.apache.airavata.model.workflow.AiravataWorkflow)value);
      }
      break;

    }
  }

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

    case PROJECT_ID:
      return getProjectId();

    case GATEWAY_ID:
      return getGatewayId();

    case EXPERIMENT_TYPE:
      return getExperimentType();

    case USER_NAME:
      return getUserName();

    case EXPERIMENT_NAME:
      return getExperimentName();

    case CREATION_TIME:
      return getCreationTime();

    case DESCRIPTION:
      return getDescription();

    case EXECUTION_ID:
      return getExecutionId();

    case GATEWAY_EXECUTION_ID:
      return getGatewayExecutionId();

    case GATEWAY_INSTANCE_ID:
      return getGatewayInstanceId();

    case ENABLE_EMAIL_NOTIFICATION:
      return isEnableEmailNotification();

    case EMAIL_ADDRESSES:
      return getEmailAddresses();

    case USER_CONFIGURATION_DATA:
      return getUserConfigurationData();

    case EXPERIMENT_INPUTS:
      return getExperimentInputs();

    case EXPERIMENT_OUTPUTS:
      return getExperimentOutputs();

    case EXPERIMENT_STATUS:
      return getExperimentStatus();

    case ERRORS:
      return getErrors();

    case PROCESSES:
      return getProcesses();

    case WORKFLOW:
      return getWorkflow();

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

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

    switch (field) {
    case EXPERIMENT_ID:
      return isSetExperimentId();
    case PROJECT_ID:
      return isSetProjectId();
    case GATEWAY_ID:
      return isSetGatewayId();
    case EXPERIMENT_TYPE:
      return isSetExperimentType();
    case USER_NAME:
      return isSetUserName();
    case EXPERIMENT_NAME:
      return isSetExperimentName();
    case CREATION_TIME:
      return isSetCreationTime();
    case DESCRIPTION:
      return isSetDescription();
    case EXECUTION_ID:
      return isSetExecutionId();
    case GATEWAY_EXECUTION_ID:
      return isSetGatewayExecutionId();
    case GATEWAY_INSTANCE_ID:
      return isSetGatewayInstanceId();
    case ENABLE_EMAIL_NOTIFICATION:
      return isSetEnableEmailNotification();
    case EMAIL_ADDRESSES:
      return isSetEmailAddresses();
    case USER_CONFIGURATION_DATA:
      return isSetUserConfigurationData();
    case EXPERIMENT_INPUTS:
      return isSetExperimentInputs();
    case EXPERIMENT_OUTPUTS:
      return isSetExperimentOutputs();
    case EXPERIMENT_STATUS:
      return isSetExperimentStatus();
    case ERRORS:
      return isSetErrors();
    case PROCESSES:
      return isSetProcesses();
    case WORKFLOW:
      return isSetWorkflow();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_experimentId = true && this.isSetExperimentId();
    boolean that_present_experimentId = true && that.isSetExperimentId();
    if (this_present_experimentId || that_present_experimentId) {
      if (!(this_present_experimentId && that_present_experimentId))
        return false;
      if (!this.experimentId.equals(that.experimentId))
        return false;
    }

    boolean this_present_projectId = true && this.isSetProjectId();
    boolean that_present_projectId = true && that.isSetProjectId();
    if (this_present_projectId || that_present_projectId) {
      if (!(this_present_projectId && that_present_projectId))
        return false;
      if (!this.projectId.equals(that.projectId))
        return false;
    }

    boolean this_present_gatewayId = true && this.isSetGatewayId();
    boolean that_present_gatewayId = true && that.isSetGatewayId();
    if (this_present_gatewayId || that_present_gatewayId) {
      if (!(this_present_gatewayId && that_present_gatewayId))
        return false;
      if (!this.gatewayId.equals(that.gatewayId))
        return false;
    }

    boolean this_present_experimentType = true && this.isSetExperimentType();
    boolean that_present_experimentType = true && that.isSetExperimentType();
    if (this_present_experimentType || that_present_experimentType) {
      if (!(this_present_experimentType && that_present_experimentType))
        return false;
      if (!this.experimentType.equals(that.experimentType))
        return false;
    }

    boolean this_present_userName = true && this.isSetUserName();
    boolean that_present_userName = true && that.isSetUserName();
    if (this_present_userName || that_present_userName) {
      if (!(this_present_userName && that_present_userName))
        return false;
      if (!this.userName.equals(that.userName))
        return false;
    }

    boolean this_present_experimentName = true && this.isSetExperimentName();
    boolean that_present_experimentName = true && that.isSetExperimentName();
    if (this_present_experimentName || that_present_experimentName) {
      if (!(this_present_experimentName && that_present_experimentName))
        return false;
      if (!this.experimentName.equals(that.experimentName))
        return false;
    }

    boolean this_present_creationTime = true && this.isSetCreationTime();
    boolean that_present_creationTime = true && that.isSetCreationTime();
    if (this_present_creationTime || that_present_creationTime) {
      if (!(this_present_creationTime && that_present_creationTime))
        return false;
      if (this.creationTime != that.creationTime)
        return false;
    }

    boolean this_present_description = true && this.isSetDescription();
    boolean that_present_description = true && that.isSetDescription();
    if (this_present_description || that_present_description) {
      if (!(this_present_description && that_present_description))
        return false;
      if (!this.description.equals(that.description))
        return false;
    }

    boolean this_present_executionId = true && this.isSetExecutionId();
    boolean that_present_executionId = true && that.isSetExecutionId();
    if (this_present_executionId || that_present_executionId) {
      if (!(this_present_executionId && that_present_executionId))
        return false;
      if (!this.executionId.equals(that.executionId))
        return false;
    }

    boolean this_present_gatewayExecutionId = true && this.isSetGatewayExecutionId();
    boolean that_present_gatewayExecutionId = true && that.isSetGatewayExecutionId();
    if (this_present_gatewayExecutionId || that_present_gatewayExecutionId) {
      if (!(this_present_gatewayExecutionId && that_present_gatewayExecutionId))
        return false;
      if (!this.gatewayExecutionId.equals(that.gatewayExecutionId))
        return false;
    }

    boolean this_present_gatewayInstanceId = true && this.isSetGatewayInstanceId();
    boolean that_present_gatewayInstanceId = true && that.isSetGatewayInstanceId();
    if (this_present_gatewayInstanceId || that_present_gatewayInstanceId) {
      if (!(this_present_gatewayInstanceId && that_present_gatewayInstanceId))
        return false;
      if (!this.gatewayInstanceId.equals(that.gatewayInstanceId))
        return false;
    }

    boolean this_present_enableEmailNotification = true && this.isSetEnableEmailNotification();
    boolean that_present_enableEmailNotification = true && that.isSetEnableEmailNotification();
    if (this_present_enableEmailNotification || that_present_enableEmailNotification) {
      if (!(this_present_enableEmailNotification && that_present_enableEmailNotification))
        return false;
      if (this.enableEmailNotification != that.enableEmailNotification)
        return false;
    }

    boolean this_present_emailAddresses = true && this.isSetEmailAddresses();
    boolean that_present_emailAddresses = true && that.isSetEmailAddresses();
    if (this_present_emailAddresses || that_present_emailAddresses) {
      if (!(this_present_emailAddresses && that_present_emailAddresses))
        return false;
      if (!this.emailAddresses.equals(that.emailAddresses))
        return false;
    }

    boolean this_present_userConfigurationData = true && this.isSetUserConfigurationData();
    boolean that_present_userConfigurationData = true && that.isSetUserConfigurationData();
    if (this_present_userConfigurationData || that_present_userConfigurationData) {
      if (!(this_present_userConfigurationData && that_present_userConfigurationData))
        return false;
      if (!this.userConfigurationData.equals(that.userConfigurationData))
        return false;
    }

    boolean this_present_experimentInputs = true && this.isSetExperimentInputs();
    boolean that_present_experimentInputs = true && that.isSetExperimentInputs();
    if (this_present_experimentInputs || that_present_experimentInputs) {
      if (!(this_present_experimentInputs && that_present_experimentInputs))
        return false;
      if (!this.experimentInputs.equals(that.experimentInputs))
        return false;
    }

    boolean this_present_experimentOutputs = true && this.isSetExperimentOutputs();
    boolean that_present_experimentOutputs = true && that.isSetExperimentOutputs();
    if (this_present_experimentOutputs || that_present_experimentOutputs) {
      if (!(this_present_experimentOutputs && that_present_experimentOutputs))
        return false;
      if (!this.experimentOutputs.equals(that.experimentOutputs))
        return false;
    }

    boolean this_present_experimentStatus = true && this.isSetExperimentStatus();
    boolean that_present_experimentStatus = true && that.isSetExperimentStatus();
    if (this_present_experimentStatus || that_present_experimentStatus) {
      if (!(this_present_experimentStatus && that_present_experimentStatus))
        return false;
      if (!this.experimentStatus.equals(that.experimentStatus))
        return false;
    }

    boolean this_present_errors = true && this.isSetErrors();
    boolean that_present_errors = true && that.isSetErrors();
    if (this_present_errors || that_present_errors) {
      if (!(this_present_errors && that_present_errors))
        return false;
      if (!this.errors.equals(that.errors))
        return false;
    }

    boolean this_present_processes = true && this.isSetProcesses();
    boolean that_present_processes = true && that.isSetProcesses();
    if (this_present_processes || that_present_processes) {
      if (!(this_present_processes && that_present_processes))
        return false;
      if (!this.processes.equals(that.processes))
        return false;
    }

    boolean this_present_workflow = true && this.isSetWorkflow();
    boolean that_present_workflow = true && that.isSetWorkflow();
    if (this_present_workflow || that_present_workflow) {
      if (!(this_present_workflow && that_present_workflow))
        return false;
      if (!this.workflow.equals(that.workflow))
        return false;
    }

    return true;
  }

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

    hashCode = hashCode * 8191 + ((isSetExperimentId()) ? 131071 : 524287);
    if (isSetExperimentId())
      hashCode = hashCode * 8191 + experimentId.hashCode();

    hashCode = hashCode * 8191 + ((isSetProjectId()) ? 131071 : 524287);
    if (isSetProjectId())
      hashCode = hashCode * 8191 + projectId.hashCode();

    hashCode = hashCode * 8191 + ((isSetGatewayId()) ? 131071 : 524287);
    if (isSetGatewayId())
      hashCode = hashCode * 8191 + gatewayId.hashCode();

    hashCode = hashCode * 8191 + ((isSetExperimentType()) ? 131071 : 524287);
    if (isSetExperimentType())
      hashCode = hashCode * 8191 + experimentType.getValue();

    hashCode = hashCode * 8191 + ((isSetUserName()) ? 131071 : 524287);
    if (isSetUserName())
      hashCode = hashCode * 8191 + userName.hashCode();

    hashCode = hashCode * 8191 + ((isSetExperimentName()) ? 131071 : 524287);
    if (isSetExperimentName())
      hashCode = hashCode * 8191 + experimentName.hashCode();

    hashCode = hashCode * 8191 + ((isSetCreationTime()) ? 131071 : 524287);
    if (isSetCreationTime())
      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(creationTime);

    hashCode = hashCode * 8191 + ((isSetDescription()) ? 131071 : 524287);
    if (isSetDescription())
      hashCode = hashCode * 8191 + description.hashCode();

    hashCode = hashCode * 8191 + ((isSetExecutionId()) ? 131071 : 524287);
    if (isSetExecutionId())
      hashCode = hashCode * 8191 + executionId.hashCode();

    hashCode = hashCode * 8191 + ((isSetGatewayExecutionId()) ? 131071 : 524287);
    if (isSetGatewayExecutionId())
      hashCode = hashCode * 8191 + gatewayExecutionId.hashCode();

    hashCode = hashCode * 8191 + ((isSetGatewayInstanceId()) ? 131071 : 524287);
    if (isSetGatewayInstanceId())
      hashCode = hashCode * 8191 + gatewayInstanceId.hashCode();

    hashCode = hashCode * 8191 + ((isSetEnableEmailNotification()) ? 131071 : 524287);
    if (isSetEnableEmailNotification())
      hashCode = hashCode * 8191 + ((enableEmailNotification) ? 131071 : 524287);

    hashCode = hashCode * 8191 + ((isSetEmailAddresses()) ? 131071 : 524287);
    if (isSetEmailAddresses())
      hashCode = hashCode * 8191 + emailAddresses.hashCode();

    hashCode = hashCode * 8191 + ((isSetUserConfigurationData()) ? 131071 : 524287);
    if (isSetUserConfigurationData())
      hashCode = hashCode * 8191 + userConfigurationData.hashCode();

    hashCode = hashCode * 8191 + ((isSetExperimentInputs()) ? 131071 : 524287);
    if (isSetExperimentInputs())
      hashCode = hashCode * 8191 + experimentInputs.hashCode();

    hashCode = hashCode * 8191 + ((isSetExperimentOutputs()) ? 131071 : 524287);
    if (isSetExperimentOutputs())
      hashCode = hashCode * 8191 + experimentOutputs.hashCode();

    hashCode = hashCode * 8191 + ((isSetExperimentStatus()) ? 131071 : 524287);
    if (isSetExperimentStatus())
      hashCode = hashCode * 8191 + experimentStatus.hashCode();

    hashCode = hashCode * 8191 + ((isSetErrors()) ? 131071 : 524287);
    if (isSetErrors())
      hashCode = hashCode * 8191 + errors.hashCode();

    hashCode = hashCode * 8191 + ((isSetProcesses()) ? 131071 : 524287);
    if (isSetProcesses())
      hashCode = hashCode * 8191 + processes.hashCode();

    hashCode = hashCode * 8191 + ((isSetWorkflow()) ? 131071 : 524287);
    if (isSetWorkflow())
      hashCode = hashCode * 8191 + workflow.hashCode();

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.compare(isSetExperimentId(), other.isSetExperimentId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetExperimentId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.experimentId, other.experimentId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetProjectId(), other.isSetProjectId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetProjectId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.projectId, other.projectId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetGatewayId(), other.isSetGatewayId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetGatewayId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.gatewayId, other.gatewayId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetExperimentType(), other.isSetExperimentType());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetExperimentType()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.experimentType, other.experimentType);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetUserName(), other.isSetUserName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetUserName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetExperimentName(), other.isSetExperimentName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetExperimentName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.experimentName, other.experimentName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetCreationTime(), other.isSetCreationTime());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetCreationTime()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.creationTime, other.creationTime);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetDescription(), other.isSetDescription());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetDescription()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.description, other.description);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetExecutionId(), other.isSetExecutionId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetExecutionId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.executionId, other.executionId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetGatewayExecutionId(), other.isSetGatewayExecutionId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetGatewayExecutionId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.gatewayExecutionId, other.gatewayExecutionId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetGatewayInstanceId(), other.isSetGatewayInstanceId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetGatewayInstanceId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.gatewayInstanceId, other.gatewayInstanceId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetEnableEmailNotification(), other.isSetEnableEmailNotification());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetEnableEmailNotification()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.enableEmailNotification, other.enableEmailNotification);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetEmailAddresses(), other.isSetEmailAddresses());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetEmailAddresses()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.emailAddresses, other.emailAddresses);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetUserConfigurationData(), other.isSetUserConfigurationData());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetUserConfigurationData()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userConfigurationData, other.userConfigurationData);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetExperimentInputs(), other.isSetExperimentInputs());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetExperimentInputs()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.experimentInputs, other.experimentInputs);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetExperimentOutputs(), other.isSetExperimentOutputs());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetExperimentOutputs()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.experimentOutputs, other.experimentOutputs);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetExperimentStatus(), other.isSetExperimentStatus());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetExperimentStatus()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.experimentStatus, other.experimentStatus);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetErrors(), other.isSetErrors());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetErrors()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.errors, other.errors);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetProcesses(), other.isSetProcesses());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetProcesses()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.processes, other.processes);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetWorkflow(), other.isSetWorkflow());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetWorkflow()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.workflow, other.workflow);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

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

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

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

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

    sb.append("experimentId:");
    if (this.experimentId == null) {
      sb.append("null");
    } else {
      sb.append(this.experimentId);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("projectId:");
    if (this.projectId == null) {
      sb.append("null");
    } else {
      sb.append(this.projectId);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("gatewayId:");
    if (this.gatewayId == null) {
      sb.append("null");
    } else {
      sb.append(this.gatewayId);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("experimentType:");
    if (this.experimentType == null) {
      sb.append("null");
    } else {
      sb.append(this.experimentType);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("userName:");
    if (this.userName == null) {
      sb.append("null");
    } else {
      sb.append(this.userName);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("experimentName:");
    if (this.experimentName == null) {
      sb.append("null");
    } else {
      sb.append(this.experimentName);
    }
    first = false;
    if (isSetCreationTime()) {
      if (!first) sb.append(", ");
      sb.append("creationTime:");
      sb.append(this.creationTime);
      first = false;
    }
    if (isSetDescription()) {
      if (!first) sb.append(", ");
      sb.append("description:");
      if (this.description == null) {
        sb.append("null");
      } else {
        sb.append(this.description);
      }
      first = false;
    }
    if (isSetExecutionId()) {
      if (!first) sb.append(", ");
      sb.append("executionId:");
      if (this.executionId == null) {
        sb.append("null");
      } else {
        sb.append(this.executionId);
      }
      first = false;
    }
    if (isSetGatewayExecutionId()) {
      if (!first) sb.append(", ");
      sb.append("gatewayExecutionId:");
      if (this.gatewayExecutionId == null) {
        sb.append("null");
      } else {
        sb.append(this.gatewayExecutionId);
      }
      first = false;
    }
    if (isSetGatewayInstanceId()) {
      if (!first) sb.append(", ");
      sb.append("gatewayInstanceId:");
      if (this.gatewayInstanceId == null) {
        sb.append("null");
      } else {
        sb.append(this.gatewayInstanceId);
      }
      first = false;
    }
    if (isSetEnableEmailNotification()) {
      if (!first) sb.append(", ");
      sb.append("enableEmailNotification:");
      sb.append(this.enableEmailNotification);
      first = false;
    }
    if (isSetEmailAddresses()) {
      if (!first) sb.append(", ");
      sb.append("emailAddresses:");
      if (this.emailAddresses == null) {
        sb.append("null");
      } else {
        sb.append(this.emailAddresses);
      }
      first = false;
    }
    if (isSetUserConfigurationData()) {
      if (!first) sb.append(", ");
      sb.append("userConfigurationData:");
      if (this.userConfigurationData == null) {
        sb.append("null");
      } else {
        sb.append(this.userConfigurationData);
      }
      first = false;
    }
    if (isSetExperimentInputs()) {
      if (!first) sb.append(", ");
      sb.append("experimentInputs:");
      if (this.experimentInputs == null) {
        sb.append("null");
      } else {
        sb.append(this.experimentInputs);
      }
      first = false;
    }
    if (isSetExperimentOutputs()) {
      if (!first) sb.append(", ");
      sb.append("experimentOutputs:");
      if (this.experimentOutputs == null) {
        sb.append("null");
      } else {
        sb.append(this.experimentOutputs);
      }
      first = false;
    }
    if (isSetExperimentStatus()) {
      if (!first) sb.append(", ");
      sb.append("experimentStatus:");
      if (this.experimentStatus == null) {
        sb.append("null");
      } else {
        sb.append(this.experimentStatus);
      }
      first = false;
    }
    if (isSetErrors()) {
      if (!first) sb.append(", ");
      sb.append("errors:");
      if (this.errors == null) {
        sb.append("null");
      } else {
        sb.append(this.errors);
      }
      first = false;
    }
    if (isSetProcesses()) {
      if (!first) sb.append(", ");
      sb.append("processes:");
      if (this.processes == null) {
        sb.append("null");
      } else {
        sb.append(this.processes);
      }
      first = false;
    }
    if (isSetWorkflow()) {
      if (!first) sb.append(", ");
      sb.append("workflow:");
      if (this.workflow == null) {
        sb.append("null");
      } else {
        sb.append(this.workflow);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

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

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

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

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

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

    // check for sub-struct validity
    if (userConfigurationData != null) {
      userConfigurationData.validate();
    }
    if (workflow != null) {
      workflow.validate();
    }
  }

  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
    try {
      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
    try {
      // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
      __isset_bitfield = 0;
      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

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

  private static class ExperimentModelStandardScheme extends org.apache.thrift.scheme.StandardScheme<ExperimentModel> {

    @Override
    public void read(org.apache.thrift.protocol.TProtocol iprot, ExperimentModel 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: // EXPERIMENT_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.experimentId = iprot.readString();
              struct.setExperimentIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // PROJECT_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.projectId = iprot.readString();
              struct.setProjectIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // GATEWAY_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.gatewayId = iprot.readString();
              struct.setGatewayIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // EXPERIMENT_TYPE
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.experimentType = org.apache.airavata.model.experiment.ExperimentType.findByValue(iprot.readI32());
              struct.setExperimentTypeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // USER_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.userName = iprot.readString();
              struct.setUserNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // EXPERIMENT_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.experimentName = iprot.readString();
              struct.setExperimentNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // CREATION_TIME
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.creationTime = iprot.readI64();
              struct.setCreationTimeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // DESCRIPTION
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.description = iprot.readString();
              struct.setDescriptionIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // EXECUTION_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.executionId = iprot.readString();
              struct.setExecutionIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // GATEWAY_EXECUTION_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.gatewayExecutionId = iprot.readString();
              struct.setGatewayExecutionIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 11: // GATEWAY_INSTANCE_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.gatewayInstanceId = iprot.readString();
              struct.setGatewayInstanceIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 12: // ENABLE_EMAIL_NOTIFICATION
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.enableEmailNotification = iprot.readBool();
              struct.setEnableEmailNotificationIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 13: // EMAIL_ADDRESSES
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list8 = iprot.readListBegin();
                struct.emailAddresses = new java.util.ArrayList<java.lang.String>(_list8.size);
                @org.apache.thrift.annotation.Nullable java.lang.String _elem9;
                for (int _i10 = 0; _i10 < _list8.size; ++_i10)
                {
                  _elem9 = iprot.readString();
                  struct.emailAddresses.add(_elem9);
                }
                iprot.readListEnd();
              }
              struct.setEmailAddressesIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 14: // USER_CONFIGURATION_DATA
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.userConfigurationData = new UserConfigurationDataModel();
              struct.userConfigurationData.read(iprot);
              struct.setUserConfigurationDataIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 15: // EXPERIMENT_INPUTS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list11 = iprot.readListBegin();
                struct.experimentInputs = new java.util.ArrayList<org.apache.airavata.model.application.io.InputDataObjectType>(_list11.size);
                @org.apache.thrift.annotation.Nullable org.apache.airavata.model.application.io.InputDataObjectType _elem12;
                for (int _i13 = 0; _i13 < _list11.size; ++_i13)
                {
                  _elem12 = new org.apache.airavata.model.application.io.InputDataObjectType();
                  _elem12.read(iprot);
                  struct.experimentInputs.add(_elem12);
                }
                iprot.readListEnd();
              }
              struct.setExperimentInputsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 16: // EXPERIMENT_OUTPUTS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list14 = iprot.readListBegin();
                struct.experimentOutputs = new java.util.ArrayList<org.apache.airavata.model.application.io.OutputDataObjectType>(_list14.size);
                @org.apache.thrift.annotation.Nullable org.apache.airavata.model.application.io.OutputDataObjectType _elem15;
                for (int _i16 = 0; _i16 < _list14.size; ++_i16)
                {
                  _elem15 = new org.apache.airavata.model.application.io.OutputDataObjectType();
                  _elem15.read(iprot);
                  struct.experimentOutputs.add(_elem15);
                }
                iprot.readListEnd();
              }
              struct.setExperimentOutputsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 17: // EXPERIMENT_STATUS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list17 = iprot.readListBegin();
                struct.experimentStatus = new java.util.ArrayList<org.apache.airavata.model.status.ExperimentStatus>(_list17.size);
                @org.apache.thrift.annotation.Nullable org.apache.airavata.model.status.ExperimentStatus _elem18;
                for (int _i19 = 0; _i19 < _list17.size; ++_i19)
                {
                  _elem18 = new org.apache.airavata.model.status.ExperimentStatus();
                  _elem18.read(iprot);
                  struct.experimentStatus.add(_elem18);
                }
                iprot.readListEnd();
              }
              struct.setExperimentStatusIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 18: // ERRORS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list20 = iprot.readListBegin();
                struct.errors = new java.util.ArrayList<org.apache.airavata.model.commons.ErrorModel>(_list20.size);
                @org.apache.thrift.annotation.Nullable org.apache.airavata.model.commons.ErrorModel _elem21;
                for (int _i22 = 0; _i22 < _list20.size; ++_i22)
                {
                  _elem21 = new org.apache.airavata.model.commons.ErrorModel();
                  _elem21.read(iprot);
                  struct.errors.add(_elem21);
                }
                iprot.readListEnd();
              }
              struct.setErrorsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 19: // PROCESSES
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list23 = iprot.readListBegin();
                struct.processes = new java.util.ArrayList<org.apache.airavata.model.process.ProcessModel>(_list23.size);
                @org.apache.thrift.annotation.Nullable org.apache.airavata.model.process.ProcessModel _elem24;
                for (int _i25 = 0; _i25 < _list23.size; ++_i25)
                {
                  _elem24 = new org.apache.airavata.model.process.ProcessModel();
                  _elem24.read(iprot);
                  struct.processes.add(_elem24);
                }
                iprot.readListEnd();
              }
              struct.setProcessesIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 20: // WORKFLOW
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.workflow = new org.apache.airavata.model.workflow.AiravataWorkflow();
              struct.workflow.read(iprot);
              struct.setWorkflowIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          default:
            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
      struct.validate();
    }

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

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.experimentId != null) {
        oprot.writeFieldBegin(EXPERIMENT_ID_FIELD_DESC);
        oprot.writeString(struct.experimentId);
        oprot.writeFieldEnd();
      }
      if (struct.projectId != null) {
        oprot.writeFieldBegin(PROJECT_ID_FIELD_DESC);
        oprot.writeString(struct.projectId);
        oprot.writeFieldEnd();
      }
      if (struct.gatewayId != null) {
        oprot.writeFieldBegin(GATEWAY_ID_FIELD_DESC);
        oprot.writeString(struct.gatewayId);
        oprot.writeFieldEnd();
      }
      if (struct.experimentType != null) {
        oprot.writeFieldBegin(EXPERIMENT_TYPE_FIELD_DESC);
        oprot.writeI32(struct.experimentType.getValue());
        oprot.writeFieldEnd();
      }
      if (struct.userName != null) {
        oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
        oprot.writeString(struct.userName);
        oprot.writeFieldEnd();
      }
      if (struct.experimentName != null) {
        oprot.writeFieldBegin(EXPERIMENT_NAME_FIELD_DESC);
        oprot.writeString(struct.experimentName);
        oprot.writeFieldEnd();
      }
      if (struct.isSetCreationTime()) {
        oprot.writeFieldBegin(CREATION_TIME_FIELD_DESC);
        oprot.writeI64(struct.creationTime);
        oprot.writeFieldEnd();
      }
      if (struct.description != null) {
        if (struct.isSetDescription()) {
          oprot.writeFieldBegin(DESCRIPTION_FIELD_DESC);
          oprot.writeString(struct.description);
          oprot.writeFieldEnd();
        }
      }
      if (struct.executionId != null) {
        if (struct.isSetExecutionId()) {
          oprot.writeFieldBegin(EXECUTION_ID_FIELD_DESC);
          oprot.writeString(struct.executionId);
          oprot.writeFieldEnd();
        }
      }
      if (struct.gatewayExecutionId != null) {
        if (struct.isSetGatewayExecutionId()) {
          oprot.writeFieldBegin(GATEWAY_EXECUTION_ID_FIELD_DESC);
          oprot.writeString(struct.gatewayExecutionId);
          oprot.writeFieldEnd();
        }
      }
      if (struct.gatewayInstanceId != null) {
        if (struct.isSetGatewayInstanceId()) {
          oprot.writeFieldBegin(GATEWAY_INSTANCE_ID_FIELD_DESC);
          oprot.writeString(struct.gatewayInstanceId);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetEnableEmailNotification()) {
        oprot.writeFieldBegin(ENABLE_EMAIL_NOTIFICATION_FIELD_DESC);
        oprot.writeBool(struct.enableEmailNotification);
        oprot.writeFieldEnd();
      }
      if (struct.emailAddresses != null) {
        if (struct.isSetEmailAddresses()) {
          oprot.writeFieldBegin(EMAIL_ADDRESSES_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.emailAddresses.size()));
            for (java.lang.String _iter26 : struct.emailAddresses)
            {
              oprot.writeString(_iter26);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.userConfigurationData != null) {
        if (struct.isSetUserConfigurationData()) {
          oprot.writeFieldBegin(USER_CONFIGURATION_DATA_FIELD_DESC);
          struct.userConfigurationData.write(oprot);
          oprot.writeFieldEnd();
        }
      }
      if (struct.experimentInputs != null) {
        if (struct.isSetExperimentInputs()) {
          oprot.writeFieldBegin(EXPERIMENT_INPUTS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.experimentInputs.size()));
            for (org.apache.airavata.model.application.io.InputDataObjectType _iter27 : struct.experimentInputs)
            {
              _iter27.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.experimentOutputs != null) {
        if (struct.isSetExperimentOutputs()) {
          oprot.writeFieldBegin(EXPERIMENT_OUTPUTS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.experimentOutputs.size()));
            for (org.apache.airavata.model.application.io.OutputDataObjectType _iter28 : struct.experimentOutputs)
            {
              _iter28.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.experimentStatus != null) {
        if (struct.isSetExperimentStatus()) {
          oprot.writeFieldBegin(EXPERIMENT_STATUS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.experimentStatus.size()));
            for (org.apache.airavata.model.status.ExperimentStatus _iter29 : struct.experimentStatus)
            {
              _iter29.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.errors != null) {
        if (struct.isSetErrors()) {
          oprot.writeFieldBegin(ERRORS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.errors.size()));
            for (org.apache.airavata.model.commons.ErrorModel _iter30 : struct.errors)
            {
              _iter30.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.processes != null) {
        if (struct.isSetProcesses()) {
          oprot.writeFieldBegin(PROCESSES_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.processes.size()));
            for (org.apache.airavata.model.process.ProcessModel _iter31 : struct.processes)
            {
              _iter31.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.workflow != null) {
        if (struct.isSetWorkflow()) {
          oprot.writeFieldBegin(WORKFLOW_FIELD_DESC);
          struct.workflow.write(oprot);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

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

  private static class ExperimentModelTupleScheme extends org.apache.thrift.scheme.TupleScheme<ExperimentModel> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, ExperimentModel struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      oprot.writeString(struct.experimentId);
      oprot.writeString(struct.projectId);
      oprot.writeString(struct.gatewayId);
      oprot.writeI32(struct.experimentType.getValue());
      oprot.writeString(struct.userName);
      oprot.writeString(struct.experimentName);
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.isSetCreationTime()) {
        optionals.set(0);
      }
      if (struct.isSetDescription()) {
        optionals.set(1);
      }
      if (struct.isSetExecutionId()) {
        optionals.set(2);
      }
      if (struct.isSetGatewayExecutionId()) {
        optionals.set(3);
      }
      if (struct.isSetGatewayInstanceId()) {
        optionals.set(4);
      }
      if (struct.isSetEnableEmailNotification()) {
        optionals.set(5);
      }
      if (struct.isSetEmailAddresses()) {
        optionals.set(6);
      }
      if (struct.isSetUserConfigurationData()) {
        optionals.set(7);
      }
      if (struct.isSetExperimentInputs()) {
        optionals.set(8);
      }
      if (struct.isSetExperimentOutputs()) {
        optionals.set(9);
      }
      if (struct.isSetExperimentStatus()) {
        optionals.set(10);
      }
      if (struct.isSetErrors()) {
        optionals.set(11);
      }
      if (struct.isSetProcesses()) {
        optionals.set(12);
      }
      if (struct.isSetWorkflow()) {
        optionals.set(13);
      }
      oprot.writeBitSet(optionals, 14);
      if (struct.isSetCreationTime()) {
        oprot.writeI64(struct.creationTime);
      }
      if (struct.isSetDescription()) {
        oprot.writeString(struct.description);
      }
      if (struct.isSetExecutionId()) {
        oprot.writeString(struct.executionId);
      }
      if (struct.isSetGatewayExecutionId()) {
        oprot.writeString(struct.gatewayExecutionId);
      }
      if (struct.isSetGatewayInstanceId()) {
        oprot.writeString(struct.gatewayInstanceId);
      }
      if (struct.isSetEnableEmailNotification()) {
        oprot.writeBool(struct.enableEmailNotification);
      }
      if (struct.isSetEmailAddresses()) {
        {
          oprot.writeI32(struct.emailAddresses.size());
          for (java.lang.String _iter32 : struct.emailAddresses)
          {
            oprot.writeString(_iter32);
          }
        }
      }
      if (struct.isSetUserConfigurationData()) {
        struct.userConfigurationData.write(oprot);
      }
      if (struct.isSetExperimentInputs()) {
        {
          oprot.writeI32(struct.experimentInputs.size());
          for (org.apache.airavata.model.application.io.InputDataObjectType _iter33 : struct.experimentInputs)
          {
            _iter33.write(oprot);
          }
        }
      }
      if (struct.isSetExperimentOutputs()) {
        {
          oprot.writeI32(struct.experimentOutputs.size());
          for (org.apache.airavata.model.application.io.OutputDataObjectType _iter34 : struct.experimentOutputs)
          {
            _iter34.write(oprot);
          }
        }
      }
      if (struct.isSetExperimentStatus()) {
        {
          oprot.writeI32(struct.experimentStatus.size());
          for (org.apache.airavata.model.status.ExperimentStatus _iter35 : struct.experimentStatus)
          {
            _iter35.write(oprot);
          }
        }
      }
      if (struct.isSetErrors()) {
        {
          oprot.writeI32(struct.errors.size());
          for (org.apache.airavata.model.commons.ErrorModel _iter36 : struct.errors)
          {
            _iter36.write(oprot);
          }
        }
      }
      if (struct.isSetProcesses()) {
        {
          oprot.writeI32(struct.processes.size());
          for (org.apache.airavata.model.process.ProcessModel _iter37 : struct.processes)
          {
            _iter37.write(oprot);
          }
        }
      }
      if (struct.isSetWorkflow()) {
        struct.workflow.write(oprot);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, ExperimentModel struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      struct.experimentId = iprot.readString();
      struct.setExperimentIdIsSet(true);
      struct.projectId = iprot.readString();
      struct.setProjectIdIsSet(true);
      struct.gatewayId = iprot.readString();
      struct.setGatewayIdIsSet(true);
      struct.experimentType = org.apache.airavata.model.experiment.ExperimentType.findByValue(iprot.readI32());
      struct.setExperimentTypeIsSet(true);
      struct.userName = iprot.readString();
      struct.setUserNameIsSet(true);
      struct.experimentName = iprot.readString();
      struct.setExperimentNameIsSet(true);
      java.util.BitSet incoming = iprot.readBitSet(14);
      if (incoming.get(0)) {
        struct.creationTime = iprot.readI64();
        struct.setCreationTimeIsSet(true);
      }
      if (incoming.get(1)) {
        struct.description = iprot.readString();
        struct.setDescriptionIsSet(true);
      }
      if (incoming.get(2)) {
        struct.executionId = iprot.readString();
        struct.setExecutionIdIsSet(true);
      }
      if (incoming.get(3)) {
        struct.gatewayExecutionId = iprot.readString();
        struct.setGatewayExecutionIdIsSet(true);
      }
      if (incoming.get(4)) {
        struct.gatewayInstanceId = iprot.readString();
        struct.setGatewayInstanceIdIsSet(true);
      }
      if (incoming.get(5)) {
        struct.enableEmailNotification = iprot.readBool();
        struct.setEnableEmailNotificationIsSet(true);
      }
      if (incoming.get(6)) {
        {
          org.apache.thrift.protocol.TList _list38 = iprot.readListBegin(org.apache.thrift.protocol.TType.STRING);
          struct.emailAddresses = new java.util.ArrayList<java.lang.String>(_list38.size);
          @org.apache.thrift.annotation.Nullable java.lang.String _elem39;
          for (int _i40 = 0; _i40 < _list38.size; ++_i40)
          {
            _elem39 = iprot.readString();
            struct.emailAddresses.add(_elem39);
          }
        }
        struct.setEmailAddressesIsSet(true);
      }
      if (incoming.get(7)) {
        struct.userConfigurationData = new UserConfigurationDataModel();
        struct.userConfigurationData.read(iprot);
        struct.setUserConfigurationDataIsSet(true);
      }
      if (incoming.get(8)) {
        {
          org.apache.thrift.protocol.TList _list41 = iprot.readListBegin(org.apache.thrift.protocol.TType.STRUCT);
          struct.experimentInputs = new java.util.ArrayList<org.apache.airavata.model.application.io.InputDataObjectType>(_list41.size);
          @org.apache.thrift.annotation.Nullable org.apache.airavata.model.application.io.InputDataObjectType _elem42;
          for (int _i43 = 0; _i43 < _list41.size; ++_i43)
          {
            _elem42 = new org.apache.airavata.model.application.io.InputDataObjectType();
            _elem42.read(iprot);
            struct.experimentInputs.add(_elem42);
          }
        }
        struct.setExperimentInputsIsSet(true);
      }
      if (incoming.get(9)) {
        {
          org.apache.thrift.protocol.TList _list44 = iprot.readListBegin(org.apache.thrift.protocol.TType.STRUCT);
          struct.experimentOutputs = new java.util.ArrayList<org.apache.airavata.model.application.io.OutputDataObjectType>(_list44.size);
          @org.apache.thrift.annotation.Nullable org.apache.airavata.model.application.io.OutputDataObjectType _elem45;
          for (int _i46 = 0; _i46 < _list44.size; ++_i46)
          {
            _elem45 = new org.apache.airavata.model.application.io.OutputDataObjectType();
            _elem45.read(iprot);
            struct.experimentOutputs.add(_elem45);
          }
        }
        struct.setExperimentOutputsIsSet(true);
      }
      if (incoming.get(10)) {
        {
          org.apache.thrift.protocol.TList _list47 = iprot.readListBegin(org.apache.thrift.protocol.TType.STRUCT);
          struct.experimentStatus = new java.util.ArrayList<org.apache.airavata.model.status.ExperimentStatus>(_list47.size);
          @org.apache.thrift.annotation.Nullable org.apache.airavata.model.status.ExperimentStatus _elem48;
          for (int _i49 = 0; _i49 < _list47.size; ++_i49)
          {
            _elem48 = new org.apache.airavata.model.status.ExperimentStatus();
            _elem48.read(iprot);
            struct.experimentStatus.add(_elem48);
          }
        }
        struct.setExperimentStatusIsSet(true);
      }
      if (incoming.get(11)) {
        {
          org.apache.thrift.protocol.TList _list50 = iprot.readListBegin(org.apache.thrift.protocol.TType.STRUCT);
          struct.errors = new java.util.ArrayList<org.apache.airavata.model.commons.ErrorModel>(_list50.size);
          @org.apache.thrift.annotation.Nullable org.apache.airavata.model.commons.ErrorModel _elem51;
          for (int _i52 = 0; _i52 < _list50.size; ++_i52)
          {
            _elem51 = new org.apache.airavata.model.commons.ErrorModel();
            _elem51.read(iprot);
            struct.errors.add(_elem51);
          }
        }
        struct.setErrorsIsSet(true);
      }
      if (incoming.get(12)) {
        {
          org.apache.thrift.protocol.TList _list53 = iprot.readListBegin(org.apache.thrift.protocol.TType.STRUCT);
          struct.processes = new java.util.ArrayList<org.apache.airavata.model.process.ProcessModel>(_list53.size);
          @org.apache.thrift.annotation.Nullable org.apache.airavata.model.process.ProcessModel _elem54;
          for (int _i55 = 0; _i55 < _list53.size; ++_i55)
          {
            _elem54 = new org.apache.airavata.model.process.ProcessModel();
            _elem54.read(iprot);
            struct.processes.add(_elem54);
          }
        }
        struct.setProcessesIsSet(true);
      }
      if (incoming.get(13)) {
        struct.workflow = new org.apache.airavata.model.workflow.AiravataWorkflow();
        struct.workflow.read(iprot);
        struct.setWorkflowIsSet(true);
      }
    }
  }

  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
  }
}

