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

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

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
public class WorkflowApplication implements org.apache.thrift.TBase<WorkflowApplication, WorkflowApplication._Fields>, java.io.Serializable, Cloneable, Comparable<WorkflowApplication> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("WorkflowApplication");

  private static final org.apache.thrift.protocol.TField ID_FIELD_DESC = new org.apache.thrift.protocol.TField("id", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField PROCESS_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("processId", org.apache.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.thrift.protocol.TField APPLICATION_INTERFACE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationInterfaceId", org.apache.thrift.protocol.TType.STRING, (short)3);
  private static final org.apache.thrift.protocol.TField COMPUTE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceId", org.apache.thrift.protocol.TType.STRING, (short)4);
  private static final org.apache.thrift.protocol.TField QUEUE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("queueName", org.apache.thrift.protocol.TType.STRING, (short)5);
  private static final org.apache.thrift.protocol.TField NODE_COUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("nodeCount", org.apache.thrift.protocol.TType.I32, (short)6);
  private static final org.apache.thrift.protocol.TField CORE_COUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("coreCount", org.apache.thrift.protocol.TType.I32, (short)7);
  private static final org.apache.thrift.protocol.TField WALL_TIME_LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("wallTimeLimit", org.apache.thrift.protocol.TType.I32, (short)8);
  private static final org.apache.thrift.protocol.TField PHYSICAL_MEMORY_FIELD_DESC = new org.apache.thrift.protocol.TField("physicalMemory", org.apache.thrift.protocol.TType.I32, (short)9);
  private static final org.apache.thrift.protocol.TField STATUSES_FIELD_DESC = new org.apache.thrift.protocol.TField("statuses", org.apache.thrift.protocol.TType.LIST, (short)10);
  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)11);
  private static final org.apache.thrift.protocol.TField CREATED_AT_FIELD_DESC = new org.apache.thrift.protocol.TField("createdAt", org.apache.thrift.protocol.TType.I64, (short)12);
  private static final org.apache.thrift.protocol.TField UPDATED_AT_FIELD_DESC = new org.apache.thrift.protocol.TField("updatedAt", org.apache.thrift.protocol.TType.I64, (short)13);

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

  private java.lang.String id; // required
  private java.lang.String processId; // optional
  private java.lang.String applicationInterfaceId; // optional
  private java.lang.String computeResourceId; // optional
  private java.lang.String queueName; // optional
  private int nodeCount; // optional
  private int coreCount; // optional
  private int wallTimeLimit; // optional
  private int physicalMemory; // optional
  private java.util.List<ApplicationStatus> statuses; // optional
  private java.util.List<org.apache.airavata.model.commons.ErrorModel> errors; // optional
  private long createdAt; // optional
  private long updatedAt; // 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 {
    ID((short)1, "id"),
    PROCESS_ID((short)2, "processId"),
    APPLICATION_INTERFACE_ID((short)3, "applicationInterfaceId"),
    COMPUTE_RESOURCE_ID((short)4, "computeResourceId"),
    QUEUE_NAME((short)5, "queueName"),
    NODE_COUNT((short)6, "nodeCount"),
    CORE_COUNT((short)7, "coreCount"),
    WALL_TIME_LIMIT((short)8, "wallTimeLimit"),
    PHYSICAL_MEMORY((short)9, "physicalMemory"),
    STATUSES((short)10, "statuses"),
    ERRORS((short)11, "errors"),
    CREATED_AT((short)12, "createdAt"),
    UPDATED_AT((short)13, "updatedAt");

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

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

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // ID
          return ID;
        case 2: // PROCESS_ID
          return PROCESS_ID;
        case 3: // APPLICATION_INTERFACE_ID
          return APPLICATION_INTERFACE_ID;
        case 4: // COMPUTE_RESOURCE_ID
          return COMPUTE_RESOURCE_ID;
        case 5: // QUEUE_NAME
          return QUEUE_NAME;
        case 6: // NODE_COUNT
          return NODE_COUNT;
        case 7: // CORE_COUNT
          return CORE_COUNT;
        case 8: // WALL_TIME_LIMIT
          return WALL_TIME_LIMIT;
        case 9: // PHYSICAL_MEMORY
          return PHYSICAL_MEMORY;
        case 10: // STATUSES
          return STATUSES;
        case 11: // ERRORS
          return ERRORS;
        case 12: // CREATED_AT
          return CREATED_AT;
        case 13: // UPDATED_AT
          return UPDATED_AT;
        default:
          return null;
      }
    }

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

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

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

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

    public short getThriftFieldId() {
      return _thriftId;
    }

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

  // isset id assignments
  private static final int __NODECOUNT_ISSET_ID = 0;
  private static final int __CORECOUNT_ISSET_ID = 1;
  private static final int __WALLTIMELIMIT_ISSET_ID = 2;
  private static final int __PHYSICALMEMORY_ISSET_ID = 3;
  private static final int __CREATEDAT_ISSET_ID = 4;
  private static final int __UPDATEDAT_ISSET_ID = 5;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.PROCESS_ID,_Fields.APPLICATION_INTERFACE_ID,_Fields.COMPUTE_RESOURCE_ID,_Fields.QUEUE_NAME,_Fields.NODE_COUNT,_Fields.CORE_COUNT,_Fields.WALL_TIME_LIMIT,_Fields.PHYSICAL_MEMORY,_Fields.STATUSES,_Fields.ERRORS,_Fields.CREATED_AT,_Fields.UPDATED_AT};
  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.ID, new org.apache.thrift.meta_data.FieldMetaData("id", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.PROCESS_ID, new org.apache.thrift.meta_data.FieldMetaData("processId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.APPLICATION_INTERFACE_ID, new org.apache.thrift.meta_data.FieldMetaData("applicationInterfaceId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.QUEUE_NAME, new org.apache.thrift.meta_data.FieldMetaData("queueName", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.NODE_COUNT, new org.apache.thrift.meta_data.FieldMetaData("nodeCount", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.CORE_COUNT, new org.apache.thrift.meta_data.FieldMetaData("coreCount", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.WALL_TIME_LIMIT, new org.apache.thrift.meta_data.FieldMetaData("wallTimeLimit", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.PHYSICAL_MEMORY, new org.apache.thrift.meta_data.FieldMetaData("physicalMemory", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.STATUSES, new org.apache.thrift.meta_data.FieldMetaData("statuses", 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, ApplicationStatus.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.CREATED_AT, new org.apache.thrift.meta_data.FieldMetaData("createdAt", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.UPDATED_AT, new org.apache.thrift.meta_data.FieldMetaData("updatedAt", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(WorkflowApplication.class, metaDataMap);
  }

  public WorkflowApplication() {
  }

  public WorkflowApplication(
    java.lang.String id)
  {
    this();
    this.id = id;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public WorkflowApplication(WorkflowApplication other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetId()) {
      this.id = other.id;
    }
    if (other.isSetProcessId()) {
      this.processId = other.processId;
    }
    if (other.isSetApplicationInterfaceId()) {
      this.applicationInterfaceId = other.applicationInterfaceId;
    }
    if (other.isSetComputeResourceId()) {
      this.computeResourceId = other.computeResourceId;
    }
    if (other.isSetQueueName()) {
      this.queueName = other.queueName;
    }
    this.nodeCount = other.nodeCount;
    this.coreCount = other.coreCount;
    this.wallTimeLimit = other.wallTimeLimit;
    this.physicalMemory = other.physicalMemory;
    if (other.isSetStatuses()) {
      java.util.List<ApplicationStatus> __this__statuses = new java.util.ArrayList<ApplicationStatus>(other.statuses.size());
      for (ApplicationStatus other_element : other.statuses) {
        __this__statuses.add(new ApplicationStatus(other_element));
      }
      this.statuses = __this__statuses;
    }
    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;
    }
    this.createdAt = other.createdAt;
    this.updatedAt = other.updatedAt;
  }

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

  @Override
  public void clear() {
    this.id = null;
    this.processId = null;
    this.applicationInterfaceId = null;
    this.computeResourceId = null;
    this.queueName = null;
    setNodeCountIsSet(false);
    this.nodeCount = 0;
    setCoreCountIsSet(false);
    this.coreCount = 0;
    setWallTimeLimitIsSet(false);
    this.wallTimeLimit = 0;
    setPhysicalMemoryIsSet(false);
    this.physicalMemory = 0;
    this.statuses = null;
    this.errors = null;
    setCreatedAtIsSet(false);
    this.createdAt = 0;
    setUpdatedAtIsSet(false);
    this.updatedAt = 0;
  }

  public java.lang.String getId() {
    return this.id;
  }

  public void setId(java.lang.String id) {
    this.id = id;
  }

  public void unsetId() {
    this.id = null;
  }

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

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

  public java.lang.String getProcessId() {
    return this.processId;
  }

  public void setProcessId(java.lang.String processId) {
    this.processId = processId;
  }

  public void unsetProcessId() {
    this.processId = null;
  }

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

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

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

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

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

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

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

  public java.lang.String getComputeResourceId() {
    return this.computeResourceId;
  }

  public void setComputeResourceId(java.lang.String computeResourceId) {
    this.computeResourceId = computeResourceId;
  }

  public void unsetComputeResourceId() {
    this.computeResourceId = null;
  }

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

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

  public java.lang.String getQueueName() {
    return this.queueName;
  }

  public void setQueueName(java.lang.String queueName) {
    this.queueName = queueName;
  }

  public void unsetQueueName() {
    this.queueName = null;
  }

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

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

  public int getNodeCount() {
    return this.nodeCount;
  }

  public void setNodeCount(int nodeCount) {
    this.nodeCount = nodeCount;
    setNodeCountIsSet(true);
  }

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

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

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

  public int getCoreCount() {
    return this.coreCount;
  }

  public void setCoreCount(int coreCount) {
    this.coreCount = coreCount;
    setCoreCountIsSet(true);
  }

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

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

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

  public int getWallTimeLimit() {
    return this.wallTimeLimit;
  }

  public void setWallTimeLimit(int wallTimeLimit) {
    this.wallTimeLimit = wallTimeLimit;
    setWallTimeLimitIsSet(true);
  }

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

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

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

  public int getPhysicalMemory() {
    return this.physicalMemory;
  }

  public void setPhysicalMemory(int physicalMemory) {
    this.physicalMemory = physicalMemory;
    setPhysicalMemoryIsSet(true);
  }

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

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

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

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

  public java.util.Iterator<ApplicationStatus> getStatusesIterator() {
    return (this.statuses == null) ? null : this.statuses.iterator();
  }

  public void addToStatuses(ApplicationStatus elem) {
    if (this.statuses == null) {
      this.statuses = new java.util.ArrayList<ApplicationStatus>();
    }
    this.statuses.add(elem);
  }

  public java.util.List<ApplicationStatus> getStatuses() {
    return this.statuses;
  }

  public void setStatuses(java.util.List<ApplicationStatus> statuses) {
    this.statuses = statuses;
  }

  public void unsetStatuses() {
    this.statuses = null;
  }

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

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

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

  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);
  }

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

  public void setErrors(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 long getCreatedAt() {
    return this.createdAt;
  }

  public void setCreatedAt(long createdAt) {
    this.createdAt = createdAt;
    setCreatedAtIsSet(true);
  }

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

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

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

  public long getUpdatedAt() {
    return this.updatedAt;
  }

  public void setUpdatedAt(long updatedAt) {
    this.updatedAt = updatedAt;
    setUpdatedAtIsSet(true);
  }

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

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

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

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

    case PROCESS_ID:
      if (value == null) {
        unsetProcessId();
      } else {
        setProcessId((java.lang.String)value);
      }
      break;

    case APPLICATION_INTERFACE_ID:
      if (value == null) {
        unsetApplicationInterfaceId();
      } else {
        setApplicationInterfaceId((java.lang.String)value);
      }
      break;

    case COMPUTE_RESOURCE_ID:
      if (value == null) {
        unsetComputeResourceId();
      } else {
        setComputeResourceId((java.lang.String)value);
      }
      break;

    case QUEUE_NAME:
      if (value == null) {
        unsetQueueName();
      } else {
        setQueueName((java.lang.String)value);
      }
      break;

    case NODE_COUNT:
      if (value == null) {
        unsetNodeCount();
      } else {
        setNodeCount((java.lang.Integer)value);
      }
      break;

    case CORE_COUNT:
      if (value == null) {
        unsetCoreCount();
      } else {
        setCoreCount((java.lang.Integer)value);
      }
      break;

    case WALL_TIME_LIMIT:
      if (value == null) {
        unsetWallTimeLimit();
      } else {
        setWallTimeLimit((java.lang.Integer)value);
      }
      break;

    case PHYSICAL_MEMORY:
      if (value == null) {
        unsetPhysicalMemory();
      } else {
        setPhysicalMemory((java.lang.Integer)value);
      }
      break;

    case STATUSES:
      if (value == null) {
        unsetStatuses();
      } else {
        setStatuses((java.util.List<ApplicationStatus>)value);
      }
      break;

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

    case CREATED_AT:
      if (value == null) {
        unsetCreatedAt();
      } else {
        setCreatedAt((java.lang.Long)value);
      }
      break;

    case UPDATED_AT:
      if (value == null) {
        unsetUpdatedAt();
      } else {
        setUpdatedAt((java.lang.Long)value);
      }
      break;

    }
  }

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

    case PROCESS_ID:
      return getProcessId();

    case APPLICATION_INTERFACE_ID:
      return getApplicationInterfaceId();

    case COMPUTE_RESOURCE_ID:
      return getComputeResourceId();

    case QUEUE_NAME:
      return getQueueName();

    case NODE_COUNT:
      return getNodeCount();

    case CORE_COUNT:
      return getCoreCount();

    case WALL_TIME_LIMIT:
      return getWallTimeLimit();

    case PHYSICAL_MEMORY:
      return getPhysicalMemory();

    case STATUSES:
      return getStatuses();

    case ERRORS:
      return getErrors();

    case CREATED_AT:
      return getCreatedAt();

    case UPDATED_AT:
      return getUpdatedAt();

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

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

    switch (field) {
    case ID:
      return isSetId();
    case PROCESS_ID:
      return isSetProcessId();
    case APPLICATION_INTERFACE_ID:
      return isSetApplicationInterfaceId();
    case COMPUTE_RESOURCE_ID:
      return isSetComputeResourceId();
    case QUEUE_NAME:
      return isSetQueueName();
    case NODE_COUNT:
      return isSetNodeCount();
    case CORE_COUNT:
      return isSetCoreCount();
    case WALL_TIME_LIMIT:
      return isSetWallTimeLimit();
    case PHYSICAL_MEMORY:
      return isSetPhysicalMemory();
    case STATUSES:
      return isSetStatuses();
    case ERRORS:
      return isSetErrors();
    case CREATED_AT:
      return isSetCreatedAt();
    case UPDATED_AT:
      return isSetUpdatedAt();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_id = true && this.isSetId();
    boolean that_present_id = true && that.isSetId();
    if (this_present_id || that_present_id) {
      if (!(this_present_id && that_present_id))
        return false;
      if (!this.id.equals(that.id))
        return false;
    }

    boolean this_present_processId = true && this.isSetProcessId();
    boolean that_present_processId = true && that.isSetProcessId();
    if (this_present_processId || that_present_processId) {
      if (!(this_present_processId && that_present_processId))
        return false;
      if (!this.processId.equals(that.processId))
        return false;
    }

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

    boolean this_present_computeResourceId = true && this.isSetComputeResourceId();
    boolean that_present_computeResourceId = true && that.isSetComputeResourceId();
    if (this_present_computeResourceId || that_present_computeResourceId) {
      if (!(this_present_computeResourceId && that_present_computeResourceId))
        return false;
      if (!this.computeResourceId.equals(that.computeResourceId))
        return false;
    }

    boolean this_present_queueName = true && this.isSetQueueName();
    boolean that_present_queueName = true && that.isSetQueueName();
    if (this_present_queueName || that_present_queueName) {
      if (!(this_present_queueName && that_present_queueName))
        return false;
      if (!this.queueName.equals(that.queueName))
        return false;
    }

    boolean this_present_nodeCount = true && this.isSetNodeCount();
    boolean that_present_nodeCount = true && that.isSetNodeCount();
    if (this_present_nodeCount || that_present_nodeCount) {
      if (!(this_present_nodeCount && that_present_nodeCount))
        return false;
      if (this.nodeCount != that.nodeCount)
        return false;
    }

    boolean this_present_coreCount = true && this.isSetCoreCount();
    boolean that_present_coreCount = true && that.isSetCoreCount();
    if (this_present_coreCount || that_present_coreCount) {
      if (!(this_present_coreCount && that_present_coreCount))
        return false;
      if (this.coreCount != that.coreCount)
        return false;
    }

    boolean this_present_wallTimeLimit = true && this.isSetWallTimeLimit();
    boolean that_present_wallTimeLimit = true && that.isSetWallTimeLimit();
    if (this_present_wallTimeLimit || that_present_wallTimeLimit) {
      if (!(this_present_wallTimeLimit && that_present_wallTimeLimit))
        return false;
      if (this.wallTimeLimit != that.wallTimeLimit)
        return false;
    }

    boolean this_present_physicalMemory = true && this.isSetPhysicalMemory();
    boolean that_present_physicalMemory = true && that.isSetPhysicalMemory();
    if (this_present_physicalMemory || that_present_physicalMemory) {
      if (!(this_present_physicalMemory && that_present_physicalMemory))
        return false;
      if (this.physicalMemory != that.physicalMemory)
        return false;
    }

    boolean this_present_statuses = true && this.isSetStatuses();
    boolean that_present_statuses = true && that.isSetStatuses();
    if (this_present_statuses || that_present_statuses) {
      if (!(this_present_statuses && that_present_statuses))
        return false;
      if (!this.statuses.equals(that.statuses))
        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_createdAt = true && this.isSetCreatedAt();
    boolean that_present_createdAt = true && that.isSetCreatedAt();
    if (this_present_createdAt || that_present_createdAt) {
      if (!(this_present_createdAt && that_present_createdAt))
        return false;
      if (this.createdAt != that.createdAt)
        return false;
    }

    boolean this_present_updatedAt = true && this.isSetUpdatedAt();
    boolean that_present_updatedAt = true && that.isSetUpdatedAt();
    if (this_present_updatedAt || that_present_updatedAt) {
      if (!(this_present_updatedAt && that_present_updatedAt))
        return false;
      if (this.updatedAt != that.updatedAt)
        return false;
    }

    return true;
  }

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

    hashCode = hashCode * 8191 + ((isSetId()) ? 131071 : 524287);
    if (isSetId())
      hashCode = hashCode * 8191 + id.hashCode();

    hashCode = hashCode * 8191 + ((isSetProcessId()) ? 131071 : 524287);
    if (isSetProcessId())
      hashCode = hashCode * 8191 + processId.hashCode();

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

    hashCode = hashCode * 8191 + ((isSetComputeResourceId()) ? 131071 : 524287);
    if (isSetComputeResourceId())
      hashCode = hashCode * 8191 + computeResourceId.hashCode();

    hashCode = hashCode * 8191 + ((isSetQueueName()) ? 131071 : 524287);
    if (isSetQueueName())
      hashCode = hashCode * 8191 + queueName.hashCode();

    hashCode = hashCode * 8191 + ((isSetNodeCount()) ? 131071 : 524287);
    if (isSetNodeCount())
      hashCode = hashCode * 8191 + nodeCount;

    hashCode = hashCode * 8191 + ((isSetCoreCount()) ? 131071 : 524287);
    if (isSetCoreCount())
      hashCode = hashCode * 8191 + coreCount;

    hashCode = hashCode * 8191 + ((isSetWallTimeLimit()) ? 131071 : 524287);
    if (isSetWallTimeLimit())
      hashCode = hashCode * 8191 + wallTimeLimit;

    hashCode = hashCode * 8191 + ((isSetPhysicalMemory()) ? 131071 : 524287);
    if (isSetPhysicalMemory())
      hashCode = hashCode * 8191 + physicalMemory;

    hashCode = hashCode * 8191 + ((isSetStatuses()) ? 131071 : 524287);
    if (isSetStatuses())
      hashCode = hashCode * 8191 + statuses.hashCode();

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

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

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

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(isSetId()).compareTo(other.isSetId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.id, other.id);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetProcessId()).compareTo(other.isSetProcessId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetProcessId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.processId, other.processId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetApplicationInterfaceId()).compareTo(other.isSetApplicationInterfaceId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetApplicationInterfaceId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationInterfaceId, other.applicationInterfaceId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetComputeResourceId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetQueueName()).compareTo(other.isSetQueueName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetQueueName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.queueName, other.queueName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetNodeCount()).compareTo(other.isSetNodeCount());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetNodeCount()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.nodeCount, other.nodeCount);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetCoreCount()).compareTo(other.isSetCoreCount());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetCoreCount()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.coreCount, other.coreCount);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetWallTimeLimit()).compareTo(other.isSetWallTimeLimit());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetWallTimeLimit()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.wallTimeLimit, other.wallTimeLimit);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetPhysicalMemory()).compareTo(other.isSetPhysicalMemory());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetPhysicalMemory()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.physicalMemory, other.physicalMemory);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetStatuses()).compareTo(other.isSetStatuses());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetStatuses()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.statuses, other.statuses);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetErrors()).compareTo(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.valueOf(isSetCreatedAt()).compareTo(other.isSetCreatedAt());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetCreatedAt()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.createdAt, other.createdAt);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetUpdatedAt()).compareTo(other.isSetUpdatedAt());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetUpdatedAt()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.updatedAt, other.updatedAt);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

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

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

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

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

    sb.append("id:");
    if (this.id == null) {
      sb.append("null");
    } else {
      sb.append(this.id);
    }
    first = false;
    if (isSetProcessId()) {
      if (!first) sb.append(", ");
      sb.append("processId:");
      if (this.processId == null) {
        sb.append("null");
      } else {
        sb.append(this.processId);
      }
      first = false;
    }
    if (isSetApplicationInterfaceId()) {
      if (!first) sb.append(", ");
      sb.append("applicationInterfaceId:");
      if (this.applicationInterfaceId == null) {
        sb.append("null");
      } else {
        sb.append(this.applicationInterfaceId);
      }
      first = false;
    }
    if (isSetComputeResourceId()) {
      if (!first) sb.append(", ");
      sb.append("computeResourceId:");
      if (this.computeResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceId);
      }
      first = false;
    }
    if (isSetQueueName()) {
      if (!first) sb.append(", ");
      sb.append("queueName:");
      if (this.queueName == null) {
        sb.append("null");
      } else {
        sb.append(this.queueName);
      }
      first = false;
    }
    if (isSetNodeCount()) {
      if (!first) sb.append(", ");
      sb.append("nodeCount:");
      sb.append(this.nodeCount);
      first = false;
    }
    if (isSetCoreCount()) {
      if (!first) sb.append(", ");
      sb.append("coreCount:");
      sb.append(this.coreCount);
      first = false;
    }
    if (isSetWallTimeLimit()) {
      if (!first) sb.append(", ");
      sb.append("wallTimeLimit:");
      sb.append(this.wallTimeLimit);
      first = false;
    }
    if (isSetPhysicalMemory()) {
      if (!first) sb.append(", ");
      sb.append("physicalMemory:");
      sb.append(this.physicalMemory);
      first = false;
    }
    if (isSetStatuses()) {
      if (!first) sb.append(", ");
      sb.append("statuses:");
      if (this.statuses == null) {
        sb.append("null");
      } else {
        sb.append(this.statuses);
      }
      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 (isSetCreatedAt()) {
      if (!first) sb.append(", ");
      sb.append("createdAt:");
      sb.append(this.createdAt);
      first = false;
    }
    if (isSetUpdatedAt()) {
      if (!first) sb.append(", ");
      sb.append("updatedAt:");
      sb.append(this.updatedAt);
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

    // check for sub-struct validity
  }

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

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

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

  private static class WorkflowApplicationStandardScheme extends org.apache.thrift.scheme.StandardScheme<WorkflowApplication> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, WorkflowApplication 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: // ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.id = iprot.readString();
              struct.setIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // PROCESS_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.processId = iprot.readString();
              struct.setProcessIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // APPLICATION_INTERFACE_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.applicationInterfaceId = iprot.readString();
              struct.setApplicationInterfaceIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // COMPUTE_RESOURCE_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.computeResourceId = iprot.readString();
              struct.setComputeResourceIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // QUEUE_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.queueName = iprot.readString();
              struct.setQueueNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // NODE_COUNT
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.nodeCount = iprot.readI32();
              struct.setNodeCountIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // CORE_COUNT
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.coreCount = iprot.readI32();
              struct.setCoreCountIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // WALL_TIME_LIMIT
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.wallTimeLimit = iprot.readI32();
              struct.setWallTimeLimitIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // PHYSICAL_MEMORY
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.physicalMemory = iprot.readI32();
              struct.setPhysicalMemoryIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // STATUSES
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list0 = iprot.readListBegin();
                struct.statuses = new java.util.ArrayList<ApplicationStatus>(_list0.size);
                ApplicationStatus _elem1;
                for (int _i2 = 0; _i2 < _list0.size; ++_i2)
                {
                  _elem1 = new ApplicationStatus();
                  _elem1.read(iprot);
                  struct.statuses.add(_elem1);
                }
                iprot.readListEnd();
              }
              struct.setStatusesIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 11: // ERRORS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list3 = iprot.readListBegin();
                struct.errors = new java.util.ArrayList<org.apache.airavata.model.commons.ErrorModel>(_list3.size);
                org.apache.airavata.model.commons.ErrorModel _elem4;
                for (int _i5 = 0; _i5 < _list3.size; ++_i5)
                {
                  _elem4 = new org.apache.airavata.model.commons.ErrorModel();
                  _elem4.read(iprot);
                  struct.errors.add(_elem4);
                }
                iprot.readListEnd();
              }
              struct.setErrorsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 12: // CREATED_AT
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.createdAt = iprot.readI64();
              struct.setCreatedAtIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 13: // UPDATED_AT
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.updatedAt = iprot.readI64();
              struct.setUpdatedAtIsSet(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, WorkflowApplication struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.id != null) {
        oprot.writeFieldBegin(ID_FIELD_DESC);
        oprot.writeString(struct.id);
        oprot.writeFieldEnd();
      }
      if (struct.processId != null) {
        if (struct.isSetProcessId()) {
          oprot.writeFieldBegin(PROCESS_ID_FIELD_DESC);
          oprot.writeString(struct.processId);
          oprot.writeFieldEnd();
        }
      }
      if (struct.applicationInterfaceId != null) {
        if (struct.isSetApplicationInterfaceId()) {
          oprot.writeFieldBegin(APPLICATION_INTERFACE_ID_FIELD_DESC);
          oprot.writeString(struct.applicationInterfaceId);
          oprot.writeFieldEnd();
        }
      }
      if (struct.computeResourceId != null) {
        if (struct.isSetComputeResourceId()) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.computeResourceId);
          oprot.writeFieldEnd();
        }
      }
      if (struct.queueName != null) {
        if (struct.isSetQueueName()) {
          oprot.writeFieldBegin(QUEUE_NAME_FIELD_DESC);
          oprot.writeString(struct.queueName);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetNodeCount()) {
        oprot.writeFieldBegin(NODE_COUNT_FIELD_DESC);
        oprot.writeI32(struct.nodeCount);
        oprot.writeFieldEnd();
      }
      if (struct.isSetCoreCount()) {
        oprot.writeFieldBegin(CORE_COUNT_FIELD_DESC);
        oprot.writeI32(struct.coreCount);
        oprot.writeFieldEnd();
      }
      if (struct.isSetWallTimeLimit()) {
        oprot.writeFieldBegin(WALL_TIME_LIMIT_FIELD_DESC);
        oprot.writeI32(struct.wallTimeLimit);
        oprot.writeFieldEnd();
      }
      if (struct.isSetPhysicalMemory()) {
        oprot.writeFieldBegin(PHYSICAL_MEMORY_FIELD_DESC);
        oprot.writeI32(struct.physicalMemory);
        oprot.writeFieldEnd();
      }
      if (struct.statuses != null) {
        if (struct.isSetStatuses()) {
          oprot.writeFieldBegin(STATUSES_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.statuses.size()));
            for (ApplicationStatus _iter6 : struct.statuses)
            {
              _iter6.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 _iter7 : struct.errors)
            {
              _iter7.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetCreatedAt()) {
        oprot.writeFieldBegin(CREATED_AT_FIELD_DESC);
        oprot.writeI64(struct.createdAt);
        oprot.writeFieldEnd();
      }
      if (struct.isSetUpdatedAt()) {
        oprot.writeFieldBegin(UPDATED_AT_FIELD_DESC);
        oprot.writeI64(struct.updatedAt);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

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

  private static class WorkflowApplicationTupleScheme extends org.apache.thrift.scheme.TupleScheme<WorkflowApplication> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, WorkflowApplication struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      oprot.writeString(struct.id);
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.isSetProcessId()) {
        optionals.set(0);
      }
      if (struct.isSetApplicationInterfaceId()) {
        optionals.set(1);
      }
      if (struct.isSetComputeResourceId()) {
        optionals.set(2);
      }
      if (struct.isSetQueueName()) {
        optionals.set(3);
      }
      if (struct.isSetNodeCount()) {
        optionals.set(4);
      }
      if (struct.isSetCoreCount()) {
        optionals.set(5);
      }
      if (struct.isSetWallTimeLimit()) {
        optionals.set(6);
      }
      if (struct.isSetPhysicalMemory()) {
        optionals.set(7);
      }
      if (struct.isSetStatuses()) {
        optionals.set(8);
      }
      if (struct.isSetErrors()) {
        optionals.set(9);
      }
      if (struct.isSetCreatedAt()) {
        optionals.set(10);
      }
      if (struct.isSetUpdatedAt()) {
        optionals.set(11);
      }
      oprot.writeBitSet(optionals, 12);
      if (struct.isSetProcessId()) {
        oprot.writeString(struct.processId);
      }
      if (struct.isSetApplicationInterfaceId()) {
        oprot.writeString(struct.applicationInterfaceId);
      }
      if (struct.isSetComputeResourceId()) {
        oprot.writeString(struct.computeResourceId);
      }
      if (struct.isSetQueueName()) {
        oprot.writeString(struct.queueName);
      }
      if (struct.isSetNodeCount()) {
        oprot.writeI32(struct.nodeCount);
      }
      if (struct.isSetCoreCount()) {
        oprot.writeI32(struct.coreCount);
      }
      if (struct.isSetWallTimeLimit()) {
        oprot.writeI32(struct.wallTimeLimit);
      }
      if (struct.isSetPhysicalMemory()) {
        oprot.writeI32(struct.physicalMemory);
      }
      if (struct.isSetStatuses()) {
        {
          oprot.writeI32(struct.statuses.size());
          for (ApplicationStatus _iter8 : struct.statuses)
          {
            _iter8.write(oprot);
          }
        }
      }
      if (struct.isSetErrors()) {
        {
          oprot.writeI32(struct.errors.size());
          for (org.apache.airavata.model.commons.ErrorModel _iter9 : struct.errors)
          {
            _iter9.write(oprot);
          }
        }
      }
      if (struct.isSetCreatedAt()) {
        oprot.writeI64(struct.createdAt);
      }
      if (struct.isSetUpdatedAt()) {
        oprot.writeI64(struct.updatedAt);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, WorkflowApplication struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      struct.id = iprot.readString();
      struct.setIdIsSet(true);
      java.util.BitSet incoming = iprot.readBitSet(12);
      if (incoming.get(0)) {
        struct.processId = iprot.readString();
        struct.setProcessIdIsSet(true);
      }
      if (incoming.get(1)) {
        struct.applicationInterfaceId = iprot.readString();
        struct.setApplicationInterfaceIdIsSet(true);
      }
      if (incoming.get(2)) {
        struct.computeResourceId = iprot.readString();
        struct.setComputeResourceIdIsSet(true);
      }
      if (incoming.get(3)) {
        struct.queueName = iprot.readString();
        struct.setQueueNameIsSet(true);
      }
      if (incoming.get(4)) {
        struct.nodeCount = iprot.readI32();
        struct.setNodeCountIsSet(true);
      }
      if (incoming.get(5)) {
        struct.coreCount = iprot.readI32();
        struct.setCoreCountIsSet(true);
      }
      if (incoming.get(6)) {
        struct.wallTimeLimit = iprot.readI32();
        struct.setWallTimeLimitIsSet(true);
      }
      if (incoming.get(7)) {
        struct.physicalMemory = iprot.readI32();
        struct.setPhysicalMemoryIsSet(true);
      }
      if (incoming.get(8)) {
        {
          org.apache.thrift.protocol.TList _list10 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.statuses = new java.util.ArrayList<ApplicationStatus>(_list10.size);
          ApplicationStatus _elem11;
          for (int _i12 = 0; _i12 < _list10.size; ++_i12)
          {
            _elem11 = new ApplicationStatus();
            _elem11.read(iprot);
            struct.statuses.add(_elem11);
          }
        }
        struct.setStatusesIsSet(true);
      }
      if (incoming.get(9)) {
        {
          org.apache.thrift.protocol.TList _list13 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.errors = new java.util.ArrayList<org.apache.airavata.model.commons.ErrorModel>(_list13.size);
          org.apache.airavata.model.commons.ErrorModel _elem14;
          for (int _i15 = 0; _i15 < _list13.size; ++_i15)
          {
            _elem14 = new org.apache.airavata.model.commons.ErrorModel();
            _elem14.read(iprot);
            struct.errors.add(_elem14);
          }
        }
        struct.setErrorsIsSet(true);
      }
      if (incoming.get(10)) {
        struct.createdAt = iprot.readI64();
        struct.setCreatedAtIsSet(true);
      }
      if (incoming.get(11)) {
        struct.updatedAt = iprot.readI64();
        struct.setUpdatedAtIsSet(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();
  }
}

