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

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

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

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

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)", date = "2016-01-12")
public class MetadataModel implements org.apache.thrift.TBase<MetadataModel, MetadataModel._Fields>, java.io.Serializable, Cloneable, Comparable<MetadataModel> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("MetadataModel");

  private static final org.apache.thrift.protocol.TField METADATA_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("metadataId", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField GATEWAY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("gatewayId", org.apache.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.thrift.protocol.TField USERNAME_FIELD_DESC = new org.apache.thrift.protocol.TField("username", org.apache.thrift.protocol.TType.STRING, (short)3);
  private static final org.apache.thrift.protocol.TField SHARED_USERS_FIELD_DESC = new org.apache.thrift.protocol.TField("sharedUsers", org.apache.thrift.protocol.TType.LIST, (short)4);
  private static final org.apache.thrift.protocol.TField SHARED_PUBLIC_FIELD_DESC = new org.apache.thrift.protocol.TField("sharedPublic", org.apache.thrift.protocol.TType.BOOL, (short)5);
  private static final org.apache.thrift.protocol.TField USER_FRIENDLY_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userFriendlyName", org.apache.thrift.protocol.TType.STRING, (short)6);
  private static final org.apache.thrift.protocol.TField USER_FRIENDLY_DESCRIPTION_FIELD_DESC = new org.apache.thrift.protocol.TField("userFriendlyDescription", org.apache.thrift.protocol.TType.STRING, (short)7);
  private static final org.apache.thrift.protocol.TField METADATA_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("metadataType", org.apache.thrift.protocol.TType.I32, (short)8);
  private static final org.apache.thrift.protocol.TField ASSOCIATED_ENTITY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("associatedEntityId", org.apache.thrift.protocol.TType.STRING, (short)9);
  private static final org.apache.thrift.protocol.TField CUSTOM_INFORMATION_FIELD_DESC = new org.apache.thrift.protocol.TField("customInformation", org.apache.thrift.protocol.TType.MAP, (short)10);

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

  private String metadataId; // optional
  private String gatewayId; // optional
  private String username; // optional
  private List<String> sharedUsers; // optional
  private boolean sharedPublic; // optional
  private String userFriendlyName; // optional
  private String userFriendlyDescription; // optional
  private MetadataType metadataType; // optional
  private String associatedEntityId; // optional
  private Map<String,String> customInformation; // 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 {
    METADATA_ID((short)1, "metadataId"),
    GATEWAY_ID((short)2, "gatewayId"),
    USERNAME((short)3, "username"),
    SHARED_USERS((short)4, "sharedUsers"),
    SHARED_PUBLIC((short)5, "sharedPublic"),
    USER_FRIENDLY_NAME((short)6, "userFriendlyName"),
    USER_FRIENDLY_DESCRIPTION((short)7, "userFriendlyDescription"),
    /**
     * 
     * @see MetadataType
     */
    METADATA_TYPE((short)8, "metadataType"),
    ASSOCIATED_ENTITY_ID((short)9, "associatedEntityId"),
    CUSTOM_INFORMATION((short)10, "customInformation");

    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: // METADATA_ID
          return METADATA_ID;
        case 2: // GATEWAY_ID
          return GATEWAY_ID;
        case 3: // USERNAME
          return USERNAME;
        case 4: // SHARED_USERS
          return SHARED_USERS;
        case 5: // SHARED_PUBLIC
          return SHARED_PUBLIC;
        case 6: // USER_FRIENDLY_NAME
          return USER_FRIENDLY_NAME;
        case 7: // USER_FRIENDLY_DESCRIPTION
          return USER_FRIENDLY_DESCRIPTION;
        case 8: // METADATA_TYPE
          return METADATA_TYPE;
        case 9: // ASSOCIATED_ENTITY_ID
          return ASSOCIATED_ENTITY_ID;
        case 10: // CUSTOM_INFORMATION
          return CUSTOM_INFORMATION;
        default:
          return null;
      }
    }

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

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

    private final short _thriftId;
    private final String _fieldName;

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

    public short getThriftFieldId() {
      return _thriftId;
    }

    public String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final int __SHAREDPUBLIC_ISSET_ID = 0;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.METADATA_ID,_Fields.GATEWAY_ID,_Fields.USERNAME,_Fields.SHARED_USERS,_Fields.SHARED_PUBLIC,_Fields.USER_FRIENDLY_NAME,_Fields.USER_FRIENDLY_DESCRIPTION,_Fields.METADATA_TYPE,_Fields.ASSOCIATED_ENTITY_ID,_Fields.CUSTOM_INFORMATION};
  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.METADATA_ID, new org.apache.thrift.meta_data.FieldMetaData("metadataId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.GATEWAY_ID, new org.apache.thrift.meta_data.FieldMetaData("gatewayId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.USERNAME, new org.apache.thrift.meta_data.FieldMetaData("username", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.SHARED_USERS, new org.apache.thrift.meta_data.FieldMetaData("sharedUsers", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
    tmpMap.put(_Fields.SHARED_PUBLIC, new org.apache.thrift.meta_data.FieldMetaData("sharedPublic", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.USER_FRIENDLY_NAME, new org.apache.thrift.meta_data.FieldMetaData("userFriendlyName", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.USER_FRIENDLY_DESCRIPTION, new org.apache.thrift.meta_data.FieldMetaData("userFriendlyDescription", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.METADATA_TYPE, new org.apache.thrift.meta_data.FieldMetaData("metadataType", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, MetadataType.class)));
    tmpMap.put(_Fields.ASSOCIATED_ENTITY_ID, new org.apache.thrift.meta_data.FieldMetaData("associatedEntityId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.CUSTOM_INFORMATION, new org.apache.thrift.meta_data.FieldMetaData("customInformation", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(MetadataModel.class, metaDataMap);
  }

  public MetadataModel() {
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public MetadataModel(MetadataModel other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetMetadataId()) {
      this.metadataId = other.metadataId;
    }
    if (other.isSetGatewayId()) {
      this.gatewayId = other.gatewayId;
    }
    if (other.isSetUsername()) {
      this.username = other.username;
    }
    if (other.isSetSharedUsers()) {
      List<String> __this__sharedUsers = new ArrayList<String>(other.sharedUsers);
      this.sharedUsers = __this__sharedUsers;
    }
    this.sharedPublic = other.sharedPublic;
    if (other.isSetUserFriendlyName()) {
      this.userFriendlyName = other.userFriendlyName;
    }
    if (other.isSetUserFriendlyDescription()) {
      this.userFriendlyDescription = other.userFriendlyDescription;
    }
    if (other.isSetMetadataType()) {
      this.metadataType = other.metadataType;
    }
    if (other.isSetAssociatedEntityId()) {
      this.associatedEntityId = other.associatedEntityId;
    }
    if (other.isSetCustomInformation()) {
      Map<String,String> __this__customInformation = new HashMap<String,String>(other.customInformation);
      this.customInformation = __this__customInformation;
    }
  }

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

  @Override
  public void clear() {
    this.metadataId = null;
    this.gatewayId = null;
    this.username = null;
    this.sharedUsers = null;
    setSharedPublicIsSet(false);
    this.sharedPublic = false;
    this.userFriendlyName = null;
    this.userFriendlyDescription = null;
    this.metadataType = null;
    this.associatedEntityId = null;
    this.customInformation = null;
  }

  public String getMetadataId() {
    return this.metadataId;
  }

  public void setMetadataId(String metadataId) {
    this.metadataId = metadataId;
  }

  public void unsetMetadataId() {
    this.metadataId = null;
  }

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

  public void setMetadataIdIsSet(boolean value) {
    if (!value) {
      this.metadataId = null;
    }
  }

  public String getGatewayId() {
    return this.gatewayId;
  }

  public void setGatewayId(String gatewayId) {
    this.gatewayId = gatewayId;
  }

  public void unsetGatewayId() {
    this.gatewayId = null;
  }

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

  public void setGatewayIdIsSet(boolean value) {
    if (!value) {
      this.gatewayId = null;
    }
  }

  public String getUsername() {
    return this.username;
  }

  public void setUsername(String username) {
    this.username = username;
  }

  public void unsetUsername() {
    this.username = null;
  }

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

  public void setUsernameIsSet(boolean value) {
    if (!value) {
      this.username = null;
    }
  }

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

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

  public void addToSharedUsers(String elem) {
    if (this.sharedUsers == null) {
      this.sharedUsers = new ArrayList<String>();
    }
    this.sharedUsers.add(elem);
  }

  public List<String> getSharedUsers() {
    return this.sharedUsers;
  }

  public void setSharedUsers(List<String> sharedUsers) {
    this.sharedUsers = sharedUsers;
  }

  public void unsetSharedUsers() {
    this.sharedUsers = null;
  }

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

  public void setSharedUsersIsSet(boolean value) {
    if (!value) {
      this.sharedUsers = null;
    }
  }

  public boolean isSharedPublic() {
    return this.sharedPublic;
  }

  public void setSharedPublic(boolean sharedPublic) {
    this.sharedPublic = sharedPublic;
    setSharedPublicIsSet(true);
  }

  public void unsetSharedPublic() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SHAREDPUBLIC_ISSET_ID);
  }

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

  public void setSharedPublicIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SHAREDPUBLIC_ISSET_ID, value);
  }

  public String getUserFriendlyName() {
    return this.userFriendlyName;
  }

  public void setUserFriendlyName(String userFriendlyName) {
    this.userFriendlyName = userFriendlyName;
  }

  public void unsetUserFriendlyName() {
    this.userFriendlyName = null;
  }

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

  public void setUserFriendlyNameIsSet(boolean value) {
    if (!value) {
      this.userFriendlyName = null;
    }
  }

  public String getUserFriendlyDescription() {
    return this.userFriendlyDescription;
  }

  public void setUserFriendlyDescription(String userFriendlyDescription) {
    this.userFriendlyDescription = userFriendlyDescription;
  }

  public void unsetUserFriendlyDescription() {
    this.userFriendlyDescription = null;
  }

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

  public void setUserFriendlyDescriptionIsSet(boolean value) {
    if (!value) {
      this.userFriendlyDescription = null;
    }
  }

  /**
   * 
   * @see MetadataType
   */
  public MetadataType getMetadataType() {
    return this.metadataType;
  }

  /**
   * 
   * @see MetadataType
   */
  public void setMetadataType(MetadataType metadataType) {
    this.metadataType = metadataType;
  }

  public void unsetMetadataType() {
    this.metadataType = null;
  }

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

  public void setMetadataTypeIsSet(boolean value) {
    if (!value) {
      this.metadataType = null;
    }
  }

  public String getAssociatedEntityId() {
    return this.associatedEntityId;
  }

  public void setAssociatedEntityId(String associatedEntityId) {
    this.associatedEntityId = associatedEntityId;
  }

  public void unsetAssociatedEntityId() {
    this.associatedEntityId = null;
  }

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

  public void setAssociatedEntityIdIsSet(boolean value) {
    if (!value) {
      this.associatedEntityId = null;
    }
  }

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

  public void putToCustomInformation(String key, String val) {
    if (this.customInformation == null) {
      this.customInformation = new HashMap<String,String>();
    }
    this.customInformation.put(key, val);
  }

  public Map<String,String> getCustomInformation() {
    return this.customInformation;
  }

  public void setCustomInformation(Map<String,String> customInformation) {
    this.customInformation = customInformation;
  }

  public void unsetCustomInformation() {
    this.customInformation = null;
  }

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

  public void setCustomInformationIsSet(boolean value) {
    if (!value) {
      this.customInformation = null;
    }
  }

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case METADATA_ID:
      if (value == null) {
        unsetMetadataId();
      } else {
        setMetadataId((String)value);
      }
      break;

    case GATEWAY_ID:
      if (value == null) {
        unsetGatewayId();
      } else {
        setGatewayId((String)value);
      }
      break;

    case USERNAME:
      if (value == null) {
        unsetUsername();
      } else {
        setUsername((String)value);
      }
      break;

    case SHARED_USERS:
      if (value == null) {
        unsetSharedUsers();
      } else {
        setSharedUsers((List<String>)value);
      }
      break;

    case SHARED_PUBLIC:
      if (value == null) {
        unsetSharedPublic();
      } else {
        setSharedPublic((Boolean)value);
      }
      break;

    case USER_FRIENDLY_NAME:
      if (value == null) {
        unsetUserFriendlyName();
      } else {
        setUserFriendlyName((String)value);
      }
      break;

    case USER_FRIENDLY_DESCRIPTION:
      if (value == null) {
        unsetUserFriendlyDescription();
      } else {
        setUserFriendlyDescription((String)value);
      }
      break;

    case METADATA_TYPE:
      if (value == null) {
        unsetMetadataType();
      } else {
        setMetadataType((MetadataType)value);
      }
      break;

    case ASSOCIATED_ENTITY_ID:
      if (value == null) {
        unsetAssociatedEntityId();
      } else {
        setAssociatedEntityId((String)value);
      }
      break;

    case CUSTOM_INFORMATION:
      if (value == null) {
        unsetCustomInformation();
      } else {
        setCustomInformation((Map<String,String>)value);
      }
      break;

    }
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case METADATA_ID:
      return getMetadataId();

    case GATEWAY_ID:
      return getGatewayId();

    case USERNAME:
      return getUsername();

    case SHARED_USERS:
      return getSharedUsers();

    case SHARED_PUBLIC:
      return isSharedPublic();

    case USER_FRIENDLY_NAME:
      return getUserFriendlyName();

    case USER_FRIENDLY_DESCRIPTION:
      return getUserFriendlyDescription();

    case METADATA_TYPE:
      return getMetadataType();

    case ASSOCIATED_ENTITY_ID:
      return getAssociatedEntityId();

    case CUSTOM_INFORMATION:
      return getCustomInformation();

    }
    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 METADATA_ID:
      return isSetMetadataId();
    case GATEWAY_ID:
      return isSetGatewayId();
    case USERNAME:
      return isSetUsername();
    case SHARED_USERS:
      return isSetSharedUsers();
    case SHARED_PUBLIC:
      return isSetSharedPublic();
    case USER_FRIENDLY_NAME:
      return isSetUserFriendlyName();
    case USER_FRIENDLY_DESCRIPTION:
      return isSetUserFriendlyDescription();
    case METADATA_TYPE:
      return isSetMetadataType();
    case ASSOCIATED_ENTITY_ID:
      return isSetAssociatedEntityId();
    case CUSTOM_INFORMATION:
      return isSetCustomInformation();
    }
    throw new IllegalStateException();
  }

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

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

    boolean this_present_metadataId = true && this.isSetMetadataId();
    boolean that_present_metadataId = true && that.isSetMetadataId();
    if (this_present_metadataId || that_present_metadataId) {
      if (!(this_present_metadataId && that_present_metadataId))
        return false;
      if (!this.metadataId.equals(that.metadataId))
        return false;
    }

    boolean this_present_gatewayId = true && this.isSetGatewayId();
    boolean that_present_gatewayId = true && that.isSetGatewayId();
    if (this_present_gatewayId || that_present_gatewayId) {
      if (!(this_present_gatewayId && that_present_gatewayId))
        return false;
      if (!this.gatewayId.equals(that.gatewayId))
        return false;
    }

    boolean this_present_username = true && this.isSetUsername();
    boolean that_present_username = true && that.isSetUsername();
    if (this_present_username || that_present_username) {
      if (!(this_present_username && that_present_username))
        return false;
      if (!this.username.equals(that.username))
        return false;
    }

    boolean this_present_sharedUsers = true && this.isSetSharedUsers();
    boolean that_present_sharedUsers = true && that.isSetSharedUsers();
    if (this_present_sharedUsers || that_present_sharedUsers) {
      if (!(this_present_sharedUsers && that_present_sharedUsers))
        return false;
      if (!this.sharedUsers.equals(that.sharedUsers))
        return false;
    }

    boolean this_present_sharedPublic = true && this.isSetSharedPublic();
    boolean that_present_sharedPublic = true && that.isSetSharedPublic();
    if (this_present_sharedPublic || that_present_sharedPublic) {
      if (!(this_present_sharedPublic && that_present_sharedPublic))
        return false;
      if (this.sharedPublic != that.sharedPublic)
        return false;
    }

    boolean this_present_userFriendlyName = true && this.isSetUserFriendlyName();
    boolean that_present_userFriendlyName = true && that.isSetUserFriendlyName();
    if (this_present_userFriendlyName || that_present_userFriendlyName) {
      if (!(this_present_userFriendlyName && that_present_userFriendlyName))
        return false;
      if (!this.userFriendlyName.equals(that.userFriendlyName))
        return false;
    }

    boolean this_present_userFriendlyDescription = true && this.isSetUserFriendlyDescription();
    boolean that_present_userFriendlyDescription = true && that.isSetUserFriendlyDescription();
    if (this_present_userFriendlyDescription || that_present_userFriendlyDescription) {
      if (!(this_present_userFriendlyDescription && that_present_userFriendlyDescription))
        return false;
      if (!this.userFriendlyDescription.equals(that.userFriendlyDescription))
        return false;
    }

    boolean this_present_metadataType = true && this.isSetMetadataType();
    boolean that_present_metadataType = true && that.isSetMetadataType();
    if (this_present_metadataType || that_present_metadataType) {
      if (!(this_present_metadataType && that_present_metadataType))
        return false;
      if (!this.metadataType.equals(that.metadataType))
        return false;
    }

    boolean this_present_associatedEntityId = true && this.isSetAssociatedEntityId();
    boolean that_present_associatedEntityId = true && that.isSetAssociatedEntityId();
    if (this_present_associatedEntityId || that_present_associatedEntityId) {
      if (!(this_present_associatedEntityId && that_present_associatedEntityId))
        return false;
      if (!this.associatedEntityId.equals(that.associatedEntityId))
        return false;
    }

    boolean this_present_customInformation = true && this.isSetCustomInformation();
    boolean that_present_customInformation = true && that.isSetCustomInformation();
    if (this_present_customInformation || that_present_customInformation) {
      if (!(this_present_customInformation && that_present_customInformation))
        return false;
      if (!this.customInformation.equals(that.customInformation))
        return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    List<Object> list = new ArrayList<Object>();

    boolean present_metadataId = true && (isSetMetadataId());
    list.add(present_metadataId);
    if (present_metadataId)
      list.add(metadataId);

    boolean present_gatewayId = true && (isSetGatewayId());
    list.add(present_gatewayId);
    if (present_gatewayId)
      list.add(gatewayId);

    boolean present_username = true && (isSetUsername());
    list.add(present_username);
    if (present_username)
      list.add(username);

    boolean present_sharedUsers = true && (isSetSharedUsers());
    list.add(present_sharedUsers);
    if (present_sharedUsers)
      list.add(sharedUsers);

    boolean present_sharedPublic = true && (isSetSharedPublic());
    list.add(present_sharedPublic);
    if (present_sharedPublic)
      list.add(sharedPublic);

    boolean present_userFriendlyName = true && (isSetUserFriendlyName());
    list.add(present_userFriendlyName);
    if (present_userFriendlyName)
      list.add(userFriendlyName);

    boolean present_userFriendlyDescription = true && (isSetUserFriendlyDescription());
    list.add(present_userFriendlyDescription);
    if (present_userFriendlyDescription)
      list.add(userFriendlyDescription);

    boolean present_metadataType = true && (isSetMetadataType());
    list.add(present_metadataType);
    if (present_metadataType)
      list.add(metadataType.getValue());

    boolean present_associatedEntityId = true && (isSetAssociatedEntityId());
    list.add(present_associatedEntityId);
    if (present_associatedEntityId)
      list.add(associatedEntityId);

    boolean present_customInformation = true && (isSetCustomInformation());
    list.add(present_customInformation);
    if (present_customInformation)
      list.add(customInformation);

    return list.hashCode();
  }

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

    int lastComparison = 0;

    lastComparison = Boolean.valueOf(isSetMetadataId()).compareTo(other.isSetMetadataId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetMetadataId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.metadataId, other.metadataId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetGatewayId()).compareTo(other.isSetGatewayId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetGatewayId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.gatewayId, other.gatewayId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetUsername()).compareTo(other.isSetUsername());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetUsername()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.username, other.username);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetSharedUsers()).compareTo(other.isSetSharedUsers());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetSharedUsers()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sharedUsers, other.sharedUsers);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetSharedPublic()).compareTo(other.isSetSharedPublic());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetSharedPublic()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sharedPublic, other.sharedPublic);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetUserFriendlyName()).compareTo(other.isSetUserFriendlyName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetUserFriendlyName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userFriendlyName, other.userFriendlyName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetUserFriendlyDescription()).compareTo(other.isSetUserFriendlyDescription());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetUserFriendlyDescription()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userFriendlyDescription, other.userFriendlyDescription);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetMetadataType()).compareTo(other.isSetMetadataType());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetMetadataType()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.metadataType, other.metadataType);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetAssociatedEntityId()).compareTo(other.isSetAssociatedEntityId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetAssociatedEntityId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.associatedEntityId, other.associatedEntityId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetCustomInformation()).compareTo(other.isSetCustomInformation());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetCustomInformation()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.customInformation, other.customInformation);
      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("MetadataModel(");
    boolean first = true;

    if (isSetMetadataId()) {
      sb.append("metadataId:");
      if (this.metadataId == null) {
        sb.append("null");
      } else {
        sb.append(this.metadataId);
      }
      first = false;
    }
    if (isSetGatewayId()) {
      if (!first) sb.append(", ");
      sb.append("gatewayId:");
      if (this.gatewayId == null) {
        sb.append("null");
      } else {
        sb.append(this.gatewayId);
      }
      first = false;
    }
    if (isSetUsername()) {
      if (!first) sb.append(", ");
      sb.append("username:");
      if (this.username == null) {
        sb.append("null");
      } else {
        sb.append(this.username);
      }
      first = false;
    }
    if (isSetSharedUsers()) {
      if (!first) sb.append(", ");
      sb.append("sharedUsers:");
      if (this.sharedUsers == null) {
        sb.append("null");
      } else {
        sb.append(this.sharedUsers);
      }
      first = false;
    }
    if (isSetSharedPublic()) {
      if (!first) sb.append(", ");
      sb.append("sharedPublic:");
      sb.append(this.sharedPublic);
      first = false;
    }
    if (isSetUserFriendlyName()) {
      if (!first) sb.append(", ");
      sb.append("userFriendlyName:");
      if (this.userFriendlyName == null) {
        sb.append("null");
      } else {
        sb.append(this.userFriendlyName);
      }
      first = false;
    }
    if (isSetUserFriendlyDescription()) {
      if (!first) sb.append(", ");
      sb.append("userFriendlyDescription:");
      if (this.userFriendlyDescription == null) {
        sb.append("null");
      } else {
        sb.append(this.userFriendlyDescription);
      }
      first = false;
    }
    if (isSetMetadataType()) {
      if (!first) sb.append(", ");
      sb.append("metadataType:");
      if (this.metadataType == null) {
        sb.append("null");
      } else {
        sb.append(this.metadataType);
      }
      first = false;
    }
    if (isSetAssociatedEntityId()) {
      if (!first) sb.append(", ");
      sb.append("associatedEntityId:");
      if (this.associatedEntityId == null) {
        sb.append("null");
      } else {
        sb.append(this.associatedEntityId);
      }
      first = false;
    }
    if (isSetCustomInformation()) {
      if (!first) sb.append(", ");
      sb.append("customInformation:");
      if (this.customInformation == null) {
        sb.append("null");
      } else {
        sb.append(this.customInformation);
      }
      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, 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 MetadataModelStandardSchemeFactory implements SchemeFactory {
    public MetadataModelStandardScheme getScheme() {
      return new MetadataModelStandardScheme();
    }
  }

  private static class MetadataModelStandardScheme extends StandardScheme<MetadataModel> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, MetadataModel 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: // METADATA_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.metadataId = iprot.readString();
              struct.setMetadataIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // GATEWAY_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.gatewayId = iprot.readString();
              struct.setGatewayIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // USERNAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.username = iprot.readString();
              struct.setUsernameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // SHARED_USERS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list0 = iprot.readListBegin();
                struct.sharedUsers = new ArrayList<String>(_list0.size);
                String _elem1;
                for (int _i2 = 0; _i2 < _list0.size; ++_i2)
                {
                  _elem1 = iprot.readString();
                  struct.sharedUsers.add(_elem1);
                }
                iprot.readListEnd();
              }
              struct.setSharedUsersIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // SHARED_PUBLIC
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.sharedPublic = iprot.readBool();
              struct.setSharedPublicIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // USER_FRIENDLY_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.userFriendlyName = iprot.readString();
              struct.setUserFriendlyNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // USER_FRIENDLY_DESCRIPTION
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.userFriendlyDescription = iprot.readString();
              struct.setUserFriendlyDescriptionIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // METADATA_TYPE
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.metadataType = org.apache.airavata.model.data.metadata.MetadataType.findByValue(iprot.readI32());
              struct.setMetadataTypeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // ASSOCIATED_ENTITY_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.associatedEntityId = iprot.readString();
              struct.setAssociatedEntityIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // CUSTOM_INFORMATION
            if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
              {
                org.apache.thrift.protocol.TMap _map3 = iprot.readMapBegin();
                struct.customInformation = new HashMap<String,String>(2*_map3.size);
                String _key4;
                String _val5;
                for (int _i6 = 0; _i6 < _map3.size; ++_i6)
                {
                  _key4 = iprot.readString();
                  _val5 = iprot.readString();
                  struct.customInformation.put(_key4, _val5);
                }
                iprot.readMapEnd();
              }
              struct.setCustomInformationIsSet(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, MetadataModel struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.metadataId != null) {
        if (struct.isSetMetadataId()) {
          oprot.writeFieldBegin(METADATA_ID_FIELD_DESC);
          oprot.writeString(struct.metadataId);
          oprot.writeFieldEnd();
        }
      }
      if (struct.gatewayId != null) {
        if (struct.isSetGatewayId()) {
          oprot.writeFieldBegin(GATEWAY_ID_FIELD_DESC);
          oprot.writeString(struct.gatewayId);
          oprot.writeFieldEnd();
        }
      }
      if (struct.username != null) {
        if (struct.isSetUsername()) {
          oprot.writeFieldBegin(USERNAME_FIELD_DESC);
          oprot.writeString(struct.username);
          oprot.writeFieldEnd();
        }
      }
      if (struct.sharedUsers != null) {
        if (struct.isSetSharedUsers()) {
          oprot.writeFieldBegin(SHARED_USERS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.sharedUsers.size()));
            for (String _iter7 : struct.sharedUsers)
            {
              oprot.writeString(_iter7);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetSharedPublic()) {
        oprot.writeFieldBegin(SHARED_PUBLIC_FIELD_DESC);
        oprot.writeBool(struct.sharedPublic);
        oprot.writeFieldEnd();
      }
      if (struct.userFriendlyName != null) {
        if (struct.isSetUserFriendlyName()) {
          oprot.writeFieldBegin(USER_FRIENDLY_NAME_FIELD_DESC);
          oprot.writeString(struct.userFriendlyName);
          oprot.writeFieldEnd();
        }
      }
      if (struct.userFriendlyDescription != null) {
        if (struct.isSetUserFriendlyDescription()) {
          oprot.writeFieldBegin(USER_FRIENDLY_DESCRIPTION_FIELD_DESC);
          oprot.writeString(struct.userFriendlyDescription);
          oprot.writeFieldEnd();
        }
      }
      if (struct.metadataType != null) {
        if (struct.isSetMetadataType()) {
          oprot.writeFieldBegin(METADATA_TYPE_FIELD_DESC);
          oprot.writeI32(struct.metadataType.getValue());
          oprot.writeFieldEnd();
        }
      }
      if (struct.associatedEntityId != null) {
        if (struct.isSetAssociatedEntityId()) {
          oprot.writeFieldBegin(ASSOCIATED_ENTITY_ID_FIELD_DESC);
          oprot.writeString(struct.associatedEntityId);
          oprot.writeFieldEnd();
        }
      }
      if (struct.customInformation != null) {
        if (struct.isSetCustomInformation()) {
          oprot.writeFieldBegin(CUSTOM_INFORMATION_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.customInformation.size()));
            for (Map.Entry<String, String> _iter8 : struct.customInformation.entrySet())
            {
              oprot.writeString(_iter8.getKey());
              oprot.writeString(_iter8.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class MetadataModelTupleSchemeFactory implements SchemeFactory {
    public MetadataModelTupleScheme getScheme() {
      return new MetadataModelTupleScheme();
    }
  }

  private static class MetadataModelTupleScheme extends TupleScheme<MetadataModel> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, MetadataModel struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      BitSet optionals = new BitSet();
      if (struct.isSetMetadataId()) {
        optionals.set(0);
      }
      if (struct.isSetGatewayId()) {
        optionals.set(1);
      }
      if (struct.isSetUsername()) {
        optionals.set(2);
      }
      if (struct.isSetSharedUsers()) {
        optionals.set(3);
      }
      if (struct.isSetSharedPublic()) {
        optionals.set(4);
      }
      if (struct.isSetUserFriendlyName()) {
        optionals.set(5);
      }
      if (struct.isSetUserFriendlyDescription()) {
        optionals.set(6);
      }
      if (struct.isSetMetadataType()) {
        optionals.set(7);
      }
      if (struct.isSetAssociatedEntityId()) {
        optionals.set(8);
      }
      if (struct.isSetCustomInformation()) {
        optionals.set(9);
      }
      oprot.writeBitSet(optionals, 10);
      if (struct.isSetMetadataId()) {
        oprot.writeString(struct.metadataId);
      }
      if (struct.isSetGatewayId()) {
        oprot.writeString(struct.gatewayId);
      }
      if (struct.isSetUsername()) {
        oprot.writeString(struct.username);
      }
      if (struct.isSetSharedUsers()) {
        {
          oprot.writeI32(struct.sharedUsers.size());
          for (String _iter9 : struct.sharedUsers)
          {
            oprot.writeString(_iter9);
          }
        }
      }
      if (struct.isSetSharedPublic()) {
        oprot.writeBool(struct.sharedPublic);
      }
      if (struct.isSetUserFriendlyName()) {
        oprot.writeString(struct.userFriendlyName);
      }
      if (struct.isSetUserFriendlyDescription()) {
        oprot.writeString(struct.userFriendlyDescription);
      }
      if (struct.isSetMetadataType()) {
        oprot.writeI32(struct.metadataType.getValue());
      }
      if (struct.isSetAssociatedEntityId()) {
        oprot.writeString(struct.associatedEntityId);
      }
      if (struct.isSetCustomInformation()) {
        {
          oprot.writeI32(struct.customInformation.size());
          for (Map.Entry<String, String> _iter10 : struct.customInformation.entrySet())
          {
            oprot.writeString(_iter10.getKey());
            oprot.writeString(_iter10.getValue());
          }
        }
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, MetadataModel struct) throws org.apache.thrift.TException {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      BitSet incoming = iprot.readBitSet(10);
      if (incoming.get(0)) {
        struct.metadataId = iprot.readString();
        struct.setMetadataIdIsSet(true);
      }
      if (incoming.get(1)) {
        struct.gatewayId = iprot.readString();
        struct.setGatewayIdIsSet(true);
      }
      if (incoming.get(2)) {
        struct.username = iprot.readString();
        struct.setUsernameIsSet(true);
      }
      if (incoming.get(3)) {
        {
          org.apache.thrift.protocol.TList _list11 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.sharedUsers = new ArrayList<String>(_list11.size);
          String _elem12;
          for (int _i13 = 0; _i13 < _list11.size; ++_i13)
          {
            _elem12 = iprot.readString();
            struct.sharedUsers.add(_elem12);
          }
        }
        struct.setSharedUsersIsSet(true);
      }
      if (incoming.get(4)) {
        struct.sharedPublic = iprot.readBool();
        struct.setSharedPublicIsSet(true);
      }
      if (incoming.get(5)) {
        struct.userFriendlyName = iprot.readString();
        struct.setUserFriendlyNameIsSet(true);
      }
      if (incoming.get(6)) {
        struct.userFriendlyDescription = iprot.readString();
        struct.setUserFriendlyDescriptionIsSet(true);
      }
      if (incoming.get(7)) {
        struct.metadataType = org.apache.airavata.model.data.metadata.MetadataType.findByValue(iprot.readI32());
        struct.setMetadataTypeIsSet(true);
      }
      if (incoming.get(8)) {
        struct.associatedEntityId = iprot.readString();
        struct.setAssociatedEntityIdIsSet(true);
      }
      if (incoming.get(9)) {
        {
          org.apache.thrift.protocol.TMap _map14 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.customInformation = new HashMap<String,String>(2*_map14.size);
          String _key15;
          String _val16;
          for (int _i17 = 0; _i17 < _map14.size; ++_i17)
          {
            _key15 = iprot.readString();
            _val16 = iprot.readString();
            struct.customInformation.put(_key15, _val16);
          }
        }
        struct.setCustomInformationIsSet(true);
      }
    }
  }

}

