/**
 * Autogenerated by Thrift Compiler (0.9.1)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.avro.thrift.test;

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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Test implements org.apache.thrift.TBase<Test, Test._Fields>, java.io.Serializable, Cloneable, Comparable<Test> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Test");

  private static final org.apache.thrift.protocol.TField BOOL_FIELD_FIELD_DESC = new org.apache.thrift.protocol.TField("boolField", org.apache.thrift.protocol.TType.BOOL, (short)1);
  private static final org.apache.thrift.protocol.TField BYTE_FIELD_FIELD_DESC = new org.apache.thrift.protocol.TField("byteField", org.apache.thrift.protocol.TType.BYTE, (short)2);
  private static final org.apache.thrift.protocol.TField BYTE_OPTIONAL_FIELD_FIELD_DESC = new org.apache.thrift.protocol.TField("byteOptionalField", org.apache.thrift.protocol.TType.BYTE, (short)16);
  private static final org.apache.thrift.protocol.TField I16_FIELD_FIELD_DESC = new org.apache.thrift.protocol.TField("i16Field", org.apache.thrift.protocol.TType.I16, (short)3);
  private static final org.apache.thrift.protocol.TField I16_OPTIONAL_FIELD_FIELD_DESC = new org.apache.thrift.protocol.TField("i16OptionalField", org.apache.thrift.protocol.TType.I16, (short)15);
  private static final org.apache.thrift.protocol.TField I32_FIELD_FIELD_DESC = new org.apache.thrift.protocol.TField("i32Field", org.apache.thrift.protocol.TType.I32, (short)4);
  private static final org.apache.thrift.protocol.TField I64_FIELD_FIELD_DESC = new org.apache.thrift.protocol.TField("i64Field", org.apache.thrift.protocol.TType.I64, (short)5);
  private static final org.apache.thrift.protocol.TField DOUBLE_FIELD_FIELD_DESC = new org.apache.thrift.protocol.TField("doubleField", org.apache.thrift.protocol.TType.DOUBLE, (short)6);
  private static final org.apache.thrift.protocol.TField STRING_FIELD_FIELD_DESC = new org.apache.thrift.protocol.TField("stringField", org.apache.thrift.protocol.TType.STRING, (short)7);
  private static final org.apache.thrift.protocol.TField BINARY_FIELD_FIELD_DESC = new org.apache.thrift.protocol.TField("binaryField", org.apache.thrift.protocol.TType.STRING, (short)8);
  private static final org.apache.thrift.protocol.TField MAP_FIELD_FIELD_DESC = new org.apache.thrift.protocol.TField("mapField", org.apache.thrift.protocol.TType.MAP, (short)9);
  private static final org.apache.thrift.protocol.TField LIST_FIELD_FIELD_DESC = new org.apache.thrift.protocol.TField("listField", org.apache.thrift.protocol.TType.LIST, (short)10);
  private static final org.apache.thrift.protocol.TField SET_FIELD_FIELD_DESC = new org.apache.thrift.protocol.TField("setField", org.apache.thrift.protocol.TType.SET, (short)11);
  private static final org.apache.thrift.protocol.TField ENUM_FIELD_FIELD_DESC = new org.apache.thrift.protocol.TField("enumField", org.apache.thrift.protocol.TType.I32, (short)12);
  private static final org.apache.thrift.protocol.TField STRUCT_FIELD_FIELD_DESC = new org.apache.thrift.protocol.TField("structField", org.apache.thrift.protocol.TType.STRUCT, (short)13);
  private static final org.apache.thrift.protocol.TField FOO_OR_BAR_FIELD_DESC = new org.apache.thrift.protocol.TField("fooOrBar", org.apache.thrift.protocol.TType.STRUCT, (short)14);

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

  private boolean boolField; // required
  private byte byteField; // required
  private byte byteOptionalField; // optional
  private short i16Field; // required
  private short i16OptionalField; // optional
  private int i32Field; // optional
  private long i64Field; // required
  private double doubleField; // required
  private String stringField; // required
  private ByteBuffer binaryField; // optional
  private Map<String,Integer> mapField; // required
  private List<Integer> listField; // required
  private Set<Integer> setField; // required
  private E enumField; // required
  private Nested structField; // required
  private FooOrBar fooOrBar; // required

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
    BOOL_FIELD((short)1, "boolField"),
    BYTE_FIELD((short)2, "byteField"),
    BYTE_OPTIONAL_FIELD((short)16, "byteOptionalField"),
    I16_FIELD((short)3, "i16Field"),
    I16_OPTIONAL_FIELD((short)15, "i16OptionalField"),
    I32_FIELD((short)4, "i32Field"),
    I64_FIELD((short)5, "i64Field"),
    DOUBLE_FIELD((short)6, "doubleField"),
    STRING_FIELD((short)7, "stringField"),
    BINARY_FIELD((short)8, "binaryField"),
    MAP_FIELD((short)9, "mapField"),
    LIST_FIELD((short)10, "listField"),
    SET_FIELD((short)11, "setField"),
    /**
     *
     * @see E
     */
    ENUM_FIELD((short)12, "enumField"),
    STRUCT_FIELD((short)13, "structField"),
    FOO_OR_BAR((short)14, "fooOrBar");

    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: // BOOL_FIELD
          return BOOL_FIELD;
        case 2: // BYTE_FIELD
          return BYTE_FIELD;
        case 16: // BYTE_OPTIONAL_FIELD
          return BYTE_OPTIONAL_FIELD;
        case 3: // I16_FIELD
          return I16_FIELD;
        case 15: // I16_OPTIONAL_FIELD
          return I16_OPTIONAL_FIELD;
        case 4: // I32_FIELD
          return I32_FIELD;
        case 5: // I64_FIELD
          return I64_FIELD;
        case 6: // DOUBLE_FIELD
          return DOUBLE_FIELD;
        case 7: // STRING_FIELD
          return STRING_FIELD;
        case 8: // BINARY_FIELD
          return BINARY_FIELD;
        case 9: // MAP_FIELD
          return MAP_FIELD;
        case 10: // LIST_FIELD
          return LIST_FIELD;
        case 11: // SET_FIELD
          return SET_FIELD;
        case 12: // ENUM_FIELD
          return ENUM_FIELD;
        case 13: // STRUCT_FIELD
          return STRUCT_FIELD;
        case 14: // FOO_OR_BAR
          return FOO_OR_BAR;
        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 __BOOLFIELD_ISSET_ID = 0;
  private static final int __BYTEFIELD_ISSET_ID = 1;
  private static final int __BYTEOPTIONALFIELD_ISSET_ID = 2;
  private static final int __I16FIELD_ISSET_ID = 3;
  private static final int __I16OPTIONALFIELD_ISSET_ID = 4;
  private static final int __I32FIELD_ISSET_ID = 5;
  private static final int __I64FIELD_ISSET_ID = 6;
  private static final int __DOUBLEFIELD_ISSET_ID = 7;
  private byte __isset_bitfield = 0;
  private _Fields optionals[] = {_Fields.BYTE_OPTIONAL_FIELD,_Fields.I16_OPTIONAL_FIELD,_Fields.I32_FIELD,_Fields.BINARY_FIELD};
  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.BOOL_FIELD, new org.apache.thrift.meta_data.FieldMetaData("boolField", org.apache.thrift.TFieldRequirementType.DEFAULT,
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.BYTE_FIELD, new org.apache.thrift.meta_data.FieldMetaData("byteField", org.apache.thrift.TFieldRequirementType.DEFAULT,
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BYTE)));
    tmpMap.put(_Fields.BYTE_OPTIONAL_FIELD, new org.apache.thrift.meta_data.FieldMetaData("byteOptionalField", org.apache.thrift.TFieldRequirementType.OPTIONAL,
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BYTE)));
    tmpMap.put(_Fields.I16_FIELD, new org.apache.thrift.meta_data.FieldMetaData("i16Field", org.apache.thrift.TFieldRequirementType.DEFAULT,
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16)));
    tmpMap.put(_Fields.I16_OPTIONAL_FIELD, new org.apache.thrift.meta_data.FieldMetaData("i16OptionalField", org.apache.thrift.TFieldRequirementType.OPTIONAL,
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16)));
    tmpMap.put(_Fields.I32_FIELD, new org.apache.thrift.meta_data.FieldMetaData("i32Field", org.apache.thrift.TFieldRequirementType.OPTIONAL,
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.I64_FIELD, new org.apache.thrift.meta_data.FieldMetaData("i64Field", org.apache.thrift.TFieldRequirementType.DEFAULT,
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.DOUBLE_FIELD, new org.apache.thrift.meta_data.FieldMetaData("doubleField", org.apache.thrift.TFieldRequirementType.DEFAULT,
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.STRING_FIELD, new org.apache.thrift.meta_data.FieldMetaData("stringField", org.apache.thrift.TFieldRequirementType.DEFAULT,
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.BINARY_FIELD, new org.apache.thrift.meta_data.FieldMetaData("binaryField", org.apache.thrift.TFieldRequirementType.OPTIONAL,
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
    tmpMap.put(_Fields.MAP_FIELD, new org.apache.thrift.meta_data.FieldMetaData("mapField", org.apache.thrift.TFieldRequirementType.DEFAULT,
        new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP,
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING),
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))));
    tmpMap.put(_Fields.LIST_FIELD, new org.apache.thrift.meta_data.FieldMetaData("listField", org.apache.thrift.TFieldRequirementType.DEFAULT,
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST,
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))));
    tmpMap.put(_Fields.SET_FIELD, new org.apache.thrift.meta_data.FieldMetaData("setField", org.apache.thrift.TFieldRequirementType.DEFAULT,
        new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET,
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))));
    tmpMap.put(_Fields.ENUM_FIELD, new org.apache.thrift.meta_data.FieldMetaData("enumField", org.apache.thrift.TFieldRequirementType.DEFAULT,
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, E.class)));
    tmpMap.put(_Fields.STRUCT_FIELD, new org.apache.thrift.meta_data.FieldMetaData("structField", org.apache.thrift.TFieldRequirementType.DEFAULT,
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Nested.class)));
    tmpMap.put(_Fields.FOO_OR_BAR, new org.apache.thrift.meta_data.FieldMetaData("fooOrBar", org.apache.thrift.TFieldRequirementType.DEFAULT,
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, FooOrBar.class)));
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Test.class, metaDataMap);
  }

  public Test() {
  }

  public Test(
    boolean boolField,
    byte byteField,
    short i16Field,
    long i64Field,
    double doubleField,
    String stringField,
    Map<String,Integer> mapField,
    List<Integer> listField,
    Set<Integer> setField,
    E enumField,
    Nested structField,
    FooOrBar fooOrBar)
  {
    this();
    this.boolField = boolField;
    setBoolFieldIsSet(true);
    this.byteField = byteField;
    setByteFieldIsSet(true);
    this.i16Field = i16Field;
    setI16FieldIsSet(true);
    this.i64Field = i64Field;
    setI64FieldIsSet(true);
    this.doubleField = doubleField;
    setDoubleFieldIsSet(true);
    this.stringField = stringField;
    this.mapField = mapField;
    this.listField = listField;
    this.setField = setField;
    this.enumField = enumField;
    this.structField = structField;
    this.fooOrBar = fooOrBar;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public Test(Test other) {
    __isset_bitfield = other.__isset_bitfield;
    this.boolField = other.boolField;
    this.byteField = other.byteField;
    this.byteOptionalField = other.byteOptionalField;
    this.i16Field = other.i16Field;
    this.i16OptionalField = other.i16OptionalField;
    this.i32Field = other.i32Field;
    this.i64Field = other.i64Field;
    this.doubleField = other.doubleField;
    if (other.isSetStringField()) {
      this.stringField = other.stringField;
    }
    if (other.isSetBinaryField()) {
      this.binaryField = org.apache.thrift.TBaseHelper.copyBinary(other.binaryField);
;
    }
    if (other.isSetMapField()) {
      Map<String,Integer> __this__mapField = new HashMap<String,Integer>(other.mapField);
      this.mapField = __this__mapField;
    }
    if (other.isSetListField()) {
      List<Integer> __this__listField = new ArrayList<Integer>(other.listField);
      this.listField = __this__listField;
    }
    if (other.isSetSetField()) {
      Set<Integer> __this__setField = new HashSet<Integer>(other.setField);
      this.setField = __this__setField;
    }
    if (other.isSetEnumField()) {
      this.enumField = other.enumField;
    }
    if (other.isSetStructField()) {
      this.structField = new Nested(other.structField);
    }
    if (other.isSetFooOrBar()) {
      this.fooOrBar = new FooOrBar(other.fooOrBar);
    }
  }

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

  @Override
  public void clear() {
    setBoolFieldIsSet(false);
    this.boolField = false;
    setByteFieldIsSet(false);
    this.byteField = 0;
    setByteOptionalFieldIsSet(false);
    this.byteOptionalField = 0;
    setI16FieldIsSet(false);
    this.i16Field = 0;
    setI16OptionalFieldIsSet(false);
    this.i16OptionalField = 0;
    setI32FieldIsSet(false);
    this.i32Field = 0;
    setI64FieldIsSet(false);
    this.i64Field = 0;
    setDoubleFieldIsSet(false);
    this.doubleField = 0.0;
    this.stringField = null;
    this.binaryField = null;
    this.mapField = null;
    this.listField = null;
    this.setField = null;
    this.enumField = null;
    this.structField = null;
    this.fooOrBar = null;
  }

  public boolean isBoolField() {
    return this.boolField;
  }

  public void setBoolField(boolean boolField) {
    this.boolField = boolField;
    setBoolFieldIsSet(true);
  }

  public void unsetBoolField() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __BOOLFIELD_ISSET_ID);
  }

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

  public void setBoolFieldIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __BOOLFIELD_ISSET_ID, value);
  }

  public byte getByteField() {
    return this.byteField;
  }

  public void setByteField(byte byteField) {
    this.byteField = byteField;
    setByteFieldIsSet(true);
  }

  public void unsetByteField() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __BYTEFIELD_ISSET_ID);
  }

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

  public void setByteFieldIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __BYTEFIELD_ISSET_ID, value);
  }

  public byte getByteOptionalField() {
    return this.byteOptionalField;
  }

  public void setByteOptionalField(byte byteOptionalField) {
    this.byteOptionalField = byteOptionalField;
    setByteOptionalFieldIsSet(true);
  }

  public void unsetByteOptionalField() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __BYTEOPTIONALFIELD_ISSET_ID);
  }

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

  public void setByteOptionalFieldIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __BYTEOPTIONALFIELD_ISSET_ID, value);
  }

  public short getI16Field() {
    return this.i16Field;
  }

  public void setI16Field(short i16Field) {
    this.i16Field = i16Field;
    setI16FieldIsSet(true);
  }

  public void unsetI16Field() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __I16FIELD_ISSET_ID);
  }

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

  public void setI16FieldIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __I16FIELD_ISSET_ID, value);
  }

  public short getI16OptionalField() {
    return this.i16OptionalField;
  }

  public void setI16OptionalField(short i16OptionalField) {
    this.i16OptionalField = i16OptionalField;
    setI16OptionalFieldIsSet(true);
  }

  public void unsetI16OptionalField() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __I16OPTIONALFIELD_ISSET_ID);
  }

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

  public void setI16OptionalFieldIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __I16OPTIONALFIELD_ISSET_ID, value);
  }

  public int getI32Field() {
    return this.i32Field;
  }

  public void setI32Field(int i32Field) {
    this.i32Field = i32Field;
    setI32FieldIsSet(true);
  }

  public void unsetI32Field() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __I32FIELD_ISSET_ID);
  }

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

  public void setI32FieldIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __I32FIELD_ISSET_ID, value);
  }

  public long getI64Field() {
    return this.i64Field;
  }

  public void setI64Field(long i64Field) {
    this.i64Field = i64Field;
    setI64FieldIsSet(true);
  }

  public void unsetI64Field() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __I64FIELD_ISSET_ID);
  }

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

  public void setI64FieldIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __I64FIELD_ISSET_ID, value);
  }

  public double getDoubleField() {
    return this.doubleField;
  }

  public void setDoubleField(double doubleField) {
    this.doubleField = doubleField;
    setDoubleFieldIsSet(true);
  }

  public void unsetDoubleField() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __DOUBLEFIELD_ISSET_ID);
  }

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

  public void setDoubleFieldIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __DOUBLEFIELD_ISSET_ID, value);
  }

  public String getStringField() {
    return this.stringField;
  }

  public void setStringField(String stringField) {
    this.stringField = stringField;
  }

  public void unsetStringField() {
    this.stringField = null;
  }

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

  public void setStringFieldIsSet(boolean value) {
    if (!value) {
      this.stringField = null;
    }
  }

  public byte[] getBinaryField() {
    setBinaryField(org.apache.thrift.TBaseHelper.rightSize(binaryField));
    return binaryField == null ? null : binaryField.array();
  }

  public ByteBuffer bufferForBinaryField() {
    return binaryField;
  }

  public void setBinaryField(byte[] binaryField) {
    setBinaryField(binaryField == null ? (ByteBuffer)null : ByteBuffer.wrap(binaryField));
  }

  public void setBinaryField(ByteBuffer binaryField) {
    this.binaryField = binaryField;
  }

  public void unsetBinaryField() {
    this.binaryField = null;
  }

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

  public void setBinaryFieldIsSet(boolean value) {
    if (!value) {
      this.binaryField = null;
    }
  }

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

  public void putToMapField(String key, int val) {
    if (this.mapField == null) {
      this.mapField = new HashMap<String,Integer>();
    }
    this.mapField.put(key, val);
  }

  public Map<String,Integer> getMapField() {
    return this.mapField;
  }

  public void setMapField(Map<String,Integer> mapField) {
    this.mapField = mapField;
  }

  public void unsetMapField() {
    this.mapField = null;
  }

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

  public void setMapFieldIsSet(boolean value) {
    if (!value) {
      this.mapField = null;
    }
  }

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

  public java.util.Iterator<Integer> getListFieldIterator() {
    return (this.listField == null) ? null : this.listField.iterator();
  }

  public void addToListField(int elem) {
    if (this.listField == null) {
      this.listField = new ArrayList<Integer>();
    }
    this.listField.add(elem);
  }

  public List<Integer> getListField() {
    return this.listField;
  }

  public void setListField(List<Integer> listField) {
    this.listField = listField;
  }

  public void unsetListField() {
    this.listField = null;
  }

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

  public void setListFieldIsSet(boolean value) {
    if (!value) {
      this.listField = null;
    }
  }

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

  public java.util.Iterator<Integer> getSetFieldIterator() {
    return (this.setField == null) ? null : this.setField.iterator();
  }

  public void addToSetField(int elem) {
    if (this.setField == null) {
      this.setField = new HashSet<Integer>();
    }
    this.setField.add(elem);
  }

  public Set<Integer> getSetField() {
    return this.setField;
  }

  public void setSetField(Set<Integer> setField) {
    this.setField = setField;
  }

  public void unsetSetField() {
    this.setField = null;
  }

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

  public void setSetFieldIsSet(boolean value) {
    if (!value) {
      this.setField = null;
    }
  }

  /**
   *
   * @see E
   */
  public E getEnumField() {
    return this.enumField;
  }

  /**
   *
   * @see E
   */
  public void setEnumField(E enumField) {
    this.enumField = enumField;
  }

  public void unsetEnumField() {
    this.enumField = null;
  }

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

  public void setEnumFieldIsSet(boolean value) {
    if (!value) {
      this.enumField = null;
    }
  }

  public Nested getStructField() {
    return this.structField;
  }

  public void setStructField(Nested structField) {
    this.structField = structField;
  }

  public void unsetStructField() {
    this.structField = null;
  }

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

  public void setStructFieldIsSet(boolean value) {
    if (!value) {
      this.structField = null;
    }
  }

  public FooOrBar getFooOrBar() {
    return this.fooOrBar;
  }

  public void setFooOrBar(FooOrBar fooOrBar) {
    this.fooOrBar = fooOrBar;
  }

  public void unsetFooOrBar() {
    this.fooOrBar = null;
  }

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

  public void setFooOrBarIsSet(boolean value) {
    if (!value) {
      this.fooOrBar = null;
    }
  }

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case BOOL_FIELD:
      if (value == null) {
        unsetBoolField();
      } else {
        setBoolField((Boolean)value);
      }
      break;

    case BYTE_FIELD:
      if (value == null) {
        unsetByteField();
      } else {
        setByteField((Byte)value);
      }
      break;

    case BYTE_OPTIONAL_FIELD:
      if (value == null) {
        unsetByteOptionalField();
      } else {
        setByteOptionalField((Byte)value);
      }
      break;

    case I16_FIELD:
      if (value == null) {
        unsetI16Field();
      } else {
        setI16Field((Short)value);
      }
      break;

    case I16_OPTIONAL_FIELD:
      if (value == null) {
        unsetI16OptionalField();
      } else {
        setI16OptionalField((Short)value);
      }
      break;

    case I32_FIELD:
      if (value == null) {
        unsetI32Field();
      } else {
        setI32Field((Integer)value);
      }
      break;

    case I64_FIELD:
      if (value == null) {
        unsetI64Field();
      } else {
        setI64Field((Long)value);
      }
      break;

    case DOUBLE_FIELD:
      if (value == null) {
        unsetDoubleField();
      } else {
        setDoubleField((Double)value);
      }
      break;

    case STRING_FIELD:
      if (value == null) {
        unsetStringField();
      } else {
        setStringField((String)value);
      }
      break;

    case BINARY_FIELD:
      if (value == null) {
        unsetBinaryField();
      } else {
        setBinaryField((ByteBuffer)value);
      }
      break;

    case MAP_FIELD:
      if (value == null) {
        unsetMapField();
      } else {
        setMapField((Map<String,Integer>)value);
      }
      break;

    case LIST_FIELD:
      if (value == null) {
        unsetListField();
      } else {
        setListField((List<Integer>)value);
      }
      break;

    case SET_FIELD:
      if (value == null) {
        unsetSetField();
      } else {
        setSetField((Set<Integer>)value);
      }
      break;

    case ENUM_FIELD:
      if (value == null) {
        unsetEnumField();
      } else {
        setEnumField((E)value);
      }
      break;

    case STRUCT_FIELD:
      if (value == null) {
        unsetStructField();
      } else {
        setStructField((Nested)value);
      }
      break;

    case FOO_OR_BAR:
      if (value == null) {
        unsetFooOrBar();
      } else {
        setFooOrBar((FooOrBar)value);
      }
      break;

    }
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case BOOL_FIELD:
      return Boolean.valueOf(isBoolField());

    case BYTE_FIELD:
      return Byte.valueOf(getByteField());

    case BYTE_OPTIONAL_FIELD:
      return Byte.valueOf(getByteOptionalField());

    case I16_FIELD:
      return Short.valueOf(getI16Field());

    case I16_OPTIONAL_FIELD:
      return Short.valueOf(getI16OptionalField());

    case I32_FIELD:
      return Integer.valueOf(getI32Field());

    case I64_FIELD:
      return Long.valueOf(getI64Field());

    case DOUBLE_FIELD:
      return Double.valueOf(getDoubleField());

    case STRING_FIELD:
      return getStringField();

    case BINARY_FIELD:
      return getBinaryField();

    case MAP_FIELD:
      return getMapField();

    case LIST_FIELD:
      return getListField();

    case SET_FIELD:
      return getSetField();

    case ENUM_FIELD:
      return getEnumField();

    case STRUCT_FIELD:
      return getStructField();

    case FOO_OR_BAR:
      return getFooOrBar();

    }
    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 BOOL_FIELD:
      return isSetBoolField();
    case BYTE_FIELD:
      return isSetByteField();
    case BYTE_OPTIONAL_FIELD:
      return isSetByteOptionalField();
    case I16_FIELD:
      return isSetI16Field();
    case I16_OPTIONAL_FIELD:
      return isSetI16OptionalField();
    case I32_FIELD:
      return isSetI32Field();
    case I64_FIELD:
      return isSetI64Field();
    case DOUBLE_FIELD:
      return isSetDoubleField();
    case STRING_FIELD:
      return isSetStringField();
    case BINARY_FIELD:
      return isSetBinaryField();
    case MAP_FIELD:
      return isSetMapField();
    case LIST_FIELD:
      return isSetListField();
    case SET_FIELD:
      return isSetSetField();
    case ENUM_FIELD:
      return isSetEnumField();
    case STRUCT_FIELD:
      return isSetStructField();
    case FOO_OR_BAR:
      return isSetFooOrBar();
    }
    throw new IllegalStateException();
  }

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

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

    boolean this_present_boolField = true;
    boolean that_present_boolField = true;
    if (this_present_boolField || that_present_boolField) {
      if (!(this_present_boolField && that_present_boolField))
        return false;
      if (this.boolField != that.boolField)
        return false;
    }

    boolean this_present_byteField = true;
    boolean that_present_byteField = true;
    if (this_present_byteField || that_present_byteField) {
      if (!(this_present_byteField && that_present_byteField))
        return false;
      if (this.byteField != that.byteField)
        return false;
    }

    boolean this_present_byteOptionalField = true && this.isSetByteOptionalField();
    boolean that_present_byteOptionalField = true && that.isSetByteOptionalField();
    if (this_present_byteOptionalField || that_present_byteOptionalField) {
      if (!(this_present_byteOptionalField && that_present_byteOptionalField))
        return false;
      if (this.byteOptionalField != that.byteOptionalField)
        return false;
    }

    boolean this_present_i16Field = true;
    boolean that_present_i16Field = true;
    if (this_present_i16Field || that_present_i16Field) {
      if (!(this_present_i16Field && that_present_i16Field))
        return false;
      if (this.i16Field != that.i16Field)
        return false;
    }

    boolean this_present_i16OptionalField = true && this.isSetI16OptionalField();
    boolean that_present_i16OptionalField = true && that.isSetI16OptionalField();
    if (this_present_i16OptionalField || that_present_i16OptionalField) {
      if (!(this_present_i16OptionalField && that_present_i16OptionalField))
        return false;
      if (this.i16OptionalField != that.i16OptionalField)
        return false;
    }

    boolean this_present_i32Field = true && this.isSetI32Field();
    boolean that_present_i32Field = true && that.isSetI32Field();
    if (this_present_i32Field || that_present_i32Field) {
      if (!(this_present_i32Field && that_present_i32Field))
        return false;
      if (this.i32Field != that.i32Field)
        return false;
    }

    boolean this_present_i64Field = true;
    boolean that_present_i64Field = true;
    if (this_present_i64Field || that_present_i64Field) {
      if (!(this_present_i64Field && that_present_i64Field))
        return false;
      if (this.i64Field != that.i64Field)
        return false;
    }

    boolean this_present_doubleField = true;
    boolean that_present_doubleField = true;
    if (this_present_doubleField || that_present_doubleField) {
      if (!(this_present_doubleField && that_present_doubleField))
        return false;
      if (this.doubleField != that.doubleField)
        return false;
    }

    boolean this_present_stringField = true && this.isSetStringField();
    boolean that_present_stringField = true && that.isSetStringField();
    if (this_present_stringField || that_present_stringField) {
      if (!(this_present_stringField && that_present_stringField))
        return false;
      if (!this.stringField.equals(that.stringField))
        return false;
    }

    boolean this_present_binaryField = true && this.isSetBinaryField();
    boolean that_present_binaryField = true && that.isSetBinaryField();
    if (this_present_binaryField || that_present_binaryField) {
      if (!(this_present_binaryField && that_present_binaryField))
        return false;
      if (!this.binaryField.equals(that.binaryField))
        return false;
    }

    boolean this_present_mapField = true && this.isSetMapField();
    boolean that_present_mapField = true && that.isSetMapField();
    if (this_present_mapField || that_present_mapField) {
      if (!(this_present_mapField && that_present_mapField))
        return false;
      if (!this.mapField.equals(that.mapField))
        return false;
    }

    boolean this_present_listField = true && this.isSetListField();
    boolean that_present_listField = true && that.isSetListField();
    if (this_present_listField || that_present_listField) {
      if (!(this_present_listField && that_present_listField))
        return false;
      if (!this.listField.equals(that.listField))
        return false;
    }

    boolean this_present_setField = true && this.isSetSetField();
    boolean that_present_setField = true && that.isSetSetField();
    if (this_present_setField || that_present_setField) {
      if (!(this_present_setField && that_present_setField))
        return false;
      if (!this.setField.equals(that.setField))
        return false;
    }

    boolean this_present_enumField = true && this.isSetEnumField();
    boolean that_present_enumField = true && that.isSetEnumField();
    if (this_present_enumField || that_present_enumField) {
      if (!(this_present_enumField && that_present_enumField))
        return false;
      if (!this.enumField.equals(that.enumField))
        return false;
    }

    boolean this_present_structField = true && this.isSetStructField();
    boolean that_present_structField = true && that.isSetStructField();
    if (this_present_structField || that_present_structField) {
      if (!(this_present_structField && that_present_structField))
        return false;
      if (!this.structField.equals(that.structField))
        return false;
    }

    boolean this_present_fooOrBar = true && this.isSetFooOrBar();
    boolean that_present_fooOrBar = true && that.isSetFooOrBar();
    if (this_present_fooOrBar || that_present_fooOrBar) {
      if (!(this_present_fooOrBar && that_present_fooOrBar))
        return false;
      if (!this.fooOrBar.equals(that.fooOrBar))
        return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    return 0;
  }

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

    int lastComparison = 0;

    lastComparison = Boolean.valueOf(isSetBoolField()).compareTo(other.isSetBoolField());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetBoolField()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.boolField, other.boolField);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetByteField()).compareTo(other.isSetByteField());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetByteField()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.byteField, other.byteField);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetByteOptionalField()).compareTo(other.isSetByteOptionalField());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetByteOptionalField()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.byteOptionalField, other.byteOptionalField);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetI16Field()).compareTo(other.isSetI16Field());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetI16Field()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.i16Field, other.i16Field);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetI16OptionalField()).compareTo(other.isSetI16OptionalField());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetI16OptionalField()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.i16OptionalField, other.i16OptionalField);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetI32Field()).compareTo(other.isSetI32Field());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetI32Field()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.i32Field, other.i32Field);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetI64Field()).compareTo(other.isSetI64Field());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetI64Field()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.i64Field, other.i64Field);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetDoubleField()).compareTo(other.isSetDoubleField());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetDoubleField()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.doubleField, other.doubleField);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetStringField()).compareTo(other.isSetStringField());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetStringField()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.stringField, other.stringField);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetBinaryField()).compareTo(other.isSetBinaryField());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetBinaryField()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.binaryField, other.binaryField);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetMapField()).compareTo(other.isSetMapField());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetMapField()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.mapField, other.mapField);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetListField()).compareTo(other.isSetListField());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetListField()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.listField, other.listField);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetSetField()).compareTo(other.isSetSetField());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetSetField()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.setField, other.setField);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetEnumField()).compareTo(other.isSetEnumField());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetEnumField()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.enumField, other.enumField);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetStructField()).compareTo(other.isSetStructField());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetStructField()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.structField, other.structField);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetFooOrBar()).compareTo(other.isSetFooOrBar());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetFooOrBar()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.fooOrBar, other.fooOrBar);
      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("Test(");
    boolean first = true;

    sb.append("boolField:");
    sb.append(this.boolField);
    first = false;
    if (!first) sb.append(", ");
    sb.append("byteField:");
    sb.append(this.byteField);
    first = false;
    if (isSetByteOptionalField()) {
      if (!first) sb.append(", ");
      sb.append("byteOptionalField:");
      sb.append(this.byteOptionalField);
      first = false;
    }
    if (!first) sb.append(", ");
    sb.append("i16Field:");
    sb.append(this.i16Field);
    first = false;
    if (isSetI16OptionalField()) {
      if (!first) sb.append(", ");
      sb.append("i16OptionalField:");
      sb.append(this.i16OptionalField);
      first = false;
    }
    if (isSetI32Field()) {
      if (!first) sb.append(", ");
      sb.append("i32Field:");
      sb.append(this.i32Field);
      first = false;
    }
    if (!first) sb.append(", ");
    sb.append("i64Field:");
    sb.append(this.i64Field);
    first = false;
    if (!first) sb.append(", ");
    sb.append("doubleField:");
    sb.append(this.doubleField);
    first = false;
    if (!first) sb.append(", ");
    sb.append("stringField:");
    if (this.stringField == null) {
      sb.append("null");
    } else {
      sb.append(this.stringField);
    }
    first = false;
    if (isSetBinaryField()) {
      if (!first) sb.append(", ");
      sb.append("binaryField:");
      if (this.binaryField == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.binaryField, sb);
      }
      first = false;
    }
    if (!first) sb.append(", ");
    sb.append("mapField:");
    if (this.mapField == null) {
      sb.append("null");
    } else {
      sb.append(this.mapField);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("listField:");
    if (this.listField == null) {
      sb.append("null");
    } else {
      sb.append(this.listField);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("setField:");
    if (this.setField == null) {
      sb.append("null");
    } else {
      sb.append(this.setField);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("enumField:");
    if (this.enumField == null) {
      sb.append("null");
    } else {
      sb.append(this.enumField);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("structField:");
    if (this.structField == null) {
      sb.append("null");
    } else {
      sb.append(this.structField);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("fooOrBar:");
    if (this.fooOrBar == null) {
      sb.append("null");
    } else {
      sb.append(this.fooOrBar);
    }
    first = false;
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.thrift.TException {
    // check for required fields
    // check for sub-struct validity
    if (structField != null) {
      structField.validate();
    }
  }

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

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

  private static class TestStandardSchemeFactory implements SchemeFactory {
    public TestStandardScheme getScheme() {
      return new TestStandardScheme();
    }
  }

  private static class TestStandardScheme extends StandardScheme<Test> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, Test 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: // BOOL_FIELD
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.boolField = iprot.readBool();
              struct.setBoolFieldIsSet(true);
            } else {
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // BYTE_FIELD
            if (schemeField.type == org.apache.thrift.protocol.TType.BYTE) {
              struct.byteField = iprot.readByte();
              struct.setByteFieldIsSet(true);
            } else {
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 16: // BYTE_OPTIONAL_FIELD
            if (schemeField.type == org.apache.thrift.protocol.TType.BYTE) {
              struct.byteOptionalField = iprot.readByte();
              struct.setByteOptionalFieldIsSet(true);
            } else {
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // I16_FIELD
            if (schemeField.type == org.apache.thrift.protocol.TType.I16) {
              struct.i16Field = iprot.readI16();
              struct.setI16FieldIsSet(true);
            } else {
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 15: // I16_OPTIONAL_FIELD
            if (schemeField.type == org.apache.thrift.protocol.TType.I16) {
              struct.i16OptionalField = iprot.readI16();
              struct.setI16OptionalFieldIsSet(true);
            } else {
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // I32_FIELD
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.i32Field = iprot.readI32();
              struct.setI32FieldIsSet(true);
            } else {
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // I64_FIELD
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.i64Field = iprot.readI64();
              struct.setI64FieldIsSet(true);
            } else {
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // DOUBLE_FIELD
            if (schemeField.type == org.apache.thrift.protocol.TType.DOUBLE) {
              struct.doubleField = iprot.readDouble();
              struct.setDoubleFieldIsSet(true);
            } else {
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // STRING_FIELD
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.stringField = iprot.readString();
              struct.setStringFieldIsSet(true);
            } else {
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // BINARY_FIELD
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.binaryField = iprot.readBinary();
              struct.setBinaryFieldIsSet(true);
            } else {
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // MAP_FIELD
            if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
              {
                org.apache.thrift.protocol.TMap _map0 = iprot.readMapBegin();
                struct.mapField = new HashMap<String,Integer>(2*_map0.size);
                for (int _i1 = 0; _i1 < _map0.size; ++_i1)
                {
                  String _key2;
                  int _val3;
                  _key2 = iprot.readString();
                  _val3 = iprot.readI32();
                  struct.mapField.put(_key2, _val3);
                }
                iprot.readMapEnd();
              }
              struct.setMapFieldIsSet(true);
            } else {
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // LIST_FIELD
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list4 = iprot.readListBegin();
                struct.listField = new ArrayList<Integer>(_list4.size);
                for (int _i5 = 0; _i5 < _list4.size; ++_i5)
                {
                  int _elem6;
                  _elem6 = iprot.readI32();
                  struct.listField.add(_elem6);
                }
                iprot.readListEnd();
              }
              struct.setListFieldIsSet(true);
            } else {
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 11: // SET_FIELD
            if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
              {
                org.apache.thrift.protocol.TSet _set7 = iprot.readSetBegin();
                struct.setField = new HashSet<Integer>(2*_set7.size);
                for (int _i8 = 0; _i8 < _set7.size; ++_i8)
                {
                  int _elem9;
                  _elem9 = iprot.readI32();
                  struct.setField.add(_elem9);
                }
                iprot.readSetEnd();
              }
              struct.setSetFieldIsSet(true);
            } else {
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 12: // ENUM_FIELD
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.enumField = E.findByValue(iprot.readI32());
              struct.setEnumFieldIsSet(true);
            } else {
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 13: // STRUCT_FIELD
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.structField = new Nested();
              struct.structField.read(iprot);
              struct.setStructFieldIsSet(true);
            } else {
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 14: // FOO_OR_BAR
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.fooOrBar = new FooOrBar();
              struct.fooOrBar.read(iprot);
              struct.setFooOrBarIsSet(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, Test struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      oprot.writeFieldBegin(BOOL_FIELD_FIELD_DESC);
      oprot.writeBool(struct.boolField);
      oprot.writeFieldEnd();
      oprot.writeFieldBegin(BYTE_FIELD_FIELD_DESC);
      oprot.writeByte(struct.byteField);
      oprot.writeFieldEnd();
      oprot.writeFieldBegin(I16_FIELD_FIELD_DESC);
      oprot.writeI16(struct.i16Field);
      oprot.writeFieldEnd();
      if (struct.isSetI32Field()) {
        oprot.writeFieldBegin(I32_FIELD_FIELD_DESC);
        oprot.writeI32(struct.i32Field);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldBegin(I64_FIELD_FIELD_DESC);
      oprot.writeI64(struct.i64Field);
      oprot.writeFieldEnd();
      oprot.writeFieldBegin(DOUBLE_FIELD_FIELD_DESC);
      oprot.writeDouble(struct.doubleField);
      oprot.writeFieldEnd();
      if (struct.stringField != null) {
        oprot.writeFieldBegin(STRING_FIELD_FIELD_DESC);
        oprot.writeString(struct.stringField);
        oprot.writeFieldEnd();
      }
      if (struct.binaryField != null) {
        if (struct.isSetBinaryField()) {
          oprot.writeFieldBegin(BINARY_FIELD_FIELD_DESC);
          oprot.writeBinary(struct.binaryField);
          oprot.writeFieldEnd();
        }
      }
      if (struct.mapField != null) {
        oprot.writeFieldBegin(MAP_FIELD_FIELD_DESC);
        {
          oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.I32, struct.mapField.size()));
          for (Map.Entry<String, Integer> _iter10 : struct.mapField.entrySet())
          {
            oprot.writeString(_iter10.getKey());
            oprot.writeI32(_iter10.getValue());
          }
          oprot.writeMapEnd();
        }
        oprot.writeFieldEnd();
      }
      if (struct.listField != null) {
        oprot.writeFieldBegin(LIST_FIELD_FIELD_DESC);
        {
          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.I32, struct.listField.size()));
          for (int _iter11 : struct.listField)
          {
            oprot.writeI32(_iter11);
          }
          oprot.writeListEnd();
        }
        oprot.writeFieldEnd();
      }
      if (struct.setField != null) {
        oprot.writeFieldBegin(SET_FIELD_FIELD_DESC);
        {
          oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, struct.setField.size()));
          for (int _iter12 : struct.setField)
          {
            oprot.writeI32(_iter12);
          }
          oprot.writeSetEnd();
        }
        oprot.writeFieldEnd();
      }
      if (struct.enumField != null) {
        oprot.writeFieldBegin(ENUM_FIELD_FIELD_DESC);
        oprot.writeI32(struct.enumField.getValue());
        oprot.writeFieldEnd();
      }
      if (struct.structField != null) {
        oprot.writeFieldBegin(STRUCT_FIELD_FIELD_DESC);
        struct.structField.write(oprot);
        oprot.writeFieldEnd();
      }
      if (struct.fooOrBar != null) {
        oprot.writeFieldBegin(FOO_OR_BAR_FIELD_DESC);
        struct.fooOrBar.write(oprot);
        oprot.writeFieldEnd();
      }
      if (struct.isSetI16OptionalField()) {
        oprot.writeFieldBegin(I16_OPTIONAL_FIELD_FIELD_DESC);
        oprot.writeI16(struct.i16OptionalField);
        oprot.writeFieldEnd();
      }
      if (struct.isSetByteOptionalField()) {
        oprot.writeFieldBegin(BYTE_OPTIONAL_FIELD_FIELD_DESC);
        oprot.writeByte(struct.byteOptionalField);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class TestTupleSchemeFactory implements SchemeFactory {
    public TestTupleScheme getScheme() {
      return new TestTupleScheme();
    }
  }

  private static class TestTupleScheme extends TupleScheme<Test> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, Test struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      BitSet optionals = new BitSet();
      if (struct.isSetBoolField()) {
        optionals.set(0);
      }
      if (struct.isSetByteField()) {
        optionals.set(1);
      }
      if (struct.isSetByteOptionalField()) {
        optionals.set(2);
      }
      if (struct.isSetI16Field()) {
        optionals.set(3);
      }
      if (struct.isSetI16OptionalField()) {
        optionals.set(4);
      }
      if (struct.isSetI32Field()) {
        optionals.set(5);
      }
      if (struct.isSetI64Field()) {
        optionals.set(6);
      }
      if (struct.isSetDoubleField()) {
        optionals.set(7);
      }
      if (struct.isSetStringField()) {
        optionals.set(8);
      }
      if (struct.isSetBinaryField()) {
        optionals.set(9);
      }
      if (struct.isSetMapField()) {
        optionals.set(10);
      }
      if (struct.isSetListField()) {
        optionals.set(11);
      }
      if (struct.isSetSetField()) {
        optionals.set(12);
      }
      if (struct.isSetEnumField()) {
        optionals.set(13);
      }
      if (struct.isSetStructField()) {
        optionals.set(14);
      }
      if (struct.isSetFooOrBar()) {
        optionals.set(15);
      }
      oprot.writeBitSet(optionals, 16);
      if (struct.isSetBoolField()) {
        oprot.writeBool(struct.boolField);
      }
      if (struct.isSetByteField()) {
        oprot.writeByte(struct.byteField);
      }
      if (struct.isSetByteOptionalField()) {
        oprot.writeByte(struct.byteOptionalField);
      }
      if (struct.isSetI16Field()) {
        oprot.writeI16(struct.i16Field);
      }
      if (struct.isSetI16OptionalField()) {
        oprot.writeI16(struct.i16OptionalField);
      }
      if (struct.isSetI32Field()) {
        oprot.writeI32(struct.i32Field);
      }
      if (struct.isSetI64Field()) {
        oprot.writeI64(struct.i64Field);
      }
      if (struct.isSetDoubleField()) {
        oprot.writeDouble(struct.doubleField);
      }
      if (struct.isSetStringField()) {
        oprot.writeString(struct.stringField);
      }
      if (struct.isSetBinaryField()) {
        oprot.writeBinary(struct.binaryField);
      }
      if (struct.isSetMapField()) {
        {
          oprot.writeI32(struct.mapField.size());
          for (Map.Entry<String, Integer> _iter13 : struct.mapField.entrySet())
          {
            oprot.writeString(_iter13.getKey());
            oprot.writeI32(_iter13.getValue());
          }
        }
      }
      if (struct.isSetListField()) {
        {
          oprot.writeI32(struct.listField.size());
          for (int _iter14 : struct.listField)
          {
            oprot.writeI32(_iter14);
          }
        }
      }
      if (struct.isSetSetField()) {
        {
          oprot.writeI32(struct.setField.size());
          for (int _iter15 : struct.setField)
          {
            oprot.writeI32(_iter15);
          }
        }
      }
      if (struct.isSetEnumField()) {
        oprot.writeI32(struct.enumField.getValue());
      }
      if (struct.isSetStructField()) {
        struct.structField.write(oprot);
      }
      if (struct.isSetFooOrBar()) {
        struct.fooOrBar.write(oprot);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, Test struct) throws org.apache.thrift.TException {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      BitSet incoming = iprot.readBitSet(16);
      if (incoming.get(0)) {
        struct.boolField = iprot.readBool();
        struct.setBoolFieldIsSet(true);
      }
      if (incoming.get(1)) {
        struct.byteField = iprot.readByte();
        struct.setByteFieldIsSet(true);
      }
      if (incoming.get(2)) {
        struct.byteOptionalField = iprot.readByte();
        struct.setByteOptionalFieldIsSet(true);
      }
      if (incoming.get(3)) {
        struct.i16Field = iprot.readI16();
        struct.setI16FieldIsSet(true);
      }
      if (incoming.get(4)) {
        struct.i16OptionalField = iprot.readI16();
        struct.setI16OptionalFieldIsSet(true);
      }
      if (incoming.get(5)) {
        struct.i32Field = iprot.readI32();
        struct.setI32FieldIsSet(true);
      }
      if (incoming.get(6)) {
        struct.i64Field = iprot.readI64();
        struct.setI64FieldIsSet(true);
      }
      if (incoming.get(7)) {
        struct.doubleField = iprot.readDouble();
        struct.setDoubleFieldIsSet(true);
      }
      if (incoming.get(8)) {
        struct.stringField = iprot.readString();
        struct.setStringFieldIsSet(true);
      }
      if (incoming.get(9)) {
        struct.binaryField = iprot.readBinary();
        struct.setBinaryFieldIsSet(true);
      }
      if (incoming.get(10)) {
        {
          org.apache.thrift.protocol.TMap _map16 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.I32, iprot.readI32());
          struct.mapField = new HashMap<String,Integer>(2*_map16.size);
          for (int _i17 = 0; _i17 < _map16.size; ++_i17)
          {
            String _key18;
            int _val19;
            _key18 = iprot.readString();
            _val19 = iprot.readI32();
            struct.mapField.put(_key18, _val19);
          }
        }
        struct.setMapFieldIsSet(true);
      }
      if (incoming.get(11)) {
        {
          org.apache.thrift.protocol.TList _list20 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.I32, iprot.readI32());
          struct.listField = new ArrayList<Integer>(_list20.size);
          for (int _i21 = 0; _i21 < _list20.size; ++_i21)
          {
            int _elem22;
            _elem22 = iprot.readI32();
            struct.listField.add(_elem22);
          }
        }
        struct.setListFieldIsSet(true);
      }
      if (incoming.get(12)) {
        {
          org.apache.thrift.protocol.TSet _set23 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, iprot.readI32());
          struct.setField = new HashSet<Integer>(2*_set23.size);
          for (int _i24 = 0; _i24 < _set23.size; ++_i24)
          {
            int _elem25;
            _elem25 = iprot.readI32();
            struct.setField.add(_elem25);
          }
        }
        struct.setSetFieldIsSet(true);
      }
      if (incoming.get(13)) {
        struct.enumField = E.findByValue(iprot.readI32());
        struct.setEnumFieldIsSet(true);
      }
      if (incoming.get(14)) {
        struct.structField = new Nested();
        struct.structField.read(iprot);
        struct.setStructFieldIsSet(true);
      }
      if (incoming.get(15)) {
        struct.fooOrBar = new FooOrBar();
        struct.fooOrBar.read(iprot);
        struct.setFooOrBarIsSet(true);
      }
    }
  }

}

