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

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

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

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

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
  static {
    schemes.put(StandardScheme.class, new ExperimentStatisticsStandardSchemeFactory());
    schemes.put(TupleScheme.class, 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 List<ExperimentSummaryModel> allExperiments; // required
  private List<ExperimentSummaryModel> completedExperiments; // optional
  private List<ExperimentSummaryModel> failedExperiments; // optional
  private List<ExperimentSummaryModel> cancelledExperiments; // optional
  private List<ExperimentSummaryModel> createdExperiments; // optional
  private 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 Map<String, _Fields> byName = new HashMap<String, _Fields>();

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

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
      return fields;
    }

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

    private final short _thriftId;
    private final String _fieldName;

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

    public short getThriftFieldId() {
      return _thriftId;
    }

    public String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final int __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 Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.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 = 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,
    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()) {
      List<ExperimentSummaryModel> __this__allExperiments = new 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()) {
      List<ExperimentSummaryModel> __this__completedExperiments = new 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()) {
      List<ExperimentSummaryModel> __this__failedExperiments = new 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()) {
      List<ExperimentSummaryModel> __this__cancelledExperiments = new 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()) {
      List<ExperimentSummaryModel> __this__createdExperiments = new 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()) {
      List<ExperimentSummaryModel> __this__runningExperiments = new 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 = 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 EncodingUtils.testBit(__isset_bitfield, __ALLEXPERIMENTCOUNT_ISSET_ID);
  }

  public void setAllExperimentCountIsSet(boolean value) {
    __isset_bitfield = 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 = 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 EncodingUtils.testBit(__isset_bitfield, __COMPLETEDEXPERIMENTCOUNT_ISSET_ID);
  }

  public void setCompletedExperimentCountIsSet(boolean value) {
    __isset_bitfield = 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 = 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 EncodingUtils.testBit(__isset_bitfield, __CANCELLEDEXPERIMENTCOUNT_ISSET_ID);
  }

  public void setCancelledExperimentCountIsSet(boolean value) {
    __isset_bitfield = 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 = 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 EncodingUtils.testBit(__isset_bitfield, __FAILEDEXPERIMENTCOUNT_ISSET_ID);
  }

  public void setFailedExperimentCountIsSet(boolean value) {
    __isset_bitfield = 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 = 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 EncodingUtils.testBit(__isset_bitfield, __CREATEDEXPERIMENTCOUNT_ISSET_ID);
  }

  public void setCreatedExperimentCountIsSet(boolean value) {
    __isset_bitfield = 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 = 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 EncodingUtils.testBit(__isset_bitfield, __RUNNINGEXPERIMENTCOUNT_ISSET_ID);
  }

  public void setRunningExperimentCountIsSet(boolean value) {
    __isset_bitfield = 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 ArrayList<ExperimentSummaryModel>();
    }
    this.allExperiments.add(elem);
  }

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

  public void setAllExperiments(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 ArrayList<ExperimentSummaryModel>();
    }
    this.completedExperiments.add(elem);
  }

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

  public void setCompletedExperiments(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 ArrayList<ExperimentSummaryModel>();
    }
    this.failedExperiments.add(elem);
  }

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

  public void setFailedExperiments(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 ArrayList<ExperimentSummaryModel>();
    }
    this.cancelledExperiments.add(elem);
  }

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

  public void setCancelledExperiments(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 ArrayList<ExperimentSummaryModel>();
    }
    this.createdExperiments.add(elem);
  }

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

  public void setCreatedExperiments(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 ArrayList<ExperimentSummaryModel>();
    }
    this.runningExperiments.add(elem);
  }

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

  public void setRunningExperiments(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, Object value) {
    switch (field) {
    case ALL_EXPERIMENT_COUNT:
      if (value == null) {
        unsetAllExperimentCount();
      } else {
        setAllExperimentCount((Integer)value);
      }
      break;

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

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

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

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

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

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

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

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

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

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

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

    }
  }

  public 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 IllegalStateException();
  }

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

    switch (field) {
    case 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 IllegalStateException();
  }

  @Override
  public boolean equals(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;

    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() {
    List<Object> list = new ArrayList<Object>();

    boolean present_allExperimentCount = true;
    list.add(present_allExperimentCount);
    if (present_allExperimentCount)
      list.add(allExperimentCount);

    boolean present_completedExperimentCount = true;
    list.add(present_completedExperimentCount);
    if (present_completedExperimentCount)
      list.add(completedExperimentCount);

    boolean present_cancelledExperimentCount = true && (isSetCancelledExperimentCount());
    list.add(present_cancelledExperimentCount);
    if (present_cancelledExperimentCount)
      list.add(cancelledExperimentCount);

    boolean present_failedExperimentCount = true;
    list.add(present_failedExperimentCount);
    if (present_failedExperimentCount)
      list.add(failedExperimentCount);

    boolean present_createdExperimentCount = true;
    list.add(present_createdExperimentCount);
    if (present_createdExperimentCount)
      list.add(createdExperimentCount);

    boolean present_runningExperimentCount = true;
    list.add(present_runningExperimentCount);
    if (present_runningExperimentCount)
      list.add(runningExperimentCount);

    boolean present_allExperiments = true && (isSetAllExperiments());
    list.add(present_allExperiments);
    if (present_allExperiments)
      list.add(allExperiments);

    boolean present_completedExperiments = true && (isSetCompletedExperiments());
    list.add(present_completedExperiments);
    if (present_completedExperiments)
      list.add(completedExperiments);

    boolean present_failedExperiments = true && (isSetFailedExperiments());
    list.add(present_failedExperiments);
    if (present_failedExperiments)
      list.add(failedExperiments);

    boolean present_cancelledExperiments = true && (isSetCancelledExperiments());
    list.add(present_cancelledExperiments);
    if (present_cancelledExperiments)
      list.add(cancelledExperiments);

    boolean present_createdExperiments = true && (isSetCreatedExperiments());
    list.add(present_createdExperiments);
    if (present_createdExperiments)
      list.add(createdExperiments);

    boolean present_runningExperiments = true && (isSetRunningExperiments());
    list.add(present_runningExperiments);
    if (present_runningExperiments)
      list.add(runningExperiments);

    return list.hashCode();
  }

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

    int lastComparison = 0;

    lastComparison = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 {
    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
  }

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

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder("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, 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 SchemeFactory {
    public ExperimentStatisticsStandardScheme getScheme() {
      return new ExperimentStatisticsStandardScheme();
    }
  }

  private static class ExperimentStatisticsStandardScheme extends 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 _list40 = iprot.readListBegin();
                struct.allExperiments = new ArrayList<ExperimentSummaryModel>(_list40.size);
                ExperimentSummaryModel _elem41;
                for (int _i42 = 0; _i42 < _list40.size; ++_i42)
                {
                  _elem41 = new ExperimentSummaryModel();
                  _elem41.read(iprot);
                  struct.allExperiments.add(_elem41);
                }
                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 _list43 = iprot.readListBegin();
                struct.completedExperiments = new ArrayList<ExperimentSummaryModel>(_list43.size);
                ExperimentSummaryModel _elem44;
                for (int _i45 = 0; _i45 < _list43.size; ++_i45)
                {
                  _elem44 = new ExperimentSummaryModel();
                  _elem44.read(iprot);
                  struct.completedExperiments.add(_elem44);
                }
                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 _list46 = iprot.readListBegin();
                struct.failedExperiments = new ArrayList<ExperimentSummaryModel>(_list46.size);
                ExperimentSummaryModel _elem47;
                for (int _i48 = 0; _i48 < _list46.size; ++_i48)
                {
                  _elem47 = new ExperimentSummaryModel();
                  _elem47.read(iprot);
                  struct.failedExperiments.add(_elem47);
                }
                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 _list49 = iprot.readListBegin();
                struct.cancelledExperiments = new ArrayList<ExperimentSummaryModel>(_list49.size);
                ExperimentSummaryModel _elem50;
                for (int _i51 = 0; _i51 < _list49.size; ++_i51)
                {
                  _elem50 = new ExperimentSummaryModel();
                  _elem50.read(iprot);
                  struct.cancelledExperiments.add(_elem50);
                }
                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 _list52 = iprot.readListBegin();
                struct.createdExperiments = new ArrayList<ExperimentSummaryModel>(_list52.size);
                ExperimentSummaryModel _elem53;
                for (int _i54 = 0; _i54 < _list52.size; ++_i54)
                {
                  _elem53 = new ExperimentSummaryModel();
                  _elem53.read(iprot);
                  struct.createdExperiments.add(_elem53);
                }
                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 _list55 = iprot.readListBegin();
                struct.runningExperiments = new ArrayList<ExperimentSummaryModel>(_list55.size);
                ExperimentSummaryModel _elem56;
                for (int _i57 = 0; _i57 < _list55.size; ++_i57)
                {
                  _elem56 = new ExperimentSummaryModel();
                  _elem56.read(iprot);
                  struct.runningExperiments.add(_elem56);
                }
                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 _iter58 : struct.allExperiments)
          {
            _iter58.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 _iter59 : struct.completedExperiments)
            {
              _iter59.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 _iter60 : struct.failedExperiments)
            {
              _iter60.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 _iter61 : struct.cancelledExperiments)
            {
              _iter61.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 _iter62 : struct.createdExperiments)
            {
              _iter62.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 _iter63 : struct.runningExperiments)
            {
              _iter63.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class ExperimentStatisticsTupleSchemeFactory implements SchemeFactory {
    public ExperimentStatisticsTupleScheme getScheme() {
      return new ExperimentStatisticsTupleScheme();
    }
  }

  private static class ExperimentStatisticsTupleScheme extends TupleScheme<ExperimentStatistics> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, ExperimentStatistics struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (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 _iter64 : struct.allExperiments)
        {
          _iter64.write(oprot);
        }
      }
      BitSet optionals = new 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 _iter65 : struct.completedExperiments)
          {
            _iter65.write(oprot);
          }
        }
      }
      if (struct.isSetFailedExperiments()) {
        {
          oprot.writeI32(struct.failedExperiments.size());
          for (ExperimentSummaryModel _iter66 : struct.failedExperiments)
          {
            _iter66.write(oprot);
          }
        }
      }
      if (struct.isSetCancelledExperiments()) {
        {
          oprot.writeI32(struct.cancelledExperiments.size());
          for (ExperimentSummaryModel _iter67 : struct.cancelledExperiments)
          {
            _iter67.write(oprot);
          }
        }
      }
      if (struct.isSetCreatedExperiments()) {
        {
          oprot.writeI32(struct.createdExperiments.size());
          for (ExperimentSummaryModel _iter68 : struct.createdExperiments)
          {
            _iter68.write(oprot);
          }
        }
      }
      if (struct.isSetRunningExperiments()) {
        {
          oprot.writeI32(struct.runningExperiments.size());
          for (ExperimentSummaryModel _iter69 : struct.runningExperiments)
          {
            _iter69.write(oprot);
          }
        }
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, ExperimentStatistics struct) throws org.apache.thrift.TException {
      TTupleProtocol iprot = (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 _list70 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
        struct.allExperiments = new ArrayList<ExperimentSummaryModel>(_list70.size);
        ExperimentSummaryModel _elem71;
        for (int _i72 = 0; _i72 < _list70.size; ++_i72)
        {
          _elem71 = new ExperimentSummaryModel();
          _elem71.read(iprot);
          struct.allExperiments.add(_elem71);
        }
      }
      struct.setAllExperimentsIsSet(true);
      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 _list73 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.completedExperiments = new ArrayList<ExperimentSummaryModel>(_list73.size);
          ExperimentSummaryModel _elem74;
          for (int _i75 = 0; _i75 < _list73.size; ++_i75)
          {
            _elem74 = new ExperimentSummaryModel();
            _elem74.read(iprot);
            struct.completedExperiments.add(_elem74);
          }
        }
        struct.setCompletedExperimentsIsSet(true);
      }
      if (incoming.get(2)) {
        {
          org.apache.thrift.protocol.TList _list76 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.failedExperiments = new ArrayList<ExperimentSummaryModel>(_list76.size);
          ExperimentSummaryModel _elem77;
          for (int _i78 = 0; _i78 < _list76.size; ++_i78)
          {
            _elem77 = new ExperimentSummaryModel();
            _elem77.read(iprot);
            struct.failedExperiments.add(_elem77);
          }
        }
        struct.setFailedExperimentsIsSet(true);
      }
      if (incoming.get(3)) {
        {
          org.apache.thrift.protocol.TList _list79 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.cancelledExperiments = new ArrayList<ExperimentSummaryModel>(_list79.size);
          ExperimentSummaryModel _elem80;
          for (int _i81 = 0; _i81 < _list79.size; ++_i81)
          {
            _elem80 = new ExperimentSummaryModel();
            _elem80.read(iprot);
            struct.cancelledExperiments.add(_elem80);
          }
        }
        struct.setCancelledExperimentsIsSet(true);
      }
      if (incoming.get(4)) {
        {
          org.apache.thrift.protocol.TList _list82 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.createdExperiments = new ArrayList<ExperimentSummaryModel>(_list82.size);
          ExperimentSummaryModel _elem83;
          for (int _i84 = 0; _i84 < _list82.size; ++_i84)
          {
            _elem83 = new ExperimentSummaryModel();
            _elem83.read(iprot);
            struct.createdExperiments.add(_elem83);
          }
        }
        struct.setCreatedExperimentsIsSet(true);
      }
      if (incoming.get(5)) {
        {
          org.apache.thrift.protocol.TList _list85 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.runningExperiments = new ArrayList<ExperimentSummaryModel>(_list85.size);
          ExperimentSummaryModel _elem86;
          for (int _i87 = 0; _i87 < _list85.size; ++_i87)
          {
            _elem86 = new ExperimentSummaryModel();
            _elem86.read(iprot);
            struct.runningExperiments.add(_elem86);
          }
        }
        struct.setRunningExperimentsIsSet(true);
      }
    }
  }

}

