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

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

  private static final org.apache.thrift.protocol.TField ALL_EXPERIMENT_COUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("allExperimentCount", org.apache.thrift.protocol.TType.I32, (short)1);
  private static final org.apache.thrift.protocol.TField COMPLETED_EXPERIMENT_COUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("completedExperimentCount", org.apache.thrift.protocol.TType.I32, (short)2);
  private static final org.apache.thrift.protocol.TField CANCELLED_EXPERIMENT_COUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("cancelledExperimentCount", org.apache.thrift.protocol.TType.I32, (short)3);
  private static final org.apache.thrift.protocol.TField FAILED_EXPERIMENT_COUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("failedExperimentCount", org.apache.thrift.protocol.TType.I32, (short)4);
  private static final org.apache.thrift.protocol.TField CREATED_EXPERIMENT_COUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("createdExperimentCount", org.apache.thrift.protocol.TType.I32, (short)5);
  private static final org.apache.thrift.protocol.TField RUNNING_EXPERIMENT_COUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("runningExperimentCount", org.apache.thrift.protocol.TType.I32, (short)6);
  private static final org.apache.thrift.protocol.TField ALL_EXPERIMENTS_FIELD_DESC = new org.apache.thrift.protocol.TField("allExperiments", org.apache.thrift.protocol.TType.LIST, (short)7);
  private static final org.apache.thrift.protocol.TField COMPLETED_EXPERIMENTS_FIELD_DESC = new org.apache.thrift.protocol.TField("completedExperiments", org.apache.thrift.protocol.TType.LIST, (short)8);
  private static final org.apache.thrift.protocol.TField FAILED_EXPERIMENTS_FIELD_DESC = new org.apache.thrift.protocol.TField("failedExperiments", org.apache.thrift.protocol.TType.LIST, (short)9);
  private static final org.apache.thrift.protocol.TField CANCELLED_EXPERIMENTS_FIELD_DESC = new org.apache.thrift.protocol.TField("cancelledExperiments", org.apache.thrift.protocol.TType.LIST, (short)10);
  private static final org.apache.thrift.protocol.TField CREATED_EXPERIMENTS_FIELD_DESC = new org.apache.thrift.protocol.TField("createdExperiments", org.apache.thrift.protocol.TType.LIST, (short)11);
  private static final org.apache.thrift.protocol.TField RUNNING_EXPERIMENTS_FIELD_DESC = new org.apache.thrift.protocol.TField("runningExperiments", org.apache.thrift.protocol.TType.LIST, (short)12);

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

  private int allExperimentCount; // required
  private int completedExperimentCount; // required
  private int cancelledExperimentCount; // optional
  private int failedExperimentCount; // required
  private int createdExperimentCount; // required
  private int runningExperimentCount; // required
  private java.util.List<ExperimentSummaryModel> allExperiments; // required
  private java.util.List<ExperimentSummaryModel> completedExperiments; // optional
  private java.util.List<ExperimentSummaryModel> failedExperiments; // optional
  private java.util.List<ExperimentSummaryModel> cancelledExperiments; // optional
  private java.util.List<ExperimentSummaryModel> createdExperiments; // optional
  private java.util.List<ExperimentSummaryModel> runningExperiments; // 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 {
    ALL_EXPERIMENT_COUNT((short)1, "allExperimentCount"),
    COMPLETED_EXPERIMENT_COUNT((short)2, "completedExperimentCount"),
    CANCELLED_EXPERIMENT_COUNT((short)3, "cancelledExperimentCount"),
    FAILED_EXPERIMENT_COUNT((short)4, "failedExperimentCount"),
    CREATED_EXPERIMENT_COUNT((short)5, "createdExperimentCount"),
    RUNNING_EXPERIMENT_COUNT((short)6, "runningExperimentCount"),
    ALL_EXPERIMENTS((short)7, "allExperiments"),
    COMPLETED_EXPERIMENTS((short)8, "completedExperiments"),
    FAILED_EXPERIMENTS((short)9, "failedExperiments"),
    CANCELLED_EXPERIMENTS((short)10, "cancelledExperiments"),
    CREATED_EXPERIMENTS((short)11, "createdExperiments"),
    RUNNING_EXPERIMENTS((short)12, "runningExperiments");

    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: // ALL_EXPERIMENT_COUNT
          return ALL_EXPERIMENT_COUNT;
        case 2: // COMPLETED_EXPERIMENT_COUNT
          return COMPLETED_EXPERIMENT_COUNT;
        case 3: // CANCELLED_EXPERIMENT_COUNT
          return CANCELLED_EXPERIMENT_COUNT;
        case 4: // FAILED_EXPERIMENT_COUNT
          return FAILED_EXPERIMENT_COUNT;
        case 5: // CREATED_EXPERIMENT_COUNT
          return CREATED_EXPERIMENT_COUNT;
        case 6: // RUNNING_EXPERIMENT_COUNT
          return RUNNING_EXPERIMENT_COUNT;
        case 7: // ALL_EXPERIMENTS
          return ALL_EXPERIMENTS;
        case 8: // COMPLETED_EXPERIMENTS
          return COMPLETED_EXPERIMENTS;
        case 9: // FAILED_EXPERIMENTS
          return FAILED_EXPERIMENTS;
        case 10: // CANCELLED_EXPERIMENTS
          return CANCELLED_EXPERIMENTS;
        case 11: // CREATED_EXPERIMENTS
          return CREATED_EXPERIMENTS;
        case 12: // RUNNING_EXPERIMENTS
          return RUNNING_EXPERIMENTS;
        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 __ALLEXPERIMENTCOUNT_ISSET_ID = 0;
  private static final int __COMPLETEDEXPERIMENTCOUNT_ISSET_ID = 1;
  private static final int __CANCELLEDEXPERIMENTCOUNT_ISSET_ID = 2;
  private static final int __FAILEDEXPERIMENTCOUNT_ISSET_ID = 3;
  private static final int __CREATEDEXPERIMENTCOUNT_ISSET_ID = 4;
  private static final int __RUNNINGEXPERIMENTCOUNT_ISSET_ID = 5;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.CANCELLED_EXPERIMENT_COUNT,_Fields.COMPLETED_EXPERIMENTS,_Fields.FAILED_EXPERIMENTS,_Fields.CANCELLED_EXPERIMENTS,_Fields.CREATED_EXPERIMENTS,_Fields.RUNNING_EXPERIMENTS};
  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.ALL_EXPERIMENT_COUNT, new org.apache.thrift.meta_data.FieldMetaData("allExperimentCount", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.COMPLETED_EXPERIMENT_COUNT, new org.apache.thrift.meta_data.FieldMetaData("completedExperimentCount", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.CANCELLED_EXPERIMENT_COUNT, new org.apache.thrift.meta_data.FieldMetaData("cancelledExperimentCount", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.FAILED_EXPERIMENT_COUNT, new org.apache.thrift.meta_data.FieldMetaData("failedExperimentCount", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.CREATED_EXPERIMENT_COUNT, new org.apache.thrift.meta_data.FieldMetaData("createdExperimentCount", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.RUNNING_EXPERIMENT_COUNT, new org.apache.thrift.meta_data.FieldMetaData("runningExperimentCount", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.ALL_EXPERIMENTS, new org.apache.thrift.meta_data.FieldMetaData("allExperiments", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        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, ExperimentSummaryModel.class))));
    tmpMap.put(_Fields.COMPLETED_EXPERIMENTS, new org.apache.thrift.meta_data.FieldMetaData("completedExperiments", 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, ExperimentSummaryModel.class))));
    tmpMap.put(_Fields.FAILED_EXPERIMENTS, new org.apache.thrift.meta_data.FieldMetaData("failedExperiments", 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, ExperimentSummaryModel.class))));
    tmpMap.put(_Fields.CANCELLED_EXPERIMENTS, new org.apache.thrift.meta_data.FieldMetaData("cancelledExperiments", 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, ExperimentSummaryModel.class))));
    tmpMap.put(_Fields.CREATED_EXPERIMENTS, new org.apache.thrift.meta_data.FieldMetaData("createdExperiments", 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, ExperimentSummaryModel.class))));
    tmpMap.put(_Fields.RUNNING_EXPERIMENTS, new org.apache.thrift.meta_data.FieldMetaData("runningExperiments", 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, ExperimentSummaryModel.class))));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ExperimentStatistics.class, metaDataMap);
  }

  public ExperimentStatistics() {
  }

  public ExperimentStatistics(
    int allExperimentCount,
    int completedExperimentCount,
    int failedExperimentCount,
    int createdExperimentCount,
    int runningExperimentCount,
    java.util.List<ExperimentSummaryModel> allExperiments)
  {
    this();
    this.allExperimentCount = allExperimentCount;
    setAllExperimentCountIsSet(true);
    this.completedExperimentCount = completedExperimentCount;
    setCompletedExperimentCountIsSet(true);
    this.failedExperimentCount = failedExperimentCount;
    setFailedExperimentCountIsSet(true);
    this.createdExperimentCount = createdExperimentCount;
    setCreatedExperimentCountIsSet(true);
    this.runningExperimentCount = runningExperimentCount;
    setRunningExperimentCountIsSet(true);
    this.allExperiments = allExperiments;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public ExperimentStatistics(ExperimentStatistics other) {
    __isset_bitfield = other.__isset_bitfield;
    this.allExperimentCount = other.allExperimentCount;
    this.completedExperimentCount = other.completedExperimentCount;
    this.cancelledExperimentCount = other.cancelledExperimentCount;
    this.failedExperimentCount = other.failedExperimentCount;
    this.createdExperimentCount = other.createdExperimentCount;
    this.runningExperimentCount = other.runningExperimentCount;
    if (other.isSetAllExperiments()) {
      java.util.List<ExperimentSummaryModel> __this__allExperiments = new java.util.ArrayList<ExperimentSummaryModel>(other.allExperiments.size());
      for (ExperimentSummaryModel other_element : other.allExperiments) {
        __this__allExperiments.add(new ExperimentSummaryModel(other_element));
      }
      this.allExperiments = __this__allExperiments;
    }
    if (other.isSetCompletedExperiments()) {
      java.util.List<ExperimentSummaryModel> __this__completedExperiments = new java.util.ArrayList<ExperimentSummaryModel>(other.completedExperiments.size());
      for (ExperimentSummaryModel other_element : other.completedExperiments) {
        __this__completedExperiments.add(new ExperimentSummaryModel(other_element));
      }
      this.completedExperiments = __this__completedExperiments;
    }
    if (other.isSetFailedExperiments()) {
      java.util.List<ExperimentSummaryModel> __this__failedExperiments = new java.util.ArrayList<ExperimentSummaryModel>(other.failedExperiments.size());
      for (ExperimentSummaryModel other_element : other.failedExperiments) {
        __this__failedExperiments.add(new ExperimentSummaryModel(other_element));
      }
      this.failedExperiments = __this__failedExperiments;
    }
    if (other.isSetCancelledExperiments()) {
      java.util.List<ExperimentSummaryModel> __this__cancelledExperiments = new java.util.ArrayList<ExperimentSummaryModel>(other.cancelledExperiments.size());
      for (ExperimentSummaryModel other_element : other.cancelledExperiments) {
        __this__cancelledExperiments.add(new ExperimentSummaryModel(other_element));
      }
      this.cancelledExperiments = __this__cancelledExperiments;
    }
    if (other.isSetCreatedExperiments()) {
      java.util.List<ExperimentSummaryModel> __this__createdExperiments = new java.util.ArrayList<ExperimentSummaryModel>(other.createdExperiments.size());
      for (ExperimentSummaryModel other_element : other.createdExperiments) {
        __this__createdExperiments.add(new ExperimentSummaryModel(other_element));
      }
      this.createdExperiments = __this__createdExperiments;
    }
    if (other.isSetRunningExperiments()) {
      java.util.List<ExperimentSummaryModel> __this__runningExperiments = new java.util.ArrayList<ExperimentSummaryModel>(other.runningExperiments.size());
      for (ExperimentSummaryModel other_element : other.runningExperiments) {
        __this__runningExperiments.add(new ExperimentSummaryModel(other_element));
      }
      this.runningExperiments = __this__runningExperiments;
    }
  }

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

  @Override
  public void clear() {
    setAllExperimentCountIsSet(false);
    this.allExperimentCount = 0;
    setCompletedExperimentCountIsSet(false);
    this.completedExperimentCount = 0;
    setCancelledExperimentCountIsSet(false);
    this.cancelledExperimentCount = 0;
    setFailedExperimentCountIsSet(false);
    this.failedExperimentCount = 0;
    setCreatedExperimentCountIsSet(false);
    this.createdExperimentCount = 0;
    setRunningExperimentCountIsSet(false);
    this.runningExperimentCount = 0;
    this.allExperiments = null;
    this.completedExperiments = null;
    this.failedExperiments = null;
    this.cancelledExperiments = null;
    this.createdExperiments = null;
    this.runningExperiments = null;
  }

  public int getAllExperimentCount() {
    return this.allExperimentCount;
  }

  public void setAllExperimentCount(int allExperimentCount) {
    this.allExperimentCount = allExperimentCount;
    setAllExperimentCountIsSet(true);
  }

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

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

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

  public int getCompletedExperimentCount() {
    return this.completedExperimentCount;
  }

  public void setCompletedExperimentCount(int completedExperimentCount) {
    this.completedExperimentCount = completedExperimentCount;
    setCompletedExperimentCountIsSet(true);
  }

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

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

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

  public int getCancelledExperimentCount() {
    return this.cancelledExperimentCount;
  }

  public void setCancelledExperimentCount(int cancelledExperimentCount) {
    this.cancelledExperimentCount = cancelledExperimentCount;
    setCancelledExperimentCountIsSet(true);
  }

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

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

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

  public int getFailedExperimentCount() {
    return this.failedExperimentCount;
  }

  public void setFailedExperimentCount(int failedExperimentCount) {
    this.failedExperimentCount = failedExperimentCount;
    setFailedExperimentCountIsSet(true);
  }

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

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

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

  public int getCreatedExperimentCount() {
    return this.createdExperimentCount;
  }

  public void setCreatedExperimentCount(int createdExperimentCount) {
    this.createdExperimentCount = createdExperimentCount;
    setCreatedExperimentCountIsSet(true);
  }

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

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

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

  public int getRunningExperimentCount() {
    return this.runningExperimentCount;
  }

  public void setRunningExperimentCount(int runningExperimentCount) {
    this.runningExperimentCount = runningExperimentCount;
    setRunningExperimentCountIsSet(true);
  }

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

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

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

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

  public java.util.Iterator<ExperimentSummaryModel> getAllExperimentsIterator() {
    return (this.allExperiments == null) ? null : this.allExperiments.iterator();
  }

  public void addToAllExperiments(ExperimentSummaryModel elem) {
    if (this.allExperiments == null) {
      this.allExperiments = new java.util.ArrayList<ExperimentSummaryModel>();
    }
    this.allExperiments.add(elem);
  }

  public java.util.List<ExperimentSummaryModel> getAllExperiments() {
    return this.allExperiments;
  }

  public void setAllExperiments(java.util.List<ExperimentSummaryModel> allExperiments) {
    this.allExperiments = allExperiments;
  }

  public void unsetAllExperiments() {
    this.allExperiments = null;
  }

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

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

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

  public java.util.Iterator<ExperimentSummaryModel> getCompletedExperimentsIterator() {
    return (this.completedExperiments == null) ? null : this.completedExperiments.iterator();
  }

  public void addToCompletedExperiments(ExperimentSummaryModel elem) {
    if (this.completedExperiments == null) {
      this.completedExperiments = new java.util.ArrayList<ExperimentSummaryModel>();
    }
    this.completedExperiments.add(elem);
  }

  public java.util.List<ExperimentSummaryModel> getCompletedExperiments() {
    return this.completedExperiments;
  }

  public void setCompletedExperiments(java.util.List<ExperimentSummaryModel> completedExperiments) {
    this.completedExperiments = completedExperiments;
  }

  public void unsetCompletedExperiments() {
    this.completedExperiments = null;
  }

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

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

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

  public java.util.Iterator<ExperimentSummaryModel> getFailedExperimentsIterator() {
    return (this.failedExperiments == null) ? null : this.failedExperiments.iterator();
  }

  public void addToFailedExperiments(ExperimentSummaryModel elem) {
    if (this.failedExperiments == null) {
      this.failedExperiments = new java.util.ArrayList<ExperimentSummaryModel>();
    }
    this.failedExperiments.add(elem);
  }

  public java.util.List<ExperimentSummaryModel> getFailedExperiments() {
    return this.failedExperiments;
  }

  public void setFailedExperiments(java.util.List<ExperimentSummaryModel> failedExperiments) {
    this.failedExperiments = failedExperiments;
  }

  public void unsetFailedExperiments() {
    this.failedExperiments = null;
  }

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

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

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

  public java.util.Iterator<ExperimentSummaryModel> getCancelledExperimentsIterator() {
    return (this.cancelledExperiments == null) ? null : this.cancelledExperiments.iterator();
  }

  public void addToCancelledExperiments(ExperimentSummaryModel elem) {
    if (this.cancelledExperiments == null) {
      this.cancelledExperiments = new java.util.ArrayList<ExperimentSummaryModel>();
    }
    this.cancelledExperiments.add(elem);
  }

  public java.util.List<ExperimentSummaryModel> getCancelledExperiments() {
    return this.cancelledExperiments;
  }

  public void setCancelledExperiments(java.util.List<ExperimentSummaryModel> cancelledExperiments) {
    this.cancelledExperiments = cancelledExperiments;
  }

  public void unsetCancelledExperiments() {
    this.cancelledExperiments = null;
  }

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

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

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

  public java.util.Iterator<ExperimentSummaryModel> getCreatedExperimentsIterator() {
    return (this.createdExperiments == null) ? null : this.createdExperiments.iterator();
  }

  public void addToCreatedExperiments(ExperimentSummaryModel elem) {
    if (this.createdExperiments == null) {
      this.createdExperiments = new java.util.ArrayList<ExperimentSummaryModel>();
    }
    this.createdExperiments.add(elem);
  }

  public java.util.List<ExperimentSummaryModel> getCreatedExperiments() {
    return this.createdExperiments;
  }

  public void setCreatedExperiments(java.util.List<ExperimentSummaryModel> createdExperiments) {
    this.createdExperiments = createdExperiments;
  }

  public void unsetCreatedExperiments() {
    this.createdExperiments = null;
  }

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

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

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

  public java.util.Iterator<ExperimentSummaryModel> getRunningExperimentsIterator() {
    return (this.runningExperiments == null) ? null : this.runningExperiments.iterator();
  }

  public void addToRunningExperiments(ExperimentSummaryModel elem) {
    if (this.runningExperiments == null) {
      this.runningExperiments = new java.util.ArrayList<ExperimentSummaryModel>();
    }
    this.runningExperiments.add(elem);
  }

  public java.util.List<ExperimentSummaryModel> getRunningExperiments() {
    return this.runningExperiments;
  }

  public void setRunningExperiments(java.util.List<ExperimentSummaryModel> runningExperiments) {
    this.runningExperiments = runningExperiments;
  }

  public void unsetRunningExperiments() {
    this.runningExperiments = null;
  }

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

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

  public void setFieldValue(_Fields field, java.lang.Object value) {
    switch (field) {
    case ALL_EXPERIMENT_COUNT:
      if (value == null) {
        unsetAllExperimentCount();
      } else {
        setAllExperimentCount((java.lang.Integer)value);
      }
      break;

    case COMPLETED_EXPERIMENT_COUNT:
      if (value == null) {
        unsetCompletedExperimentCount();
      } else {
        setCompletedExperimentCount((java.lang.Integer)value);
      }
      break;

    case CANCELLED_EXPERIMENT_COUNT:
      if (value == null) {
        unsetCancelledExperimentCount();
      } else {
        setCancelledExperimentCount((java.lang.Integer)value);
      }
      break;

    case FAILED_EXPERIMENT_COUNT:
      if (value == null) {
        unsetFailedExperimentCount();
      } else {
        setFailedExperimentCount((java.lang.Integer)value);
      }
      break;

    case CREATED_EXPERIMENT_COUNT:
      if (value == null) {
        unsetCreatedExperimentCount();
      } else {
        setCreatedExperimentCount((java.lang.Integer)value);
      }
      break;

    case RUNNING_EXPERIMENT_COUNT:
      if (value == null) {
        unsetRunningExperimentCount();
      } else {
        setRunningExperimentCount((java.lang.Integer)value);
      }
      break;

    case ALL_EXPERIMENTS:
      if (value == null) {
        unsetAllExperiments();
      } else {
        setAllExperiments((java.util.List<ExperimentSummaryModel>)value);
      }
      break;

    case COMPLETED_EXPERIMENTS:
      if (value == null) {
        unsetCompletedExperiments();
      } else {
        setCompletedExperiments((java.util.List<ExperimentSummaryModel>)value);
      }
      break;

    case FAILED_EXPERIMENTS:
      if (value == null) {
        unsetFailedExperiments();
      } else {
        setFailedExperiments((java.util.List<ExperimentSummaryModel>)value);
      }
      break;

    case CANCELLED_EXPERIMENTS:
      if (value == null) {
        unsetCancelledExperiments();
      } else {
        setCancelledExperiments((java.util.List<ExperimentSummaryModel>)value);
      }
      break;

    case CREATED_EXPERIMENTS:
      if (value == null) {
        unsetCreatedExperiments();
      } else {
        setCreatedExperiments((java.util.List<ExperimentSummaryModel>)value);
      }
      break;

    case RUNNING_EXPERIMENTS:
      if (value == null) {
        unsetRunningExperiments();
      } else {
        setRunningExperiments((java.util.List<ExperimentSummaryModel>)value);
      }
      break;

    }
  }

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

    case COMPLETED_EXPERIMENT_COUNT:
      return getCompletedExperimentCount();

    case CANCELLED_EXPERIMENT_COUNT:
      return getCancelledExperimentCount();

    case FAILED_EXPERIMENT_COUNT:
      return getFailedExperimentCount();

    case CREATED_EXPERIMENT_COUNT:
      return getCreatedExperimentCount();

    case RUNNING_EXPERIMENT_COUNT:
      return getRunningExperimentCount();

    case ALL_EXPERIMENTS:
      return getAllExperiments();

    case COMPLETED_EXPERIMENTS:
      return getCompletedExperiments();

    case FAILED_EXPERIMENTS:
      return getFailedExperiments();

    case CANCELLED_EXPERIMENTS:
      return getCancelledExperiments();

    case CREATED_EXPERIMENTS:
      return getCreatedExperiments();

    case RUNNING_EXPERIMENTS:
      return getRunningExperiments();

    }
    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 ALL_EXPERIMENT_COUNT:
      return isSetAllExperimentCount();
    case COMPLETED_EXPERIMENT_COUNT:
      return isSetCompletedExperimentCount();
    case CANCELLED_EXPERIMENT_COUNT:
      return isSetCancelledExperimentCount();
    case FAILED_EXPERIMENT_COUNT:
      return isSetFailedExperimentCount();
    case CREATED_EXPERIMENT_COUNT:
      return isSetCreatedExperimentCount();
    case RUNNING_EXPERIMENT_COUNT:
      return isSetRunningExperimentCount();
    case ALL_EXPERIMENTS:
      return isSetAllExperiments();
    case COMPLETED_EXPERIMENTS:
      return isSetCompletedExperiments();
    case FAILED_EXPERIMENTS:
      return isSetFailedExperiments();
    case CANCELLED_EXPERIMENTS:
      return isSetCancelledExperiments();
    case CREATED_EXPERIMENTS:
      return isSetCreatedExperiments();
    case RUNNING_EXPERIMENTS:
      return isSetRunningExperiments();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_allExperimentCount = true;
    boolean that_present_allExperimentCount = true;
    if (this_present_allExperimentCount || that_present_allExperimentCount) {
      if (!(this_present_allExperimentCount && that_present_allExperimentCount))
        return false;
      if (this.allExperimentCount != that.allExperimentCount)
        return false;
    }

    boolean this_present_completedExperimentCount = true;
    boolean that_present_completedExperimentCount = true;
    if (this_present_completedExperimentCount || that_present_completedExperimentCount) {
      if (!(this_present_completedExperimentCount && that_present_completedExperimentCount))
        return false;
      if (this.completedExperimentCount != that.completedExperimentCount)
        return false;
    }

    boolean this_present_cancelledExperimentCount = true && this.isSetCancelledExperimentCount();
    boolean that_present_cancelledExperimentCount = true && that.isSetCancelledExperimentCount();
    if (this_present_cancelledExperimentCount || that_present_cancelledExperimentCount) {
      if (!(this_present_cancelledExperimentCount && that_present_cancelledExperimentCount))
        return false;
      if (this.cancelledExperimentCount != that.cancelledExperimentCount)
        return false;
    }

    boolean this_present_failedExperimentCount = true;
    boolean that_present_failedExperimentCount = true;
    if (this_present_failedExperimentCount || that_present_failedExperimentCount) {
      if (!(this_present_failedExperimentCount && that_present_failedExperimentCount))
        return false;
      if (this.failedExperimentCount != that.failedExperimentCount)
        return false;
    }

    boolean this_present_createdExperimentCount = true;
    boolean that_present_createdExperimentCount = true;
    if (this_present_createdExperimentCount || that_present_createdExperimentCount) {
      if (!(this_present_createdExperimentCount && that_present_createdExperimentCount))
        return false;
      if (this.createdExperimentCount != that.createdExperimentCount)
        return false;
    }

    boolean this_present_runningExperimentCount = true;
    boolean that_present_runningExperimentCount = true;
    if (this_present_runningExperimentCount || that_present_runningExperimentCount) {
      if (!(this_present_runningExperimentCount && that_present_runningExperimentCount))
        return false;
      if (this.runningExperimentCount != that.runningExperimentCount)
        return false;
    }

    boolean this_present_allExperiments = true && this.isSetAllExperiments();
    boolean that_present_allExperiments = true && that.isSetAllExperiments();
    if (this_present_allExperiments || that_present_allExperiments) {
      if (!(this_present_allExperiments && that_present_allExperiments))
        return false;
      if (!this.allExperiments.equals(that.allExperiments))
        return false;
    }

    boolean this_present_completedExperiments = true && this.isSetCompletedExperiments();
    boolean that_present_completedExperiments = true && that.isSetCompletedExperiments();
    if (this_present_completedExperiments || that_present_completedExperiments) {
      if (!(this_present_completedExperiments && that_present_completedExperiments))
        return false;
      if (!this.completedExperiments.equals(that.completedExperiments))
        return false;
    }

    boolean this_present_failedExperiments = true && this.isSetFailedExperiments();
    boolean that_present_failedExperiments = true && that.isSetFailedExperiments();
    if (this_present_failedExperiments || that_present_failedExperiments) {
      if (!(this_present_failedExperiments && that_present_failedExperiments))
        return false;
      if (!this.failedExperiments.equals(that.failedExperiments))
        return false;
    }

    boolean this_present_cancelledExperiments = true && this.isSetCancelledExperiments();
    boolean that_present_cancelledExperiments = true && that.isSetCancelledExperiments();
    if (this_present_cancelledExperiments || that_present_cancelledExperiments) {
      if (!(this_present_cancelledExperiments && that_present_cancelledExperiments))
        return false;
      if (!this.cancelledExperiments.equals(that.cancelledExperiments))
        return false;
    }

    boolean this_present_createdExperiments = true && this.isSetCreatedExperiments();
    boolean that_present_createdExperiments = true && that.isSetCreatedExperiments();
    if (this_present_createdExperiments || that_present_createdExperiments) {
      if (!(this_present_createdExperiments && that_present_createdExperiments))
        return false;
      if (!this.createdExperiments.equals(that.createdExperiments))
        return false;
    }

    boolean this_present_runningExperiments = true && this.isSetRunningExperiments();
    boolean that_present_runningExperiments = true && that.isSetRunningExperiments();
    if (this_present_runningExperiments || that_present_runningExperiments) {
      if (!(this_present_runningExperiments && that_present_runningExperiments))
        return false;
      if (!this.runningExperiments.equals(that.runningExperiments))
        return false;
    }

    return true;
  }

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

    hashCode = hashCode * 8191 + allExperimentCount;

    hashCode = hashCode * 8191 + completedExperimentCount;

    hashCode = hashCode * 8191 + ((isSetCancelledExperimentCount()) ? 131071 : 524287);
    if (isSetCancelledExperimentCount())
      hashCode = hashCode * 8191 + cancelledExperimentCount;

    hashCode = hashCode * 8191 + failedExperimentCount;

    hashCode = hashCode * 8191 + createdExperimentCount;

    hashCode = hashCode * 8191 + runningExperimentCount;

    hashCode = hashCode * 8191 + ((isSetAllExperiments()) ? 131071 : 524287);
    if (isSetAllExperiments())
      hashCode = hashCode * 8191 + allExperiments.hashCode();

    hashCode = hashCode * 8191 + ((isSetCompletedExperiments()) ? 131071 : 524287);
    if (isSetCompletedExperiments())
      hashCode = hashCode * 8191 + completedExperiments.hashCode();

    hashCode = hashCode * 8191 + ((isSetFailedExperiments()) ? 131071 : 524287);
    if (isSetFailedExperiments())
      hashCode = hashCode * 8191 + failedExperiments.hashCode();

    hashCode = hashCode * 8191 + ((isSetCancelledExperiments()) ? 131071 : 524287);
    if (isSetCancelledExperiments())
      hashCode = hashCode * 8191 + cancelledExperiments.hashCode();

    hashCode = hashCode * 8191 + ((isSetCreatedExperiments()) ? 131071 : 524287);
    if (isSetCreatedExperiments())
      hashCode = hashCode * 8191 + createdExperiments.hashCode();

    hashCode = hashCode * 8191 + ((isSetRunningExperiments()) ? 131071 : 524287);
    if (isSetRunningExperiments())
      hashCode = hashCode * 8191 + runningExperiments.hashCode();

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(isSetAllExperimentCount()).compareTo(other.isSetAllExperimentCount());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetAllExperimentCount()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.allExperimentCount, other.allExperimentCount);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetCompletedExperimentCount()).compareTo(other.isSetCompletedExperimentCount());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetCompletedExperimentCount()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.completedExperimentCount, other.completedExperimentCount);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetCancelledExperimentCount()).compareTo(other.isSetCancelledExperimentCount());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetCancelledExperimentCount()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cancelledExperimentCount, other.cancelledExperimentCount);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetFailedExperimentCount()).compareTo(other.isSetFailedExperimentCount());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetFailedExperimentCount()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.failedExperimentCount, other.failedExperimentCount);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetCreatedExperimentCount()).compareTo(other.isSetCreatedExperimentCount());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetCreatedExperimentCount()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.createdExperimentCount, other.createdExperimentCount);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetRunningExperimentCount()).compareTo(other.isSetRunningExperimentCount());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetRunningExperimentCount()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.runningExperimentCount, other.runningExperimentCount);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetAllExperiments()).compareTo(other.isSetAllExperiments());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetAllExperiments()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.allExperiments, other.allExperiments);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetCompletedExperiments()).compareTo(other.isSetCompletedExperiments());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetCompletedExperiments()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.completedExperiments, other.completedExperiments);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetFailedExperiments()).compareTo(other.isSetFailedExperiments());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetFailedExperiments()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.failedExperiments, other.failedExperiments);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetCancelledExperiments()).compareTo(other.isSetCancelledExperiments());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetCancelledExperiments()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cancelledExperiments, other.cancelledExperiments);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetCreatedExperiments()).compareTo(other.isSetCreatedExperiments());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetCreatedExperiments()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.createdExperiments, other.createdExperiments);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetRunningExperiments()).compareTo(other.isSetRunningExperiments());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetRunningExperiments()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.runningExperiments, other.runningExperiments);
      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("ExperimentStatistics(");
    boolean first = true;

    sb.append("allExperimentCount:");
    sb.append(this.allExperimentCount);
    first = false;
    if (!first) sb.append(", ");
    sb.append("completedExperimentCount:");
    sb.append(this.completedExperimentCount);
    first = false;
    if (isSetCancelledExperimentCount()) {
      if (!first) sb.append(", ");
      sb.append("cancelledExperimentCount:");
      sb.append(this.cancelledExperimentCount);
      first = false;
    }
    if (!first) sb.append(", ");
    sb.append("failedExperimentCount:");
    sb.append(this.failedExperimentCount);
    first = false;
    if (!first) sb.append(", ");
    sb.append("createdExperimentCount:");
    sb.append(this.createdExperimentCount);
    first = false;
    if (!first) sb.append(", ");
    sb.append("runningExperimentCount:");
    sb.append(this.runningExperimentCount);
    first = false;
    if (!first) sb.append(", ");
    sb.append("allExperiments:");
    if (this.allExperiments == null) {
      sb.append("null");
    } else {
      sb.append(this.allExperiments);
    }
    first = false;
    if (isSetCompletedExperiments()) {
      if (!first) sb.append(", ");
      sb.append("completedExperiments:");
      if (this.completedExperiments == null) {
        sb.append("null");
      } else {
        sb.append(this.completedExperiments);
      }
      first = false;
    }
    if (isSetFailedExperiments()) {
      if (!first) sb.append(", ");
      sb.append("failedExperiments:");
      if (this.failedExperiments == null) {
        sb.append("null");
      } else {
        sb.append(this.failedExperiments);
      }
      first = false;
    }
    if (isSetCancelledExperiments()) {
      if (!first) sb.append(", ");
      sb.append("cancelledExperiments:");
      if (this.cancelledExperiments == null) {
        sb.append("null");
      } else {
        sb.append(this.cancelledExperiments);
      }
      first = false;
    }
    if (isSetCreatedExperiments()) {
      if (!first) sb.append(", ");
      sb.append("createdExperiments:");
      if (this.createdExperiments == null) {
        sb.append("null");
      } else {
        sb.append(this.createdExperiments);
      }
      first = false;
    }
    if (isSetRunningExperiments()) {
      if (!first) sb.append(", ");
      sb.append("runningExperiments:");
      if (this.runningExperiments == null) {
        sb.append("null");
      } else {
        sb.append(this.runningExperiments);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

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

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

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

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

    if (!isSetAllExperiments()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'allExperiments' 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 ExperimentStatisticsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public ExperimentStatisticsStandardScheme getScheme() {
      return new ExperimentStatisticsStandardScheme();
    }
  }

  private static class ExperimentStatisticsStandardScheme extends org.apache.thrift.scheme.StandardScheme<ExperimentStatistics> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, ExperimentStatistics 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: // ALL_EXPERIMENT_COUNT
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.allExperimentCount = iprot.readI32();
              struct.setAllExperimentCountIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // COMPLETED_EXPERIMENT_COUNT
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.completedExperimentCount = iprot.readI32();
              struct.setCompletedExperimentCountIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // CANCELLED_EXPERIMENT_COUNT
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.cancelledExperimentCount = iprot.readI32();
              struct.setCancelledExperimentCountIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // FAILED_EXPERIMENT_COUNT
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.failedExperimentCount = iprot.readI32();
              struct.setFailedExperimentCountIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // CREATED_EXPERIMENT_COUNT
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.createdExperimentCount = iprot.readI32();
              struct.setCreatedExperimentCountIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // RUNNING_EXPERIMENT_COUNT
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.runningExperimentCount = iprot.readI32();
              struct.setRunningExperimentCountIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // ALL_EXPERIMENTS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list48 = iprot.readListBegin();
                struct.allExperiments = new java.util.ArrayList<ExperimentSummaryModel>(_list48.size);
                ExperimentSummaryModel _elem49;
                for (int _i50 = 0; _i50 < _list48.size; ++_i50)
                {
                  _elem49 = new ExperimentSummaryModel();
                  _elem49.read(iprot);
                  struct.allExperiments.add(_elem49);
                }
                iprot.readListEnd();
              }
              struct.setAllExperimentsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // COMPLETED_EXPERIMENTS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list51 = iprot.readListBegin();
                struct.completedExperiments = new java.util.ArrayList<ExperimentSummaryModel>(_list51.size);
                ExperimentSummaryModel _elem52;
                for (int _i53 = 0; _i53 < _list51.size; ++_i53)
                {
                  _elem52 = new ExperimentSummaryModel();
                  _elem52.read(iprot);
                  struct.completedExperiments.add(_elem52);
                }
                iprot.readListEnd();
              }
              struct.setCompletedExperimentsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // FAILED_EXPERIMENTS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list54 = iprot.readListBegin();
                struct.failedExperiments = new java.util.ArrayList<ExperimentSummaryModel>(_list54.size);
                ExperimentSummaryModel _elem55;
                for (int _i56 = 0; _i56 < _list54.size; ++_i56)
                {
                  _elem55 = new ExperimentSummaryModel();
                  _elem55.read(iprot);
                  struct.failedExperiments.add(_elem55);
                }
                iprot.readListEnd();
              }
              struct.setFailedExperimentsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // CANCELLED_EXPERIMENTS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list57 = iprot.readListBegin();
                struct.cancelledExperiments = new java.util.ArrayList<ExperimentSummaryModel>(_list57.size);
                ExperimentSummaryModel _elem58;
                for (int _i59 = 0; _i59 < _list57.size; ++_i59)
                {
                  _elem58 = new ExperimentSummaryModel();
                  _elem58.read(iprot);
                  struct.cancelledExperiments.add(_elem58);
                }
                iprot.readListEnd();
              }
              struct.setCancelledExperimentsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 11: // CREATED_EXPERIMENTS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list60 = iprot.readListBegin();
                struct.createdExperiments = new java.util.ArrayList<ExperimentSummaryModel>(_list60.size);
                ExperimentSummaryModel _elem61;
                for (int _i62 = 0; _i62 < _list60.size; ++_i62)
                {
                  _elem61 = new ExperimentSummaryModel();
                  _elem61.read(iprot);
                  struct.createdExperiments.add(_elem61);
                }
                iprot.readListEnd();
              }
              struct.setCreatedExperimentsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 12: // RUNNING_EXPERIMENTS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list63 = iprot.readListBegin();
                struct.runningExperiments = new java.util.ArrayList<ExperimentSummaryModel>(_list63.size);
                ExperimentSummaryModel _elem64;
                for (int _i65 = 0; _i65 < _list63.size; ++_i65)
                {
                  _elem64 = new ExperimentSummaryModel();
                  _elem64.read(iprot);
                  struct.runningExperiments.add(_elem64);
                }
                iprot.readListEnd();
              }
              struct.setRunningExperimentsIsSet(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, ExperimentStatistics struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      oprot.writeFieldBegin(ALL_EXPERIMENT_COUNT_FIELD_DESC);
      oprot.writeI32(struct.allExperimentCount);
      oprot.writeFieldEnd();
      oprot.writeFieldBegin(COMPLETED_EXPERIMENT_COUNT_FIELD_DESC);
      oprot.writeI32(struct.completedExperimentCount);
      oprot.writeFieldEnd();
      if (struct.isSetCancelledExperimentCount()) {
        oprot.writeFieldBegin(CANCELLED_EXPERIMENT_COUNT_FIELD_DESC);
        oprot.writeI32(struct.cancelledExperimentCount);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldBegin(FAILED_EXPERIMENT_COUNT_FIELD_DESC);
      oprot.writeI32(struct.failedExperimentCount);
      oprot.writeFieldEnd();
      oprot.writeFieldBegin(CREATED_EXPERIMENT_COUNT_FIELD_DESC);
      oprot.writeI32(struct.createdExperimentCount);
      oprot.writeFieldEnd();
      oprot.writeFieldBegin(RUNNING_EXPERIMENT_COUNT_FIELD_DESC);
      oprot.writeI32(struct.runningExperimentCount);
      oprot.writeFieldEnd();
      if (struct.allExperiments != null) {
        oprot.writeFieldBegin(ALL_EXPERIMENTS_FIELD_DESC);
        {
          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.allExperiments.size()));
          for (ExperimentSummaryModel _iter66 : struct.allExperiments)
          {
            _iter66.write(oprot);
          }
          oprot.writeListEnd();
        }
        oprot.writeFieldEnd();
      }
      if (struct.completedExperiments != null) {
        if (struct.isSetCompletedExperiments()) {
          oprot.writeFieldBegin(COMPLETED_EXPERIMENTS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.completedExperiments.size()));
            for (ExperimentSummaryModel _iter67 : struct.completedExperiments)
            {
              _iter67.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.failedExperiments != null) {
        if (struct.isSetFailedExperiments()) {
          oprot.writeFieldBegin(FAILED_EXPERIMENTS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.failedExperiments.size()));
            for (ExperimentSummaryModel _iter68 : struct.failedExperiments)
            {
              _iter68.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.cancelledExperiments != null) {
        if (struct.isSetCancelledExperiments()) {
          oprot.writeFieldBegin(CANCELLED_EXPERIMENTS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.cancelledExperiments.size()));
            for (ExperimentSummaryModel _iter69 : struct.cancelledExperiments)
            {
              _iter69.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.createdExperiments != null) {
        if (struct.isSetCreatedExperiments()) {
          oprot.writeFieldBegin(CREATED_EXPERIMENTS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.createdExperiments.size()));
            for (ExperimentSummaryModel _iter70 : struct.createdExperiments)
            {
              _iter70.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.runningExperiments != null) {
        if (struct.isSetRunningExperiments()) {
          oprot.writeFieldBegin(RUNNING_EXPERIMENTS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.runningExperiments.size()));
            for (ExperimentSummaryModel _iter71 : struct.runningExperiments)
            {
              _iter71.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

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

  private static class ExperimentStatisticsTupleScheme extends org.apache.thrift.scheme.TupleScheme<ExperimentStatistics> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, ExperimentStatistics struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      oprot.writeI32(struct.allExperimentCount);
      oprot.writeI32(struct.completedExperimentCount);
      oprot.writeI32(struct.failedExperimentCount);
      oprot.writeI32(struct.createdExperimentCount);
      oprot.writeI32(struct.runningExperimentCount);
      {
        oprot.writeI32(struct.allExperiments.size());
        for (ExperimentSummaryModel _iter72 : struct.allExperiments)
        {
          _iter72.write(oprot);
        }
      }
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.isSetCancelledExperimentCount()) {
        optionals.set(0);
      }
      if (struct.isSetCompletedExperiments()) {
        optionals.set(1);
      }
      if (struct.isSetFailedExperiments()) {
        optionals.set(2);
      }
      if (struct.isSetCancelledExperiments()) {
        optionals.set(3);
      }
      if (struct.isSetCreatedExperiments()) {
        optionals.set(4);
      }
      if (struct.isSetRunningExperiments()) {
        optionals.set(5);
      }
      oprot.writeBitSet(optionals, 6);
      if (struct.isSetCancelledExperimentCount()) {
        oprot.writeI32(struct.cancelledExperimentCount);
      }
      if (struct.isSetCompletedExperiments()) {
        {
          oprot.writeI32(struct.completedExperiments.size());
          for (ExperimentSummaryModel _iter73 : struct.completedExperiments)
          {
            _iter73.write(oprot);
          }
        }
      }
      if (struct.isSetFailedExperiments()) {
        {
          oprot.writeI32(struct.failedExperiments.size());
          for (ExperimentSummaryModel _iter74 : struct.failedExperiments)
          {
            _iter74.write(oprot);
          }
        }
      }
      if (struct.isSetCancelledExperiments()) {
        {
          oprot.writeI32(struct.cancelledExperiments.size());
          for (ExperimentSummaryModel _iter75 : struct.cancelledExperiments)
          {
            _iter75.write(oprot);
          }
        }
      }
      if (struct.isSetCreatedExperiments()) {
        {
          oprot.writeI32(struct.createdExperiments.size());
          for (ExperimentSummaryModel _iter76 : struct.createdExperiments)
          {
            _iter76.write(oprot);
          }
        }
      }
      if (struct.isSetRunningExperiments()) {
        {
          oprot.writeI32(struct.runningExperiments.size());
          for (ExperimentSummaryModel _iter77 : struct.runningExperiments)
          {
            _iter77.write(oprot);
          }
        }
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, ExperimentStatistics struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      struct.allExperimentCount = iprot.readI32();
      struct.setAllExperimentCountIsSet(true);
      struct.completedExperimentCount = iprot.readI32();
      struct.setCompletedExperimentCountIsSet(true);
      struct.failedExperimentCount = iprot.readI32();
      struct.setFailedExperimentCountIsSet(true);
      struct.createdExperimentCount = iprot.readI32();
      struct.setCreatedExperimentCountIsSet(true);
      struct.runningExperimentCount = iprot.readI32();
      struct.setRunningExperimentCountIsSet(true);
      {
        org.apache.thrift.protocol.TList _list78 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
        struct.allExperiments = new java.util.ArrayList<ExperimentSummaryModel>(_list78.size);
        ExperimentSummaryModel _elem79;
        for (int _i80 = 0; _i80 < _list78.size; ++_i80)
        {
          _elem79 = new ExperimentSummaryModel();
          _elem79.read(iprot);
          struct.allExperiments.add(_elem79);
        }
      }
      struct.setAllExperimentsIsSet(true);
      java.util.BitSet incoming = iprot.readBitSet(6);
      if (incoming.get(0)) {
        struct.cancelledExperimentCount = iprot.readI32();
        struct.setCancelledExperimentCountIsSet(true);
      }
      if (incoming.get(1)) {
        {
          org.apache.thrift.protocol.TList _list81 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.completedExperiments = new java.util.ArrayList<ExperimentSummaryModel>(_list81.size);
          ExperimentSummaryModel _elem82;
          for (int _i83 = 0; _i83 < _list81.size; ++_i83)
          {
            _elem82 = new ExperimentSummaryModel();
            _elem82.read(iprot);
            struct.completedExperiments.add(_elem82);
          }
        }
        struct.setCompletedExperimentsIsSet(true);
      }
      if (incoming.get(2)) {
        {
          org.apache.thrift.protocol.TList _list84 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.failedExperiments = new java.util.ArrayList<ExperimentSummaryModel>(_list84.size);
          ExperimentSummaryModel _elem85;
          for (int _i86 = 0; _i86 < _list84.size; ++_i86)
          {
            _elem85 = new ExperimentSummaryModel();
            _elem85.read(iprot);
            struct.failedExperiments.add(_elem85);
          }
        }
        struct.setFailedExperimentsIsSet(true);
      }
      if (incoming.get(3)) {
        {
          org.apache.thrift.protocol.TList _list87 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.cancelledExperiments = new java.util.ArrayList<ExperimentSummaryModel>(_list87.size);
          ExperimentSummaryModel _elem88;
          for (int _i89 = 0; _i89 < _list87.size; ++_i89)
          {
            _elem88 = new ExperimentSummaryModel();
            _elem88.read(iprot);
            struct.cancelledExperiments.add(_elem88);
          }
        }
        struct.setCancelledExperimentsIsSet(true);
      }
      if (incoming.get(4)) {
        {
          org.apache.thrift.protocol.TList _list90 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.createdExperiments = new java.util.ArrayList<ExperimentSummaryModel>(_list90.size);
          ExperimentSummaryModel _elem91;
          for (int _i92 = 0; _i92 < _list90.size; ++_i92)
          {
            _elem91 = new ExperimentSummaryModel();
            _elem91.read(iprot);
            struct.createdExperiments.add(_elem91);
          }
        }
        struct.setCreatedExperimentsIsSet(true);
      }
      if (incoming.get(5)) {
        {
          org.apache.thrift.protocol.TList _list93 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.runningExperiments = new java.util.ArrayList<ExperimentSummaryModel>(_list93.size);
          ExperimentSummaryModel _elem94;
          for (int _i95 = 0; _i95 < _list93.size; ++_i95)
          {
            _elem94 = new ExperimentSummaryModel();
            _elem94.read(iprot);
            struct.runningExperiments.add(_elem94);
          }
        }
        struct.setRunningExperimentsIsSet(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();
  }
}

