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

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

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
/**
 * <p>Entity object which is used to register an entity in the system.</p>
 * <li><b>entityId</b> : Entity id provided by the client</li>
 * <li><b>domainId</b> : Domain id</li>
 * <li><b>entityTypeId</b> : Entity type id</li>
 * <li><b>ownerId</b> : Owner id</li>
 * <li>parentEntityId : Parent entity id</li>
 * <li><b>name</b> : Name</li>
 * <li>description : Short description for the entity</li>
 * <li>binaryData : Any information stored in binary format</li>
 * <li>fullText : A string which will be considered for full text search</li>
 * <li><b>originalEntityCreationTime</b> : When registering old records what is the original entity creation time. If not
 * set will be default to current time</li>
 * <li>createdTime : Will be set by the system</li>
 * <li>updatedTime : Will be set by the system</li>
 * 
 */
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
public class Entity implements org.apache.thrift.TBase<Entity, Entity._Fields>, java.io.Serializable, Cloneable, Comparable<Entity> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Entity");

  private static final org.apache.thrift.protocol.TField ENTITY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("entityId", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.thrift.protocol.TField ENTITY_TYPE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("entityTypeId", org.apache.thrift.protocol.TType.STRING, (short)3);
  private static final org.apache.thrift.protocol.TField OWNER_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("ownerId", org.apache.thrift.protocol.TType.STRING, (short)4);
  private static final org.apache.thrift.protocol.TField PARENT_ENTITY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("parentEntityId", org.apache.thrift.protocol.TType.STRING, (short)5);
  private static final org.apache.thrift.protocol.TField NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("name", org.apache.thrift.protocol.TType.STRING, (short)6);
  private static final org.apache.thrift.protocol.TField DESCRIPTION_FIELD_DESC = new org.apache.thrift.protocol.TField("description", org.apache.thrift.protocol.TType.STRING, (short)7);
  private static final org.apache.thrift.protocol.TField BINARY_DATA_FIELD_DESC = new org.apache.thrift.protocol.TField("binaryData", org.apache.thrift.protocol.TType.STRING, (short)8);
  private static final org.apache.thrift.protocol.TField FULL_TEXT_FIELD_DESC = new org.apache.thrift.protocol.TField("fullText", org.apache.thrift.protocol.TType.STRING, (short)9);
  private static final org.apache.thrift.protocol.TField SHARED_COUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("sharedCount", org.apache.thrift.protocol.TType.I64, (short)10);
  private static final org.apache.thrift.protocol.TField ORIGINAL_ENTITY_CREATION_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("originalEntityCreationTime", org.apache.thrift.protocol.TType.I64, (short)11);
  private static final org.apache.thrift.protocol.TField CREATED_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("createdTime", org.apache.thrift.protocol.TType.I64, (short)12);
  private static final org.apache.thrift.protocol.TField UPDATED_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("updatedTime", org.apache.thrift.protocol.TType.I64, (short)13);

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

  private java.lang.String entityId; // optional
  private java.lang.String domainId; // optional
  private java.lang.String entityTypeId; // optional
  private java.lang.String ownerId; // optional
  private java.lang.String parentEntityId; // optional
  private java.lang.String name; // optional
  private java.lang.String description; // optional
  private java.nio.ByteBuffer binaryData; // optional
  private java.lang.String fullText; // optional
  private long sharedCount; // optional
  private long originalEntityCreationTime; // optional
  private long createdTime; // optional
  private long updatedTime; // 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 {
    ENTITY_ID((short)1, "entityId"),
    DOMAIN_ID((short)2, "domainId"),
    ENTITY_TYPE_ID((short)3, "entityTypeId"),
    OWNER_ID((short)4, "ownerId"),
    PARENT_ENTITY_ID((short)5, "parentEntityId"),
    NAME((short)6, "name"),
    DESCRIPTION((short)7, "description"),
    BINARY_DATA((short)8, "binaryData"),
    FULL_TEXT((short)9, "fullText"),
    SHARED_COUNT((short)10, "sharedCount"),
    ORIGINAL_ENTITY_CREATION_TIME((short)11, "originalEntityCreationTime"),
    CREATED_TIME((short)12, "createdTime"),
    UPDATED_TIME((short)13, "updatedTime");

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

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

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // ENTITY_ID
          return ENTITY_ID;
        case 2: // DOMAIN_ID
          return DOMAIN_ID;
        case 3: // ENTITY_TYPE_ID
          return ENTITY_TYPE_ID;
        case 4: // OWNER_ID
          return OWNER_ID;
        case 5: // PARENT_ENTITY_ID
          return PARENT_ENTITY_ID;
        case 6: // NAME
          return NAME;
        case 7: // DESCRIPTION
          return DESCRIPTION;
        case 8: // BINARY_DATA
          return BINARY_DATA;
        case 9: // FULL_TEXT
          return FULL_TEXT;
        case 10: // SHARED_COUNT
          return SHARED_COUNT;
        case 11: // ORIGINAL_ENTITY_CREATION_TIME
          return ORIGINAL_ENTITY_CREATION_TIME;
        case 12: // CREATED_TIME
          return CREATED_TIME;
        case 13: // UPDATED_TIME
          return UPDATED_TIME;
        default:
          return null;
      }
    }

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

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

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

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

    public short getThriftFieldId() {
      return _thriftId;
    }

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

  // isset id assignments
  private static final int __SHAREDCOUNT_ISSET_ID = 0;
  private static final int __ORIGINALENTITYCREATIONTIME_ISSET_ID = 1;
  private static final int __CREATEDTIME_ISSET_ID = 2;
  private static final int __UPDATEDTIME_ISSET_ID = 3;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.ENTITY_ID,_Fields.DOMAIN_ID,_Fields.ENTITY_TYPE_ID,_Fields.OWNER_ID,_Fields.PARENT_ENTITY_ID,_Fields.NAME,_Fields.DESCRIPTION,_Fields.BINARY_DATA,_Fields.FULL_TEXT,_Fields.SHARED_COUNT,_Fields.ORIGINAL_ENTITY_CREATION_TIME,_Fields.CREATED_TIME,_Fields.UPDATED_TIME};
  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.ENTITY_ID, new org.apache.thrift.meta_data.FieldMetaData("entityId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.ENTITY_TYPE_ID, new org.apache.thrift.meta_data.FieldMetaData("entityTypeId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.OWNER_ID, new org.apache.thrift.meta_data.FieldMetaData("ownerId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.PARENT_ENTITY_ID, new org.apache.thrift.meta_data.FieldMetaData("parentEntityId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.NAME, new org.apache.thrift.meta_data.FieldMetaData("name", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.DESCRIPTION, new org.apache.thrift.meta_data.FieldMetaData("description", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.BINARY_DATA, new org.apache.thrift.meta_data.FieldMetaData("binaryData", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
    tmpMap.put(_Fields.FULL_TEXT, new org.apache.thrift.meta_data.FieldMetaData("fullText", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.SHARED_COUNT, new org.apache.thrift.meta_data.FieldMetaData("sharedCount", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.ORIGINAL_ENTITY_CREATION_TIME, new org.apache.thrift.meta_data.FieldMetaData("originalEntityCreationTime", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.CREATED_TIME, new org.apache.thrift.meta_data.FieldMetaData("createdTime", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.UPDATED_TIME, new org.apache.thrift.meta_data.FieldMetaData("updatedTime", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Entity.class, metaDataMap);
  }

  public Entity() {
    this.sharedCount = 0L;

  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public Entity(Entity other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetEntityId()) {
      this.entityId = other.entityId;
    }
    if (other.isSetDomainId()) {
      this.domainId = other.domainId;
    }
    if (other.isSetEntityTypeId()) {
      this.entityTypeId = other.entityTypeId;
    }
    if (other.isSetOwnerId()) {
      this.ownerId = other.ownerId;
    }
    if (other.isSetParentEntityId()) {
      this.parentEntityId = other.parentEntityId;
    }
    if (other.isSetName()) {
      this.name = other.name;
    }
    if (other.isSetDescription()) {
      this.description = other.description;
    }
    if (other.isSetBinaryData()) {
      this.binaryData = org.apache.thrift.TBaseHelper.copyBinary(other.binaryData);
    }
    if (other.isSetFullText()) {
      this.fullText = other.fullText;
    }
    this.sharedCount = other.sharedCount;
    this.originalEntityCreationTime = other.originalEntityCreationTime;
    this.createdTime = other.createdTime;
    this.updatedTime = other.updatedTime;
  }

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

  @Override
  public void clear() {
    this.entityId = null;
    this.domainId = null;
    this.entityTypeId = null;
    this.ownerId = null;
    this.parentEntityId = null;
    this.name = null;
    this.description = null;
    this.binaryData = null;
    this.fullText = null;
    this.sharedCount = 0L;

    setOriginalEntityCreationTimeIsSet(false);
    this.originalEntityCreationTime = 0;
    setCreatedTimeIsSet(false);
    this.createdTime = 0;
    setUpdatedTimeIsSet(false);
    this.updatedTime = 0;
  }

  public java.lang.String getEntityId() {
    return this.entityId;
  }

  public void setEntityId(java.lang.String entityId) {
    this.entityId = entityId;
  }

  public void unsetEntityId() {
    this.entityId = null;
  }

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

  public void setEntityIdIsSet(boolean value) {
    if (!value) {
      this.entityId = null;
    }
  }

  public java.lang.String getDomainId() {
    return this.domainId;
  }

  public void setDomainId(java.lang.String domainId) {
    this.domainId = domainId;
  }

  public void unsetDomainId() {
    this.domainId = null;
  }

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

  public void setDomainIdIsSet(boolean value) {
    if (!value) {
      this.domainId = null;
    }
  }

  public java.lang.String getEntityTypeId() {
    return this.entityTypeId;
  }

  public void setEntityTypeId(java.lang.String entityTypeId) {
    this.entityTypeId = entityTypeId;
  }

  public void unsetEntityTypeId() {
    this.entityTypeId = null;
  }

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

  public void setEntityTypeIdIsSet(boolean value) {
    if (!value) {
      this.entityTypeId = null;
    }
  }

  public java.lang.String getOwnerId() {
    return this.ownerId;
  }

  public void setOwnerId(java.lang.String ownerId) {
    this.ownerId = ownerId;
  }

  public void unsetOwnerId() {
    this.ownerId = null;
  }

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

  public void setOwnerIdIsSet(boolean value) {
    if (!value) {
      this.ownerId = null;
    }
  }

  public java.lang.String getParentEntityId() {
    return this.parentEntityId;
  }

  public void setParentEntityId(java.lang.String parentEntityId) {
    this.parentEntityId = parentEntityId;
  }

  public void unsetParentEntityId() {
    this.parentEntityId = null;
  }

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

  public void setParentEntityIdIsSet(boolean value) {
    if (!value) {
      this.parentEntityId = null;
    }
  }

  public java.lang.String getName() {
    return this.name;
  }

  public void setName(java.lang.String name) {
    this.name = name;
  }

  public void unsetName() {
    this.name = null;
  }

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

  public void setNameIsSet(boolean value) {
    if (!value) {
      this.name = null;
    }
  }

  public java.lang.String getDescription() {
    return this.description;
  }

  public void setDescription(java.lang.String description) {
    this.description = description;
  }

  public void unsetDescription() {
    this.description = null;
  }

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

  public void setDescriptionIsSet(boolean value) {
    if (!value) {
      this.description = null;
    }
  }

  public byte[] getBinaryData() {
    setBinaryData(org.apache.thrift.TBaseHelper.rightSize(binaryData));
    return binaryData == null ? null : binaryData.array();
  }

  public java.nio.ByteBuffer bufferForBinaryData() {
    return org.apache.thrift.TBaseHelper.copyBinary(binaryData);
  }

  public void setBinaryData(byte[] binaryData) {
    this.binaryData = binaryData == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(binaryData.clone());
  }

  public void setBinaryData(java.nio.ByteBuffer binaryData) {
    this.binaryData = org.apache.thrift.TBaseHelper.copyBinary(binaryData);
  }

  public void unsetBinaryData() {
    this.binaryData = null;
  }

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

  public void setBinaryDataIsSet(boolean value) {
    if (!value) {
      this.binaryData = null;
    }
  }

  public java.lang.String getFullText() {
    return this.fullText;
  }

  public void setFullText(java.lang.String fullText) {
    this.fullText = fullText;
  }

  public void unsetFullText() {
    this.fullText = null;
  }

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

  public void setFullTextIsSet(boolean value) {
    if (!value) {
      this.fullText = null;
    }
  }

  public long getSharedCount() {
    return this.sharedCount;
  }

  public void setSharedCount(long sharedCount) {
    this.sharedCount = sharedCount;
    setSharedCountIsSet(true);
  }

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

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

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

  public long getOriginalEntityCreationTime() {
    return this.originalEntityCreationTime;
  }

  public void setOriginalEntityCreationTime(long originalEntityCreationTime) {
    this.originalEntityCreationTime = originalEntityCreationTime;
    setOriginalEntityCreationTimeIsSet(true);
  }

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

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

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

  public long getCreatedTime() {
    return this.createdTime;
  }

  public void setCreatedTime(long createdTime) {
    this.createdTime = createdTime;
    setCreatedTimeIsSet(true);
  }

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

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

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

  public long getUpdatedTime() {
    return this.updatedTime;
  }

  public void setUpdatedTime(long updatedTime) {
    this.updatedTime = updatedTime;
    setUpdatedTimeIsSet(true);
  }

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

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

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

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

    case DOMAIN_ID:
      if (value == null) {
        unsetDomainId();
      } else {
        setDomainId((java.lang.String)value);
      }
      break;

    case ENTITY_TYPE_ID:
      if (value == null) {
        unsetEntityTypeId();
      } else {
        setEntityTypeId((java.lang.String)value);
      }
      break;

    case OWNER_ID:
      if (value == null) {
        unsetOwnerId();
      } else {
        setOwnerId((java.lang.String)value);
      }
      break;

    case PARENT_ENTITY_ID:
      if (value == null) {
        unsetParentEntityId();
      } else {
        setParentEntityId((java.lang.String)value);
      }
      break;

    case NAME:
      if (value == null) {
        unsetName();
      } else {
        setName((java.lang.String)value);
      }
      break;

    case DESCRIPTION:
      if (value == null) {
        unsetDescription();
      } else {
        setDescription((java.lang.String)value);
      }
      break;

    case BINARY_DATA:
      if (value == null) {
        unsetBinaryData();
      } else {
        if (value instanceof byte[]) {
          setBinaryData((byte[])value);
        } else {
          setBinaryData((java.nio.ByteBuffer)value);
        }
      }
      break;

    case FULL_TEXT:
      if (value == null) {
        unsetFullText();
      } else {
        setFullText((java.lang.String)value);
      }
      break;

    case SHARED_COUNT:
      if (value == null) {
        unsetSharedCount();
      } else {
        setSharedCount((java.lang.Long)value);
      }
      break;

    case ORIGINAL_ENTITY_CREATION_TIME:
      if (value == null) {
        unsetOriginalEntityCreationTime();
      } else {
        setOriginalEntityCreationTime((java.lang.Long)value);
      }
      break;

    case CREATED_TIME:
      if (value == null) {
        unsetCreatedTime();
      } else {
        setCreatedTime((java.lang.Long)value);
      }
      break;

    case UPDATED_TIME:
      if (value == null) {
        unsetUpdatedTime();
      } else {
        setUpdatedTime((java.lang.Long)value);
      }
      break;

    }
  }

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

    case DOMAIN_ID:
      return getDomainId();

    case ENTITY_TYPE_ID:
      return getEntityTypeId();

    case OWNER_ID:
      return getOwnerId();

    case PARENT_ENTITY_ID:
      return getParentEntityId();

    case NAME:
      return getName();

    case DESCRIPTION:
      return getDescription();

    case BINARY_DATA:
      return getBinaryData();

    case FULL_TEXT:
      return getFullText();

    case SHARED_COUNT:
      return getSharedCount();

    case ORIGINAL_ENTITY_CREATION_TIME:
      return getOriginalEntityCreationTime();

    case CREATED_TIME:
      return getCreatedTime();

    case UPDATED_TIME:
      return getUpdatedTime();

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

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

    switch (field) {
    case ENTITY_ID:
      return isSetEntityId();
    case DOMAIN_ID:
      return isSetDomainId();
    case ENTITY_TYPE_ID:
      return isSetEntityTypeId();
    case OWNER_ID:
      return isSetOwnerId();
    case PARENT_ENTITY_ID:
      return isSetParentEntityId();
    case NAME:
      return isSetName();
    case DESCRIPTION:
      return isSetDescription();
    case BINARY_DATA:
      return isSetBinaryData();
    case FULL_TEXT:
      return isSetFullText();
    case SHARED_COUNT:
      return isSetSharedCount();
    case ORIGINAL_ENTITY_CREATION_TIME:
      return isSetOriginalEntityCreationTime();
    case CREATED_TIME:
      return isSetCreatedTime();
    case UPDATED_TIME:
      return isSetUpdatedTime();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_entityId = true && this.isSetEntityId();
    boolean that_present_entityId = true && that.isSetEntityId();
    if (this_present_entityId || that_present_entityId) {
      if (!(this_present_entityId && that_present_entityId))
        return false;
      if (!this.entityId.equals(that.entityId))
        return false;
    }

    boolean this_present_domainId = true && this.isSetDomainId();
    boolean that_present_domainId = true && that.isSetDomainId();
    if (this_present_domainId || that_present_domainId) {
      if (!(this_present_domainId && that_present_domainId))
        return false;
      if (!this.domainId.equals(that.domainId))
        return false;
    }

    boolean this_present_entityTypeId = true && this.isSetEntityTypeId();
    boolean that_present_entityTypeId = true && that.isSetEntityTypeId();
    if (this_present_entityTypeId || that_present_entityTypeId) {
      if (!(this_present_entityTypeId && that_present_entityTypeId))
        return false;
      if (!this.entityTypeId.equals(that.entityTypeId))
        return false;
    }

    boolean this_present_ownerId = true && this.isSetOwnerId();
    boolean that_present_ownerId = true && that.isSetOwnerId();
    if (this_present_ownerId || that_present_ownerId) {
      if (!(this_present_ownerId && that_present_ownerId))
        return false;
      if (!this.ownerId.equals(that.ownerId))
        return false;
    }

    boolean this_present_parentEntityId = true && this.isSetParentEntityId();
    boolean that_present_parentEntityId = true && that.isSetParentEntityId();
    if (this_present_parentEntityId || that_present_parentEntityId) {
      if (!(this_present_parentEntityId && that_present_parentEntityId))
        return false;
      if (!this.parentEntityId.equals(that.parentEntityId))
        return false;
    }

    boolean this_present_name = true && this.isSetName();
    boolean that_present_name = true && that.isSetName();
    if (this_present_name || that_present_name) {
      if (!(this_present_name && that_present_name))
        return false;
      if (!this.name.equals(that.name))
        return false;
    }

    boolean this_present_description = true && this.isSetDescription();
    boolean that_present_description = true && that.isSetDescription();
    if (this_present_description || that_present_description) {
      if (!(this_present_description && that_present_description))
        return false;
      if (!this.description.equals(that.description))
        return false;
    }

    boolean this_present_binaryData = true && this.isSetBinaryData();
    boolean that_present_binaryData = true && that.isSetBinaryData();
    if (this_present_binaryData || that_present_binaryData) {
      if (!(this_present_binaryData && that_present_binaryData))
        return false;
      if (!this.binaryData.equals(that.binaryData))
        return false;
    }

    boolean this_present_fullText = true && this.isSetFullText();
    boolean that_present_fullText = true && that.isSetFullText();
    if (this_present_fullText || that_present_fullText) {
      if (!(this_present_fullText && that_present_fullText))
        return false;
      if (!this.fullText.equals(that.fullText))
        return false;
    }

    boolean this_present_sharedCount = true && this.isSetSharedCount();
    boolean that_present_sharedCount = true && that.isSetSharedCount();
    if (this_present_sharedCount || that_present_sharedCount) {
      if (!(this_present_sharedCount && that_present_sharedCount))
        return false;
      if (this.sharedCount != that.sharedCount)
        return false;
    }

    boolean this_present_originalEntityCreationTime = true && this.isSetOriginalEntityCreationTime();
    boolean that_present_originalEntityCreationTime = true && that.isSetOriginalEntityCreationTime();
    if (this_present_originalEntityCreationTime || that_present_originalEntityCreationTime) {
      if (!(this_present_originalEntityCreationTime && that_present_originalEntityCreationTime))
        return false;
      if (this.originalEntityCreationTime != that.originalEntityCreationTime)
        return false;
    }

    boolean this_present_createdTime = true && this.isSetCreatedTime();
    boolean that_present_createdTime = true && that.isSetCreatedTime();
    if (this_present_createdTime || that_present_createdTime) {
      if (!(this_present_createdTime && that_present_createdTime))
        return false;
      if (this.createdTime != that.createdTime)
        return false;
    }

    boolean this_present_updatedTime = true && this.isSetUpdatedTime();
    boolean that_present_updatedTime = true && that.isSetUpdatedTime();
    if (this_present_updatedTime || that_present_updatedTime) {
      if (!(this_present_updatedTime && that_present_updatedTime))
        return false;
      if (this.updatedTime != that.updatedTime)
        return false;
    }

    return true;
  }

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

    hashCode = hashCode * 8191 + ((isSetEntityId()) ? 131071 : 524287);
    if (isSetEntityId())
      hashCode = hashCode * 8191 + entityId.hashCode();

    hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
    if (isSetDomainId())
      hashCode = hashCode * 8191 + domainId.hashCode();

    hashCode = hashCode * 8191 + ((isSetEntityTypeId()) ? 131071 : 524287);
    if (isSetEntityTypeId())
      hashCode = hashCode * 8191 + entityTypeId.hashCode();

    hashCode = hashCode * 8191 + ((isSetOwnerId()) ? 131071 : 524287);
    if (isSetOwnerId())
      hashCode = hashCode * 8191 + ownerId.hashCode();

    hashCode = hashCode * 8191 + ((isSetParentEntityId()) ? 131071 : 524287);
    if (isSetParentEntityId())
      hashCode = hashCode * 8191 + parentEntityId.hashCode();

    hashCode = hashCode * 8191 + ((isSetName()) ? 131071 : 524287);
    if (isSetName())
      hashCode = hashCode * 8191 + name.hashCode();

    hashCode = hashCode * 8191 + ((isSetDescription()) ? 131071 : 524287);
    if (isSetDescription())
      hashCode = hashCode * 8191 + description.hashCode();

    hashCode = hashCode * 8191 + ((isSetBinaryData()) ? 131071 : 524287);
    if (isSetBinaryData())
      hashCode = hashCode * 8191 + binaryData.hashCode();

    hashCode = hashCode * 8191 + ((isSetFullText()) ? 131071 : 524287);
    if (isSetFullText())
      hashCode = hashCode * 8191 + fullText.hashCode();

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

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

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

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

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(isSetEntityId()).compareTo(other.isSetEntityId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetEntityId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityId, other.entityId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetDomainId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetEntityTypeId()).compareTo(other.isSetEntityTypeId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetEntityTypeId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityTypeId, other.entityTypeId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetOwnerId()).compareTo(other.isSetOwnerId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetOwnerId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ownerId, other.ownerId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetParentEntityId()).compareTo(other.isSetParentEntityId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetParentEntityId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.parentEntityId, other.parentEntityId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetName()).compareTo(other.isSetName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.name, other.name);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetDescription()).compareTo(other.isSetDescription());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetDescription()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.description, other.description);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetBinaryData()).compareTo(other.isSetBinaryData());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetBinaryData()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.binaryData, other.binaryData);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetFullText()).compareTo(other.isSetFullText());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetFullText()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.fullText, other.fullText);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetSharedCount()).compareTo(other.isSetSharedCount());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetSharedCount()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sharedCount, other.sharedCount);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetOriginalEntityCreationTime()).compareTo(other.isSetOriginalEntityCreationTime());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetOriginalEntityCreationTime()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.originalEntityCreationTime, other.originalEntityCreationTime);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetCreatedTime()).compareTo(other.isSetCreatedTime());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetCreatedTime()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.createdTime, other.createdTime);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetUpdatedTime()).compareTo(other.isSetUpdatedTime());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetUpdatedTime()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.updatedTime, other.updatedTime);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

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

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

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

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

    if (isSetEntityId()) {
      sb.append("entityId:");
      if (this.entityId == null) {
        sb.append("null");
      } else {
        sb.append(this.entityId);
      }
      first = false;
    }
    if (isSetDomainId()) {
      if (!first) sb.append(", ");
      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
    }
    if (isSetEntityTypeId()) {
      if (!first) sb.append(", ");
      sb.append("entityTypeId:");
      if (this.entityTypeId == null) {
        sb.append("null");
      } else {
        sb.append(this.entityTypeId);
      }
      first = false;
    }
    if (isSetOwnerId()) {
      if (!first) sb.append(", ");
      sb.append("ownerId:");
      if (this.ownerId == null) {
        sb.append("null");
      } else {
        sb.append(this.ownerId);
      }
      first = false;
    }
    if (isSetParentEntityId()) {
      if (!first) sb.append(", ");
      sb.append("parentEntityId:");
      if (this.parentEntityId == null) {
        sb.append("null");
      } else {
        sb.append(this.parentEntityId);
      }
      first = false;
    }
    if (isSetName()) {
      if (!first) sb.append(", ");
      sb.append("name:");
      if (this.name == null) {
        sb.append("null");
      } else {
        sb.append(this.name);
      }
      first = false;
    }
    if (isSetDescription()) {
      if (!first) sb.append(", ");
      sb.append("description:");
      if (this.description == null) {
        sb.append("null");
      } else {
        sb.append(this.description);
      }
      first = false;
    }
    if (isSetBinaryData()) {
      if (!first) sb.append(", ");
      sb.append("binaryData:");
      if (this.binaryData == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.binaryData, sb);
      }
      first = false;
    }
    if (isSetFullText()) {
      if (!first) sb.append(", ");
      sb.append("fullText:");
      if (this.fullText == null) {
        sb.append("null");
      } else {
        sb.append(this.fullText);
      }
      first = false;
    }
    if (isSetSharedCount()) {
      if (!first) sb.append(", ");
      sb.append("sharedCount:");
      sb.append(this.sharedCount);
      first = false;
    }
    if (isSetOriginalEntityCreationTime()) {
      if (!first) sb.append(", ");
      sb.append("originalEntityCreationTime:");
      sb.append(this.originalEntityCreationTime);
      first = false;
    }
    if (isSetCreatedTime()) {
      if (!first) sb.append(", ");
      sb.append("createdTime:");
      sb.append(this.createdTime);
      first = false;
    }
    if (isSetUpdatedTime()) {
      if (!first) sb.append(", ");
      sb.append("updatedTime:");
      sb.append(this.updatedTime);
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.thrift.TException {
    // check for required fields
    // check for sub-struct validity
  }

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

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

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

  private static class EntityStandardScheme extends org.apache.thrift.scheme.StandardScheme<Entity> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, Entity 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: // ENTITY_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.entityId = iprot.readString();
              struct.setEntityIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // DOMAIN_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.domainId = iprot.readString();
              struct.setDomainIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // ENTITY_TYPE_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.entityTypeId = iprot.readString();
              struct.setEntityTypeIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // OWNER_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.ownerId = iprot.readString();
              struct.setOwnerIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // PARENT_ENTITY_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.parentEntityId = iprot.readString();
              struct.setParentEntityIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.name = iprot.readString();
              struct.setNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // DESCRIPTION
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.description = iprot.readString();
              struct.setDescriptionIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // BINARY_DATA
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.binaryData = iprot.readBinary();
              struct.setBinaryDataIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // FULL_TEXT
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.fullText = iprot.readString();
              struct.setFullTextIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // SHARED_COUNT
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.sharedCount = iprot.readI64();
              struct.setSharedCountIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 11: // ORIGINAL_ENTITY_CREATION_TIME
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.originalEntityCreationTime = iprot.readI64();
              struct.setOriginalEntityCreationTimeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 12: // CREATED_TIME
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.createdTime = iprot.readI64();
              struct.setCreatedTimeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 13: // UPDATED_TIME
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.updatedTime = iprot.readI64();
              struct.setUpdatedTimeIsSet(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, Entity struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.entityId != null) {
        if (struct.isSetEntityId()) {
          oprot.writeFieldBegin(ENTITY_ID_FIELD_DESC);
          oprot.writeString(struct.entityId);
          oprot.writeFieldEnd();
        }
      }
      if (struct.domainId != null) {
        if (struct.isSetDomainId()) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
      }
      if (struct.entityTypeId != null) {
        if (struct.isSetEntityTypeId()) {
          oprot.writeFieldBegin(ENTITY_TYPE_ID_FIELD_DESC);
          oprot.writeString(struct.entityTypeId);
          oprot.writeFieldEnd();
        }
      }
      if (struct.ownerId != null) {
        if (struct.isSetOwnerId()) {
          oprot.writeFieldBegin(OWNER_ID_FIELD_DESC);
          oprot.writeString(struct.ownerId);
          oprot.writeFieldEnd();
        }
      }
      if (struct.parentEntityId != null) {
        if (struct.isSetParentEntityId()) {
          oprot.writeFieldBegin(PARENT_ENTITY_ID_FIELD_DESC);
          oprot.writeString(struct.parentEntityId);
          oprot.writeFieldEnd();
        }
      }
      if (struct.name != null) {
        if (struct.isSetName()) {
          oprot.writeFieldBegin(NAME_FIELD_DESC);
          oprot.writeString(struct.name);
          oprot.writeFieldEnd();
        }
      }
      if (struct.description != null) {
        if (struct.isSetDescription()) {
          oprot.writeFieldBegin(DESCRIPTION_FIELD_DESC);
          oprot.writeString(struct.description);
          oprot.writeFieldEnd();
        }
      }
      if (struct.binaryData != null) {
        if (struct.isSetBinaryData()) {
          oprot.writeFieldBegin(BINARY_DATA_FIELD_DESC);
          oprot.writeBinary(struct.binaryData);
          oprot.writeFieldEnd();
        }
      }
      if (struct.fullText != null) {
        if (struct.isSetFullText()) {
          oprot.writeFieldBegin(FULL_TEXT_FIELD_DESC);
          oprot.writeString(struct.fullText);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetSharedCount()) {
        oprot.writeFieldBegin(SHARED_COUNT_FIELD_DESC);
        oprot.writeI64(struct.sharedCount);
        oprot.writeFieldEnd();
      }
      if (struct.isSetOriginalEntityCreationTime()) {
        oprot.writeFieldBegin(ORIGINAL_ENTITY_CREATION_TIME_FIELD_DESC);
        oprot.writeI64(struct.originalEntityCreationTime);
        oprot.writeFieldEnd();
      }
      if (struct.isSetCreatedTime()) {
        oprot.writeFieldBegin(CREATED_TIME_FIELD_DESC);
        oprot.writeI64(struct.createdTime);
        oprot.writeFieldEnd();
      }
      if (struct.isSetUpdatedTime()) {
        oprot.writeFieldBegin(UPDATED_TIME_FIELD_DESC);
        oprot.writeI64(struct.updatedTime);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

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

  private static class EntityTupleScheme extends org.apache.thrift.scheme.TupleScheme<Entity> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, Entity struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.isSetEntityId()) {
        optionals.set(0);
      }
      if (struct.isSetDomainId()) {
        optionals.set(1);
      }
      if (struct.isSetEntityTypeId()) {
        optionals.set(2);
      }
      if (struct.isSetOwnerId()) {
        optionals.set(3);
      }
      if (struct.isSetParentEntityId()) {
        optionals.set(4);
      }
      if (struct.isSetName()) {
        optionals.set(5);
      }
      if (struct.isSetDescription()) {
        optionals.set(6);
      }
      if (struct.isSetBinaryData()) {
        optionals.set(7);
      }
      if (struct.isSetFullText()) {
        optionals.set(8);
      }
      if (struct.isSetSharedCount()) {
        optionals.set(9);
      }
      if (struct.isSetOriginalEntityCreationTime()) {
        optionals.set(10);
      }
      if (struct.isSetCreatedTime()) {
        optionals.set(11);
      }
      if (struct.isSetUpdatedTime()) {
        optionals.set(12);
      }
      oprot.writeBitSet(optionals, 13);
      if (struct.isSetEntityId()) {
        oprot.writeString(struct.entityId);
      }
      if (struct.isSetDomainId()) {
        oprot.writeString(struct.domainId);
      }
      if (struct.isSetEntityTypeId()) {
        oprot.writeString(struct.entityTypeId);
      }
      if (struct.isSetOwnerId()) {
        oprot.writeString(struct.ownerId);
      }
      if (struct.isSetParentEntityId()) {
        oprot.writeString(struct.parentEntityId);
      }
      if (struct.isSetName()) {
        oprot.writeString(struct.name);
      }
      if (struct.isSetDescription()) {
        oprot.writeString(struct.description);
      }
      if (struct.isSetBinaryData()) {
        oprot.writeBinary(struct.binaryData);
      }
      if (struct.isSetFullText()) {
        oprot.writeString(struct.fullText);
      }
      if (struct.isSetSharedCount()) {
        oprot.writeI64(struct.sharedCount);
      }
      if (struct.isSetOriginalEntityCreationTime()) {
        oprot.writeI64(struct.originalEntityCreationTime);
      }
      if (struct.isSetCreatedTime()) {
        oprot.writeI64(struct.createdTime);
      }
      if (struct.isSetUpdatedTime()) {
        oprot.writeI64(struct.updatedTime);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, Entity struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      java.util.BitSet incoming = iprot.readBitSet(13);
      if (incoming.get(0)) {
        struct.entityId = iprot.readString();
        struct.setEntityIdIsSet(true);
      }
      if (incoming.get(1)) {
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
      }
      if (incoming.get(2)) {
        struct.entityTypeId = iprot.readString();
        struct.setEntityTypeIdIsSet(true);
      }
      if (incoming.get(3)) {
        struct.ownerId = iprot.readString();
        struct.setOwnerIdIsSet(true);
      }
      if (incoming.get(4)) {
        struct.parentEntityId = iprot.readString();
        struct.setParentEntityIdIsSet(true);
      }
      if (incoming.get(5)) {
        struct.name = iprot.readString();
        struct.setNameIsSet(true);
      }
      if (incoming.get(6)) {
        struct.description = iprot.readString();
        struct.setDescriptionIsSet(true);
      }
      if (incoming.get(7)) {
        struct.binaryData = iprot.readBinary();
        struct.setBinaryDataIsSet(true);
      }
      if (incoming.get(8)) {
        struct.fullText = iprot.readString();
        struct.setFullTextIsSet(true);
      }
      if (incoming.get(9)) {
        struct.sharedCount = iprot.readI64();
        struct.setSharedCountIsSet(true);
      }
      if (incoming.get(10)) {
        struct.originalEntityCreationTime = iprot.readI64();
        struct.setOriginalEntityCreationTimeIsSet(true);
      }
      if (incoming.get(11)) {
        struct.createdTime = iprot.readI64();
        struct.setCreatedTimeIsSet(true);
      }
      if (incoming.get(12)) {
        struct.updatedTime = iprot.readI64();
        struct.setUpdatedTimeIsSet(true);
      }
    }
  }

  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
  }
}

