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

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

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

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

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
/**
 * TaskModel: A structure holding the generic task details.
 * 
 * taskDetail:
 *   A friendly description of the task, usally used to communicate information to users.
 * 
 * subTaskModel:
 *   A generic byte object for the Task developer to store internal serialized data into registry catalogs.
 */
@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)", date = "2016-07-14")
public class TaskModel implements org.apache.thrift.TBase<TaskModel, TaskModel._Fields>, java.io.Serializable, Cloneable, Comparable<TaskModel> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TaskModel");

  private static final org.apache.thrift.protocol.TField TASK_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("taskId", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField TASK_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("taskType", org.apache.thrift.protocol.TType.I32, (short)2);
  private static final org.apache.thrift.protocol.TField PARENT_PROCESS_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("parentProcessId", org.apache.thrift.protocol.TType.STRING, (short)3);
  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)4);
  private static final org.apache.thrift.protocol.TField LAST_UPDATE_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("lastUpdateTime", org.apache.thrift.protocol.TType.I64, (short)5);
  private static final org.apache.thrift.protocol.TField TASK_STATUS_FIELD_DESC = new org.apache.thrift.protocol.TField("taskStatus", org.apache.thrift.protocol.TType.STRUCT, (short)6);
  private static final org.apache.thrift.protocol.TField TASK_DETAIL_FIELD_DESC = new org.apache.thrift.protocol.TField("taskDetail", org.apache.thrift.protocol.TType.STRING, (short)7);
  private static final org.apache.thrift.protocol.TField SUB_TASK_MODEL_FIELD_DESC = new org.apache.thrift.protocol.TField("subTaskModel", org.apache.thrift.protocol.TType.STRING, (short)8);
  private static final org.apache.thrift.protocol.TField TASK_ERROR_FIELD_DESC = new org.apache.thrift.protocol.TField("taskError", org.apache.thrift.protocol.TType.STRUCT, (short)9);
  private static final org.apache.thrift.protocol.TField JOBS_FIELD_DESC = new org.apache.thrift.protocol.TField("jobs", org.apache.thrift.protocol.TType.LIST, (short)10);

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

  private String taskId; // required
  private TaskTypes taskType; // required
  private String parentProcessId; // required
  private long creationTime; // required
  private long lastUpdateTime; // required
  private org.apache.airavata.model.status.TaskStatus taskStatus; // required
  private String taskDetail; // optional
  private ByteBuffer subTaskModel; // optional
  private org.apache.airavata.model.commons.ErrorModel taskError; // optional
  private List<org.apache.airavata.model.job.JobModel> jobs; // 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 {
    TASK_ID((short)1, "taskId"),
    /**
     * 
     * @see TaskTypes
     */
    TASK_TYPE((short)2, "taskType"),
    PARENT_PROCESS_ID((short)3, "parentProcessId"),
    CREATION_TIME((short)4, "creationTime"),
    LAST_UPDATE_TIME((short)5, "lastUpdateTime"),
    TASK_STATUS((short)6, "taskStatus"),
    TASK_DETAIL((short)7, "taskDetail"),
    SUB_TASK_MODEL((short)8, "subTaskModel"),
    TASK_ERROR((short)9, "taskError"),
    JOBS((short)10, "jobs");

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

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

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // TASK_ID
          return TASK_ID;
        case 2: // TASK_TYPE
          return TASK_TYPE;
        case 3: // PARENT_PROCESS_ID
          return PARENT_PROCESS_ID;
        case 4: // CREATION_TIME
          return CREATION_TIME;
        case 5: // LAST_UPDATE_TIME
          return LAST_UPDATE_TIME;
        case 6: // TASK_STATUS
          return TASK_STATUS;
        case 7: // TASK_DETAIL
          return TASK_DETAIL;
        case 8: // SUB_TASK_MODEL
          return SUB_TASK_MODEL;
        case 9: // TASK_ERROR
          return TASK_ERROR;
        case 10: // JOBS
          return JOBS;
        default:
          return null;
      }
    }

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

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

    private final short _thriftId;
    private final String _fieldName;

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

    public short getThriftFieldId() {
      return _thriftId;
    }

    public String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final int __CREATIONTIME_ISSET_ID = 0;
  private static final int __LASTUPDATETIME_ISSET_ID = 1;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.TASK_DETAIL,_Fields.SUB_TASK_MODEL,_Fields.TASK_ERROR,_Fields.JOBS};
  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.TASK_ID, new org.apache.thrift.meta_data.FieldMetaData("taskId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.TASK_TYPE, new org.apache.thrift.meta_data.FieldMetaData("taskType", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, TaskTypes.class)));
    tmpMap.put(_Fields.PARENT_PROCESS_ID, new org.apache.thrift.meta_data.FieldMetaData("parentProcessId", 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.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.LAST_UPDATE_TIME, new org.apache.thrift.meta_data.FieldMetaData("lastUpdateTime", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.TASK_STATUS, new org.apache.thrift.meta_data.FieldMetaData("taskStatus", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.status.TaskStatus.class)));
    tmpMap.put(_Fields.TASK_DETAIL, new org.apache.thrift.meta_data.FieldMetaData("taskDetail", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.SUB_TASK_MODEL, new org.apache.thrift.meta_data.FieldMetaData("subTaskModel", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
    tmpMap.put(_Fields.TASK_ERROR, new org.apache.thrift.meta_data.FieldMetaData("taskError", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.commons.ErrorModel.class)));
    tmpMap.put(_Fields.JOBS, new org.apache.thrift.meta_data.FieldMetaData("jobs", 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.job.JobModel.class))));
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TaskModel.class, metaDataMap);
  }

  public TaskModel() {
    this.taskId = "DO_NOT_SET_AT_CLIENTS";

  }

  public TaskModel(
    String taskId,
    TaskTypes taskType,
    String parentProcessId,
    long creationTime,
    long lastUpdateTime,
    org.apache.airavata.model.status.TaskStatus taskStatus)
  {
    this();
    this.taskId = taskId;
    this.taskType = taskType;
    this.parentProcessId = parentProcessId;
    this.creationTime = creationTime;
    setCreationTimeIsSet(true);
    this.lastUpdateTime = lastUpdateTime;
    setLastUpdateTimeIsSet(true);
    this.taskStatus = taskStatus;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public TaskModel(TaskModel other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetTaskId()) {
      this.taskId = other.taskId;
    }
    if (other.isSetTaskType()) {
      this.taskType = other.taskType;
    }
    if (other.isSetParentProcessId()) {
      this.parentProcessId = other.parentProcessId;
    }
    this.creationTime = other.creationTime;
    this.lastUpdateTime = other.lastUpdateTime;
    if (other.isSetTaskStatus()) {
      this.taskStatus = new org.apache.airavata.model.status.TaskStatus(other.taskStatus);
    }
    if (other.isSetTaskDetail()) {
      this.taskDetail = other.taskDetail;
    }
    if (other.isSetSubTaskModel()) {
      this.subTaskModel = org.apache.thrift.TBaseHelper.copyBinary(other.subTaskModel);
    }
    if (other.isSetTaskError()) {
      this.taskError = new org.apache.airavata.model.commons.ErrorModel(other.taskError);
    }
    if (other.isSetJobs()) {
      List<org.apache.airavata.model.job.JobModel> __this__jobs = new ArrayList<org.apache.airavata.model.job.JobModel>(other.jobs.size());
      for (org.apache.airavata.model.job.JobModel other_element : other.jobs) {
        __this__jobs.add(new org.apache.airavata.model.job.JobModel(other_element));
      }
      this.jobs = __this__jobs;
    }
  }

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

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

    this.taskType = null;
    this.parentProcessId = null;
    setCreationTimeIsSet(false);
    this.creationTime = 0;
    setLastUpdateTimeIsSet(false);
    this.lastUpdateTime = 0;
    this.taskStatus = null;
    this.taskDetail = null;
    this.subTaskModel = null;
    this.taskError = null;
    this.jobs = null;
  }

  public String getTaskId() {
    return this.taskId;
  }

  public void setTaskId(String taskId) {
    this.taskId = taskId;
  }

  public void unsetTaskId() {
    this.taskId = null;
  }

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

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

  /**
   * 
   * @see TaskTypes
   */
  public TaskTypes getTaskType() {
    return this.taskType;
  }

  /**
   * 
   * @see TaskTypes
   */
  public void setTaskType(TaskTypes taskType) {
    this.taskType = taskType;
  }

  public void unsetTaskType() {
    this.taskType = null;
  }

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

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

  public String getParentProcessId() {
    return this.parentProcessId;
  }

  public void setParentProcessId(String parentProcessId) {
    this.parentProcessId = parentProcessId;
  }

  public void unsetParentProcessId() {
    this.parentProcessId = null;
  }

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

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

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

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

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

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

  public long getLastUpdateTime() {
    return this.lastUpdateTime;
  }

  public void setLastUpdateTime(long lastUpdateTime) {
    this.lastUpdateTime = lastUpdateTime;
    setLastUpdateTimeIsSet(true);
  }

  public void unsetLastUpdateTime() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __LASTUPDATETIME_ISSET_ID);
  }

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

  public void setLastUpdateTimeIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __LASTUPDATETIME_ISSET_ID, value);
  }

  public org.apache.airavata.model.status.TaskStatus getTaskStatus() {
    return this.taskStatus;
  }

  public void setTaskStatus(org.apache.airavata.model.status.TaskStatus taskStatus) {
    this.taskStatus = taskStatus;
  }

  public void unsetTaskStatus() {
    this.taskStatus = null;
  }

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

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

  public String getTaskDetail() {
    return this.taskDetail;
  }

  public void setTaskDetail(String taskDetail) {
    this.taskDetail = taskDetail;
  }

  public void unsetTaskDetail() {
    this.taskDetail = null;
  }

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

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

  public byte[] getSubTaskModel() {
    setSubTaskModel(org.apache.thrift.TBaseHelper.rightSize(subTaskModel));
    return subTaskModel == null ? null : subTaskModel.array();
  }

  public ByteBuffer bufferForSubTaskModel() {
    return org.apache.thrift.TBaseHelper.copyBinary(subTaskModel);
  }

  public void setSubTaskModel(byte[] subTaskModel) {
    this.subTaskModel = subTaskModel == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(subTaskModel, subTaskModel.length));
  }

  public void setSubTaskModel(ByteBuffer subTaskModel) {
    this.subTaskModel = org.apache.thrift.TBaseHelper.copyBinary(subTaskModel);
  }

  public void unsetSubTaskModel() {
    this.subTaskModel = null;
  }

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

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

  public org.apache.airavata.model.commons.ErrorModel getTaskError() {
    return this.taskError;
  }

  public void setTaskError(org.apache.airavata.model.commons.ErrorModel taskError) {
    this.taskError = taskError;
  }

  public void unsetTaskError() {
    this.taskError = null;
  }

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

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

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

  public java.util.Iterator<org.apache.airavata.model.job.JobModel> getJobsIterator() {
    return (this.jobs == null) ? null : this.jobs.iterator();
  }

  public void addToJobs(org.apache.airavata.model.job.JobModel elem) {
    if (this.jobs == null) {
      this.jobs = new ArrayList<org.apache.airavata.model.job.JobModel>();
    }
    this.jobs.add(elem);
  }

  public List<org.apache.airavata.model.job.JobModel> getJobs() {
    return this.jobs;
  }

  public void setJobs(List<org.apache.airavata.model.job.JobModel> jobs) {
    this.jobs = jobs;
  }

  public void unsetJobs() {
    this.jobs = null;
  }

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

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

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case TASK_ID:
      if (value == null) {
        unsetTaskId();
      } else {
        setTaskId((String)value);
      }
      break;

    case TASK_TYPE:
      if (value == null) {
        unsetTaskType();
      } else {
        setTaskType((TaskTypes)value);
      }
      break;

    case PARENT_PROCESS_ID:
      if (value == null) {
        unsetParentProcessId();
      } else {
        setParentProcessId((String)value);
      }
      break;

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

    case LAST_UPDATE_TIME:
      if (value == null) {
        unsetLastUpdateTime();
      } else {
        setLastUpdateTime((Long)value);
      }
      break;

    case TASK_STATUS:
      if (value == null) {
        unsetTaskStatus();
      } else {
        setTaskStatus((org.apache.airavata.model.status.TaskStatus)value);
      }
      break;

    case TASK_DETAIL:
      if (value == null) {
        unsetTaskDetail();
      } else {
        setTaskDetail((String)value);
      }
      break;

    case SUB_TASK_MODEL:
      if (value == null) {
        unsetSubTaskModel();
      } else {
        setSubTaskModel((ByteBuffer)value);
      }
      break;

    case TASK_ERROR:
      if (value == null) {
        unsetTaskError();
      } else {
        setTaskError((org.apache.airavata.model.commons.ErrorModel)value);
      }
      break;

    case JOBS:
      if (value == null) {
        unsetJobs();
      } else {
        setJobs((List<org.apache.airavata.model.job.JobModel>)value);
      }
      break;

    }
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case TASK_ID:
      return getTaskId();

    case TASK_TYPE:
      return getTaskType();

    case PARENT_PROCESS_ID:
      return getParentProcessId();

    case CREATION_TIME:
      return getCreationTime();

    case LAST_UPDATE_TIME:
      return getLastUpdateTime();

    case TASK_STATUS:
      return getTaskStatus();

    case TASK_DETAIL:
      return getTaskDetail();

    case SUB_TASK_MODEL:
      return getSubTaskModel();

    case TASK_ERROR:
      return getTaskError();

    case JOBS:
      return getJobs();

    }
    throw new IllegalStateException();
  }

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

    switch (field) {
    case TASK_ID:
      return isSetTaskId();
    case TASK_TYPE:
      return isSetTaskType();
    case PARENT_PROCESS_ID:
      return isSetParentProcessId();
    case CREATION_TIME:
      return isSetCreationTime();
    case LAST_UPDATE_TIME:
      return isSetLastUpdateTime();
    case TASK_STATUS:
      return isSetTaskStatus();
    case TASK_DETAIL:
      return isSetTaskDetail();
    case SUB_TASK_MODEL:
      return isSetSubTaskModel();
    case TASK_ERROR:
      return isSetTaskError();
    case JOBS:
      return isSetJobs();
    }
    throw new IllegalStateException();
  }

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

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

    boolean this_present_taskId = true && this.isSetTaskId();
    boolean that_present_taskId = true && that.isSetTaskId();
    if (this_present_taskId || that_present_taskId) {
      if (!(this_present_taskId && that_present_taskId))
        return false;
      if (!this.taskId.equals(that.taskId))
        return false;
    }

    boolean this_present_taskType = true && this.isSetTaskType();
    boolean that_present_taskType = true && that.isSetTaskType();
    if (this_present_taskType || that_present_taskType) {
      if (!(this_present_taskType && that_present_taskType))
        return false;
      if (!this.taskType.equals(that.taskType))
        return false;
    }

    boolean this_present_parentProcessId = true && this.isSetParentProcessId();
    boolean that_present_parentProcessId = true && that.isSetParentProcessId();
    if (this_present_parentProcessId || that_present_parentProcessId) {
      if (!(this_present_parentProcessId && that_present_parentProcessId))
        return false;
      if (!this.parentProcessId.equals(that.parentProcessId))
        return false;
    }

    boolean this_present_creationTime = true;
    boolean that_present_creationTime = true;
    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_lastUpdateTime = true;
    boolean that_present_lastUpdateTime = true;
    if (this_present_lastUpdateTime || that_present_lastUpdateTime) {
      if (!(this_present_lastUpdateTime && that_present_lastUpdateTime))
        return false;
      if (this.lastUpdateTime != that.lastUpdateTime)
        return false;
    }

    boolean this_present_taskStatus = true && this.isSetTaskStatus();
    boolean that_present_taskStatus = true && that.isSetTaskStatus();
    if (this_present_taskStatus || that_present_taskStatus) {
      if (!(this_present_taskStatus && that_present_taskStatus))
        return false;
      if (!this.taskStatus.equals(that.taskStatus))
        return false;
    }

    boolean this_present_taskDetail = true && this.isSetTaskDetail();
    boolean that_present_taskDetail = true && that.isSetTaskDetail();
    if (this_present_taskDetail || that_present_taskDetail) {
      if (!(this_present_taskDetail && that_present_taskDetail))
        return false;
      if (!this.taskDetail.equals(that.taskDetail))
        return false;
    }

    boolean this_present_subTaskModel = true && this.isSetSubTaskModel();
    boolean that_present_subTaskModel = true && that.isSetSubTaskModel();
    if (this_present_subTaskModel || that_present_subTaskModel) {
      if (!(this_present_subTaskModel && that_present_subTaskModel))
        return false;
      if (!this.subTaskModel.equals(that.subTaskModel))
        return false;
    }

    boolean this_present_taskError = true && this.isSetTaskError();
    boolean that_present_taskError = true && that.isSetTaskError();
    if (this_present_taskError || that_present_taskError) {
      if (!(this_present_taskError && that_present_taskError))
        return false;
      if (!this.taskError.equals(that.taskError))
        return false;
    }

    boolean this_present_jobs = true && this.isSetJobs();
    boolean that_present_jobs = true && that.isSetJobs();
    if (this_present_jobs || that_present_jobs) {
      if (!(this_present_jobs && that_present_jobs))
        return false;
      if (!this.jobs.equals(that.jobs))
        return false;
    }

    return true;
  }

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

    boolean present_taskId = true && (isSetTaskId());
    list.add(present_taskId);
    if (present_taskId)
      list.add(taskId);

    boolean present_taskType = true && (isSetTaskType());
    list.add(present_taskType);
    if (present_taskType)
      list.add(taskType.getValue());

    boolean present_parentProcessId = true && (isSetParentProcessId());
    list.add(present_parentProcessId);
    if (present_parentProcessId)
      list.add(parentProcessId);

    boolean present_creationTime = true;
    list.add(present_creationTime);
    if (present_creationTime)
      list.add(creationTime);

    boolean present_lastUpdateTime = true;
    list.add(present_lastUpdateTime);
    if (present_lastUpdateTime)
      list.add(lastUpdateTime);

    boolean present_taskStatus = true && (isSetTaskStatus());
    list.add(present_taskStatus);
    if (present_taskStatus)
      list.add(taskStatus);

    boolean present_taskDetail = true && (isSetTaskDetail());
    list.add(present_taskDetail);
    if (present_taskDetail)
      list.add(taskDetail);

    boolean present_subTaskModel = true && (isSetSubTaskModel());
    list.add(present_subTaskModel);
    if (present_subTaskModel)
      list.add(subTaskModel);

    boolean present_taskError = true && (isSetTaskError());
    list.add(present_taskError);
    if (present_taskError)
      list.add(taskError);

    boolean present_jobs = true && (isSetJobs());
    list.add(present_jobs);
    if (present_jobs)
      list.add(jobs);

    return list.hashCode();
  }

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

    int lastComparison = 0;

    lastComparison = Boolean.valueOf(isSetTaskId()).compareTo(other.isSetTaskId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetTaskId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.taskId, other.taskId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetTaskType()).compareTo(other.isSetTaskType());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetTaskType()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.taskType, other.taskType);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetParentProcessId()).compareTo(other.isSetParentProcessId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetParentProcessId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.parentProcessId, other.parentProcessId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetCreationTime()).compareTo(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 = Boolean.valueOf(isSetLastUpdateTime()).compareTo(other.isSetLastUpdateTime());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetLastUpdateTime()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.lastUpdateTime, other.lastUpdateTime);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetTaskStatus()).compareTo(other.isSetTaskStatus());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetTaskStatus()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.taskStatus, other.taskStatus);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetTaskDetail()).compareTo(other.isSetTaskDetail());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetTaskDetail()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.taskDetail, other.taskDetail);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetSubTaskModel()).compareTo(other.isSetSubTaskModel());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetSubTaskModel()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.subTaskModel, other.subTaskModel);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetTaskError()).compareTo(other.isSetTaskError());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetTaskError()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.taskError, other.taskError);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetJobs()).compareTo(other.isSetJobs());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetJobs()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jobs, other.jobs);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

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

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

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

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder("TaskModel(");
    boolean first = true;

    sb.append("taskId:");
    if (this.taskId == null) {
      sb.append("null");
    } else {
      sb.append(this.taskId);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("taskType:");
    if (this.taskType == null) {
      sb.append("null");
    } else {
      sb.append(this.taskType);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("parentProcessId:");
    if (this.parentProcessId == null) {
      sb.append("null");
    } else {
      sb.append(this.parentProcessId);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("creationTime:");
    sb.append(this.creationTime);
    first = false;
    if (!first) sb.append(", ");
    sb.append("lastUpdateTime:");
    sb.append(this.lastUpdateTime);
    first = false;
    if (!first) sb.append(", ");
    sb.append("taskStatus:");
    if (this.taskStatus == null) {
      sb.append("null");
    } else {
      sb.append(this.taskStatus);
    }
    first = false;
    if (isSetTaskDetail()) {
      if (!first) sb.append(", ");
      sb.append("taskDetail:");
      if (this.taskDetail == null) {
        sb.append("null");
      } else {
        sb.append(this.taskDetail);
      }
      first = false;
    }
    if (isSetSubTaskModel()) {
      if (!first) sb.append(", ");
      sb.append("subTaskModel:");
      if (this.subTaskModel == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.subTaskModel, sb);
      }
      first = false;
    }
    if (isSetTaskError()) {
      if (!first) sb.append(", ");
      sb.append("taskError:");
      if (this.taskError == null) {
        sb.append("null");
      } else {
        sb.append(this.taskError);
      }
      first = false;
    }
    if (isSetJobs()) {
      if (!first) sb.append(", ");
      sb.append("jobs:");
      if (this.jobs == null) {
        sb.append("null");
      } else {
        sb.append(this.jobs);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

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

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

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

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

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

    // check for sub-struct validity
    if (taskStatus != null) {
      taskStatus.validate();
    }
    if (taskError != null) {
      taskError.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, 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 TaskModelStandardSchemeFactory implements SchemeFactory {
    public TaskModelStandardScheme getScheme() {
      return new TaskModelStandardScheme();
    }
  }

  private static class TaskModelStandardScheme extends StandardScheme<TaskModel> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, TaskModel 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: // TASK_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.taskId = iprot.readString();
              struct.setTaskIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // TASK_TYPE
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.taskType = org.apache.airavata.model.task.TaskTypes.findByValue(iprot.readI32());
              struct.setTaskTypeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // PARENT_PROCESS_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.parentProcessId = iprot.readString();
              struct.setParentProcessIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // 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 5: // LAST_UPDATE_TIME
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.lastUpdateTime = iprot.readI64();
              struct.setLastUpdateTimeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // TASK_STATUS
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.taskStatus = new org.apache.airavata.model.status.TaskStatus();
              struct.taskStatus.read(iprot);
              struct.setTaskStatusIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // TASK_DETAIL
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.taskDetail = iprot.readString();
              struct.setTaskDetailIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // SUB_TASK_MODEL
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.subTaskModel = iprot.readBinary();
              struct.setSubTaskModelIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // TASK_ERROR
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.taskError = new org.apache.airavata.model.commons.ErrorModel();
              struct.taskError.read(iprot);
              struct.setTaskErrorIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // JOBS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list0 = iprot.readListBegin();
                struct.jobs = new ArrayList<org.apache.airavata.model.job.JobModel>(_list0.size);
                org.apache.airavata.model.job.JobModel _elem1;
                for (int _i2 = 0; _i2 < _list0.size; ++_i2)
                {
                  _elem1 = new org.apache.airavata.model.job.JobModel();
                  _elem1.read(iprot);
                  struct.jobs.add(_elem1);
                }
                iprot.readListEnd();
              }
              struct.setJobsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          default:
            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
      struct.validate();
    }

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

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.taskId != null) {
        oprot.writeFieldBegin(TASK_ID_FIELD_DESC);
        oprot.writeString(struct.taskId);
        oprot.writeFieldEnd();
      }
      if (struct.taskType != null) {
        oprot.writeFieldBegin(TASK_TYPE_FIELD_DESC);
        oprot.writeI32(struct.taskType.getValue());
        oprot.writeFieldEnd();
      }
      if (struct.parentProcessId != null) {
        oprot.writeFieldBegin(PARENT_PROCESS_ID_FIELD_DESC);
        oprot.writeString(struct.parentProcessId);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldBegin(CREATION_TIME_FIELD_DESC);
      oprot.writeI64(struct.creationTime);
      oprot.writeFieldEnd();
      oprot.writeFieldBegin(LAST_UPDATE_TIME_FIELD_DESC);
      oprot.writeI64(struct.lastUpdateTime);
      oprot.writeFieldEnd();
      if (struct.taskStatus != null) {
        oprot.writeFieldBegin(TASK_STATUS_FIELD_DESC);
        struct.taskStatus.write(oprot);
        oprot.writeFieldEnd();
      }
      if (struct.taskDetail != null) {
        if (struct.isSetTaskDetail()) {
          oprot.writeFieldBegin(TASK_DETAIL_FIELD_DESC);
          oprot.writeString(struct.taskDetail);
          oprot.writeFieldEnd();
        }
      }
      if (struct.subTaskModel != null) {
        if (struct.isSetSubTaskModel()) {
          oprot.writeFieldBegin(SUB_TASK_MODEL_FIELD_DESC);
          oprot.writeBinary(struct.subTaskModel);
          oprot.writeFieldEnd();
        }
      }
      if (struct.taskError != null) {
        if (struct.isSetTaskError()) {
          oprot.writeFieldBegin(TASK_ERROR_FIELD_DESC);
          struct.taskError.write(oprot);
          oprot.writeFieldEnd();
        }
      }
      if (struct.jobs != null) {
        if (struct.isSetJobs()) {
          oprot.writeFieldBegin(JOBS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.jobs.size()));
            for (org.apache.airavata.model.job.JobModel _iter3 : struct.jobs)
            {
              _iter3.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class TaskModelTupleSchemeFactory implements SchemeFactory {
    public TaskModelTupleScheme getScheme() {
      return new TaskModelTupleScheme();
    }
  }

  private static class TaskModelTupleScheme extends TupleScheme<TaskModel> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, TaskModel struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      oprot.writeString(struct.taskId);
      oprot.writeI32(struct.taskType.getValue());
      oprot.writeString(struct.parentProcessId);
      oprot.writeI64(struct.creationTime);
      oprot.writeI64(struct.lastUpdateTime);
      struct.taskStatus.write(oprot);
      BitSet optionals = new BitSet();
      if (struct.isSetTaskDetail()) {
        optionals.set(0);
      }
      if (struct.isSetSubTaskModel()) {
        optionals.set(1);
      }
      if (struct.isSetTaskError()) {
        optionals.set(2);
      }
      if (struct.isSetJobs()) {
        optionals.set(3);
      }
      oprot.writeBitSet(optionals, 4);
      if (struct.isSetTaskDetail()) {
        oprot.writeString(struct.taskDetail);
      }
      if (struct.isSetSubTaskModel()) {
        oprot.writeBinary(struct.subTaskModel);
      }
      if (struct.isSetTaskError()) {
        struct.taskError.write(oprot);
      }
      if (struct.isSetJobs()) {
        {
          oprot.writeI32(struct.jobs.size());
          for (org.apache.airavata.model.job.JobModel _iter4 : struct.jobs)
          {
            _iter4.write(oprot);
          }
        }
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, TaskModel struct) throws org.apache.thrift.TException {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      struct.taskId = iprot.readString();
      struct.setTaskIdIsSet(true);
      struct.taskType = org.apache.airavata.model.task.TaskTypes.findByValue(iprot.readI32());
      struct.setTaskTypeIsSet(true);
      struct.parentProcessId = iprot.readString();
      struct.setParentProcessIdIsSet(true);
      struct.creationTime = iprot.readI64();
      struct.setCreationTimeIsSet(true);
      struct.lastUpdateTime = iprot.readI64();
      struct.setLastUpdateTimeIsSet(true);
      struct.taskStatus = new org.apache.airavata.model.status.TaskStatus();
      struct.taskStatus.read(iprot);
      struct.setTaskStatusIsSet(true);
      BitSet incoming = iprot.readBitSet(4);
      if (incoming.get(0)) {
        struct.taskDetail = iprot.readString();
        struct.setTaskDetailIsSet(true);
      }
      if (incoming.get(1)) {
        struct.subTaskModel = iprot.readBinary();
        struct.setSubTaskModelIsSet(true);
      }
      if (incoming.get(2)) {
        struct.taskError = new org.apache.airavata.model.commons.ErrorModel();
        struct.taskError.read(iprot);
        struct.setTaskErrorIsSet(true);
      }
      if (incoming.get(3)) {
        {
          org.apache.thrift.protocol.TList _list5 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.jobs = new ArrayList<org.apache.airavata.model.job.JobModel>(_list5.size);
          org.apache.airavata.model.job.JobModel _elem6;
          for (int _i7 = 0; _i7 < _list5.size; ++_i7)
          {
            _elem6 = new org.apache.airavata.model.job.JobModel();
            _elem6.read(iprot);
            struct.jobs.add(_elem6);
          }
        }
        struct.setJobsIsSet(true);
      }
    }
  }

}

