/**
 * Autogenerated by Thrift Compiler (0.9.0)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.sentry.provider.db.service.thrift;

import org.apache.commons.lang.builder.HashCodeBuilder;
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 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 TSentryStoreRecord implements org.apache.thrift.TBase<TSentryStoreRecord, TSentryStoreRecord._Fields>, java.io.Serializable, Cloneable {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TSentryStoreRecord");

  private static final org.apache.thrift.protocol.TField STORE_OP_FIELD_DESC = new org.apache.thrift.protocol.TField("storeOp", org.apache.thrift.protocol.TType.I32, (short)1);
  private static final org.apache.thrift.protocol.TField ROLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("roleName", org.apache.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.thrift.protocol.TField GRANTOR_PRINCIPAL_FIELD_DESC = new org.apache.thrift.protocol.TField("grantorPrincipal", org.apache.thrift.protocol.TType.STRING, (short)3);
  private static final org.apache.thrift.protocol.TField PRIVILEGES_FIELD_DESC = new org.apache.thrift.protocol.TField("privileges", org.apache.thrift.protocol.TType.SET, (short)4);
  private static final org.apache.thrift.protocol.TField GROUPS_FIELD_DESC = new org.apache.thrift.protocol.TField("groups", org.apache.thrift.protocol.TType.SET, (short)5);
  private static final org.apache.thrift.protocol.TField AUTHORIZABLE_FIELD_DESC = new org.apache.thrift.protocol.TField("authorizable", org.apache.thrift.protocol.TType.STRUCT, (short)6);
  private static final org.apache.thrift.protocol.TField NEW_AUTHORIZABLE_FIELD_DESC = new org.apache.thrift.protocol.TField("newAuthorizable", org.apache.thrift.protocol.TType.STRUCT, (short)7);
  private static final org.apache.thrift.protocol.TField VERSION_FIELD_DESC = new org.apache.thrift.protocol.TField("version", org.apache.thrift.protocol.TType.STRING, (short)8);
  private static final org.apache.thrift.protocol.TField VERSION_COMMENT_FIELD_DESC = new org.apache.thrift.protocol.TField("versionComment", org.apache.thrift.protocol.TType.STRING, (short)9);
  private static final org.apache.thrift.protocol.TField SNAPSHOT_FIELD_DESC = new org.apache.thrift.protocol.TField("snapshot", org.apache.thrift.protocol.TType.STRUCT, (short)10);

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

  private TSentryStoreOp storeOp; // required
  private String roleName; // optional
  private String grantorPrincipal; // optional
  private Set<TSentryPrivilege> privileges; // optional
  private Set<String> groups; // optional
  private TSentryAuthorizable authorizable; // optional
  private TSentryAuthorizable newAuthorizable; // optional
  private String version; // optional
  private String versionComment; // optional
  private TStoreSnapshot snapshot; // 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 {
    /**
     * 
     * @see TSentryStoreOp
     */
    STORE_OP((short)1, "storeOp"),
    ROLE_NAME((short)2, "roleName"),
    GRANTOR_PRINCIPAL((short)3, "grantorPrincipal"),
    PRIVILEGES((short)4, "privileges"),
    GROUPS((short)5, "groups"),
    AUTHORIZABLE((short)6, "authorizable"),
    NEW_AUTHORIZABLE((short)7, "newAuthorizable"),
    VERSION((short)8, "version"),
    VERSION_COMMENT((short)9, "versionComment"),
    SNAPSHOT((short)10, "snapshot");

    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: // STORE_OP
          return STORE_OP;
        case 2: // ROLE_NAME
          return ROLE_NAME;
        case 3: // GRANTOR_PRINCIPAL
          return GRANTOR_PRINCIPAL;
        case 4: // PRIVILEGES
          return PRIVILEGES;
        case 5: // GROUPS
          return GROUPS;
        case 6: // AUTHORIZABLE
          return AUTHORIZABLE;
        case 7: // NEW_AUTHORIZABLE
          return NEW_AUTHORIZABLE;
        case 8: // VERSION
          return VERSION;
        case 9: // VERSION_COMMENT
          return VERSION_COMMENT;
        case 10: // SNAPSHOT
          return SNAPSHOT;
        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 _Fields optionals[] = {_Fields.ROLE_NAME,_Fields.GRANTOR_PRINCIPAL,_Fields.PRIVILEGES,_Fields.GROUPS,_Fields.AUTHORIZABLE,_Fields.NEW_AUTHORIZABLE,_Fields.VERSION,_Fields.VERSION_COMMENT,_Fields.SNAPSHOT};
  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.STORE_OP, new org.apache.thrift.meta_data.FieldMetaData("storeOp", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, TSentryStoreOp.class)));
    tmpMap.put(_Fields.ROLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("roleName", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.GRANTOR_PRINCIPAL, new org.apache.thrift.meta_data.FieldMetaData("grantorPrincipal", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.PRIVILEGES, new org.apache.thrift.meta_data.FieldMetaData("privileges", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, 
            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TSentryPrivilege.class))));
    tmpMap.put(_Fields.GROUPS, new org.apache.thrift.meta_data.FieldMetaData("groups", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        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.STRING))));
    tmpMap.put(_Fields.AUTHORIZABLE, new org.apache.thrift.meta_data.FieldMetaData("authorizable", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TSentryAuthorizable.class)));
    tmpMap.put(_Fields.NEW_AUTHORIZABLE, new org.apache.thrift.meta_data.FieldMetaData("newAuthorizable", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TSentryAuthorizable.class)));
    tmpMap.put(_Fields.VERSION, new org.apache.thrift.meta_data.FieldMetaData("version", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.VERSION_COMMENT, new org.apache.thrift.meta_data.FieldMetaData("versionComment", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.SNAPSHOT, new org.apache.thrift.meta_data.FieldMetaData("snapshot", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TStoreSnapshot.class)));
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TSentryStoreRecord.class, metaDataMap);
  }

  public TSentryStoreRecord() {
  }

  public TSentryStoreRecord(
    TSentryStoreOp storeOp)
  {
    this();
    this.storeOp = storeOp;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public TSentryStoreRecord(TSentryStoreRecord other) {
    if (other.isSetStoreOp()) {
      this.storeOp = other.storeOp;
    }
    if (other.isSetRoleName()) {
      this.roleName = other.roleName;
    }
    if (other.isSetGrantorPrincipal()) {
      this.grantorPrincipal = other.grantorPrincipal;
    }
    if (other.isSetPrivileges()) {
      Set<TSentryPrivilege> __this__privileges = new HashSet<TSentryPrivilege>();
      for (TSentryPrivilege other_element : other.privileges) {
        __this__privileges.add(new TSentryPrivilege(other_element));
      }
      this.privileges = __this__privileges;
    }
    if (other.isSetGroups()) {
      Set<String> __this__groups = new HashSet<String>();
      for (String other_element : other.groups) {
        __this__groups.add(other_element);
      }
      this.groups = __this__groups;
    }
    if (other.isSetAuthorizable()) {
      this.authorizable = new TSentryAuthorizable(other.authorizable);
    }
    if (other.isSetNewAuthorizable()) {
      this.newAuthorizable = new TSentryAuthorizable(other.newAuthorizable);
    }
    if (other.isSetVersion()) {
      this.version = other.version;
    }
    if (other.isSetVersionComment()) {
      this.versionComment = other.versionComment;
    }
    if (other.isSetSnapshot()) {
      this.snapshot = new TStoreSnapshot(other.snapshot);
    }
  }

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

  @Override
  public void clear() {
    this.storeOp = null;
    this.roleName = null;
    this.grantorPrincipal = null;
    this.privileges = null;
    this.groups = null;
    this.authorizable = null;
    this.newAuthorizable = null;
    this.version = null;
    this.versionComment = null;
    this.snapshot = null;
  }

  /**
   * 
   * @see TSentryStoreOp
   */
  public TSentryStoreOp getStoreOp() {
    return this.storeOp;
  }

  /**
   * 
   * @see TSentryStoreOp
   */
  public void setStoreOp(TSentryStoreOp storeOp) {
    this.storeOp = storeOp;
  }

  public void unsetStoreOp() {
    this.storeOp = null;
  }

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

  public void setStoreOpIsSet(boolean value) {
    if (!value) {
      this.storeOp = null;
    }
  }

  public String getRoleName() {
    return this.roleName;
  }

  public void setRoleName(String roleName) {
    this.roleName = roleName;
  }

  public void unsetRoleName() {
    this.roleName = null;
  }

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

  public void setRoleNameIsSet(boolean value) {
    if (!value) {
      this.roleName = null;
    }
  }

  public String getGrantorPrincipal() {
    return this.grantorPrincipal;
  }

  public void setGrantorPrincipal(String grantorPrincipal) {
    this.grantorPrincipal = grantorPrincipal;
  }

  public void unsetGrantorPrincipal() {
    this.grantorPrincipal = null;
  }

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

  public void setGrantorPrincipalIsSet(boolean value) {
    if (!value) {
      this.grantorPrincipal = null;
    }
  }

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

  public java.util.Iterator<TSentryPrivilege> getPrivilegesIterator() {
    return (this.privileges == null) ? null : this.privileges.iterator();
  }

  public void addToPrivileges(TSentryPrivilege elem) {
    if (this.privileges == null) {
      this.privileges = new HashSet<TSentryPrivilege>();
    }
    this.privileges.add(elem);
  }

  public Set<TSentryPrivilege> getPrivileges() {
    return this.privileges;
  }

  public void setPrivileges(Set<TSentryPrivilege> privileges) {
    this.privileges = privileges;
  }

  public void unsetPrivileges() {
    this.privileges = null;
  }

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

  public void setPrivilegesIsSet(boolean value) {
    if (!value) {
      this.privileges = null;
    }
  }

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

  public java.util.Iterator<String> getGroupsIterator() {
    return (this.groups == null) ? null : this.groups.iterator();
  }

  public void addToGroups(String elem) {
    if (this.groups == null) {
      this.groups = new HashSet<String>();
    }
    this.groups.add(elem);
  }

  public Set<String> getGroups() {
    return this.groups;
  }

  public void setGroups(Set<String> groups) {
    this.groups = groups;
  }

  public void unsetGroups() {
    this.groups = null;
  }

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

  public void setGroupsIsSet(boolean value) {
    if (!value) {
      this.groups = null;
    }
  }

  public TSentryAuthorizable getAuthorizable() {
    return this.authorizable;
  }

  public void setAuthorizable(TSentryAuthorizable authorizable) {
    this.authorizable = authorizable;
  }

  public void unsetAuthorizable() {
    this.authorizable = null;
  }

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

  public void setAuthorizableIsSet(boolean value) {
    if (!value) {
      this.authorizable = null;
    }
  }

  public TSentryAuthorizable getNewAuthorizable() {
    return this.newAuthorizable;
  }

  public void setNewAuthorizable(TSentryAuthorizable newAuthorizable) {
    this.newAuthorizable = newAuthorizable;
  }

  public void unsetNewAuthorizable() {
    this.newAuthorizable = null;
  }

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

  public void setNewAuthorizableIsSet(boolean value) {
    if (!value) {
      this.newAuthorizable = null;
    }
  }

  public String getVersion() {
    return this.version;
  }

  public void setVersion(String version) {
    this.version = version;
  }

  public void unsetVersion() {
    this.version = null;
  }

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

  public void setVersionIsSet(boolean value) {
    if (!value) {
      this.version = null;
    }
  }

  public String getVersionComment() {
    return this.versionComment;
  }

  public void setVersionComment(String versionComment) {
    this.versionComment = versionComment;
  }

  public void unsetVersionComment() {
    this.versionComment = null;
  }

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

  public void setVersionCommentIsSet(boolean value) {
    if (!value) {
      this.versionComment = null;
    }
  }

  public TStoreSnapshot getSnapshot() {
    return this.snapshot;
  }

  public void setSnapshot(TStoreSnapshot snapshot) {
    this.snapshot = snapshot;
  }

  public void unsetSnapshot() {
    this.snapshot = null;
  }

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

  public void setSnapshotIsSet(boolean value) {
    if (!value) {
      this.snapshot = null;
    }
  }

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case STORE_OP:
      if (value == null) {
        unsetStoreOp();
      } else {
        setStoreOp((TSentryStoreOp)value);
      }
      break;

    case ROLE_NAME:
      if (value == null) {
        unsetRoleName();
      } else {
        setRoleName((String)value);
      }
      break;

    case GRANTOR_PRINCIPAL:
      if (value == null) {
        unsetGrantorPrincipal();
      } else {
        setGrantorPrincipal((String)value);
      }
      break;

    case PRIVILEGES:
      if (value == null) {
        unsetPrivileges();
      } else {
        setPrivileges((Set<TSentryPrivilege>)value);
      }
      break;

    case GROUPS:
      if (value == null) {
        unsetGroups();
      } else {
        setGroups((Set<String>)value);
      }
      break;

    case AUTHORIZABLE:
      if (value == null) {
        unsetAuthorizable();
      } else {
        setAuthorizable((TSentryAuthorizable)value);
      }
      break;

    case NEW_AUTHORIZABLE:
      if (value == null) {
        unsetNewAuthorizable();
      } else {
        setNewAuthorizable((TSentryAuthorizable)value);
      }
      break;

    case VERSION:
      if (value == null) {
        unsetVersion();
      } else {
        setVersion((String)value);
      }
      break;

    case VERSION_COMMENT:
      if (value == null) {
        unsetVersionComment();
      } else {
        setVersionComment((String)value);
      }
      break;

    case SNAPSHOT:
      if (value == null) {
        unsetSnapshot();
      } else {
        setSnapshot((TStoreSnapshot)value);
      }
      break;

    }
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case STORE_OP:
      return getStoreOp();

    case ROLE_NAME:
      return getRoleName();

    case GRANTOR_PRINCIPAL:
      return getGrantorPrincipal();

    case PRIVILEGES:
      return getPrivileges();

    case GROUPS:
      return getGroups();

    case AUTHORIZABLE:
      return getAuthorizable();

    case NEW_AUTHORIZABLE:
      return getNewAuthorizable();

    case VERSION:
      return getVersion();

    case VERSION_COMMENT:
      return getVersionComment();

    case SNAPSHOT:
      return getSnapshot();

    }
    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 STORE_OP:
      return isSetStoreOp();
    case ROLE_NAME:
      return isSetRoleName();
    case GRANTOR_PRINCIPAL:
      return isSetGrantorPrincipal();
    case PRIVILEGES:
      return isSetPrivileges();
    case GROUPS:
      return isSetGroups();
    case AUTHORIZABLE:
      return isSetAuthorizable();
    case NEW_AUTHORIZABLE:
      return isSetNewAuthorizable();
    case VERSION:
      return isSetVersion();
    case VERSION_COMMENT:
      return isSetVersionComment();
    case SNAPSHOT:
      return isSetSnapshot();
    }
    throw new IllegalStateException();
  }

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

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

    boolean this_present_storeOp = true && this.isSetStoreOp();
    boolean that_present_storeOp = true && that.isSetStoreOp();
    if (this_present_storeOp || that_present_storeOp) {
      if (!(this_present_storeOp && that_present_storeOp))
        return false;
      if (!this.storeOp.equals(that.storeOp))
        return false;
    }

    boolean this_present_roleName = true && this.isSetRoleName();
    boolean that_present_roleName = true && that.isSetRoleName();
    if (this_present_roleName || that_present_roleName) {
      if (!(this_present_roleName && that_present_roleName))
        return false;
      if (!this.roleName.equals(that.roleName))
        return false;
    }

    boolean this_present_grantorPrincipal = true && this.isSetGrantorPrincipal();
    boolean that_present_grantorPrincipal = true && that.isSetGrantorPrincipal();
    if (this_present_grantorPrincipal || that_present_grantorPrincipal) {
      if (!(this_present_grantorPrincipal && that_present_grantorPrincipal))
        return false;
      if (!this.grantorPrincipal.equals(that.grantorPrincipal))
        return false;
    }

    boolean this_present_privileges = true && this.isSetPrivileges();
    boolean that_present_privileges = true && that.isSetPrivileges();
    if (this_present_privileges || that_present_privileges) {
      if (!(this_present_privileges && that_present_privileges))
        return false;
      if (!this.privileges.equals(that.privileges))
        return false;
    }

    boolean this_present_groups = true && this.isSetGroups();
    boolean that_present_groups = true && that.isSetGroups();
    if (this_present_groups || that_present_groups) {
      if (!(this_present_groups && that_present_groups))
        return false;
      if (!this.groups.equals(that.groups))
        return false;
    }

    boolean this_present_authorizable = true && this.isSetAuthorizable();
    boolean that_present_authorizable = true && that.isSetAuthorizable();
    if (this_present_authorizable || that_present_authorizable) {
      if (!(this_present_authorizable && that_present_authorizable))
        return false;
      if (!this.authorizable.equals(that.authorizable))
        return false;
    }

    boolean this_present_newAuthorizable = true && this.isSetNewAuthorizable();
    boolean that_present_newAuthorizable = true && that.isSetNewAuthorizable();
    if (this_present_newAuthorizable || that_present_newAuthorizable) {
      if (!(this_present_newAuthorizable && that_present_newAuthorizable))
        return false;
      if (!this.newAuthorizable.equals(that.newAuthorizable))
        return false;
    }

    boolean this_present_version = true && this.isSetVersion();
    boolean that_present_version = true && that.isSetVersion();
    if (this_present_version || that_present_version) {
      if (!(this_present_version && that_present_version))
        return false;
      if (!this.version.equals(that.version))
        return false;
    }

    boolean this_present_versionComment = true && this.isSetVersionComment();
    boolean that_present_versionComment = true && that.isSetVersionComment();
    if (this_present_versionComment || that_present_versionComment) {
      if (!(this_present_versionComment && that_present_versionComment))
        return false;
      if (!this.versionComment.equals(that.versionComment))
        return false;
    }

    boolean this_present_snapshot = true && this.isSetSnapshot();
    boolean that_present_snapshot = true && that.isSetSnapshot();
    if (this_present_snapshot || that_present_snapshot) {
      if (!(this_present_snapshot && that_present_snapshot))
        return false;
      if (!this.snapshot.equals(that.snapshot))
        return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    HashCodeBuilder builder = new HashCodeBuilder();

    boolean present_storeOp = true && (isSetStoreOp());
    builder.append(present_storeOp);
    if (present_storeOp)
      builder.append(storeOp.getValue());

    boolean present_roleName = true && (isSetRoleName());
    builder.append(present_roleName);
    if (present_roleName)
      builder.append(roleName);

    boolean present_grantorPrincipal = true && (isSetGrantorPrincipal());
    builder.append(present_grantorPrincipal);
    if (present_grantorPrincipal)
      builder.append(grantorPrincipal);

    boolean present_privileges = true && (isSetPrivileges());
    builder.append(present_privileges);
    if (present_privileges)
      builder.append(privileges);

    boolean present_groups = true && (isSetGroups());
    builder.append(present_groups);
    if (present_groups)
      builder.append(groups);

    boolean present_authorizable = true && (isSetAuthorizable());
    builder.append(present_authorizable);
    if (present_authorizable)
      builder.append(authorizable);

    boolean present_newAuthorizable = true && (isSetNewAuthorizable());
    builder.append(present_newAuthorizable);
    if (present_newAuthorizable)
      builder.append(newAuthorizable);

    boolean present_version = true && (isSetVersion());
    builder.append(present_version);
    if (present_version)
      builder.append(version);

    boolean present_versionComment = true && (isSetVersionComment());
    builder.append(present_versionComment);
    if (present_versionComment)
      builder.append(versionComment);

    boolean present_snapshot = true && (isSetSnapshot());
    builder.append(present_snapshot);
    if (present_snapshot)
      builder.append(snapshot);

    return builder.toHashCode();
  }

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

    int lastComparison = 0;
    TSentryStoreRecord typedOther = (TSentryStoreRecord)other;

    lastComparison = Boolean.valueOf(isSetStoreOp()).compareTo(typedOther.isSetStoreOp());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetStoreOp()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.storeOp, typedOther.storeOp);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetRoleName()).compareTo(typedOther.isSetRoleName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetRoleName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.roleName, typedOther.roleName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetGrantorPrincipal()).compareTo(typedOther.isSetGrantorPrincipal());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetGrantorPrincipal()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.grantorPrincipal, typedOther.grantorPrincipal);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetPrivileges()).compareTo(typedOther.isSetPrivileges());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetPrivileges()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.privileges, typedOther.privileges);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetGroups()).compareTo(typedOther.isSetGroups());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetGroups()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.groups, typedOther.groups);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetAuthorizable()).compareTo(typedOther.isSetAuthorizable());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetAuthorizable()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.authorizable, typedOther.authorizable);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetNewAuthorizable()).compareTo(typedOther.isSetNewAuthorizable());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetNewAuthorizable()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.newAuthorizable, typedOther.newAuthorizable);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetVersion()).compareTo(typedOther.isSetVersion());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetVersion()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.version, typedOther.version);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetVersionComment()).compareTo(typedOther.isSetVersionComment());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetVersionComment()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.versionComment, typedOther.versionComment);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetSnapshot()).compareTo(typedOther.isSetSnapshot());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetSnapshot()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.snapshot, typedOther.snapshot);
      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("TSentryStoreRecord(");
    boolean first = true;

    sb.append("storeOp:");
    if (this.storeOp == null) {
      sb.append("null");
    } else {
      sb.append(this.storeOp);
    }
    first = false;
    if (isSetRoleName()) {
      if (!first) sb.append(", ");
      sb.append("roleName:");
      if (this.roleName == null) {
        sb.append("null");
      } else {
        sb.append(this.roleName);
      }
      first = false;
    }
    if (isSetGrantorPrincipal()) {
      if (!first) sb.append(", ");
      sb.append("grantorPrincipal:");
      if (this.grantorPrincipal == null) {
        sb.append("null");
      } else {
        sb.append(this.grantorPrincipal);
      }
      first = false;
    }
    if (isSetPrivileges()) {
      if (!first) sb.append(", ");
      sb.append("privileges:");
      if (this.privileges == null) {
        sb.append("null");
      } else {
        sb.append(this.privileges);
      }
      first = false;
    }
    if (isSetGroups()) {
      if (!first) sb.append(", ");
      sb.append("groups:");
      if (this.groups == null) {
        sb.append("null");
      } else {
        sb.append(this.groups);
      }
      first = false;
    }
    if (isSetAuthorizable()) {
      if (!first) sb.append(", ");
      sb.append("authorizable:");
      if (this.authorizable == null) {
        sb.append("null");
      } else {
        sb.append(this.authorizable);
      }
      first = false;
    }
    if (isSetNewAuthorizable()) {
      if (!first) sb.append(", ");
      sb.append("newAuthorizable:");
      if (this.newAuthorizable == null) {
        sb.append("null");
      } else {
        sb.append(this.newAuthorizable);
      }
      first = false;
    }
    if (isSetVersion()) {
      if (!first) sb.append(", ");
      sb.append("version:");
      if (this.version == null) {
        sb.append("null");
      } else {
        sb.append(this.version);
      }
      first = false;
    }
    if (isSetVersionComment()) {
      if (!first) sb.append(", ");
      sb.append("versionComment:");
      if (this.versionComment == null) {
        sb.append("null");
      } else {
        sb.append(this.versionComment);
      }
      first = false;
    }
    if (isSetSnapshot()) {
      if (!first) sb.append(", ");
      sb.append("snapshot:");
      if (this.snapshot == null) {
        sb.append("null");
      } else {
        sb.append(this.snapshot);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

    // check for sub-struct validity
    if (authorizable != null) {
      authorizable.validate();
    }
    if (newAuthorizable != null) {
      newAuthorizable.validate();
    }
    if (snapshot != null) {
      snapshot.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 {
      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 TSentryStoreRecordStandardSchemeFactory implements SchemeFactory {
    public TSentryStoreRecordStandardScheme getScheme() {
      return new TSentryStoreRecordStandardScheme();
    }
  }

  private static class TSentryStoreRecordStandardScheme extends StandardScheme<TSentryStoreRecord> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, TSentryStoreRecord 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: // STORE_OP
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.storeOp = TSentryStoreOp.findByValue(iprot.readI32());
              struct.setStoreOpIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // ROLE_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.roleName = iprot.readString();
              struct.setRoleNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // GRANTOR_PRINCIPAL
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.grantorPrincipal = iprot.readString();
              struct.setGrantorPrincipalIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // PRIVILEGES
            if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
              {
                org.apache.thrift.protocol.TSet _set56 = iprot.readSetBegin();
                struct.privileges = new HashSet<TSentryPrivilege>(2*_set56.size);
                for (int _i57 = 0; _i57 < _set56.size; ++_i57)
                {
                  TSentryPrivilege _elem58; // required
                  _elem58 = new TSentryPrivilege();
                  _elem58.read(iprot);
                  struct.privileges.add(_elem58);
                }
                iprot.readSetEnd();
              }
              struct.setPrivilegesIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // GROUPS
            if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
              {
                org.apache.thrift.protocol.TSet _set59 = iprot.readSetBegin();
                struct.groups = new HashSet<String>(2*_set59.size);
                for (int _i60 = 0; _i60 < _set59.size; ++_i60)
                {
                  String _elem61; // required
                  _elem61 = iprot.readString();
                  struct.groups.add(_elem61);
                }
                iprot.readSetEnd();
              }
              struct.setGroupsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // AUTHORIZABLE
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.authorizable = new TSentryAuthorizable();
              struct.authorizable.read(iprot);
              struct.setAuthorizableIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // NEW_AUTHORIZABLE
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.newAuthorizable = new TSentryAuthorizable();
              struct.newAuthorizable.read(iprot);
              struct.setNewAuthorizableIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // VERSION
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.version = iprot.readString();
              struct.setVersionIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // VERSION_COMMENT
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.versionComment = iprot.readString();
              struct.setVersionCommentIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // SNAPSHOT
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.snapshot = new TStoreSnapshot();
              struct.snapshot.read(iprot);
              struct.setSnapshotIsSet(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, TSentryStoreRecord struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.storeOp != null) {
        oprot.writeFieldBegin(STORE_OP_FIELD_DESC);
        oprot.writeI32(struct.storeOp.getValue());
        oprot.writeFieldEnd();
      }
      if (struct.roleName != null) {
        if (struct.isSetRoleName()) {
          oprot.writeFieldBegin(ROLE_NAME_FIELD_DESC);
          oprot.writeString(struct.roleName);
          oprot.writeFieldEnd();
        }
      }
      if (struct.grantorPrincipal != null) {
        if (struct.isSetGrantorPrincipal()) {
          oprot.writeFieldBegin(GRANTOR_PRINCIPAL_FIELD_DESC);
          oprot.writeString(struct.grantorPrincipal);
          oprot.writeFieldEnd();
        }
      }
      if (struct.privileges != null) {
        if (struct.isSetPrivileges()) {
          oprot.writeFieldBegin(PRIVILEGES_FIELD_DESC);
          {
            oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, struct.privileges.size()));
            for (TSentryPrivilege _iter62 : struct.privileges)
            {
              _iter62.write(oprot);
            }
            oprot.writeSetEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.groups != null) {
        if (struct.isSetGroups()) {
          oprot.writeFieldBegin(GROUPS_FIELD_DESC);
          {
            oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.groups.size()));
            for (String _iter63 : struct.groups)
            {
              oprot.writeString(_iter63);
            }
            oprot.writeSetEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.authorizable != null) {
        if (struct.isSetAuthorizable()) {
          oprot.writeFieldBegin(AUTHORIZABLE_FIELD_DESC);
          struct.authorizable.write(oprot);
          oprot.writeFieldEnd();
        }
      }
      if (struct.newAuthorizable != null) {
        if (struct.isSetNewAuthorizable()) {
          oprot.writeFieldBegin(NEW_AUTHORIZABLE_FIELD_DESC);
          struct.newAuthorizable.write(oprot);
          oprot.writeFieldEnd();
        }
      }
      if (struct.version != null) {
        if (struct.isSetVersion()) {
          oprot.writeFieldBegin(VERSION_FIELD_DESC);
          oprot.writeString(struct.version);
          oprot.writeFieldEnd();
        }
      }
      if (struct.versionComment != null) {
        if (struct.isSetVersionComment()) {
          oprot.writeFieldBegin(VERSION_COMMENT_FIELD_DESC);
          oprot.writeString(struct.versionComment);
          oprot.writeFieldEnd();
        }
      }
      if (struct.snapshot != null) {
        if (struct.isSetSnapshot()) {
          oprot.writeFieldBegin(SNAPSHOT_FIELD_DESC);
          struct.snapshot.write(oprot);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class TSentryStoreRecordTupleSchemeFactory implements SchemeFactory {
    public TSentryStoreRecordTupleScheme getScheme() {
      return new TSentryStoreRecordTupleScheme();
    }
  }

  private static class TSentryStoreRecordTupleScheme extends TupleScheme<TSentryStoreRecord> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, TSentryStoreRecord struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      oprot.writeI32(struct.storeOp.getValue());
      BitSet optionals = new BitSet();
      if (struct.isSetRoleName()) {
        optionals.set(0);
      }
      if (struct.isSetGrantorPrincipal()) {
        optionals.set(1);
      }
      if (struct.isSetPrivileges()) {
        optionals.set(2);
      }
      if (struct.isSetGroups()) {
        optionals.set(3);
      }
      if (struct.isSetAuthorizable()) {
        optionals.set(4);
      }
      if (struct.isSetNewAuthorizable()) {
        optionals.set(5);
      }
      if (struct.isSetVersion()) {
        optionals.set(6);
      }
      if (struct.isSetVersionComment()) {
        optionals.set(7);
      }
      if (struct.isSetSnapshot()) {
        optionals.set(8);
      }
      oprot.writeBitSet(optionals, 9);
      if (struct.isSetRoleName()) {
        oprot.writeString(struct.roleName);
      }
      if (struct.isSetGrantorPrincipal()) {
        oprot.writeString(struct.grantorPrincipal);
      }
      if (struct.isSetPrivileges()) {
        {
          oprot.writeI32(struct.privileges.size());
          for (TSentryPrivilege _iter64 : struct.privileges)
          {
            _iter64.write(oprot);
          }
        }
      }
      if (struct.isSetGroups()) {
        {
          oprot.writeI32(struct.groups.size());
          for (String _iter65 : struct.groups)
          {
            oprot.writeString(_iter65);
          }
        }
      }
      if (struct.isSetAuthorizable()) {
        struct.authorizable.write(oprot);
      }
      if (struct.isSetNewAuthorizable()) {
        struct.newAuthorizable.write(oprot);
      }
      if (struct.isSetVersion()) {
        oprot.writeString(struct.version);
      }
      if (struct.isSetVersionComment()) {
        oprot.writeString(struct.versionComment);
      }
      if (struct.isSetSnapshot()) {
        struct.snapshot.write(oprot);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, TSentryStoreRecord struct) throws org.apache.thrift.TException {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      struct.storeOp = TSentryStoreOp.findByValue(iprot.readI32());
      struct.setStoreOpIsSet(true);
      BitSet incoming = iprot.readBitSet(9);
      if (incoming.get(0)) {
        struct.roleName = iprot.readString();
        struct.setRoleNameIsSet(true);
      }
      if (incoming.get(1)) {
        struct.grantorPrincipal = iprot.readString();
        struct.setGrantorPrincipalIsSet(true);
      }
      if (incoming.get(2)) {
        {
          org.apache.thrift.protocol.TSet _set66 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.privileges = new HashSet<TSentryPrivilege>(2*_set66.size);
          for (int _i67 = 0; _i67 < _set66.size; ++_i67)
          {
            TSentryPrivilege _elem68; // required
            _elem68 = new TSentryPrivilege();
            _elem68.read(iprot);
            struct.privileges.add(_elem68);
          }
        }
        struct.setPrivilegesIsSet(true);
      }
      if (incoming.get(3)) {
        {
          org.apache.thrift.protocol.TSet _set69 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.groups = new HashSet<String>(2*_set69.size);
          for (int _i70 = 0; _i70 < _set69.size; ++_i70)
          {
            String _elem71; // required
            _elem71 = iprot.readString();
            struct.groups.add(_elem71);
          }
        }
        struct.setGroupsIsSet(true);
      }
      if (incoming.get(4)) {
        struct.authorizable = new TSentryAuthorizable();
        struct.authorizable.read(iprot);
        struct.setAuthorizableIsSet(true);
      }
      if (incoming.get(5)) {
        struct.newAuthorizable = new TSentryAuthorizable();
        struct.newAuthorizable.read(iprot);
        struct.setNewAuthorizableIsSet(true);
      }
      if (incoming.get(6)) {
        struct.version = iprot.readString();
        struct.setVersionIsSet(true);
      }
      if (incoming.get(7)) {
        struct.versionComment = iprot.readString();
        struct.setVersionCommentIsSet(true);
      }
      if (incoming.get(8)) {
        struct.snapshot = new TStoreSnapshot();
        struct.snapshot.read(iprot);
        struct.setSnapshotIsSet(true);
      }
    }
  }

}

